コード例 #1
0
def facebook_process(request):
    """Process the facebook redirect"""
    if request.GET.get('state') != request.session.get('facebook_state'):
        raise CSRFError(
            "CSRF Validation check failed. Request state %s is "
            "not the same as session state %s" %
            (request.GET.get('state'), request.session.get('state')))
    del request.session['facebook_state']

    code = request.GET.get('code')
    if not code:
        reason = request.GET.get('error_reason', 'No reason provided.')
        return AuthenticationDenied(reason)

    cfg = ptah.get_settings(ptahcrowd.CFG_ID_AUTH, request.registry)

    client_id = cfg['facebook_id']
    client_secret = cfg['facebook_secret']

    # Now retrieve the access token with the code
    access_url = '{0}?{1}'.format(
        'https://graph.facebook.com/oauth/access_token',
        url_encode({
            'client_id': client_id,
            'client_secret': client_secret,
            'redirect_uri': request.route_url('facebook_process'),
            'code': code
        }))
    r = requests.get(access_url)
    if r.status_code != 200:
        raise ThirdPartyFailure("Status %s: %s" % (r.status_code, r.content))

    access_token = urlparse.parse_qs(r.content)['access_token'][0]

    entry = Storage.get_by_token(access_token)
    if entry is not None:
        return FacebookAuthenticationComplete(entry)

    # Retrieve profile data
    graph_url = '{0}?{1}'.format('https://graph.facebook.com/me',
                                 url_encode({'access_token': access_token}))
    r = requests.get(graph_url)
    if r.status_code != 200:
        raise ThirdPartyFailure("Status %s: %s" % (r.status_code, r.content))

    profile = json.loads(r.content)

    id = profile['id']
    name = profile['name']
    email = profile.get('email', '')
    verified = profile.get('verified', False)

    entry = Storage.create(access_token,
                           'facebook',
                           uid='{0}:{1}'.format('facebook', id),
                           name=name,
                           email=email,
                           verified=verified,
                           profile=profile)
    return FacebookAuthenticationComplete(entry)
コード例 #2
0
ファイル: live.py プロジェクト: webmaven/ptahcrowd
def live_process(request):
    """Process the Live redirect"""
    if 'error' in request.GET:
        raise ThirdPartyFailure(request.GET.get('error_description',
                                'No reason provided.'))

    code = request.GET.get('code')
    if not code:
        reason = request.GET.get('error_reason', 'No reason provided.')
        return AuthenticationDenied(reason)

    cfg = ptah.get_settings(ptahcrowd.CFG_ID_AUTH, request.registry)

    client_id = cfg['live_id']
    client_secret = cfg['live_secret']

    # Now retrieve the access token with the code
    access_url = '{0}?{1}'.format(
        'https://oauth.live.com/token',
        url_encode({'client_id': client_id,
                    'client_secret': client_secret,
                    'redirect_uri': request.route_url('live_process'),
                    'grant_type': 'authorization_code',
                    'code': code}))

    r = requests.get(access_url)
    if r.status_code != 200:
        raise ThirdPartyFailure("Status %s: %s" % (r.status_code, r.content))

    data = json.loads(r.content)
    access_token = data['access_token']

    entry = Storage.get_by_token(access_token)
    if entry is not None:
        return LiveAuthenticationComplete(entry)

    # Retrieve profile data
    url = '{0}?{1}'.format(
        'https://apis.live.net/v5.0/me',
        url_encode({'access_token': access_token}))
    r = requests.get(url)
    if r.status_code != 200:
        raise ThirdPartyFailure("Status %s: %s" % (r.status_code, r.content))

    profile = json.loads(r.content)

    id = profile['id']
    name = profile.get('name','')
    email = profile.get('emails',{}).get('preferred')
    verified = bool(email)

    entry = Storage.create(access_token, 'live',
                           uid = 'live:{0}'.format(id),
                           name = name,
                           email = email,
                           verified = verified,
                           profile = profile)

    return LiveAuthenticationComplete(entry)
コード例 #3
0
ファイル: facebook.py プロジェクト: webmaven/ptahcrowd
def facebook_process(request):
    """Process the facebook redirect"""
    if request.GET.get('state') != request.session.get('facebook_state'):
        raise CSRFError("CSRF Validation check failed. Request state %s is "
                        "not the same as session state %s" % (
                        request.GET.get('state'), request.session.get('state')
                        ))
    del request.session['facebook_state']

    code = request.GET.get('code')
    if not code:
        reason = request.GET.get('error_reason', 'No reason provided.')
        return AuthenticationDenied(reason)

    cfg = ptah.get_settings(ptahcrowd.CFG_ID_AUTH, request.registry)

    client_id = cfg['facebook_id']
    client_secret = cfg['facebook_secret']

    # Now retrieve the access token with the code
    access_url = '{0}?{1}'.format(
        'https://graph.facebook.com/oauth/access_token',
        url_encode({'client_id': client_id,
                    'client_secret': client_secret,
                    'redirect_uri': request.route_url('facebook_process'),
                    'code': code}))
    r = requests.get(access_url)
    if r.status_code != 200:
        raise ThirdPartyFailure("Status %s: %s" % (r.status_code, r.content))

    access_token = urlparse.parse_qs(r.content)['access_token'][0]

    entry = Storage.get_by_token(access_token)
    if entry is not None:
        return FacebookAuthenticationComplete(entry)

    # Retrieve profile data
    graph_url = '{0}?{1}'.format('https://graph.facebook.com/me',
                                 url_encode({'access_token': access_token}))
    r = requests.get(graph_url)
    if r.status_code != 200:
        raise ThirdPartyFailure("Status %s: %s" % (r.status_code, r.content))

    profile = json.loads(r.content)

    id = profile['id']
    name = profile['name']
    email = profile.get('email','')
    verified = profile.get('verified', False)

    entry = Storage.create(access_token, 'facebook',
                           uid = '{0}:{1}'.format('facebook', id),
                           name = name,
                           email = email,
                           verified = verified,
                           profile = profile)
    return FacebookAuthenticationComplete(entry)
コード例 #4
0
def github_process(request):
    """Process the github redirect"""
    code = request.GET.get('code')
    if not code:
        reason = request.GET.get('error', 'No reason provided.')
        return AuthenticationDenied(reason)

    cfg = ptah.get_settings(ptahcrowd.CFG_ID_AUTH, request.registry)

    client_id = cfg['github_id']
    client_secret = cfg['github_secret']

    # Now retrieve the access token with the code
    access_url = '{0}?{1}'.format(
        'https://github.com/login/oauth/access_token',
        url_encode({
            'client_id': client_id,
            'client_secret': client_secret,
            'redirect_uri': request.route_url('github_process'),
            'code': code
        }))

    r = requests.get(access_url)
    if r.status_code != 200:
        raise ThirdPartyFailure("Status %s: %s" % (r.status_code, r.content))

    try:
        access_token = urlparse.parse_qs(r.content)['access_token'][0]
    except:
        return AuthenticationDenied("Can't get access_token.")

    entry = Storage.get_by_token(access_token)
    if entry is not None:
        return GithubAuthenticationComplete(entry)

    # Retrieve profile data
    graph_url = '{0}?{1}'.format('https://github.com/api/v2/json/user/show',
                                 url_encode({'access_token': access_token}))
    r = requests.get(graph_url)
    if r.status_code != 200:
        raise ThirdPartyFailure("Status %s: %s" % (r.status_code, r.content))

    profile = json.loads(r.content)

    entry = Storage.create(access_token,
                           'github',
                           uid='github:{0}'.format(profile['user']['id']),
                           name=profile['user']['name'],
                           email=profile['user'].get('email') or '',
                           profile=profile)

    return GithubAuthenticationComplete(entry)
コード例 #5
0
ファイル: github.py プロジェクト: djedproject/ptahcrowd
def github_process(request):
    """Process the github redirect"""
    code = request.GET.get('code')
    if not code:
        reason = request.GET.get('error', 'No reason provided.')
        return AuthenticationDenied(reason)

    cfg = ptah.get_settings(ptahcrowd.CFG_ID_AUTH, request.registry)

    client_id = cfg['github_id']
    client_secret = cfg['github_secret']

    # Now retrieve the access token with the code
    access_url ='{0}?{1}'.format(
        'https://github.com/login/oauth/access_token',
        url_encode({'client_id': client_id,
                    'client_secret': client_secret,
                    'redirect_uri': request.route_url('github_process'),
                    'code': code}))

    r = requests.get(access_url)
    if r.status_code != 200:
        raise ThirdPartyFailure("Status %s: %s" % (r.status_code, r.content))

    try:
        access_token = urlparse.parse_qs(r.content)['access_token'][0]
    except:
        return AuthenticationDenied("Can't get access_token.")

    entry = Storage.get_by_token(access_token)
    if entry is not None:
        return GithubAuthenticationComplete(entry)

    # Retrieve profile data
    graph_url = '{0}?{1}'.format(
        'https://github.com/api/v2/json/user/show',
        url_encode({'access_token': access_token}))
    r = requests.get(graph_url)
    if r.status_code != 200:
        raise ThirdPartyFailure("Status %s: %s" % (r.status_code, r.content))

    profile = json.loads(r.content)

    entry = Storage.create(access_token, 'github',
                           uid = 'github:{0}'.format(profile['user']['id']),
                           name = profile['user']['name'],
                           email = profile['user'].get('email') or '',
                           profile = profile)

    return GithubAuthenticationComplete(entry)
コード例 #6
0
ファイル: google.py プロジェクト: webmaven/ptahcrowd
def google_process(request):
    """Process the google redirect"""
    code = request.GET.get('code')
    if not code:
        reason = request.GET.get('error', 'No reason provided.')
        return AuthenticationDenied(reason)

    cfg = ptah.get_settings(ptahcrowd.CFG_ID_AUTH, request.registry)

    client_id = cfg['google_id']
    client_secret = cfg['google_secret']

    # Now retrieve the access token with the code
    r = requests.post('https://accounts.google.com/o/oauth2/token',
                      {'client_id': client_id,
                       'client_secret': client_secret,
                       'redirect_uri': request.route_url('google_process'),
                       'grant_type': 'authorization_code',
                       'code': code})
    if r.status_code != 200:
        raise ThirdPartyFailure("Status %s: %s" % (r.status_code, r.content))

    try:
        access_token = json.loads(r.content)['access_token']
    except:
        return AuthenticationDenied("Can't get access_token.")

    entry = Storage.get_by_token(access_token)
    if entry is not None:
        return GoogleAuthenticationComplete(entry)

    # Retrieve profile data
    graph_url = '{0}?{1}'.format(
        'https://www.googleapis.com/oauth2/v1/userinfo',
        url_encode({'access_token': access_token}))
    r = requests.get(graph_url)
    if r.status_code != 200:
        raise ThirdPartyFailure("Status %s: %s" % (r.status_code, r.content))

    data = json.loads(r.content)

    id = data['id']
    name = data['name']
    email = data.get('email', '')

    entry = Storage.create(access_token, 'google',
                           uid = '{0}:{1}'.format('google', id),
                           name = name,
                           email = email,
                           verified = True,
                           profile = data)

    return GoogleAuthenticationComplete(entry)
コード例 #7
0
ファイル: google.py プロジェクト: sidloki/ptahcrowd
def google_process(request):
    """Process the google redirect"""
    code = request.GET.get('code')
    if not code:
        reason = request.GET.get('error', 'No reason provided.')
        return AuthenticationDenied(reason)

    cfg = ptah.get_settings(ptahcrowd.CFG_ID_AUTH, request.registry)

    client_id = cfg['google_id']
    client_secret = cfg['google_secret']

    # Now retrieve the access token with the code
    r = requests.post('https://accounts.google.com/o/oauth2/token',
                      {'client_id': client_id,
                       'client_secret': client_secret,
                       'redirect_uri': request.route_url('google_process'),
                       'grant_type': 'authorization_code',
                       'code': code})
    if r.status_code != 200:
        raise ThirdPartyFailure("Status %s: %s" % (r.status_code, r.content))

    try:
        access_token = json.loads(r.content)['access_token']
    except:
        return AuthenticationDenied("Can't get access_token.")

    entry = Storage.get_by_token(access_token)
    if entry is not None:
        return GoogleAuthenticationComplete(entry)

    # Retrieve profile data
    graph_url = '{0}?{1}'.format(
        'https://www.googleapis.com/oauth2/v1/userinfo',
        url_encode({'access_token': access_token}))
    r = requests.get(graph_url)
    if r.status_code != 200:
        raise ThirdPartyFailure("Status %s: %s" % (r.status_code, r.content))

    data = json.loads(r.content)

    id = data['id']
    name = data['name']
    email = data.get('email', '')

    entry = Storage.create(access_token, 'google',
                           uid = '{0}:{1}'.format('google', id),
                           name = name,
                           email = email,
                           verified = True,
                           profile = data)

    return GoogleAuthenticationComplete(entry)
コード例 #8
0
ファイル: google.py プロジェクト: sidloki/ptahcrowd
def google_login(request):
    """Initiate a google login"""
    cfg = ptah.get_settings(ptahcrowd.CFG_ID_AUTH, request.registry)

    client_id = cfg['google_id']

    go_url = '{0}?{1}&scope=https://www.googleapis.com/auth/userinfo.profile+https://www.googleapis.com/auth/userinfo.email'.format(
        'https://accounts.google.com/o/oauth2/auth',
        url_encode({'client_id': client_id,
                    'redirect_uri': request.route_url('google_process'),
                    'response_type': 'code'}))

    return HTTPFound(location=go_url)
コード例 #9
0
ファイル: github.py プロジェクト: djedproject/ptahcrowd
def github_login(request):
    """Initiate a github login"""
    cfg = ptah.get_settings(ptahcrowd.CFG_ID_AUTH, request.registry)

    scope = cfg['github_scope']
    client_id = cfg['github_id']

    gh_url = '{0}?{1}'.format(
        'https://github.com/login/oauth/authorize',
        url_encode({'scope': scope,
                    'client_id': client_id,
                    'redirect_uri': request.route_url('github_process')}))

    return HTTPFound(location=gh_url)
コード例 #10
0
ファイル: live.py プロジェクト: webmaven/ptahcrowd
def live_login(request):
    """Initiate a Live login"""
    cfg = ptah.get_settings(ptahcrowd.CFG_ID_AUTH, request.registry)

    scope = 'wl.basic wl.emails wl.signin'
    client_id = cfg['live_id']

    live_url = 'https://oauth.live.com/authorize?{0}&redirect_uri={1}'.format(
        url_encode({'scope': scope,
                    'client_id': client_id,
                    'response_type': "code"}),
        request.route_url('live_process'))

    return HTTPFound(location=live_url)
コード例 #11
0
ファイル: live.py プロジェクト: sidloki/ptahcrowd
def live_login(request):
    """Initiate a Live login"""
    cfg = ptah.get_settings(ptahcrowd.CFG_ID_AUTH, request.registry)

    scope = 'wl.basic wl.emails wl.signin'
    client_id = cfg['live_id']

    live_url = 'https://oauth.live.com/authorize?{0}&redirect_uri={1}'.format(
        url_encode({
            'scope': scope,
            'client_id': client_id,
            'response_type': "code"
        }), request.route_url('live_process'))

    return HTTPFound(location=live_url)
コード例 #12
0
def github_login(request):
    """Initiate a github login"""
    cfg = ptah.get_settings(ptahcrowd.CFG_ID_AUTH, request.registry)

    scope = cfg['github_scope']
    client_id = cfg['github_id']

    gh_url = '{0}?{1}'.format(
        'https://github.com/login/oauth/authorize',
        url_encode({
            'scope': scope,
            'client_id': client_id,
            'redirect_uri': request.route_url('github_process')
        }))

    return HTTPFound(location=gh_url)
コード例 #13
0
ファイル: forbidden.py プロジェクト: sidloki/ptahcrowd
    def update(self):
        request = self.request

        context = getattr(request, 'context', None)
        if context is None:
            context = getattr(request, 'root', None)

        if context is None:
            root_factory = request.registry.queryUtility(
                IRootFactory, default=DefaultRootFactory)
            context = root_factory(request)
            request.root = context

        self.__parent__ = context

        CFG = ptah.get_settings(ptahcrowd.CFG_ID_CROWD, self.request.registry)

        user = ptah.auth_service.get_userid()
        if user is not None:
            user = ptah.auth_service.get_current_principal()
            if user is None:
                request.response.headers = security.forget(request)

        if user is None:
            loginurl = CFG['login-url']
            if loginurl and not loginurl.startswith(('http://', 'https://')):
                loginurl = self.application_url + loginurl
            elif not loginurl:
                loginurl = self.application_url + '/login.html'

            location = '%s?%s' % (loginurl,
                                  url_encode({'came_from': request.url}))

            request.add_message(
                _('To access this part of the site, you need to log in with your credentials.'
                  ), 'info')

            response = request.response
            response.status = HTTPFound.code
            response.headers['location'] = location
            return response

        PTAH = ptah.get_settings(ptah.CFG_ID_PTAH, self.request.registry)
        self.email_address = PTAH['email_from_address']

        self.request.response.status = HTTPForbidden.code
コード例 #14
0
ファイル: forbidden.py プロジェクト: ptahproject/ptahcrowd
    def update(self):
        request = self.request

        context = getattr(request, 'context', None)
        if context is None:
            context = getattr(request, 'root', None)

        if context is None:
            root_factory = request.registry.queryUtility(
                IRootFactory, default=DefaultRootFactory)
            context = root_factory(request)
            request.root = context

        self.__parent__ = context

        CFG = ptah.get_settings(ptahcrowd.CFG_ID_CROWD, self.request.registry)

        user = ptah.auth_service.get_userid()
        if user is not None:
            user = ptah.auth_service.get_current_principal()
            if user is None:
                request.response.headers = security.forget(request)

        if user is None:
            loginurl = CFG['login-url']
            if loginurl and not loginurl.startswith(('http://', 'https://')):
                loginurl = self.application_url + loginurl
            elif not loginurl:
                loginurl = self.application_url + '/login.html'

            location = '%s?%s'%(
                loginurl, url_encode({'came_from': request.url}))

            request.add_message(_('To access this part of the site, you need to log in with your credentials.'), 'info')

            response = request.response
            response.status = HTTPFound.code
            response.headers['location'] = location
            return response

        PTAH = ptah.get_settings(ptah.CFG_ID_PTAH, self.request.registry)
        self.email_address = PTAH['email_from_address']

        self.request.response.status = HTTPForbidden.code
コード例 #15
0
ファイル: facebook.py プロジェクト: webmaven/ptahcrowd
def facebook_login(request):
    """Initiate a facebook login"""
    cfg = ptah.get_settings(ptahcrowd.CFG_ID_AUTH, request.registry)

    scope = cfg['facebook_scope']
    if scope and 'email' not in scope:
        scope = '%s,email'%scope
    elif not scope:
        scope = 'email'

    client_id = cfg['facebook_id']

    request.session['facebook_state'] = state = uuid.uuid4().hex
    fb_url = '{0}?{1}'.format(
        'https://www.facebook.com/dialog/oauth/',
        url_encode({'scope': scope,
                    'client_id': client_id,
                    'redirect_uri': request.route_url('facebook_process'),
                    'state': state}))
    return HTTPFound(location=fb_url)
コード例 #16
0
def facebook_login(request):
    """Initiate a facebook login"""
    cfg = ptah.get_settings(ptahcrowd.CFG_ID_AUTH, request.registry)

    scope = cfg['facebook_scope']
    if scope and 'email' not in scope:
        scope = '%s,email' % scope
    elif not scope:
        scope = 'email'

    client_id = cfg['facebook_id']

    request.session['facebook_state'] = state = uuid.uuid4().hex
    fb_url = '{0}?{1}'.format(
        'https://www.facebook.com/dialog/oauth/',
        url_encode({
            'scope': scope,
            'client_id': client_id,
            'redirect_uri': request.route_url('facebook_process'),
            'state': state
        }))
    return HTTPFound(location=fb_url)
コード例 #17
0
ファイル: facebook.py プロジェクト: ptahproject/examples
def facebook_process(request):
    """Process the facebook redirect"""
    print request.GET

    # get session
    st = request.GET.get('state').split(',')[-1]
    manager = ptah.sockjs.get_session_manager(request.registry)
    try:
        session = manager.get(st)
    except:
        raise HTTPBadRequest("No session")

    code = request.GET.get('code')
    if not code:
        raise HTTPBadRequest("No reason")

    # auth
    cfg = ptah.get_settings(CFG_ID_AUTH, request.registry)

    client_id = cfg['facebook_id']
    client_secret = cfg['facebook_secret']

    # Now retrieve the access token with the code
    access_url = '{0}?{1}'.format(
        'https://graph.facebook.com/oauth/access_token',
        url_encode({'client_id': client_id,
                    'client_secret': client_secret,
                    'redirect_uri': request.route_url('facebook_process'),
                    'code': code}))

    r = requests.get(access_url)
    if r.status_code != 200:
        raise HTTPBadRequest("Status %s: %s" % (r.status_code, r.content))

    access_token = urlparse.parse_qs(r.content)['access_token'][0]

    with ptah.sa_session() as sa:
        user = User.get_bytoken(access_token)
        if user is not None:
            protocol = session.protocols.get('gallery')
            protocol.auth(user)
            
            response = request.response
            response.content_type = 'text/html'
            response.body = close
            return response

    # Retrieve profile data
    graph_url = '{0}?{1}'.format('https://graph.facebook.com/me',
                                 url_encode({'access_token': access_token}))
    r = requests.get(graph_url)
    if r.status_code != 200:
        raise HTTPBadRequest("Status %s: %s" % (r.status_code, r.content))

    profile = ptah.json.loads(r.content)

    id = profile['id']
    name = profile['name']
    email = profile.get('email','').lower()

    with ptah.sa_session() as sa:
        sa.query(User).filter(User.email == email).delete()

        user = User(
            token = access_token,
            source = 'facebook',
            name = name, email = email)
        sa.add(user)
        sa.flush()

        protocol = session.protocols.get('gallery')
        protocol.auth(user)

        response = request.response
        response.content_type = 'text/html'
        response.body = close
        return response
コード例 #18
0
ファイル: live.py プロジェクト: sidloki/ptahcrowd
def live_process(request):
    """Process the Live redirect"""
    if 'error' in request.GET:
        raise ThirdPartyFailure(
            request.GET.get('error_description', 'No reason provided.'))

    code = request.GET.get('code')
    if not code:
        reason = request.GET.get('error_reason', 'No reason provided.')
        return AuthenticationDenied(reason)

    cfg = ptah.get_settings(ptahcrowd.CFG_ID_AUTH, request.registry)

    client_id = cfg['live_id']
    client_secret = cfg['live_secret']

    # Now retrieve the access token with the code
    access_url = '{0}?{1}'.format(
        'https://oauth.live.com/token',
        url_encode({
            'client_id': client_id,
            'client_secret': client_secret,
            'redirect_uri': request.route_url('live_process'),
            'grant_type': 'authorization_code',
            'code': code
        }))

    r = requests.get(access_url)
    if r.status_code != 200:
        raise ThirdPartyFailure("Status %s: %s" % (r.status_code, r.content))

    data = json.loads(r.content)
    access_token = data['access_token']

    entry = Storage.get_by_token(access_token)
    if entry is not None:
        return LiveAuthenticationComplete(entry)

    # Retrieve profile data
    url = '{0}?{1}'.format('https://apis.live.net/v5.0/me',
                           url_encode({'access_token': access_token}))
    r = requests.get(url)
    if r.status_code != 200:
        raise ThirdPartyFailure("Status %s: %s" % (r.status_code, r.content))

    profile = json.loads(r.content)

    id = profile['id']
    name = profile.get('name', '')
    email = profile.get('emails', {}).get('preferred')
    verified = bool(email)

    entry = Storage.create(access_token,
                           'live',
                           uid='live:{0}'.format(id),
                           name=name,
                           email=email,
                           verified=verified,
                           profile=profile)

    return LiveAuthenticationComplete(entry)
コード例 #19
0
def facebook_process(request):
    """Process the facebook redirect"""
    print request.GET

    # get session
    st = request.GET.get('state').split(',')[-1]
    manager = ptah.sockjs.get_session_manager(request.registry)
    try:
        session = manager.get(st)
    except:
        raise HTTPBadRequest("No session")

    code = request.GET.get('code')
    if not code:
        raise HTTPBadRequest("No reason")

    # auth
    cfg = ptah.get_settings(CFG_ID_AUTH, request.registry)

    client_id = cfg['facebook_id']
    client_secret = cfg['facebook_secret']

    # Now retrieve the access token with the code
    access_url = '{0}?{1}'.format(
        'https://graph.facebook.com/oauth/access_token',
        url_encode({
            'client_id': client_id,
            'client_secret': client_secret,
            'redirect_uri': request.route_url('facebook_process'),
            'code': code
        }))

    r = requests.get(access_url)
    if r.status_code != 200:
        raise HTTPBadRequest("Status %s: %s" % (r.status_code, r.content))

    access_token = urlparse.parse_qs(r.content)['access_token'][0]

    with ptah.sa_session() as sa:
        user = User.get_bytoken(access_token)
        if user is not None:
            protocol = session.protocols.get('gallery')
            protocol.auth(user)

            response = request.response
            response.content_type = 'text/html'
            response.body = close
            return response

    # Retrieve profile data
    graph_url = '{0}?{1}'.format('https://graph.facebook.com/me',
                                 url_encode({'access_token': access_token}))
    r = requests.get(graph_url)
    if r.status_code != 200:
        raise HTTPBadRequest("Status %s: %s" % (r.status_code, r.content))

    profile = ptah.json.loads(r.content)

    id = profile['id']
    name = profile['name']
    email = profile.get('email', '').lower()

    with ptah.sa_session() as sa:
        sa.query(User).filter(User.email == email).delete()

        user = User(token=access_token,
                    source='facebook',
                    name=name,
                    email=email)
        sa.add(user)
        sa.flush()

        protocol = session.protocols.get('gallery')
        protocol.auth(user)

        response = request.response
        response.content_type = 'text/html'
        response.body = close
        return response