djangodjango-1.5

How to save records and get records on behalf of another user


I'm working on a Django 1.5 Project.

The application contains the user hierarchy of

Owner
Admin
Viewer
  • Owner owns all the data in the database.
  • Admin users are created by the owner and have different login credentials. Can add/edit/delete data under Owner.
  • Viewer users are created by the owner and have different login credentials. Can view data created under the Owner.

Users model have a field is_shared (boolean) to identify main user and shared user and access_level is mapped in another model MultiUser.

I have thought of to implement it in the way

  1. Update all viewsets and put check in get_queryset.
  2. where first check will be made if user has is_shared=True
  3. then check in MultiUser model,
  4. get the user from MultiUser and then filter records on behalf of the user.

But this will require changes throughout the application viewsets.

Is there a way to do this without making changes to the whole application. May be middleware.

Edit 2: MultiUser model

class MultiUser(models.Model):
    user = models.ForeignKey(User, related_name='owner_user')
    shared_user = models.ForeignKey(User, related_name='shared_user')
    access_level = models.CharField(max_length=50)

Solution

  • I solved this by creating a middleware with content

    class MultiUserMiddleware(object):
        def process_request(self, request):
            """
            Check if user profile is is_shared=True
            If user is a shared user, get owner user from multi user
            and assign owner user to request.user
    
            Any multi user profile created by the owner user will work on behalf of the owner user
            """
    
            user = request.user
            if not user.is_anonymous():
                # if request.path in settings.MUTLIUSER_ALLOWED_PATH:
                #     return None
    
                # Search using wildcard
                if any(fnmatch(request.path, p) for p in settings.MUTLIUSER_ALLOWED_PATH):
                    return None
    
                try:
                    if user.profile.get().is_shared:
                        owner = MultiUser.objects.filter(shared_user=user)[0].user
                        request.user = owner
                except:
                    return None
    
            return None
    

    This middleware check for if the user's account is a shared user based on is_shared and then change the request.user with the owner user object. This also prevents changing the request owner for specific paths defined in the settings file (Ex., profile, change_password, etc).