示例#1
0
 def test_successful_external_first_login_without_attributes(self, mock_service_validate, mock_get_user_from_cas_resp, mock_external_first_login_authenticate):
     service_url = 'http://localhost:5000/dashboard/'
     user, validated_credentials, cas_resp = generate_external_user_with_resp(service_url, user=False, release=False)
     mock_service_validate.return_value = cas_resp
     mock_get_user_from_cas_resp.return_value = (None, validated_credentials, 'external_first_login')
     ticket = fake.md5()
     cas.make_response_from_ticket(ticket, service_url)
     assert_equal(user, mock_external_first_login_authenticate.call_args[0][0])
示例#2
0
 def test_successful_external_first_login_without_attributes(self, mock_service_validate, mock_get_user_from_cas_resp, mock_external_first_login_authenticate):
     service_url = 'http://localhost:5000/dashboard/'
     user, validated_credentials, cas_resp = generate_external_user_with_resp(service_url, user=False, release=False)
     mock_service_validate.return_value = cas_resp
     mock_get_user_from_cas_resp.return_value = (None, validated_credentials, 'external_first_login')
     ticket = fake.md5()
     cas.make_response_from_ticket(ticket, service_url)
     assert_equal(user, mock_external_first_login_authenticate.call_args[0][0])
示例#3
0
def before_request():
    # TODO: Fix circular import
    from framework.auth.core import get_user
    from framework.auth import cas
    from website.util import time as util_time

    # Central Authentication Server Ticket Validation and Authentication
    ticket = request.args.get('ticket')
    if ticket:
        service_url = furl.furl(request.url)
        service_url.args.pop('ticket')
        # Attempt to authenticate wih CAS, and return a proper redirect response
        return cas.make_response_from_ticket(ticket=ticket,
                                             service_url=service_url.url)

    if request.authorization:
        user = get_user(email=request.authorization.username,
                        password=request.authorization.password)
        # Create an empty session
        # TODO: Shoudn't need to create a session for Basic Auth
        user_session = Session()
        set_session(user_session)

        if user:
            user_addon = user.get_addon('twofactor')
            if user_addon and user_addon.is_confirmed:
                otp = request.headers.get('X-OSF-OTP')
                if otp is None or not user_addon.verify_code(otp):
                    # Must specify two-factor authentication OTP code or invalid two-factor authentication OTP code.
                    user_session.data['auth_error_code'] = http.UNAUTHORIZED
                    return
            user_session.data['auth_user_username'] = user.username
            user_session.data['auth_user_id'] = user._primary_key
            user_session.data['auth_user_fullname'] = user.fullname
        else:
            # Invalid key: Not found in database
            user_session.data['auth_error_code'] = http.UNAUTHORIZED
        return

    cookie = request.cookies.get(settings.COOKIE_NAME)
    if cookie:
        try:
            session_id = itsdangerous.Signer(
                settings.SECRET_KEY).unsign(cookie)
            user_session = Session.load(session_id) or Session(_id=session_id)
        except itsdangerous.BadData:
            return
        if not util_time.throttle_period_expired(user_session.date_created,
                                                 settings.OSF_SESSION_TIMEOUT):
            if user_session.data.get(
                    'auth_user_id') and 'api' not in request.url:
                database['user'].update(
                    {'_id': user_session.data.get('auth_user_id')},
                    {'$set': {
                        'date_last_login': datetime.utcnow()
                    }},
                    w=0)
            set_session(user_session)
        else:
            remove_session(user_session)
示例#4
0
def before_request():
    from framework.auth import cas

    # Central Authentication Server Ticket Validation and Authentication
    ticket = request.args.get('ticket')
    if ticket:
        service_url = furl.furl(request.url)
        service_url.args.pop('ticket')
        # Attempt autn wih CAS, and return a proper redirect response
        resp = cas.make_response_from_ticket(ticket=ticket, service_url=service_url.url)
        if request.cookies.get(settings.COOKIE_NAME):
            # TODO: Delete legacy cookie, this special case can be removed anytime after 1/1/2016.
            # A cookie is received which could potentially be a legacy (pre multi-domain) cookie.
            # Issuing a targeted delete of the legacy cookie ensures the user does not end up in a
            # login loop whereby both cookies are sent to the server and one of them at random
            # read for authentication.
            resp.delete_cookie(settings.COOKIE_NAME, domain=None)
        return resp

    if request.authorization:
        # TODO: Fix circular import
        from framework.auth.core import get_user
        user = get_user(
            email=request.authorization.username,
            password=request.authorization.password
        )
        # Create empty session
        # TODO: Shoudn't need to create a session for Basic Auth
        session = Session()
        set_session(session)

        if user:
            user_addon = user.get_addon('twofactor')
            if user_addon and user_addon.is_confirmed:
                otp = request.headers.get('X-OSF-OTP')
                if otp is None or not user_addon.verify_code(otp):
                    # Must specify two-factor authentication OTP code or invalid two-factor
                    # authentication OTP code.
                    session.data['auth_error_code'] = http.UNAUTHORIZED
                    return

            session.data['auth_user_username'] = user.username
            session.data['auth_user_id'] = user._primary_key
            session.data['auth_user_fullname'] = user.fullname
        else:
            # Invalid key: Not found in database
            session.data['auth_error_code'] = http.UNAUTHORIZED
        return

    cookie = request.cookies.get(settings.COOKIE_NAME)
    if cookie:
        try:
            session_id = itsdangerous.Signer(settings.SECRET_KEY).unsign(cookie)
            session = Session.load(session_id) or Session(_id=session_id)
        except itsdangerous.BadData:
            return
        if session.data.get('auth_user_id') and 'api' not in request.url:
            database['user'].update({'_id': session.data.get('auth_user_id')}, {'$set': {'date_last_login': datetime.utcnow()}}, w=0)
        set_session(session)
示例#5
0
def before_request():
    from framework.auth import authenticate
    from framework.auth.core import User
    from framework.auth import cas

    # Central Authentication Server Ticket Validation and Authentication
    ticket = request.args.get('ticket')
    if ticket:
        service_url = furl.furl(request.url)
        service_url.args.pop('ticket')
        # Attempt autn wih CAS, and return a proper redirect response
        return cas.make_response_from_ticket(ticket=ticket, service_url=service_url.url)

    # Central Authentication Server OAuth Bearer Token
    authorization = request.headers.get('Authorization')
    if authorization and authorization.startswith('Bearer '):
        client = cas.get_client()
        try:
            access_token = cas.parse_auth_header(authorization)
        except cas.CasTokenError as err:
            # NOTE: We assume that the request is an AJAX request
            return jsonify({'message_short': 'Invalid Bearer token', 'message_long': err.args[0]}), http.UNAUTHORIZED
        cas_resp = client.profile(access_token)
        if cas_resp.authenticated:
            user = User.load(cas_resp.user)
            return authenticate(user, access_token=access_token, response=None)
        return make_response('', http.UNAUTHORIZED)

    if request.authorization:
        # TODO: Fix circular import
        from framework.auth.core import get_user
        user = get_user(
            email=request.authorization.username,
            password=request.authorization.password
        )
        # Create empty session
        # TODO: Shoudn't need to create a session for Basic Auth
        session = Session()

        if user:
            session.data['auth_user_username'] = user.username
            session.data['auth_user_id'] = user._primary_key
            session.data['auth_user_fullname'] = user.fullname
        else:
            # Invalid key: Not found in database
            session.data['auth_error_code'] = http.FORBIDDEN

        set_session(session)
        return

    cookie = request.cookies.get(settings.COOKIE_NAME)
    if cookie:
        try:
            session_id = itsdangerous.Signer(settings.SECRET_KEY).unsign(cookie)
            session = Session.load(session_id) or Session(_id=session_id)
            set_session(session)
            return
        except:
            pass
 def test_make_response_from_ticket_no_user(self, mock_service_validate):
     mock_response = make_external_response()
     mock_service_validate.return_value = mock_response
     ticket = fake.md5()
     service_url = "http://accounts.osf.io/?ticket=" + ticket
     resp = cas.make_response_from_ticket(ticket, service_url)
     assert_equal(resp.status_code, 302)
     assert_equal(resp.location, "/external-login/email")
 def test_make_response_from_ticket_failure(self, mock_service_validate):
     mock_response = make_failure_response()
     mock_service_validate.return_value = mock_response
     ticket = fake.md5()
     service_url = 'http://accounts.osf.io/?ticket=' + ticket
     resp = cas.make_response_from_ticket(ticket, service_url)
     assert_equal(resp.status_code, 302)
     assert_equal(resp.location, 'http://accounts.osf.io/')
 def test_make_response_from_ticket_failure(self, mock_service_validate):
     mock_response = make_failure_response()
     mock_service_validate.return_value = mock_response
     ticket = fake.md5()
     service_url = 'http://accounts.osf.io/?ticket=' + ticket
     resp = cas.make_response_from_ticket(ticket, service_url)
     assert_equal(resp.status_code, 302)
     assert_equal(resp.location, 'http://accounts.osf.io/')
示例#9
0
 def test_make_response_from_ticket_invalidates_verification_key(self, mock_service_validate):
     self.user.verification_key = fake.md5()
     self.user.save()
     mock_response = make_successful_response(self.user)
     mock_service_validate.return_value = mock_response
     ticket = fake.md5()
     service_url = 'http://accounts.osf.io/?ticket=' + ticket
     resp = cas.make_response_from_ticket(ticket, service_url)
示例#10
0
 def test_make_response_from_ticket_invalidates_verification_key(self, mock_service_validate):
     self.user.verification_key = fake.md5()
     self.user.save()
     mock_service_validate.return_value = make_successful_response(self.user)
     ticket = fake.md5()
     service_url = 'http://localhost:5000/'
     resp = cas.make_response_from_ticket(ticket, service_url)
     assert_true(self.user.verification_key is None)
 def test_make_response_from_ticket_invalidates_verification_key(self, mock_service_validate):
     self.user.verification_key = fake.md5()
     self.user.save()
     mock_response = make_successful_response(self.user)
     mock_service_validate.return_value = mock_response
     ticket = fake.md5()
     service_url = 'http://accounts.osf.io/?ticket=' + ticket
     resp = cas.make_response_from_ticket(ticket, service_url)
示例#12
0
 def test_make_response_from_ticket_success(self, mock_service_validate, mock_get_user_from_cas_resp):
     mock_service_validate.return_value = make_successful_response(self.user)
     mock_get_user_from_cas_resp.return_value = (self.user, None, 'authenticate')
     ticket = fake.md5()
     service_url = 'http://localhost:5000/'
     resp = cas.make_response_from_ticket(ticket, service_url)
     assert_equal(resp.status_code, 302)
     assert_equal(mock_service_validate.call_count, 1)
     assert_equal(mock_get_user_from_cas_resp.call_count, 1)
示例#13
0
 def test_make_response_from_ticket_failure(self, mock_service_validate, mock_get_user_from_cas_resp):
     mock_service_validate.return_value = make_failure_response()
     mock_get_user_from_cas_resp.return_value = (None, None, None)
     ticket = fake.md5()
     service_url = 'http://localhost:5000/'
     resp = cas.make_response_from_ticket(ticket, service_url)
     assert_equal(resp.status_code, 302)
     assert_equal(mock_service_validate.call_count, 1)
     assert_equal(mock_get_user_from_cas_resp.call_count, 0)
示例#14
0
 def test_make_response_from_ticket_invalidates_verification_key(self, mock_service_validate):
     self.user.verification_key = fake.md5()
     self.user.save()
     mock_service_validate.return_value = make_successful_response(self.user)
     ticket = fake.md5()
     service_url = 'http://localhost:5000/'
     resp = cas.make_response_from_ticket(ticket, service_url)
     self.user.reload()
     assert_true(self.user.verification_key is None)
 def test_make_response_from_ticket_failure(self, mock_service_validate, mock_get_user_from_cas_resp):
     mock_service_validate.return_value = make_failure_response()
     mock_get_user_from_cas_resp.return_value = (None, None, None)
     ticket = fake.md5()
     service_url = 'http://localhost:5000/'
     resp = cas.make_response_from_ticket(ticket, service_url)
     assert_equal(resp.status_code, 302)
     assert_equal(mock_service_validate.call_count, 1)
     assert_equal(mock_get_user_from_cas_resp.call_count, 0)
 def test_make_response_from_ticket_success(self, mock_service_validate, mock_get_user_from_cas_resp):
     mock_service_validate.return_value = make_successful_response(self.user)
     mock_get_user_from_cas_resp.return_value = (self.user, None, 'authenticate')
     ticket = fake.md5()
     service_url = 'http://localhost:5000/'
     resp = cas.make_response_from_ticket(ticket, service_url)
     assert_equal(resp.status_code, 302)
     assert_equal(mock_service_validate.call_count, 1)
     assert_equal(mock_get_user_from_cas_resp.call_count, 1)
示例#17
0
 def test_successful_external_first_login(self, mock_service_validate, mock_get_user_from_cas_resp):
     service_url = 'http://localhost:5000/dashboard/'
     _, validated_credentials, cas_resp = generate_external_user_with_resp(service_url, user=False)
     mock_service_validate.return_value = cas_resp
     mock_get_user_from_cas_resp.return_value = (None, validated_credentials, 'external_first_login')
     ticket = fake.md5()
     resp = cas.make_response_from_ticket(ticket, service_url)
     assert_equal(resp.status_code, 302, 'redirect to external login email get')
     assert_in('/external-login/email', resp.location)
示例#18
0
 def test_successful_external_first_login(self, mock_service_validate, mock_get_user_from_cas_resp):
     service_url = 'http://localhost:5000/dashboard/'
     _, validated_credentials, cas_resp = generate_external_user_with_resp(service_url, user=False)
     mock_service_validate.return_value = cas_resp
     mock_get_user_from_cas_resp.return_value = (None, validated_credentials, 'external_first_login')
     ticket = fake.md5()
     resp = cas.make_response_from_ticket(ticket, service_url)
     assert_equal(resp.status_code, 302, 'redirect to external login email get')
     assert_in('/external-login/email', resp.location)
示例#19
0
def before_request():
    from framework.auth import cas
    from website.util import time as util_time

    # Central Authentication Server Ticket Validation and Authentication
    ticket = request.args.get('ticket')
    if ticket:
        service_url = furl.furl(request.url)
        service_url.args.pop('ticket')
        # Attempt autn wih CAS, and return a proper redirect response
        return cas.make_response_from_ticket(ticket=ticket, service_url=service_url.url)

    if request.authorization:
        # TODO: Fix circular import
        from framework.auth.core import get_user
        user = get_user(
            email=request.authorization.username,
            password=request.authorization.password
        )
        # Create empty session
        # TODO: Shoudn't need to create a session for Basic Auth
        session = Session()
        set_session(session)

        if user:
            user_addon = user.get_addon('twofactor')
            if user_addon and user_addon.is_confirmed:
                otp = request.headers.get('X-OSF-OTP')
                if otp is None or not user_addon.verify_code(otp):
                    # Must specify two-factor authentication OTP code or invalid two-factor
                    # authentication OTP code.
                    session.data['auth_error_code'] = http.UNAUTHORIZED
                    return

            session.data['auth_user_username'] = user.username
            session.data['auth_user_id'] = user._primary_key
            session.data['auth_user_fullname'] = user.fullname
        else:
            # Invalid key: Not found in database
            session.data['auth_error_code'] = http.UNAUTHORIZED
        return

    cookie = request.cookies.get(settings.COOKIE_NAME)
    if cookie:
        try:
            session_id = itsdangerous.Signer(settings.SECRET_KEY).unsign(cookie)
            session = Session.load(session_id) or Session(_id=session_id)
        except itsdangerous.BadData:
            return

        if not util_time.throttle_period_expired(session.date_created, settings.OSF_SESSION_TIMEOUT):
            if session.data.get('auth_user_id') and 'api' not in request.url:
                database['user'].update({'_id': session.data.get('auth_user_id')}, {'$set': {'date_last_login': datetime.utcnow()}}, w=0)
            set_session(session)
        else:
            remove_session(session)
示例#20
0
 def test_make_response_from_ticket_invalidates_verification_key(self, mock_service_validate):
     self.user.verification_key = fake.md5()
     self.user.save()
     mock_response = make_external_response()
     validated_creds = cas.validate_external_credential(mock_response.user)
     self.user.external_identity = {validated_creds["provider"]: {validated_creds["id"]: "VERIFIED"}}
     self.user.save()
     mock_service_validate.return_value = mock_response
     ticket = fake.md5()
     service_url = "http://accounts.osf.io/?ticket=" + ticket
     resp = cas.make_response_from_ticket(ticket, service_url)
 def test_make_response_from_ticket_handles_unicode(self, mock_service_validate):
     mock_response = make_external_response(unicode=True)
     mock_service_validate.return_value = mock_response
     ticket = fake.md5()
     service_url = 'http://localhost:5000/'
     resp = cas.make_response_from_ticket(ticket, service_url)
     assert_equal(resp.status_code, 302)
     assert_equal(mock_service_validate.call_count, 1)
     first_call_args = mock_service_validate.call_args[0]
     assert_equal(first_call_args[0], ticket)
     assert_equal(first_call_args[1], 'http://localhost:5000/')
示例#22
0
 def test_make_response_from_ticket_handles_non_unicode(self, mock_service_validate):
     mock_response = make_external_response()
     mock_service_validate.return_value = mock_response
     ticket = fake.md5()
     service_url = "http://accounts.osf.io/?ticket=" + ticket
     resp = cas.make_response_from_ticket(ticket, service_url)
     assert_equal(resp.status_code, 302)
     assert_equal(mock_service_validate.call_count, 1)
     first_call_args = mock_service_validate.call_args[0]
     assert_equal(first_call_args[0], ticket)
     assert_equal(first_call_args[1], "http://accounts.osf.io/")
示例#23
0
 def test_successful_external_login_cas_redirect(self, mock_service_validate, mock_get_user_from_cas_resp):
     service_url = 'http://localhost:5000/dashboard/'
     user, validated_credentials, cas_resp = generate_external_user_with_resp(service_url)
     mock_service_validate.return_value = cas_resp
     mock_get_user_from_cas_resp.return_value = (user, validated_credentials, 'authenticate')
     ticket = fake.md5()
     resp = cas.make_response_from_ticket(ticket, service_url)
     assert_equal(resp.status_code, 302, 'redirect to CAS login')
     assert_in('/login?service=', resp.location)
     assert_in('username={}'.format(user.username), resp.location)
     assert_in('verification_key={}'.format(user.verification_key), resp.location)
示例#24
0
 def test_successful_external_login_cas_redirect(self, mock_service_validate, mock_get_user_from_cas_resp):
     user, validated_credentials, cas_resp = generate_external_user_with_resp()
     mock_service_validate.return_value = cas_resp
     mock_get_user_from_cas_resp.return_value = (user, validated_credentials, 'authenticate')
     ticket = fake.md5()
     service_url = 'http://accounts.osf.io/?ticket=' + ticket
     resp = cas.make_response_from_ticket(ticket, service_url)
     assert_equal(resp.status_code, 302, 'redirect to CAS login')
     assert_in('/login?service=', resp.location)
     assert_in('username={}'.format(user.username), resp.location)
     assert_in('verification_key={}'.format(user.verification_key), resp.location)
 def test_make_response_from_ticket_success(self, mock_service_validate):
     mock_response = make_successful_response(self.user)
     mock_service_validate.return_value = mock_response
     ticket = fake.md5()
     service_url = 'http://accounts.osf.io/?ticket=' + ticket
     resp = cas.make_response_from_ticket(ticket, service_url)
     assert_equal(resp.status_code, 302)
     mock_service_validate.assert_called_once()
     first_call_args = mock_service_validate.call_args[0]
     assert_equal(first_call_args[0], ticket)
     assert_equal(first_call_args[1], 'http://accounts.osf.io/')
示例#26
0
 def test_make_response_from_ticket_handles_non_unicode(self, mock_service_validate):
     mock_response = make_external_response()
     mock_service_validate.return_value = mock_response
     ticket = fake.md5()
     service_url = 'http://localhost:5000/'
     resp = cas.make_response_from_ticket(ticket, service_url)
     assert_equal(resp.status_code, 302)
     assert_equal(mock_service_validate.call_count, 1)
     first_call_args = mock_service_validate.call_args[0]
     assert_equal(first_call_args[0], ticket)
     assert_equal(first_call_args[1], 'http://localhost:5000/')
示例#27
0
 def test_make_response_from_ticket_success(self, mock_service_validate):
     mock_response = make_successful_response(self.user)
     mock_service_validate.return_value = mock_response
     ticket = fake.md5()
     service_url = 'http://accounts.osf.io/?ticket=' + ticket
     resp = cas.make_response_from_ticket(ticket, service_url)
     assert_equal(resp.status_code, 302)
     mock_service_validate.assert_called_once()
     first_call_args = mock_service_validate.call_args[0]
     assert_equal(first_call_args[0], ticket)
     assert_equal(first_call_args[1], 'http://accounts.osf.io/')
 def test_make_response_from_ticket_no_user(self, mock_service_validate, mock_get_user_from_cas_resp):
     mock_response = make_external_response()
     mock_service_validate.return_value = mock_response
     validated_creds = cas.validate_external_credential(mock_response.user)
     mock_get_user_from_cas_resp.return_value = (None, validated_creds, 'external_first_login')
     ticket = fake.md5()
     service_url = 'http://localhost:5000/'
     resp = cas.make_response_from_ticket(ticket, service_url)
     assert_equal(mock_service_validate.call_count, 1)
     assert_true(mock_get_user_from_cas_resp.call_count, 1)
     assert_equal(resp.status_code, 302)
     assert_equal(resp.location, '/external-login/email')
示例#29
0
 def test_make_response_from_ticket_no_user(self, mock_service_validate, mock_get_user_from_cas_resp):
     mock_response = make_external_response()
     mock_service_validate.return_value = mock_response
     validated_creds = cas.validate_external_credential(mock_response.user)
     mock_get_user_from_cas_resp.return_value = (None, validated_creds, 'external_first_login')
     ticket = fake.md5()
     service_url = 'http://localhost:5000/'
     resp = cas.make_response_from_ticket(ticket, service_url)
     assert_equal(mock_service_validate.call_count, 1)
     assert_true(mock_get_user_from_cas_resp.call_count, 1)
     assert_equal(resp.status_code, 302)
     assert_equal(resp.location, '/external-login/email')
示例#30
0
 def test_make_response_from_ticket_handles_unicode(self,
                                                    mock_service_validate):
     mock_response = make_external_response(unicode=True)
     mock_service_validate.return_value = mock_response
     ticket = fake.md5()
     service_url = 'http://accounts.osf.io/?ticket=' + ticket
     resp = cas.make_response_from_ticket(ticket, service_url)
     assert_equal(resp.status_code, 302)
     assert_equal(mock_service_validate.call_count, 1)
     first_call_args = mock_service_validate.call_args[0]
     assert_equal(first_call_args[0], ticket)
     assert_equal(first_call_args[1], 'http://accounts.osf.io/')
示例#31
0
def before_request():
    from framework.auth import cas

    # Central Authentication Server Ticket Validation and Authentication
    ticket = request.args.get('ticket')
    if ticket:
        service_url = furl.furl(request.url)
        service_url.args.pop('ticket')
        # Attempt autn wih CAS, and return a proper redirect response
        resp = cas.make_response_from_ticket(ticket=ticket, service_url=service_url.url)
        if request.cookies.get(settings.COOKIE_NAME):
            # TODO: Delete legacy cookie, this special case can be removed anytime after 1/1/2016.
            # A cookie is received which could potentially be a legacy (pre multi-domain) cookie.
            # Issuing a targeted delete of the legacy cookie ensures the user does not end up in a
            # login loop whereby both cookies are sent to the server and one of them at random
            # read for authentication.
            resp.delete_cookie(settings.COOKIE_NAME, domain=None)
        return resp

    if request.authorization:
        # TODO: Fix circular import
        from framework.auth.core import get_user
        user = get_user(
            email=request.authorization.username,
            password=request.authorization.password
        )
        # Create empty session
        # TODO: Shoudn't need to create a session for Basic Auth
        session = Session()

        if user:
            session.data['auth_user_username'] = user.username
            session.data['auth_user_id'] = user._primary_key
            session.data['auth_user_fullname'] = user.fullname
            user.date_last_login = datetime.utcnow()
            user.save()
        else:
            # Invalid key: Not found in database
            session.data['auth_error_code'] = http.FORBIDDEN

        set_session(session)
        return

    cookie = request.cookies.get(settings.COOKIE_NAME)
    if cookie:
        try:
            session_id = itsdangerous.Signer(settings.SECRET_KEY).unsign(cookie)
            session = Session.load(session_id) or Session(_id=session_id)
        except itsdangerous.BadData:
            return
        if session.data.get('auth_user_id'):
            database['user'].update({'_id': session.data.get('auth_user_id')}, {'$set': {'date_last_login': datetime.utcnow()}}, w=0)
        set_session(session)
示例#32
0
    def test_can_reset_password_if_form_success(self, mock_service_validate):
        # load reset password page and submit email
        res = self.app.get(self.get_url)
        form = res.forms['resetPasswordForm']
        form['password'] = '******'
        form['password2'] = 'newpassword'
        res = form.submit()

        # check request URL is /resetpassword with username and new verification_key_v2 token
        request_url_path = res.request.path
        assert_in('resetpassword', request_url_path)
        assert_in(self.user._id, request_url_path)
        assert_not_in(self.user.verification_key_v2['token'], request_url_path)

        # check verification_key_v2 for OSF is destroyed and verification_key for CAS is in place
        self.user.reload()
        assert_equal(self.user.verification_key_v2, {})
        assert_not_equal(self.user.verification_key, None)

        # check redirection to CAS login with username and the new verification_key(CAS)
        assert_equal(res.status_code, 302)
        location = res.headers.get('Location')
        assert_true('login?service=' in location)
        assert_true('username={}'.format(self.user.username) in location)
        assert_true('verification_key={}'.format(self.user.verification_key) in
                    location)

        # check if password was updated
        self.user.reload()
        assert_true(self.user.check_password('newpassword'))

        # check if verification_key is destroyed after service validation
        mock_service_validate.return_value = cas.CasResponse(
            authenticated=True,
            user=self.user._primary_key,
            attributes={'accessToken': fake.md5()})
        ticket = fake.md5()
        service_url = 'http://accounts.osf.io/?ticket=' + ticket
        cas.make_response_from_ticket(ticket, service_url)
        assert_equal(self.user.verification_key, None)
示例#33
0
    def test_can_reset_password_if_form_success(self, mock_service_validate):
        # load reset password page and submit email
        res = self.app.get(self.get_url)
        form = res.forms['resetPasswordForm']
        form['password'] = '******'
        form['password2'] = 'newpassword'
        res = form.submit()

        # check request URL is /resetpassword with username and new verification_key_v2 token
        request_url_path = res.request.path
        assert_in('resetpassword', request_url_path)
        assert_in(self.user._id, request_url_path)
        assert_not_in(self.user.verification_key_v2['token'], request_url_path)

        # check verification_key_v2 for OSF is destroyed and verification_key for CAS is in place
        self.user.reload()
        assert_equal(self.user.verification_key_v2, {})
        assert_not_equal(self.user.verification_key, None)

        # check redirection to CAS login with username and the new verification_key(CAS)
        assert_equal(res.status_code, 302)
        location = res.headers.get('Location')
        assert_true('login?service=' in location)
        assert_true('username={}'.format(self.user.username) in location)
        assert_true('verification_key={}'.format(self.user.verification_key) in location)

        # check if password was updated
        self.user.reload()
        assert_true(self.user.check_password('newpassword'))

        # check if verification_key is destroyed after service validation
        mock_service_validate.return_value = cas.CasResponse(
            authenticated=True,
            user=self.user._primary_key,
            attributes={'accessToken': fake.md5()}
        )
        ticket = fake.md5()
        service_url = 'http://accounts.osf.io/?ticket=' + ticket
        cas.make_response_from_ticket(ticket, service_url)
        assert_equal(self.user.verification_key, None)
示例#34
0
    def test_successful_external_login_cas_redirect(self, mock_service_validate, mock_get_user_from_cas_resp):
        service_url = 'http://*****:*****@'), safe='@')
        assert_in('username={}'.format(username_quoted), resp.location)
        assert_in('verification_key={}'.format(user.verification_key), resp.location)
示例#35
0
 def test_make_response_from_ticket_with_user(self, mock_service_validate):
     mock_response = make_external_response()
     mock_service_validate.return_value = mock_response
     validated_creds = cas.validate_external_credential(mock_response.user)
     self.user.external_identity = {validated_creds["provider"]: {validated_creds["id"]: "VERIFIED"}}
     self.user.save()
     ticket = fake.md5()
     service_url = "http://accounts.osf.io/?ticket=" + ticket
     resp = cas.make_response_from_ticket(ticket, service_url)
     assert_equal(resp.status_code, 302)
     assert_equal(mock_service_validate.call_count, 1)
     first_call_args = mock_service_validate.call_args[0]
     assert_equal(first_call_args[0], ticket)
     assert_equal(first_call_args[1], "http://accounts.osf.io/")
示例#36
0
    def test_successful_external_login_cas_redirect(self, mock_service_validate, mock_get_user_from_cas_resp):
        service_url = 'http://*****:*****@'), safe='@')
        assert_in('username={}'.format(username_quoted), resp.location)
        assert_in('verification_key={}'.format(user.verification_key), resp.location)
示例#37
0
文件: __init__.py 项目: hmoco/osf.io
def before_request():
    from framework.auth import cas

    # Central Authentication Server Ticket Validation and Authentication
    ticket = request.args.get('ticket')
    if ticket:
        service_url = furl.furl(request.url)
        service_url.args.pop('ticket')
        # Attempt autn wih CAS, and return a proper redirect response
        resp = cas.make_response_from_ticket(ticket=ticket, service_url=service_url.url)
        if request.cookies.get(settings.COOKIE_NAME):
            # TODO: Delete legacy cookie, this special case can be removed anytime after 1/1/2016.
            # A cookie is received which could potentially be a legacy (pre multi-domain) cookie.
            # Issuing a targeted delete of the legacy cookie ensures the user does not end up in a
            # login loop whereby both cookies are sent to the server and one of them at random
            # read for authentication.
            resp.delete_cookie(settings.COOKIE_NAME, domain=None)
        return resp

    if request.authorization:
        # TODO: Fix circular import
        from framework.auth.core import get_user
        user = get_user(
            email=request.authorization.username,
            password=request.authorization.password
        )
        # Create empty session
        # TODO: Shoudn't need to create a session for Basic Auth
        session = Session()

        if user:
            session.data['auth_user_username'] = user.username
            session.data['auth_user_id'] = user._primary_key
            session.data['auth_user_fullname'] = user.fullname
        else:
            # Invalid key: Not found in database
            session.data['auth_error_code'] = http.FORBIDDEN

        set_session(session)
        return

    cookie = request.cookies.get(settings.COOKIE_NAME)
    if cookie:
        try:
            session_id = itsdangerous.Signer(settings.SECRET_KEY).unsign(cookie)
            session = Session.load(session_id) or Session(_id=session_id)
            set_session(session)
            return
        except:
            pass
示例#38
0
 def test_make_response_from_ticket_invalidates_verification_key(self, mock_service_validate):
     self.user.verification_key = fake.md5()
     self.user.save()
     mock_response = make_external_response()
     validated_creds = cas.validate_external_credential(mock_response.user)
     self.user.external_identity = {
         validated_creds['provider']: {
             validated_creds['id']: 'VERIFIED'
         }
     }
     self.user.save()
     mock_service_validate.return_value = mock_response
     ticket = fake.md5()
     service_url = 'http://accounts.osf.io/?ticket=' + ticket
     resp = cas.make_response_from_ticket(ticket, service_url)
示例#39
0
 def test_make_response_from_ticket_generates_new_verification_key(self, mock_service_validate):
     self.user.verification_key = fake.md5()
     self.user.save()
     mock_response = make_external_response()
     validated_creds = cas.validate_external_credential(mock_response.user)
     self.user.external_identity = {
         validated_creds['provider']: {
             validated_creds['id']: 'VERIFIED'
         }
     }
     self.user.save()
     mock_service_validate.return_value = mock_response
     ticket = fake.md5()
     service_url = 'http://localhost:5000/'
     verification_key = self.user.verification_key
     resp = cas.make_response_from_ticket(ticket, service_url)
     assert_not_equal(self.user.verification_key, verification_key)
示例#40
0
 def test_make_response_from_ticket_with_user(self, mock_service_validate):
     mock_response = make_external_response()
     mock_service_validate.return_value = mock_response
     validated_creds = cas.validate_external_credential(mock_response.user)
     self.user.external_identity = {
         validated_creds['provider']: {
             validated_creds['id']: 'VERIFIED'
         }
     }
     self.user.save()
     ticket = fake.md5()
     service_url = 'http://accounts.osf.io/?ticket=' + ticket
     resp = cas.make_response_from_ticket(ticket, service_url)
     assert_equal(resp.status_code, 302)
     assert_equal(mock_service_validate.call_count, 1)
     first_call_args = mock_service_validate.call_args[0]
     assert_equal(first_call_args[0], ticket)
     assert_equal(first_call_args[1], 'http://accounts.osf.io/')
示例#41
0
 def test_make_response_from_ticket_generates_new_verification_key(self, mock_service_validate):
     self.user.verification_key = fake.md5()
     self.user.save()
     mock_response = make_external_response()
     validated_creds = cas.validate_external_credential(mock_response.user)
     self.user.external_identity = {
         validated_creds['provider']: {
             validated_creds['id']: 'VERIFIED'
         }
     }
     self.user.save()
     mock_service_validate.return_value = mock_response
     ticket = fake.md5()
     service_url = 'http://localhost:5000/'
     verification_key = self.user.verification_key
     resp = cas.make_response_from_ticket(ticket, service_url)
     self.user.reload()
     assert_not_equal(self.user.verification_key, verification_key)
示例#42
0
 def test_make_response_from_ticket_with_user(self, mock_service_validate, mock_get_user_from_cas_resp):
     mock_response = make_external_response()
     mock_service_validate.return_value = mock_response
     validated_creds = cas.validate_external_credential(mock_response.user)
     self.user.external_identity = {
         validated_creds['provider']: {
             validated_creds['id']: 'VERIFIED'
         }
     }
     self.user.save()
     mock_get_user_from_cas_resp.return_value = (self.user, validated_creds, 'authenticate')
     ticket = fake.md5()
     service_url = 'http://localhost:5000/'
     resp = cas.make_response_from_ticket(ticket, service_url)
     assert_equal(mock_service_validate.call_count, 1)
     assert_true(mock_get_user_from_cas_resp.call_count, 1)
     assert_equal(resp.status_code, 302)
     assert_in('/logout?service=', resp.headers['Location'])
     assert_in('/login?service=', resp.headers['Location'])
 def test_make_response_from_ticket_with_user(self, mock_service_validate, mock_get_user_from_cas_resp):
     mock_response = make_external_response()
     mock_service_validate.return_value = mock_response
     validated_creds = cas.validate_external_credential(mock_response.user)
     self.user.external_identity = {
         validated_creds['provider']: {
             validated_creds['id']: 'VERIFIED'
         }
     }
     self.user.save()
     mock_get_user_from_cas_resp.return_value = (self.user, validated_creds, 'authenticate')
     ticket = fake.md5()
     service_url = 'http://localhost:5000/'
     resp = cas.make_response_from_ticket(ticket, service_url)
     assert_equal(mock_service_validate.call_count, 1)
     assert_true(mock_get_user_from_cas_resp.call_count, 1)
     assert_equal(resp.status_code, 302)
     assert_in('/logout?service=', resp.headers['Location'])
     assert_in('/login?service=', resp.headers['Location'])
示例#44
0
def before_request():
    from framework.auth import cas

    # Central Authentication Server Ticket Validation and Authentication
    ticket = request.args.get('ticket')
    if ticket:
        service_url = furl.furl(request.url)
        service_url.args.pop('ticket')
        # Attempt autn wih CAS, and return a proper redirect response
        return cas.make_response_from_ticket(ticket=ticket, service_url=service_url.url)

    if request.authorization:
        # TODO: Fix circular import
        from framework.auth.core import get_user
        user = get_user(
            email=request.authorization.username,
            password=request.authorization.password
        )
        # Create empty session
        # TODO: Shoudn't need to create a session for Basic Auth
        session = Session()

        if user:
            session.data['auth_user_username'] = user.username
            session.data['auth_user_id'] = user._primary_key
            session.data['auth_user_fullname'] = user.fullname
        else:
            # Invalid key: Not found in database
            session.data['auth_error_code'] = http.FORBIDDEN

        set_session(session)
        return

    cookie = request.cookies.get(settings.COOKIE_NAME)
    if cookie:
        try:
            session_id = itsdangerous.Signer(settings.SECRET_KEY).unsign(cookie)
            session = Session.load(session_id) or Session(_id=session_id)
            set_session(session)
            return
        except:
            pass
示例#45
0
def before_request():
    from framework.auth import cas

    # Central Authentication Server Ticket Validation and Authentication
    ticket = request.args.get('ticket')
    if ticket:
        service_url = furl.furl(request.url)
        service_url.args.pop('ticket')
        # Attempt autn wih CAS, and return a proper redirect response
        return cas.make_response_from_ticket(ticket=ticket,
                                             service_url=service_url.url)

    if request.authorization:
        # TODO: Fix circular import
        from framework.auth.core import get_user
        user = get_user(email=request.authorization.username,
                        password=request.authorization.password)
        # Create empty session
        # TODO: Shoudn't need to create a session for Basic Auth
        session = Session()

        if user:
            session.data['auth_user_username'] = user.username
            session.data['auth_user_id'] = user._primary_key
            session.data['auth_user_fullname'] = user.fullname
        else:
            # Invalid key: Not found in database
            session.data['auth_error_code'] = http.FORBIDDEN

        set_session(session)
        return

    cookie = request.cookies.get(settings.COOKIE_NAME)
    if cookie:
        try:
            session_id = itsdangerous.Signer(
                settings.SECRET_KEY).unsign(cookie)
            session = Session.load(session_id) or Session(_id=session_id)
            set_session(session)
            return
        except:
            pass
示例#46
0
def before_request():
    from framework import sentry
    from framework.auth import cas
    from framework.auth.core import User
    from framework.auth import authenticate
    from framework.routing import json_renderer

    # Central Authentication Server Ticket Validation and Authentication
    ticket = request.args.get('ticket')
    if ticket:
        service_url = furl.furl(request.url)
        service_url.args.pop('ticket')
        # Attempt autn wih CAS, and return a proper redirect response
        return cas.make_response_from_ticket(ticket=ticket,
                                             service_url=service_url.url)

    # Central Authentication Server OAuth Bearer Token
    authorization = request.headers.get('Authorization')
    if authorization and authorization.startswith('Bearer '):
        client = cas.get_client()
        try:
            access_token = cas.parse_auth_header(authorization)
            cas_resp = client.profile(access_token)
        except cas.CasError as err:
            sentry.log_exception()
            # NOTE: We assume that the request is an AJAX request
            return json_renderer(err)
        if cas_resp.authenticated:
            user = User.load(cas_resp.user)
            return authenticate(user, access_token=access_token, response=None)
        return make_response('', http.UNAUTHORIZED)

    if request.authorization:
        # TODO: Fix circular import
        from framework.auth.core import get_user
        user = get_user(email=request.authorization.username,
                        password=request.authorization.password)
        # Create empty session
        # TODO: Shoudn't need to create a session for Basic Auth
        session = Session()

        if user:
            session.data['auth_user_username'] = user.username
            session.data['auth_user_id'] = user._primary_key
            session.data['auth_user_fullname'] = user.fullname
        else:
            # Invalid key: Not found in database
            session.data['auth_error_code'] = http.FORBIDDEN

        set_session(session)
        return

    cookie = request.cookies.get(settings.COOKIE_NAME)
    if cookie:
        try:
            session_id = itsdangerous.Signer(
                settings.SECRET_KEY).unsign(cookie)
            session = Session.load(session_id) or Session(_id=session_id)
            set_session(session)
            return
        except:
            pass
示例#47
0
文件: __init__.py 项目: leb2dg/osf.io
def before_request():
    # TODO: Fix circular import
    from framework.auth.core import get_user
    from framework.auth import cas
    from website.util import time as util_time
    Session = apps.get_model('osf.Session')

    # Central Authentication Server Ticket Validation and Authentication
    ticket = request.args.get('ticket')
    if ticket:
        service_url = furl.furl(request.url)
        service_url.args.pop('ticket')
        # Attempt to authenticate wih CAS, and return a proper redirect response
        return cas.make_response_from_ticket(ticket=ticket, service_url=service_url.url)

    if request.authorization:
        user = get_user(
            email=request.authorization.username,
            password=request.authorization.password
        )
        # Create an empty session
        # TODO: Shoudn't need to create a session for Basic Auth
        user_session = Session()
        set_session(user_session)

        if user:
            user_addon = user.get_addon('twofactor')
            if user_addon and user_addon.is_confirmed:
                otp = request.headers.get('X-OSF-OTP')
                if otp is None or not user_addon.verify_code(otp):
                    # Must specify two-factor authentication OTP code or invalid two-factor authentication OTP code.
                    user_session.data['auth_error_code'] = http.UNAUTHORIZED
                    return
            user_session.data['auth_user_username'] = user.username
            user_session.data['auth_user_fullname'] = user.fullname
            if user_session.data.get('auth_user_id', None) != user._primary_key:
                user_session.data['auth_user_id'] = user._primary_key
                user_session.save()
        else:
            # Invalid key: Not found in database
            user_session.data['auth_error_code'] = http.UNAUTHORIZED
        return

    cookie = request.cookies.get(settings.COOKIE_NAME)
    if cookie:
        try:
            session_id = itsdangerous.Signer(settings.SECRET_KEY).unsign(cookie)
            user_session = Session.load(session_id) or Session(_id=session_id)
        except itsdangerous.BadData:
            return
        if not util_time.throttle_period_expired(user_session.created, settings.OSF_SESSION_TIMEOUT):
            # Update date last login when making non-api requests
            if user_session.data.get('auth_user_id') and 'api' not in request.url:
                OSFUser = apps.get_model('osf.OSFUser')
                (
                    OSFUser.objects
                    .filter(guids___id__isnull=False, guids___id=user_session.data['auth_user_id'])
                    # Throttle updates
                    .filter(Q(date_last_login__isnull=True) | Q(date_last_login__lt=timezone.now() - dt.timedelta(seconds=settings.DATE_LAST_LOGIN_THROTTLE)))
                ).update(date_last_login=timezone.now())
            set_session(user_session)
        else:
            remove_session(user_session)
示例#48
0
def before_request():
    from framework.auth import authenticate
    from framework.auth.core import User
    from framework.auth import cas

    # Central Authentication Server Ticket Validation and Authentication
    ticket = request.args.get('ticket')
    if ticket:
        service_url = furl.furl(request.url)
        service_url.args.pop('ticket')
        # Attempt autn wih CAS, and return a proper redirect response
        return cas.make_response_from_ticket(ticket=ticket,
                                             service_url=service_url.url)

    # Central Authentication Server OAuth Bearer Token
    authorization = request.headers.get('Authorization')
    if authorization and authorization.startswith('Bearer '):
        client = cas.get_client()
        try:
            access_token = cas.parse_auth_header(authorization)
        except cas.CasTokenError as err:
            # NOTE: We assume that the request is an AJAX request
            return jsonify({
                'message_short': 'Invalid Bearer token',
                'message_long': err.args[0]
            }), http.UNAUTHORIZED
        cas_resp = client.profile(access_token)
        if cas_resp.authenticated:
            user = User.load(cas_resp.user)
            return authenticate(user, access_token=access_token, response=None)
        return make_response('', http.UNAUTHORIZED)

    if request.authorization:
        # Create a session from the API key; if key is
        # not valid, save the HTTP error code in the
        # "auth_error_code" field of session.data

        # Create empty session
        session = Session()

        # Hack: Avoid circular import
        from website.project.model import ApiKey

        api_label = request.authorization.username
        api_key_id = request.authorization.password
        api_key = ApiKey.load(api_key_id)

        if api_key:
            user = api_key.user__keyed and api_key.user__keyed[0]
            node = api_key.node__keyed and api_key.node__keyed[0]

            session.data['auth_api_label'] = api_label
            session.data['auth_api_key'] = api_key._primary_key
            if user:
                session.data['auth_user_username'] = user.username
                session.data['auth_user_id'] = user._primary_key
                session.data['auth_user_fullname'] = user.fullname
            elif node:
                session.data['auth_node_id'] = node._primary_key
            else:
                # Invalid key: Not attached to user or node
                session.data['auth_error_code'] = http.FORBIDDEN
        else:
            # Invalid key: Not found in database
            session.data['auth_error_code'] = http.FORBIDDEN

        set_session(session)
        return

    cookie = request.cookies.get(settings.COOKIE_NAME)
    if cookie:
        try:
            session_id = itsdangerous.Signer(
                settings.SECRET_KEY).unsign(cookie)
            session = Session.load(session_id) or Session(_id=session_id)
            set_session(session)
            return
        except:
            pass
    ## TODO: Create session in before_request, cookie in after_request
    ## Retry request, preserving status code
    #response = redirect(request.path, code=307)
    return create_session(None)
示例#49
0
def before_request():
    # TODO: Fix circular import
    from framework.auth.core import get_user
    from framework.auth import cas
    from framework.utils import throttle_period_expired
    Session = apps.get_model('osf.Session')

    # Central Authentication Server Ticket Validation and Authentication
    ticket = request.args.get('ticket')
    if ticket:
        service_url = furl.furl(request.url)
        service_url.args.pop('ticket')
        # Attempt to authenticate wih CAS, and return a proper redirect response
        return cas.make_response_from_ticket(ticket=ticket,
                                             service_url=service_url.url)

    if request.authorization:
        user = get_user(email=request.authorization.username,
                        password=request.authorization.password)
        # Create an empty session
        # TODO: Shoudn't need to create a session for Basic Auth
        user_session = Session()
        set_session(user_session)

        if user:
            user_addon = user.get_addon('twofactor')
            if user_addon and user_addon.is_confirmed:
                otp = request.headers.get('X-OSF-OTP')
                if otp is None or not user_addon.verify_code(otp):
                    # Must specify two-factor authentication OTP code or invalid two-factor authentication OTP code.
                    user_session.data[
                        'auth_error_code'] = http_status.HTTP_401_UNAUTHORIZED
                    return
            user_session.data['auth_user_username'] = user.username
            user_session.data['auth_user_fullname'] = user.fullname
            if user_session.data.get('auth_user_id',
                                     None) != user._primary_key:
                user_session.data['auth_user_id'] = user._primary_key
                user_session.save()
        else:
            # Invalid key: Not found in database
            user_session.data[
                'auth_error_code'] = http_status.HTTP_401_UNAUTHORIZED
        return

    cookie = request.cookies.get(settings.COOKIE_NAME)
    if cookie:
        try:
            session_id = itsdangerous.Signer(
                settings.SECRET_KEY).unsign(cookie)
            user_session = Session.load(session_id) or Session(_id=session_id)
        except itsdangerous.BadData:
            return
        if not throttle_period_expired(user_session.created,
                                       settings.OSF_SESSION_TIMEOUT):
            # Update date last login when making non-api requests
            if user_session.data.get(
                    'auth_user_id') and 'api' not in request.url:
                OSFUser = apps.get_model('osf.OSFUser')
                (OSFUser.objects.filter(
                    guids___id__isnull=False,
                    guids___id=user_session.data['auth_user_id'])
                 # Throttle updates
                 .filter(
                     Q(date_last_login__isnull=True)
                     | Q(date_last_login__lt=timezone.now() - dt.timedelta(
                         seconds=settings.DATE_LAST_LOGIN_THROTTLE)))).update(
                             date_last_login=timezone.now())
            set_session(user_session)
        else:
            remove_session(user_session)
示例#50
0
def before_request():
    from framework.auth import authenticate
    from framework.auth.core import User
    from framework.auth import cas

    # Central Authentication Server Ticket Validation and Authentication
    ticket = request.args.get('ticket')
    if ticket:
        service_url = furl.furl(request.url)
        service_url.args.pop('ticket')
        # Attempt autn wih CAS, and return a proper redirect response
        return cas.make_response_from_ticket(ticket=ticket, service_url=service_url.url)

    # Central Authentication Server OAuth Bearer Token
    authorization = request.headers.get('Authorization')
    if authorization and authorization.startswith('Bearer '):
        client = cas.get_client()
        try:
            access_token = cas.parse_auth_header(authorization)
        except cas.CasTokenError as err:
            # NOTE: We assume that the request is an AJAX request
            return jsonify({'message_short': 'Invalid Bearer token', 'message_long': err.args[0]}), http.UNAUTHORIZED
        cas_resp = client.profile(access_token)
        if cas_resp.authenticated:
            user = User.load(cas_resp.user)
            return authenticate(user, access_token=access_token, response=None)
        return make_response('', http.UNAUTHORIZED)

    if request.authorization:
        # Create a session from the API key; if key is
        # not valid, save the HTTP error code in the
        # "auth_error_code" field of session.data

        # Create empty session
        session = Session()

        # Hack: Avoid circular import
        from website.project.model import ApiKey

        api_label = request.authorization.username
        api_key_id = request.authorization.password
        api_key = ApiKey.load(api_key_id)

        if api_key:
            user = api_key.user__keyed and api_key.user__keyed[0]
            node = api_key.node__keyed and api_key.node__keyed[0]

            session.data['auth_api_label'] = api_label
            session.data['auth_api_key'] = api_key._primary_key
            if user:
                session.data['auth_user_username'] = user.username
                session.data['auth_user_id'] = user._primary_key
                session.data['auth_user_fullname'] = user.fullname
            elif node:
                session.data['auth_node_id'] = node._primary_key
            else:
                # Invalid key: Not attached to user or node
                session.data['auth_error_code'] = http.FORBIDDEN
        else:
            # Invalid key: Not found in database
            session.data['auth_error_code'] = http.FORBIDDEN

        set_session(session)
        return

    cookie = request.cookies.get(settings.COOKIE_NAME)
    if cookie:
        try:
            session_id = itsdangerous.Signer(settings.SECRET_KEY).unsign(cookie)
            session = Session.load(session_id) or Session(_id=session_id)
            set_session(session)
            return
        except:
            pass
    ## TODO: Create session in before_request, cookie in after_request
    ## Retry request, preserving status code
    #response = redirect(request.path, code=307)
    return create_session(None)