Extending url-route-view logic

The silly simple example. Let's show view only for user whos are admins.

Flask

Flasks Patterns suggest to create a new decorator for such need or use an existing one (roles_required):

def login_required(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if g.user is None:
            return redirect(url_for('login', next=request.url))
        return f(*args, **kwargs)
    return decorated_function

@app.route('/dashboard')
@login_required
@roles_required('admin', 'editor')
def dashboard():
    return 'Dashboard'

Django

View level access control done via using mixins or a decorators.

class WorkflowStateMixin(object):
    def dispatch(self, request, *args, **kwargs):
        pass

class MyView(AdminAllowedMixin,WorkflowStateMixin,...): # TestAdminAllowedMixin as result
    pass

@login_required
def my_view(request):
    pass

mixins have  a lot of down-sides but it's very common practice in Django.

Pyramid

Except the mixins and new decorators approach, Pyramid provides a concept of route predicates. You can use existing one or create new, so no mixins or additional decorators are actually required.

# use case
@view_config(..., user_role="admin")
def view(self):
    ...

@view_config(..., user_role=not_("admin"), method="get", xhr=True, csfr=False)
def view(self):
    ...

# predicate definition
class UserRolePredicate(object):
    def __init__(self, val, config):
        self.val = val
    def __call__(self, context, request):
        return request.user.role == self.val
 ...

# configurator part
config.add_view_predicate('user_role', UserRolePredicate)
...

But there actually are 'effective_principals' and 'permission' predicates existss for handling access to views in a proper way.

Afterword

mixins aren't that good approach (which comes from problem of inheritance approach) it depends on your class internals and so requires more testing. Decorator has advantage that it's not depended on view internals and cannot be affected by view code that easily, but in case of lot logic you would be required to use lot of different decorators what makes code more buggy (order of decorators matters) and grumpy. Nice way if view declaration function/decorator that allows its functionality extending.

Prev Post Next Post