Search code examples
djangofacebookpyfacebook

Require extended permissions in FBML pyfacebook app


I'm trying to get my FBML canvas page to automatically prompt new app users for permission to publish_stream. Following Facebook's documentation I tried using the required_permissions argument to require_login. That is, I tried to use the pyfacebook require_login decorator like this:

@facebook.require_login(required_permissions='publish_stream')

as in:

@decorator_from_middleware(FacebookMiddleware)
@facebook.require_login(required_permissions='publish_stream')
def canvas(request, template):
   ...

Requesting extended permissions in a pyfacebook-based Facebook iFrame app has been discussed. Requesting extended permissions in an FBML app too. My objective is to require extended permissions in an FBML app. Am I missing something or can anyone suggest a workaround?

Thanks.


Solution

  • Right, pyfacebook does not yet support required_permissions for login, but you can call (or rather, redirect to) authorize manually. I've just written the following decorator for my purposes:

    def require_permissions(*names):
        """Require extended permissions.
        XXX: in theory, the facebook.require_login() decorator should support
        this, but doesn't in pyfacebook yet."""
        def decorator(fn):
            required_perms = set(names)
            def wrapper(request, *args, **kwargs):
                fb = request.facebook
                perms = set() if fb.ext_perms is None \
                        else set(fb.ext_perms.split(','))
                if not required_perms.issubset(perms):
                    missing = required_perms.difference(perms)
                    url = fb.get_ext_perm_url(','.join(missing),
                                next='%s%s' % (fb.get_app_url(), request.path[1:]))
                    print url
                    return fb.redirect(url)
                return fn(request, *args, **kwargs)
            return wrapper
        return decorator
    

    You may have to tweak the value of next as it is passed to get_ext_perm_url, but this should otherwise be fine (works for me). Usage example:

    @facebook.require_login()
    @facebook.require_add()
    @require_permissions('email', 'offline_access')
    def index(request):
       # ...