Viewing or Editing their own Profile who is currently login

Viewed 31

I am editing profile using Django framework. The problem lies where the user login can see the profile of other user when they change the id in the web address. Could someone help me so that I can only view the user's profile who is login and if they change the id they will receive an error. Thanks

Edit User Profile

@login_required(login_url = 'signin')
@user_passes_test(check_role_super)
def sa_profile_edit(request, user_id=None):

    user = get_object_or_404(User, pk=user_id)
    user_profile = get_object_or_404(userMember, pk=user_id)
    if request.method == 'POST':
        form = UserFormAdmin(request.POST or None, instance=user)
        form_profile = MemberForm(request.POST or None, instance=user_profile)
    else:
        form = UserFormAdmin(instance=user)
        form_profile = MemberForm(instance=user_profile)       
    context = {
        'form': form,
        'user': user,
        'form_profile': form_profile,
        'user_profile': user_profile
     }
    return render(request, 'pages/sa_editProfile.html', context)

If role is super

def check_role_super(user):
    if user.role == 3:
        return True
    else:
        raise PermissionDenied

Model

class User(AbstractBaseUser):
    MEMBER = 1
    ADMIN = 2
    SUPERADMIN = 3
    ROLE_CHOICE = (
        (MEMBER, 'Member'),
        (ADMIN, 'Admin'),
        (SUPERADMIN, 'Super Admin')
    )

    ACTIVE = 1
    DELETED = 2
    DEACTIVATED = 3

    STATUS = (
        (ACTIVE, 'Active'),
        (DELETED, 'Deleted'),
        (DEACTIVATED, 'Deactivated')
    )

    first_name = models.CharField(max_length=50)
    middle_name = models.CharField(max_length=50, default="Some String")
    last_name = models.CharField(max_length=50)
    username = models.CharField(max_length=50, unique=True)
    email = models.EmailField(max_length=100, unique=True)
    mobile_number = models.CharField(max_length = 100, db_index=True, null = True, 
validators=[
    
            RegexValidator(
                regex='^(\+\d{1,3})?,?\s?\d{8,13}',
                message='Phone number must not consist of space and requires country 
code. eg : +639171234567',
            ),
        ])
    password = models.CharField(max_length = 100,validators=[MinLengthValidator(8),
        
        ])
    role = models.PositiveSmallIntegerField(choices=ROLE_CHOICE, blank=True, null=True)
    status = models.PositiveSmallIntegerField(choices=STATUS, blank=True, null=True)

# required fields
    date_joined = models.DateTimeField(auto_now_add=True)
    last_login = models.DateTimeField(auto_now_add=True)
    created_date= models.DateTimeField(auto_now_add=True)
    modified_date = models.DateTimeField(auto_now_add=True)
    is_admin = models.BooleanField(default=False)
    is_staff = models.BooleanField(default=False)
    is_active = models.BooleanField(default=False)
    is_superadmin = models.BooleanField(default=False)

    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = ['email', 'first_name', 'middle_name', 'last_name', 'mobile_number']

    objects = UserManager()

    def __str__(self):
        return self.username

    def has_perm(self, perm, obj=None):
        return self.is_admin

    def has_module_perms(self, app_label):
        return True

    def get_role(self):
        if self.role == 1:
            user_role = 'Member'
        elif self.role == 2:
            user_role = 'Admin'
        elif self.role == 3:
            user_role = 'Super Admin'
        return user_role

    def get_status(self):
        if self.status == 1:
            user_status = 'Active'
        elif self.status == 2:
            user_status = 'Deleted'
        elif self.status == 3:
            user_status = 'Deactivated'
        return user_status

class userMember(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
    birthdate = models.DateField(blank=True, null=True)
    profile_picture = models.ImageField(upload_to='users/profile_pictures', blank=True, null=True)
    cover_color = ColorField(format='hexa', blank=True, null=True)
    upload_id = models.ImageField(upload_to='member/id', blank=True, null=True)
    created_at = models.DateTimeField(auto_now=True)
    modified_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.user.username
3 Answers

You can get the current user from the request instead, replace user = get_object_or_404(User, pk=user_id) with:

user = request.user
if not user.is_authenticated:
    raise Http404()

========= view.py ===========

# User Profile Update
def ProfileView(request):
    if request.user.is_authenticated:
        form =UserProfileChangeForm(instance=request.user)
        context = {'form':form}
        if request.method == 'POST':
            form =UserProfileChangeForm(request.POST,instance=request.user)
            if form.is_valid():
                form.save()
                messages.info(request,'Profile Successfully Updated')
                return redirect('/profile/')
            else:
                form =UserProfileChangeForm(instance=request.user)
                user_data = request.user
                context = {'form':form,'user_data':user_data}
                return rend

er(request,'profile.html',context)

======= form.py ========

from django.contrib.auth.forms import UserChangeForm
    
    # User Profile
    class UserProfileChangeForm(UserChangeForm):
        password =None
        class Meta:
            model = User
            fields = ['username','first_name','last_name','email']
            widgets = {
    
            'username':forms.TextInput(attrs={'class':'form-control','placeholder':'Enter Username'}),
    
            'first_name':forms.TextInput(attrs={'class':'form-control','placeholder':'Enter First Name'}),
    
            'last_name':forms.TextInput(attrs={'class':'form-control','placeholder':'Enter Last Name'}),
    
            'email':forms.TextInput(attrs={'class':'form-control','placeholder':'Enter E-Mail'}),
    
        }

you should implement class with UUID concept. UUID meant to protect url address. but as short and not ideal solution you can overwrite id in your code by request.user.id lets say logged in user has id=3 and he tries to change it to id=4 and then view function will get called. but you can overwrite that id by as i said above and he ll end up seeing his profile anyways. but URL WILL display wrong id so this is not a good option.

Related