Andrea Parodi
Andrea Parodi

Reputation: 5614

redirecting to a specific page on auth.requires_membership failure in web2py

I have to redirect to a specific page if a user is not member of a specific group. I'm trying to use requires_membership decorator on my controller.

If I correctly understood documentation, I can specify a string in otherwise parameter in order to redirect the user to a page on failure:

@auth.requires_membership(group_id='fornitori', otherwise='/failure-page')
def index():
    return {}

Anyway, this is not working, and looking at the code, it appear that the otherwise argument is only used for the requires_login decorator.

I'm doing something wrong or it's a bug on web2py?

Do you know some other simple way of doing this redirection?

Upvotes: 0

Views: 776

Answers (2)

ProRedMax
ProRedMax

Reputation: 80

Just as a small addition. As already mentioned in the answer, 'otherwise' does not work the way you want it to. But if you still want to pass arguments, you can do it like this:

def check_membership(target_group, new_url="none"):
    def docheck():
        if len(auth.user_groups.values()) == 0:  # If no user is present
            return auth()
        for x in target_group:
            if auth.has_membership(group_id=x, cached=True):
                return True

        if new_url == "none":
            return False
        redirect(URL('default', new_url))
        return False

return docheck


@auth.requires(check_membership(['admin'], 'other'))
def index():
    # Your code goes here

Upvotes: 0

Anthony
Anthony

Reputation: 25536

otherwise does work with this decorator as well, but it only takes effect if the failure is due to login, not authorization. To make the redirect conditional upon failed authorization, there are two options. First, auth.settings.on_failed_authorization can be a function, so you could write a function that checks the requested controller/function/args and returns a different redirect URL depending on the request. Second, you could write your own "requires" function that handles the redirect itself:

def check_membership():
    if not auth.has_membership(group_id='fornitori'):
        redirect(URL('default', 'other'))

@auth.requires(check_membership)
def index():
    etc.

Upvotes: 3

Related Questions