Exemplo n.º 1
0
    def decorated_function(*args, **kwargs):
        add_auth_attribute('login_required', True)

        # Check if http referrer and given client id match a registered client
        if ('client_id' in request.values and 'session' in request.values
                and request.referrer):
            client_cred = AuthClientCredential.get(request.values['client_id'])
            if client_cred is not None and get_scheme_netloc(
                    client_cred.auth_client.website) == get_scheme_netloc(
                        request.referrer):
                if UserSession.authenticate(
                        buid=request.values['session']) is not None:
                    return f(*args, **kwargs)

        # If we didn't get a valid client_id and session, maybe there's a user?
        if current_auth.is_authenticated:
            return f(*args, **kwargs)

        # If user is not logged in, check for client credentials in the request authorization header.
        # If no error reported, call the function, else return error.
        result = _client_login_inner()
        if result is None:
            return f(*args, **kwargs)
        else:
            return result
Exemplo n.º 2
0
 def decorated_function(*args, **kwargs):
     add_auth_attribute('login_required', True)
     if not current_auth.is_authenticated:
         flash(_(u"You need to be logged in for that page"), 'info')
         session['next'] = get_current_url()
         return redirect(url_for('login'))
     return f(*args, **kwargs)
Exemplo n.º 3
0
 def decorated_function(*args, **kwargs):
     add_auth_attribute('login_required', True)
     if not current_auth.is_authenticated:
         flash(_("You need to be logged in for that page"), 'info')
         session['next'] = get_current_url()
         return redirect(url_for('login'))
     return f(*args, **kwargs)
Exemplo n.º 4
0
 def decorated_function(*args, **kwargs):
     add_auth_attribute('login_required', True)
     if not current_auth.is_authenticated:
         session['next'] = get_current_url()
         if 'message' in request.args and request.args['message']:
             flash(request.args['message'], 'info')
         return redirect(url_for('login'))
     return f(*args, **kwargs)
Exemplo n.º 5
0
 def decorated_function(*args, **kwargs):
     add_auth_attribute('login_required', True)
     if not current_auth.is_authenticated:
         session['next'] = get_current_url()
         if 'message' in request.args and request.args['message']:
             flash(request.args['message'], 'info')
         return redirect(url_for('login'))
     return f(*args, **kwargs)
Exemplo n.º 6
0
def login_internal(user):
    add_auth_attribute('user', user)
    usersession = UserSession(user=user)
    usersession.access()
    add_auth_attribute('session', usersession)
    current_auth.cookie['sessionid'] = usersession.buid
    current_auth.cookie['userid'] = user.buid
    session.permanent = True
    autoset_timezone(user)
    user_login.send(user)
Exemplo n.º 7
0
def login_internal(user):
    add_auth_attribute('user', user)
    usersession = UserSession(user=user)
    usersession.access()
    add_auth_attribute('session', usersession)
    current_auth.cookie['sessionid'] = usersession.buid
    current_auth.cookie['userid'] = user.buid
    session.permanent = True
    autoset_timezone(user)
    user_login.send(user)
Exemplo n.º 8
0
 def decorated_function(*args, **kwargs):
     add_auth_attribute('login_required', True)
     # Check for user first:
     if current_auth.is_authenticated:
         return f(*args, **kwargs)
     # If user is not logged in, check for client
     result = _client_login_inner()
     if result is None:
         return f(*args, **kwargs)
     return result
Exemplo n.º 9
0
 def test_invalid_auth_attribute(self):
     for attr in (
             'actor',
             'anchors',
             'is_anonymous',
             'not_anonymous',
             'is_authenticated',
             'not_authenticated',
     ):
         with pytest.raises(AttributeError):
             add_auth_attribute(attr, None)
Exemplo n.º 10
0
 def decorated_function(*args, **kwargs):
     add_auth_attribute('login_required', True)
     # Check for user first:
     if current_auth.is_authenticated:
         return f(*args, **kwargs)
     # If user is not logged in, check for client
     result = _client_login_inner()
     if result is None:
         return f(*args, **kwargs)
     else:
         return result
Exemplo n.º 11
0
 def test_currently_available_transitions(self):
     """State managers indicate the currently available transitions (using current_auth)"""
     assert self.post.state.DRAFT
     assert 'submit' not in self.post.state.transitions()
     add_auth_attribute(
         'user', 'author'
     )  # Add a user using the string 'author' (see MyPost.roles_for)
     assert 'submit' in self.post.state.transitions()
     self.post.state.transitions()['submit']()
     assert not self.post.state.DRAFT
     assert self.post.state.PENDING
Exemplo n.º 12
0
 def test_currently_available_transitions(self):
     """State managers indicate the currently available transitions (using current_auth)"""
     self.assertTrue(self.post.state.DRAFT)
     self.assertNotIn('submit', self.post.state.transitions())
     add_auth_attribute(
         'user', 'author'
     )  # Add a user using the string 'author' (see MyPost.roles_for)
     self.assertIn('submit', self.post.state.transitions())
     self.post.state.transitions()['submit']()
     self.assertFalse(self.post.state.DRAFT)
     self.assertTrue(self.post.state.PENDING)
Exemplo n.º 13
0
def _client_login_inner():
    if request.authorization is None or not request.authorization.username:
        return Response('Client credentials required', 401,
            {'WWW-Authenticate': 'Basic realm="Client credentials"'})
    credential = ClientCredential.get(name=request.authorization.username)
    if credential is None or not credential.secret_is(request.authorization.password):
        return Response('Invalid client credentials', 401,
            {'WWW-Authenticate': 'Basic realm="Client credentials"'})
    if credential:
        credential.accessed_at = db.func.utcnow()
        db.session.commit()
    add_auth_attribute('client', credential.client, actor=True)
Exemplo n.º 14
0
def _client_login_inner():
    if request.authorization is None or not request.authorization.username:
        return Response('Client credentials required', 401,
            {'WWW-Authenticate': 'Basic realm="Client credentials"'})
    credential = ClientCredential.get(name=request.authorization.username)
    if credential is None or not credential.secret_is(request.authorization.password):
        return Response('Invalid client credentials', 401,
            {'WWW-Authenticate': 'Basic realm="Client credentials"'})
    if credential:
        credential.accessed_at = db.func.utcnow()
        db.session.commit()
    add_auth_attribute('client', credential.client, actor=True)
Exemplo n.º 15
0
    def login_listener(self, userinfo, token):
        user = self.load_user_userinfo(userinfo, token['access_token'], update=True)
        user.lastuser_token = token['access_token']
        user.lastuser_token_type = token['token_type']
        user.lastuser_token_scope = token['scope']

        add_auth_attribute('user', user)
        g.user = user  # XXX: Deprecated, for backward compatibility only
        add_auth_attribute('lastuserinfo', self.make_userinfo(user))

        self.update_teams(user)
        signal_user_looked_up.send(current_auth.user)
        return user
Exemplo n.º 16
0
def logout_internal():
    add_auth_attribute('user', None)
    if current_auth.session:
        current_auth.session.revoke()
        add_auth_attribute('session', None)
    session.pop('sessionid', None)
    session.pop('userid', None)
    session.pop('merge_userid', None)
    session.pop('merge_buid', None)
    session.pop('userid_external', None)
    session.pop('avatar_url', None)
    current_auth.cookie.pop('sessionid', None)
    current_auth.cookie.pop('userid', None)
    session.permanent = False
Exemplo n.º 17
0
def logout():
    code = LoginCode(next_url=get_next_url(external=False, referrer=True),
        return_url=url_for('logout_return', _external=True))
    session.pop('userid', None)
    signal_logout.send(eventapp, user=current_auth.user)
    add_auth_attribute('user', None)
    g.user = None
    db.session.add(code)
    db.session.commit()
    if app.config.get('USE_SSL'):
        scheme = 'https://'
    else:
        scheme = 'http://'
    return redirect(urljoin(scheme + app.config['LOGIN_HOST'], '/logout?code=' + code.code))
Exemplo n.º 18
0
def logout_internal():
    add_auth_attribute('user', None)
    if current_auth.session:
        current_auth.session.revoke()
        add_auth_attribute('session', None)
    session.pop('sessionid', None)
    session.pop('userid', None)
    session.pop('merge_userid', None)
    session.pop('merge_buid', None)
    session.pop('userid_external', None)
    session.pop('avatar_url', None)
    current_auth.cookie.pop('sessionid', None)
    current_auth.cookie.pop('userid', None)
    session.permanent = False
Exemplo n.º 19
0
def login_internal(user, user_session=None, login_service=None):
    """
    Login a user and create a session. If the login is from funnelapp, reuse the
    existing session.
    """
    add_auth_attribute('user', user)
    if not user_session or user_session.user != user:
        user_session = UserSession(user=user, login_service=login_service)
    user_session.views.mark_accessed()
    add_auth_attribute('session', user_session)
    current_auth.cookie['sessionid'] = user_session.buid
    current_auth.cookie['userid'] = user.buid
    session.permanent = True
    autoset_timezone_and_locale(user)
    user_login.send(user)
Exemplo n.º 20
0
    def test_other_actor_authenticated(self):
        assert current_auth.is_anonymous
        assert not current_auth.is_authenticated
        assert not current_auth
        assert current_auth.user is None

        client = Client()
        add_auth_attribute('client', client, actor=True)

        assert not current_auth.is_anonymous
        assert current_auth.is_authenticated
        assert current_auth
        assert current_auth.user is None  # It's not the user
        assert current_auth.client == client  # There's now a client attribute
        assert current_auth.actor == client  # The client is also the actor
Exemplo n.º 21
0
    def test_other_actor_authenticated(self):
        self.assertTrue(current_auth.is_anonymous)
        self.assertFalse(current_auth.is_authenticated)
        self.assertFalse(current_auth)
        self.assertIsNone(current_auth.user)

        client = Client()
        add_auth_attribute('client', client, actor=True)

        self.assertFalse(current_auth.is_anonymous)
        self.assertTrue(current_auth.is_authenticated)
        self.assertTrue(current_auth)
        self.assertIsNone(current_auth.user)  # It's not the user
        self.assertEqual(current_auth.client, client)  # There's now a client attribute
        self.assertEqual(current_auth.actor, client)   # The client is also the actor
Exemplo n.º 22
0
    def test_other_actor_authenticated(self):
        self.assertTrue(current_auth.is_anonymous)
        self.assertFalse(current_auth.is_authenticated)
        self.assertFalse(current_auth)
        self.assertIsNone(current_auth.user)

        client = Client()
        add_auth_attribute('client', client, actor=True)

        self.assertFalse(current_auth.is_anonymous)
        self.assertTrue(current_auth.is_authenticated)
        self.assertTrue(current_auth)
        self.assertIsNone(current_auth.user)  # It's not the user
        self.assertEqual(current_auth.client,
                         client)  # There's now a client attribute
        self.assertEqual(current_auth.actor,
                         client)  # The client is also the actor
Exemplo n.º 23
0
    def test_class_is_available(self):
        doc = ViewDocument(name='test1', title="Test")
        self.session.add(doc)
        self.session.commit()

        # First, confirm we're working with the correct view
        assert isinstance(doc.views.main(), ModelDocumentView)
        assert isinstance(doc.views.gated(), GatedDocumentView)

        # Since ModelDocumentView.view is not gated, ModelDocumentView is always
        # available. This is not the case for GatedDocumentView
        assert doc.views.main().is_always_available is True
        assert doc.views.main().is_available() is True
        assert doc.views.gated().is_always_available is False
        assert doc.views.gated().is_available() is False

        # If we add access permissions, the availability changes
        add_auth_attribute('user', 'this-is-the-owner')  # See ViewDocument.permissions
        assert doc.views.gated().is_available() is True
Exemplo n.º 24
0
    def test_class_is_available(self):
        doc = ViewDocument(name='test1', title="Test")
        self.session.add(doc)
        self.session.commit()

        # First, confirm we're working with the correct view
        assert isinstance(doc.views.main(), ModelDocumentView)
        assert isinstance(doc.views.gated(), GatedDocumentView)

        # Since ModelDocumentView.view is not gated, ModelDocumentView is always
        # available. This is not the case for GatedDocumentView
        assert doc.views.main().is_always_available is True
        assert doc.views.main().is_available() is True
        assert doc.views.gated().is_always_available is False
        assert doc.views.gated().is_available() is False

        # If we add access permissions, the availability changes
        add_auth_attribute('user', 'this-is-the-owner')  # See ViewDocument.permissions
        assert doc.views.gated().is_available() is True
Exemplo n.º 25
0
 def test_url_dict_current_roles(self):
     doc1 = ViewDocument(name='test1', title="Test 1")
     assert set(doc1.urls) == {
         'view',  # From ModelDocumentView
         'edit',  # From ModelDocumentView
         'by_perm',  # From GatedDocumentView (`urls` can't handle permission gating)
     }
     # Adding acess permissions changes the URLs available
     add_auth_attribute('user', 'this-is-the-owner')  # See ViewDocument.permissions
     assert set(doc1.urls) == {
         # From ModelDocumentView
         'view',
         'edit',
         # From GatedDocumentView
         'by_perm',
         'by_role_perm',
         'by_perm_role',
         'by_role',
     }
Exemplo n.º 26
0
    def decorated_function(*args, **kwargs):
        add_auth_attribute('login_required', True)

        # Check if http referrer and given client id match a registered client
        if 'client_id' in request.values and 'session' in request.values and request.referrer:
            client_cred = ClientCredential.get(request.values['client_id'])
            if client_cred is not None and get_scheme_netloc(client_cred.client.website) == get_scheme_netloc(request.referrer):
                if UserSession.authenticate(buid=request.values['session']) is not None:
                    return f(*args, **kwargs)

        # If we didn't get a valid client_id and session, maybe there's a user?
        if current_auth.is_authenticated:
            return f(*args, **kwargs)

        # If user is not logged in, check for client credentials in the request authorization header.
        # If no error reported, call the function, else return error.
        result = _client_login_inner()
        if result is None:
            return f(*args, **kwargs)
        else:
            return result
Exemplo n.º 27
0
 def before_request(self, access_token=None):
     if access_token == 'owner-admin-secret':
         add_auth_attribute('permissions', InspectableSet({'siteadmin'}))
         add_auth_attribute('user', 'this-is-the-owner')  # See ViewDocument.permissions
     if access_token == 'owner-secret':
         add_auth_attribute('user', 'this-is-the-owner')  # See ViewDocument.permissions
     return super(ModelDocumentView, self).before_request()
Exemplo n.º 28
0
 def before_request(self, access_token=None):
     if access_token == 'owner-admin-secret':
         add_auth_attribute('permissions', InspectableSet({'siteadmin'}))
         add_auth_attribute('user', 'this-is-the-owner')  # See ViewDocument.permissions
     if access_token == 'owner-secret':
         add_auth_attribute('user', 'this-is-the-owner')  # See ViewDocument.permissions
     return super(ModelDocumentView, self).before_request()
Exemplo n.º 29
0
    def decorated_function(*args, **kwargs):
        add_auth_attribute('login_required', True)
        # If the user is not logged in, require login first
        if not current_auth.is_authenticated:
            flash(_("You need to be logged in for that page"), 'info')
            session['next'] = get_current_url()
            return redirect(url_for('login'))
        # If the user has not authenticated in some time, ask for the password again
        if not current_auth.session.has_sudo:
            # If the user doesn't have a password, ask them to set one first
            if not current_auth.user.pw_hash:
                flash(
                    _(
                        "This operation requires you to confirm your password. However,"
                        " your account does not have a password, so you must set one"
                        " first"
                    ),
                    'info',
                )
                session['next'] = get_current_url()
                return redirect(url_for('change_password'))
            # A future version of this form may accept password or 2FA (U2F or TOTP)
            form = PasswordForm(edit_user=current_auth.user)
            if form.validate_on_submit():
                # User has successfully authenticated. Update their sudo timestamp and
                # reload the page with a GET request, as the wrapped view may need to
                # render its own form
                current_auth.session.set_sudo()
                db.session.commit()
                return redirect(request.url, code=303)

            return render_form(
                form=form,
                title=_("Confirm with your password to proceed"),
                formid='password',
                submit=_("Confirm"),
                ajax=False,
                template='account_formlayout.html.jinja2',
            )
        return f(*args, **kwargs)
Exemplo n.º 30
0
    def test_requires_permission(self):
        with self.app.test_request_context():

            assert permission1.is_available() is False
            assert permission2.is_available() is False

            with pytest.raises(Forbidden):
                permission1()
            with pytest.raises(Forbidden):
                permission2()

            add_auth_attribute('permissions', set())

            assert permission1.is_available() is False
            assert permission2.is_available() is False

            with pytest.raises(Forbidden):
                permission1()
            with pytest.raises(Forbidden):
                permission2()

            current_auth.permissions.add(
                'allow-that'
            )  # FIXME! Shouldn't this be a frozenset?

            assert permission1.is_available() is False
            assert permission2.is_available() is True

            with pytest.raises(Forbidden):
                permission1()
            assert permission2() == 'allowed2'

            current_auth.permissions.add('allow-this')

            assert permission1.is_available() is True
            assert permission2.is_available() is True

            assert permission1() == 'allowed1'
            assert permission2() == 'allowed2'
Exemplo n.º 31
0
 def before_request(self, access_token=None):
     if access_token == 'owner-secret':
         add_auth_attribute('user', 'this-is-the-owner')  # See ViewDocument.permissions
     if access_token == 'editor-secret':
         add_auth_attribute('user', 'this-is-the-editor')  # See ViewDocument.permissions
     if access_token == 'another-owner-secret':
         add_auth_attribute('user', 'this-is-another-owner')  # See ViewDocument.permissions
     return super(GatedDocumentView, self).before_request()
Exemplo n.º 32
0
    def test_requires_permission(self):
        with self.app.test_request_context():
            with self.assertRaises(Forbidden):
                permission1()
            with self.assertRaises(Forbidden):
                permission2()

            add_auth_attribute('permissions', set())

            with self.assertRaises(Forbidden):
                permission1()
            with self.assertRaises(Forbidden):
                permission2()

            current_auth.permissions.add(
                'allow-that')  # FIXME! Shouldn't this be a frozenset?
            with self.assertRaises(Forbidden):
                permission1()
            assert permission2() == 'allowed2'

            current_auth.permissions.add('allow-this')
            assert permission1() == 'allowed1'
            assert permission2() == 'allowed2'
Exemplo n.º 33
0
    def test_requires_permission(self):
        with self.app.test_request_context():

            assert permission1.is_available() is False
            assert permission2.is_available() is False

            with self.assertRaises(Forbidden):
                permission1()
            with self.assertRaises(Forbidden):
                permission2()

            add_auth_attribute('permissions', set())

            assert permission1.is_available() is False
            assert permission2.is_available() is False

            with self.assertRaises(Forbidden):
                permission1()
            with self.assertRaises(Forbidden):
                permission2()

            current_auth.permissions.add('allow-that')  # FIXME! Shouldn't this be a frozenset?

            assert permission1.is_available() is False
            assert permission2.is_available() is True

            with self.assertRaises(Forbidden):
                permission1()
            assert permission2() == 'allowed2'

            current_auth.permissions.add('allow-this')

            assert permission1.is_available() is True
            assert permission2.is_available() is True

            assert permission1() == 'allowed1'
            assert permission2() == 'allowed2'
Exemplo n.º 34
0
    def decorated_function(*args, **kwargs):
        add_auth_attribute('login_required', True)

        # Is there a user? Go right ahead
        if current_auth.is_authenticated:
            return f(*args, **kwargs)

        # Check if http referrer and given client id match a registered client
        if (
            'client_id' in request.values
            and 'session' in request.values
            and request.referrer
        ):
            client_cred = AuthClientCredential.get(
                abort_null(request.values['client_id'])
            )
            if client_cred is not None and get_scheme_netloc(
                client_cred.auth_client.website
            ) == get_scheme_netloc(request.referrer):
                user_session = UserSession.authenticate(
                    buid=abort_null(request.values['session'])
                )
                if user_session is not None:
                    # Add this user session to current_auth so the wrapped function
                    # knows who it's operating for. However, this is not proper
                    # authentication, so do not tag this as an actor.
                    add_auth_attribute('session', user_session)
                    return f(*args, **kwargs)

        # If we didn't get a valid client_id and session, and the user is not logged in,
        # check for client credentials in the request authorization header.
        # If no error reported, call the function, else return error.
        result = _client_login_inner()
        if result is None:
            return f(*args, **kwargs)
        return result
Exemplo n.º 35
0
def lookup_current_user(user=None):
    add_auth_attribute('user', None)
    g.user = None
    add_auth_attribute('lastuserinfo', None)
    if 'userid' in session:
        if user is None:
            user = User.query.filter_by(userid=session['userid']).first()
        add_auth_attribute('user', user)
        g.user = user
        if user:
            add_auth_attribute('lastuserinfo', LastuserInfo(token=user.lastuser_token,
                token_type=user.lastuser_token_type,
                token_scope=user.lastuser_token_scope,
                userid=user.userid,
                username=user.username,
                fullname=user.fullname,
                email=user.email,
                permissions=user.userinfo.get('permissions', ()),
                organizations=user.userinfo.get('organizations')))
Exemplo n.º 36
0
 def before_request(self, access_token=None):
     if access_token == 'owner-secret':  # NOQA: S105 # nosec
         add_auth_attribute(
             'user', 'this-is-the-owner')  # See ViewDocument.permissions
     if access_token == 'editor-secret':  # NOQA: S105 # nosec
         add_auth_attribute(
             'user', 'this-is-the-editor')  # See ViewDocument.permissions
     if access_token == 'another-owner-secret':  # NOQA: S105 # nosec
         add_auth_attribute(
             'user',
             'this-is-another-owner')  # See ViewDocument.permissions
     return super(GatedDocumentView, self).before_request()
Exemplo n.º 37
0
 def _load_user(self):
     if has_request_context():
         add_auth_attribute('user', self.user)
         if self.user:
             add_auth_attribute('username', self.user.username)
Exemplo n.º 38
0
    def _load_user(self):
        """
        If there's a buid in the session, retrieve the user object and add
        to the request namespace object g.
        """
        add_auth_attribute('user', None)
        add_auth_attribute('session', None)

        lastuser_cookie = {}
        lastuser_cookie_headers = {}  # Ignored for now, intended for future changes

        # Migrate data from Flask cookie session
        if 'sessionid' in session:
            lastuser_cookie['sessionid'] = session.pop('sessionid')
        if 'userid' in session:
            lastuser_cookie['userid'] = session.pop('userid')

        if 'lastuser' in request.cookies:
            try:
                lastuser_cookie, lastuser_cookie_headers = lastuser_oauth.serializer.loads(
                    request.cookies['lastuser'], return_header=True)
            except itsdangerous.BadSignature:
                lastuser_cookie = {}

        if 'sessionid' in lastuser_cookie:
            add_auth_attribute('session', UserSession.authenticate(buid=lastuser_cookie['sessionid']))
            if current_auth.session:
                current_auth.session.access()
                db.session.commit()  # Save access
                add_auth_attribute('user', current_auth.session.user)

        # Transition users with 'userid' to 'sessionid'
        if not current_auth.session and 'userid' in lastuser_cookie:
            add_auth_attribute('user', User.get(buid=lastuser_cookie['userid']))
            if current_auth.is_authenticated:
                add_auth_attribute('session', UserSession(user=current_auth.user))
                current_auth.session.access()
                db.session.commit()  # Save access

        if current_auth.session:
            lastuser_cookie['sessionid'] = current_auth.session.buid
        else:
            lastuser_cookie.pop('sessionid', None)
        if current_auth.is_authenticated:
            lastuser_cookie['userid'] = current_auth.user.buid
        else:
            lastuser_cookie.pop('userid', None)

        add_auth_attribute('cookie', lastuser_cookie)
        # This will be set to True downstream by the requires_login decorator
        add_auth_attribute('login_required', False)
Exemplo n.º 39
0
    def _load_user(self):
        """
        If there's a buid in the session, retrieve the user object and add
        to the request namespace object g.
        """
        add_auth_attribute('user', None)
        add_auth_attribute('session', None)

        lastuser_cookie = {}
        lastuser_cookie_headers = {
        }  # Ignored for now, intended for future changes

        # Migrate data from Flask cookie session
        if 'sessionid' in session:
            lastuser_cookie['sessionid'] = session.pop('sessionid')
        if 'userid' in session:
            lastuser_cookie['userid'] = session.pop('userid')

        if 'lastuser' in request.cookies:
            try:
                lastuser_cookie, lastuser_cookie_headers = lastuser_oauth.serializer.loads(
                    request.cookies['lastuser'], return_header=True)
            except itsdangerous.BadSignature:
                lastuser_cookie = {}

        if 'sessionid' in lastuser_cookie:
            add_auth_attribute(
                'session',
                UserSession.authenticate(buid=lastuser_cookie['sessionid']))
            if current_auth.session:
                current_auth.session.access()
                db.session.commit()  # Save access
                add_auth_attribute('user', current_auth.session.user)

        # Transition users with 'userid' to 'sessionid'
        if not current_auth.session and 'userid' in lastuser_cookie:
            add_auth_attribute('user',
                               User.get(buid=lastuser_cookie['userid']))
            if current_auth.is_authenticated:
                add_auth_attribute('session',
                                   UserSession(user=current_auth.user))
                current_auth.session.access()
                db.session.commit()  # Save access

        if current_auth.session:
            lastuser_cookie['sessionid'] = current_auth.session.buid
        else:
            lastuser_cookie.pop('sessionid', None)
        if current_auth.is_authenticated:
            lastuser_cookie['userid'] = current_auth.user.buid
        else:
            lastuser_cookie.pop('userid', None)

        lastuser_cookie['updated_at'] = utcnow().isoformat()

        add_auth_attribute('cookie', lastuser_cookie)
        # This will be set to True downstream by the requires_login decorator
        add_auth_attribute('login_required', False)
Exemplo n.º 40
0
    def _load_user():
        """
        If there's a buid in the session, retrieve the user object and add
        to the request namespace object g.
        """
        add_auth_attribute('user', None)
        add_auth_attribute('session', None)

        lastuser_cookie = {}
        lastuser_cookie_headers = {}  # Ignored for now, intended for future changes

        # Migrate data from Flask cookie session
        if 'sessionid' in session:
            lastuser_cookie['sessionid'] = session.pop('sessionid')
        if 'userid' in session:
            lastuser_cookie['userid'] = session.pop('userid')

        if 'lastuser' in request.cookies:
            try:
                (
                    lastuser_cookie,
                    lastuser_cookie_headers,
                ) = lastuser_serializer().loads(
                    request.cookies['lastuser'], return_header=True
                )
            except itsdangerous.exc.BadSignature:
                lastuser_cookie = {}

        add_auth_attribute('cookie', lastuser_cookie)
        # We are dependent on `add_auth_attribute` not making a copy of the dict

        if 'sessionid' in lastuser_cookie:
            try:
                add_auth_attribute(
                    'session',
                    UserSession.authenticate(
                        buid=lastuser_cookie['sessionid'], silent=False
                    ),
                )
                if current_auth.session:
                    add_auth_attribute('user', current_auth.session.user)
                else:
                    # Invalid session. This is not supposed to happen unless there's an
                    # error that is (a) setting an invalid session id, or (b) deleting
                    # the session object instead of revoking it.
                    current_app.logger.error(
                        "Got an unknown user session %s; logging out",
                        lastuser_cookie['sessionid'],
                    )
                    logout_internal()
            except UserSessionExpired:
                flash(
                    _(
                        "Looks like you haven’t been here in a while."
                        " Please login again"
                    ),
                    'info',
                )
                current_app.logger.info("Got an expired user session; logging out")
                add_auth_attribute('session', None)
                logout_internal()
            except UserSessionRevoked:
                flash(
                    _(
                        "Your login session was revoked from another device."
                        " Please login again"
                    ),
                    'info',
                )
                current_app.logger.info("Got a revoked user session; logging out")
                add_auth_attribute('session', None)
                logout_internal()

        # Transition users with 'userid' to 'sessionid'
        if not current_auth.session and 'userid' in lastuser_cookie:
            add_auth_attribute('user', User.get(buid=lastuser_cookie['userid']))
            if current_auth.is_authenticated:
                add_auth_attribute('session', UserSession(user=current_auth.user))
                current_auth.session.views.mark_accessed()

        if current_auth.session:
            lastuser_cookie['sessionid'] = current_auth.session.buid
        else:
            lastuser_cookie.pop('sessionid', None)
        if current_auth.is_authenticated:
            lastuser_cookie['userid'] = current_auth.user.buid
        else:
            lastuser_cookie.pop('userid', None)

        # Stop tracking updated_at as it's unused and the session has its own timestamp
        lastuser_cookie.pop('updated_at', None)

        # This will be set to True downstream by the requires_login decorator
        add_auth_attribute('login_required', False)
Exemplo n.º 41
0
 def decorated_function(*args, **kwargs):
     add_auth_attribute('login_required', True)
     if not current_auth.is_authenticated:
         session['next'] = get_current_url()
         return redirect(url_for('login'))
     return f(*args, **kwargs)
Exemplo n.º 42
0
 def _load_user(self):
     if has_request_context():
         add_auth_attribute('user', self.user)
         if self.user:
             add_auth_attribute('username', self.user.username)
Exemplo n.º 43
0
 def test_invalid_auth_attribute(self):
     for attr in ('actor', 'anchors', 'is_anonymous', 'not_anonymous', 'is_authenticated', 'not_authenticated'):
         with self.assertRaises(AttributeError):
             add_auth_attribute(attr, None)