Exemple #1
0
    def test_validate_and_update(self, app, user_class, db):
        """
        This test verifies that Praetorian hashes passwords using the scheme
        specified by the HASH_SCHEME setting. If no scheme is supplied, the
        test verifies that the default scheme is used. Otherwise, the test
        verifies that the hashed password matches the supplied scheme.
        """

        default_guard = Praetorian(app, user_class)
        pbkdf2_sha512_password = default_guard.hash_password('pbkdf2_sha512')

        # create our default test user
        the_dude = user_class(
            username='******',
            email='*****@*****.**',
            password=pbkdf2_sha512_password,
        )
        db.session.add(the_dude)
        db.session.commit()
        """
        Test the current password is hashed with PRAETORIAN_HASH_SCHEME
        """
        assert default_guard.verify_and_update(user=the_dude)
        """
        Test a password hashed with something other than
            PRAETORIAN_HASH_ALLOWED_SCHEME triggers an Exception.
        """
        app.config['PRAETORIAN_HASH_SCHEME'] = 'bcrypt'
        default_guard = Praetorian(app, user_class)
        bcrypt_password = default_guard.hash_password('bcrypt_password')
        the_dude.password = bcrypt_password

        del app.config['PRAETORIAN_HASH_SCHEME']
        app.config['PRAETORIAN_HASH_DEPRECATED_SCHEMES'] = ['bcrypt']
        default_guard = Praetorian(app, user_class)
        with pytest.raises(LegacyScheme):
            default_guard.verify_and_update(the_dude)
        """
        Test a password hashed with something other than
            PRAETORIAN_HASH_SCHEME, and supplied good password
            gets the user entry's password updated and saved.
        """
        the_dude_old_password = the_dude.password
        updated_dude = default_guard.verify_and_update(the_dude,
                                                       'bcrypt_password')
        assert updated_dude.password != the_dude_old_password
        """
        Test a password hashed with something other than
            PRAETORIAN_HASH_SCHEME, and supplied bad password
            gets an Exception raised.
        """
        the_dude.password = bcrypt_password
        with pytest.raises(AuthenticationError):
            default_guard.verify_and_update(user=the_dude, password='******')

        # put away your toys
        db.session.delete(the_dude)
        db.session.commit()
Exemple #2
0
    def test_authenticate_validate_and_update(self, app, user_class, db):
        """
        This test verifies the authenticate() function, when altered by
        either 'PRAETORIAN_HASH_AUTOUPDATE' or 'PRAETORIAN_HASH_AUTOTEST'
        performs the authentication and the required subaction.
        """

        default_guard = Praetorian(app, user_class)
        pbkdf2_sha512_password = default_guard.hash_password('start_password')

        # create our default test user
        the_dude = user_class(
            username='******',
            email='*****@*****.**',
            password=pbkdf2_sha512_password,
        )
        db.session.add(the_dude)
        db.session.commit()
        """
        Test the existing model as a baseline
        """
        assert default_guard.authenticate(the_dude.username, 'start_password')
        """
        Test the existing model with a bad password as a baseline
        """
        with pytest.raises(AuthenticationError):
            default_guard.authenticate(the_dude.username, 'failme')
        """
        Test the updated model with a bad hash scheme and AUTOTEST enabled.
        Should raise and exception
        """
        app.config['PRAETORIAN_HASH_SCHEME'] = 'bcrypt'
        default_guard = Praetorian(app, user_class)
        bcrypt_password = default_guard.hash_password('bcrypt_password')
        the_dude.password = bcrypt_password

        del app.config['PRAETORIAN_HASH_SCHEME']
        app.config['PRAETORIAN_HASH_DEPRECATED_SCHEMES'] = ['bcrypt']
        app.config['PRAETORIAN_HASH_AUTOTEST'] = True
        default_guard = Praetorian(app, user_class)
        with pytest.raises(LegacyScheme):
            default_guard.authenticate(the_dude.username, 'bcrypt_password')
        """
        Test the updated model with a bad hash scheme and AUTOUPDATE enabled.
        Should return an updated user object we need to save ourselves.
        """
        the_dude_old_password = the_dude.password
        app.config['PRAETORIAN_HASH_AUTOUPDATE'] = True
        default_guard = Praetorian(app, user_class)
        updated_dude = default_guard.authenticate(the_dude.username,
                                                  'bcrypt_password')
        assert updated_dude.password != the_dude_old_password

        # put away your toys
        db.session.delete(the_dude)
        db.session.commit()
Exemple #3
0
 def test_encode_eternal_jwt_token(self, app, user_class):
     """
     This test verifies that the encode_eternal_jwt_token correctly encodes
     jwt data based on a user instance. Also verifies that the lifespan is
     set to the constant VITAM_AETERNUM
     """
     guard = Praetorian(app, user_class)
     the_dude = user_class(
         username='******',
         password=guard.hash_password('abides'),
         roles='admin,operator',
     )
     moment = pendulum.parse('2017-05-21 18:39:55')
     with freezegun.freeze_time(moment):
         token = guard.encode_eternal_jwt_token(the_dude)
         token_data = jwt.decode(
             token,
             guard.encode_key,
             algorithms=guard.allowed_algorithms,
         )
         assert token_data['iat'] == moment.int_timestamp
         assert token_data['exp'] == (moment + VITAM_AETERNUM).int_timestamp
         assert token_data[REFRESH_EXPIRATION_CLAIM] == (
             moment + VITAM_AETERNUM).int_timestamp
         assert token_data['id'] == the_dude.id
    def test_read_token_from_header(self, app, db, user_class, client):
        """
        This test verifies that a token may be properly read from a flask
        request's header using the configuration settings for header name and
        type
        """
        guard = Praetorian(app, user_class)
        the_dude = user_class(
            username="******",
            password=guard.hash_password("abides"),
            roles="admin,operator",
        )
        db.session.add(the_dude)
        db.session.commit()

        with plummet.frozen_time('2017-05-21 18:39:55'):
            token = guard.encode_jwt_token(the_dude)

        client.get(
            "/unprotected",
            headers={
                "Content-Type": "application/json",
                DEFAULT_JWT_HEADER_NAME: DEFAULT_JWT_HEADER_TYPE + " " + token,
            },
        )

        assert guard.read_token_from_header() == token
        assert guard.read_token() == token
 def test_encode_eternal_jwt_token(self, app, user_class):
     """
     This test verifies that the encode_eternal_jwt_token correctly encodes
     jwt data based on a user instance. Also verifies that the lifespan is
     set to the constant VITAM_AETERNUM
     """
     guard = Praetorian(app, user_class)
     the_dude = user_class(
         username="******",
         password=guard.hash_password("abides"),
         roles="admin,operator",
     )
     moment = plummet.momentize('2017-05-21 18:39:55')
     with plummet.frozen_time(moment):
         token = guard.encode_eternal_jwt_token(the_dude)
         token_data = jwt.decode(
             token,
             guard.encode_key,
             algorithms=guard.allowed_algorithms,
         )
         assert token_data["iat"] == moment.int_timestamp
         assert token_data["exp"] == (moment + VITAM_AETERNUM).int_timestamp
         assert (token_data[REFRESH_EXPIRATION_CLAIM] == (
             moment + VITAM_AETERNUM).int_timestamp)
         assert token_data["id"] == the_dude.id
Exemple #6
0
    def test_read_token_from_header(self, app, db, user_class, client):
        """
        This test verifies that a token may be properly read from a flask
        request's header using the configuration settings for header name and
        type
        """
        guard = Praetorian(app, user_class)
        the_dude = user_class(
            username='******',
            password=guard.hash_password('abides'),
            roles='admin,operator',
        )
        db.session.add(the_dude)
        db.session.commit()

        moment = pendulum.parse('2017-05-21 18:39:55')
        with freezegun.freeze_time(moment):
            token = guard.encode_jwt_token(the_dude)

        client.get(
            '/unprotected',
            headers={
                'Content-Type': 'application/json',
                DEFAULT_JWT_HEADER_NAME: DEFAULT_JWT_HEADER_TYPE + ' ' + token,
            },
        )

        assert guard.read_token_from_header() == token
Exemple #7
0
    def test_hash_password(self, app, user_class):
        """
        This test verifies that Praetorian hashes passwords using the scheme
        specified by the HASH_SCHEME setting. If no scheme is supplied, the
        test verifies that the default scheme is used. Otherwise, the test
        verifies that the hashed password matches the supplied scheme.
        """

        default_guard = Praetorian(app, user_class)
        secret = default_guard.hash_password('some password')
        assert default_guard.pwd_ctx.identify(secret) == 'pbkdf2_sha512'
    def test__verify_password(self, app, user_class, default_guard):
        """
        This test verifies that the _verify_password function can be used to
        successfully compare a raw password against its hashed version
        """
        secret = default_guard.hash_password('some password')
        assert default_guard._verify_password('some password', secret)
        assert not default_guard._verify_password('not right', secret)

        app.config['PRAETORIAN_HASH_SCHEME'] = 'pbkdf2_sha512'
        specified_guard = Praetorian(app, user_class)
        secret = specified_guard.hash_password('some password')
        assert specified_guard._verify_password('some password', secret)
        assert not specified_guard._verify_password('not right', secret)
Exemple #9
0
    def test_get_user_from_registration_token(self, app, user_class, db):
        """
        This test verifies that a user can be extracted from an email based
        registration token. Also verifies that a token that has expired
        cannot be used to fetch a user. Also verifies that a registration
        token may not be refreshed
        """
        app.config['TESTING'] = True
        default_guard = Praetorian(app, user_class)

        # create our default test user
        the_dude = user_class(
            username='******',
            email='*****@*****.**',
            password=default_guard.hash_password('abides'),
        )
        db.session.add(the_dude)
        db.session.commit()

        reg_token = default_guard.encode_jwt_token(
            the_dude,
            bypass_user_check=True,
            is_registration_token=True,
        )
        extracted_user = default_guard.get_user_from_registration_token(
            reg_token)
        assert extracted_user == the_dude
        """
           test to ensure a registration token that is expired
               sets off an 'ExpiredAccessError' exception
        """
        moment = pendulum.parse('2019-01-30 16:30:00')
        with freezegun.freeze_time(moment):
            expired_reg_token = default_guard.encode_jwt_token(
                the_dude,
                bypass_user_check=True,
                override_access_lifespan=pendulum.Duration(minutes=1),
                is_registration_token=True,
            )

        moment = pendulum.parse('2019-01-30 16:40:00')
        with freezegun.freeze_time(moment):
            with pytest.raises(ExpiredAccessError):
                default_guard.get_user_from_registration_token(
                    expired_reg_token)
Exemple #10
0
 def test_authenticate(self, app, user_class, db):
     """
     This test verifies that the authenticate function can be used to
     retrieve a User instance when the correct username and password are
     supplied. It also verifies that exceptions are raised when a user
     cannot be found or the passwords do not match
     """
     default_guard = Praetorian(app, user_class)
     the_dude = user_class(
         username='******',
         password=default_guard.hash_password('abides'),
     )
     db.session.add(the_dude)
     db.session.commit()
     assert default_guard.authenticate('TheDude', 'abides') == the_dude
     with pytest.raises(MissingUserError):
         default_guard.authenticate('TheBro', 'abides')
     with pytest.raises(AuthenticationError):
         default_guard.authenticate('TheDude', 'is_undudelike')
     db.session.delete(the_dude)
     db.session.commit()
    def test_read_token_from_cookie(self, app, db, user_class, client,
                                    use_cookie):
        """
        This test verifies that a token may be properly read from a flask
        request's cookies using the configuration settings for cookie
        """
        guard = Praetorian(app, user_class)
        the_dude = user_class(
            username="******",
            password=guard.hash_password("abides"),
            roles="admin,operator",
        )
        db.session.add(the_dude)
        db.session.commit()

        with plummet.frozen_time('2017-05-21 18:39:55'):
            token = guard.encode_jwt_token(the_dude)
            with use_cookie(token):
                client.get("/unprotected", )

        assert guard.read_token_from_cookie() == token
        assert guard.read_token() == token
    def test_read_token_from_cookie(self, app, db, user_class, client):
        """
        This test verifies that a token may be properly read from a flask
        request's cookies using the configuration settings for cookie
        """
        guard = Praetorian(app, user_class)
        the_dude = user_class(
            username='******',
            password=guard.hash_password('abides'),
            roles='admin,operator',
        )
        db.session.add(the_dude)
        db.session.commit()

        moment = pendulum.parse('2017-05-21 18:39:55')
        with freezegun.freeze_time(moment):
            token = guard.encode_jwt_token(the_dude)

        client.set_cookie('localhost', DEFAULT_JWT_COOKIE_NAME, token)
        client.get('/unprotected', )

        assert guard.read_token_from_cookie() == token
Exemple #13
0
    old_token = request.get_data()
    new_token = guard.refresh_jwt_token(old_token)
    return {'access_token': new_token}


if __name__ == "__main__":
    with app.app_context():
        db.create_all()
        with db.engine.begin() as conn:
            try:
                conn.execute(queries.drop_match_summary_table)
            except:
                logger.exception('Match summary view does not exist.')
            try:
                conn.execute(queries.drop_player_summary_table)
            except:
                logger.exception('Player summary view does not exist.')
            conn.execute(queries.create_player_summary_view)
            conn.execute(queries.create_match_summary_view)

        if User.query.filter_by(username='******').count() < 1:
            db.session.add(User(
                username='******',
                password=guard.hash_password(os.environ.get('ADMIN_PW')),
                roles='admin'
            ))
        initEloDiff()
        db.session.commit()
       
    app.run(debug=True)
Exemple #14
0
    def test_pack_header_for_user(self, app, user_class):
        """
        This test::
          * verifies that the pack_header_for_user method can be used to
            package a token into a header dict for a specified user
          * verifies that custom claims may be packaged as well
        """
        guard = Praetorian(app, user_class)
        the_dude = user_class(
            username='******',
            password=guard.hash_password('abides'),
            roles='admin,operator',
        )

        moment = pendulum.parse('2017-05-21 18:39:55')
        with freezegun.freeze_time(moment):
            header_dict = guard.pack_header_for_user(the_dude)
            token_header = header_dict.get(DEFAULT_JWT_HEADER_NAME)
            assert token_header is not None
            token = token_header.replace(DEFAULT_JWT_HEADER_TYPE, '')
            token = token.strip()
            token_data = jwt.decode(
                token,
                guard.encode_key,
                algorithms=guard.allowed_algorithms,
            )
            assert token_data['iat'] == moment.int_timestamp
            assert token_data['exp'] == (
                moment + DEFAULT_JWT_ACCESS_LIFESPAN).int_timestamp
            assert token_data[REFRESH_EXPIRATION_CLAIM] == (
                moment + DEFAULT_JWT_REFRESH_LIFESPAN).int_timestamp
            assert token_data['id'] == the_dude.id
            assert token_data['rls'] == 'admin,operator'

        moment = pendulum.parse('2017-05-21 18:39:55')
        override_access_lifespan = pendulum.Duration(minutes=1)
        override_refresh_lifespan = pendulum.Duration(hours=1)
        with freezegun.freeze_time(moment):
            header_dict = guard.pack_header_for_user(
                the_dude,
                override_access_lifespan=override_access_lifespan,
                override_refresh_lifespan=override_refresh_lifespan,
            )
            token_header = header_dict.get(DEFAULT_JWT_HEADER_NAME)
            assert token_header is not None
            token = token_header.replace(DEFAULT_JWT_HEADER_TYPE, '')
            token = token.strip()
            token_data = jwt.decode(
                token,
                guard.encode_key,
                algorithms=guard.allowed_algorithms,
            )
            assert token_data['exp'] == (
                moment + override_access_lifespan).int_timestamp
            assert token_data[REFRESH_EXPIRATION_CLAIM] == (
                moment + override_refresh_lifespan).int_timestamp
            assert token_data['id'] == the_dude.id

        moment = pendulum.parse('2018-08-14 09:08:39')
        with freezegun.freeze_time(moment):
            header_dict = guard.pack_header_for_user(
                the_dude,
                duder='brief',
                el_duderino='not brief',
            )
            token_header = header_dict.get(DEFAULT_JWT_HEADER_NAME)
            assert token_header is not None
            token = token_header.replace(DEFAULT_JWT_HEADER_TYPE, '')
            token = token.strip()
            token_data = jwt.decode(
                token,
                guard.encode_key,
                algorithms=guard.allowed_algorithms,
            )
            assert token_data['iat'] == moment.int_timestamp
            assert token_data['exp'] == (
                moment + DEFAULT_JWT_ACCESS_LIFESPAN).int_timestamp
            assert token_data[REFRESH_EXPIRATION_CLAIM] == (
                moment + DEFAULT_JWT_REFRESH_LIFESPAN).int_timestamp
            assert token_data['id'] == the_dude.id
            assert token_data['rls'] == 'admin,operator'
            assert token_data['duder'] == 'brief'
            assert token_data['el_duderino'] == 'not brief'
Exemple #15
0
app.config['SQLALCHEMY_DATABASE_URI'] = f"sqlite:///{os.path.join(os.getcwd(), 'database.db')}"
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db.init_app(app)

guard.init_app(app, User)
# cors.init_app(app)

fplData = FPLData(useCache=True)

with app.app_context():
    db.create_all()
    if db.session.query(User).filter_by(username='******').count() < 1:
        db.session.add(User(
            username='******',
            password=guard.hash_password('kyoto'),
            roles='admin',
            form='3-4-3',
            defs='',
            mids='',
            fwds='',
            gkps='',
            bnch=''
        ))

# Debugging purposes
@app.before_request
def log_request():
    app.logger.debug("Request Headers %s", flask.request.headers)
    return None
Exemple #16
0
    def test_refresh_jwt_token(
        self,
        app,
        db,
        user_class,
        validating_user_class,
    ):
        """
        This test::
            * verifies that the refresh_jwt_token properly generates
              a refreshed jwt token.
            * ensures that a token who's access permission has not expired may
              not be refreshed.
            * ensures that a token who's access permission has expired must not
              have an expired refresh permission for a new token to be issued.
            * ensures that if an override_access_lifespan argument is supplied
              that it is used instead of the instance's access_lifespan.
            * ensures that the access_lifespan may not exceed the refresh
              lifespan.
            * ensures that if the user_class has the instance method
              validate(), it is called an any exceptions it raises are wrapped
              in an InvalidUserError.
            * verifies that if a user is no longer identifiable that a
              MissingUserError is raised
            * verifies that any custom claims in the original token's
              payload are also packaged in the new token's payload
        """
        guard = Praetorian(app, user_class)
        the_dude = user_class(
            username='******',
            password=guard.hash_password('abides'),
            roles='admin,operator',
        )
        db.session.add(the_dude)
        db.session.commit()

        moment = pendulum.parse('2017-05-21 18:39:55')
        with freezegun.freeze_time(moment):
            token = guard.encode_jwt_token(the_dude)
        new_moment = (pendulum.parse('2017-05-21 18:39:55') +
                      DEFAULT_JWT_ACCESS_LIFESPAN +
                      pendulum.Duration(minutes=1))
        with freezegun.freeze_time(new_moment):
            new_token = guard.refresh_jwt_token(token)
            new_token_data = jwt.decode(
                new_token,
                guard.encode_key,
                algorithms=guard.allowed_algorithms,
            )
            assert new_token_data['iat'] == new_moment.int_timestamp
            assert new_token_data['exp'] == (
                new_moment + DEFAULT_JWT_ACCESS_LIFESPAN).int_timestamp
            assert new_token_data[REFRESH_EXPIRATION_CLAIM] == (
                moment + DEFAULT_JWT_REFRESH_LIFESPAN).int_timestamp
            assert new_token_data['id'] == the_dude.id
            assert new_token_data['rls'] == 'admin,operator'

        moment = pendulum.parse('2017-05-21 18:39:55')
        with freezegun.freeze_time(moment):
            token = guard.encode_jwt_token(the_dude)
        new_moment = (pendulum.parse('2017-05-21 18:39:55') +
                      DEFAULT_JWT_ACCESS_LIFESPAN +
                      pendulum.Duration(minutes=1))
        with freezegun.freeze_time(new_moment):
            new_token = guard.refresh_jwt_token(
                token,
                override_access_lifespan=pendulum.Duration(hours=2),
            )
            new_token_data = jwt.decode(
                new_token,
                guard.encode_key,
                algorithms=guard.allowed_algorithms,
            )
            assert new_token_data['exp'] == (
                new_moment + pendulum.Duration(hours=2)).int_timestamp

        moment = pendulum.parse('2017-05-21 18:39:55')
        with freezegun.freeze_time(moment):
            token = guard.encode_jwt_token(
                the_dude,
                override_refresh_lifespan=pendulum.Duration(hours=2),
                override_access_lifespan=pendulum.Duration(minutes=30),
            )
        new_moment = moment + pendulum.Duration(minutes=31)
        with freezegun.freeze_time(new_moment):
            new_token = guard.refresh_jwt_token(
                token,
                override_access_lifespan=pendulum.Duration(hours=2),
            )
            new_token_data = jwt.decode(
                new_token,
                guard.encode_key,
                algorithms=guard.allowed_algorithms,
            )
            assert new_token_data['exp'] == new_token_data[
                REFRESH_EXPIRATION_CLAIM]

        expiring_interval = (DEFAULT_JWT_ACCESS_LIFESPAN +
                             pendulum.Duration(minutes=1))
        validating_guard = Praetorian(app, validating_user_class)
        brandt = validating_user_class(
            username='******',
            password=guard.hash_password("can't watch"),
            is_active=True,
        )
        db.session.add(brandt)
        db.session.commit()
        moment = pendulum.parse('2017-05-21 18:39:55')
        with freezegun.freeze_time(moment):
            token = guard.encode_jwt_token(brandt)
        new_moment = moment + expiring_interval
        with freezegun.freeze_time(new_moment):
            validating_guard.refresh_jwt_token(token)
        brandt.is_active = False
        db.session.merge(brandt)
        db.session.commit()
        new_moment = new_moment + expiring_interval
        with freezegun.freeze_time(new_moment):
            with pytest.raises(InvalidUserError) as err_info:
                validating_guard.refresh_jwt_token(token)
        expected_message = 'The user is not valid or has had access revoked'
        assert expected_message in str(err_info.value)

        expiring_interval = (DEFAULT_JWT_ACCESS_LIFESPAN +
                             pendulum.Duration(minutes=1))
        guard = Praetorian(app, user_class)
        bunny = user_class(
            username='******',
            password=guard.hash_password("can't blow that far"),
        )
        db.session.add(bunny)
        db.session.commit()
        moment = pendulum.parse('2017-05-21 18:39:55')
        with freezegun.freeze_time(moment):
            token = guard.encode_jwt_token(bunny)
        db.session.delete(bunny)
        db.session.commit()
        new_moment = moment + expiring_interval
        with freezegun.freeze_time(new_moment):
            with pytest.raises(MissingUserError) as err_info:
                validating_guard.refresh_jwt_token(token)
        expected_message = 'Could not find the requested user'
        assert expected_message in str(err_info.value)

        moment = pendulum.parse('2018-08-14 09:05:24')
        with freezegun.freeze_time(moment):
            token = guard.encode_jwt_token(
                the_dude,
                duder='brief',
                el_duderino='not brief',
            )
        new_moment = (pendulum.parse('2018-08-14 09:05:24') +
                      DEFAULT_JWT_ACCESS_LIFESPAN +
                      pendulum.Duration(minutes=1))
        with freezegun.freeze_time(new_moment):
            new_token = guard.refresh_jwt_token(token)
            new_token_data = jwt.decode(
                new_token,
                guard.encode_key,
                algorithms=guard.allowed_algorithms,
            )
            assert new_token_data['iat'] == new_moment.int_timestamp
            assert new_token_data['exp'] == (
                new_moment + DEFAULT_JWT_ACCESS_LIFESPAN).int_timestamp
            assert new_token_data[REFRESH_EXPIRATION_CLAIM] == (
                moment + DEFAULT_JWT_REFRESH_LIFESPAN).int_timestamp
            assert new_token_data['id'] == the_dude.id
            assert new_token_data['rls'] == 'admin,operator'
            assert new_token_data['duder'] == 'brief'
            assert new_token_data['el_duderino'] == 'not brief'
    def test_pack_header_for_user(self, app, user_class):
        """
        This test::
          * verifies that the pack_header_for_user method can be used to
            package a token into a header dict for a specified user
          * verifies that custom claims may be packaged as well
        """
        guard = Praetorian(app, user_class)
        the_dude = user_class(
            username="******",
            password=guard.hash_password("abides"),
            roles="admin,operator",
        )

        moment = plummet.momentize('2017-05-21 18:39:55')
        with plummet.frozen_time(moment):
            header_dict = guard.pack_header_for_user(the_dude)
            token_header = header_dict.get(DEFAULT_JWT_HEADER_NAME)
            assert token_header is not None
            token = token_header.replace(DEFAULT_JWT_HEADER_TYPE, "")
            token = token.strip()
            token_data = jwt.decode(
                token,
                guard.encode_key,
                algorithms=guard.allowed_algorithms,
            )
            assert token_data["iat"] == moment.int_timestamp
            assert (token_data["exp"] == (
                moment + DEFAULT_JWT_ACCESS_LIFESPAN).int_timestamp)
            assert (token_data[REFRESH_EXPIRATION_CLAIM] == (
                moment + DEFAULT_JWT_REFRESH_LIFESPAN).int_timestamp)
            assert token_data["id"] == the_dude.id
            assert token_data["rls"] == "admin,operator"

        moment = plummet.momentize('2017-05-21 18:39:55')
        override_access_lifespan = pendulum.Duration(minutes=1)
        override_refresh_lifespan = pendulum.Duration(hours=1)
        with plummet.frozen_time(moment):
            header_dict = guard.pack_header_for_user(
                the_dude,
                override_access_lifespan=override_access_lifespan,
                override_refresh_lifespan=override_refresh_lifespan,
            )
            token_header = header_dict.get(DEFAULT_JWT_HEADER_NAME)
            assert token_header is not None
            token = token_header.replace(DEFAULT_JWT_HEADER_TYPE, "")
            token = token.strip()
            token_data = jwt.decode(
                token,
                guard.encode_key,
                algorithms=guard.allowed_algorithms,
            )
            assert (token_data["exp"] == (
                moment + override_access_lifespan).int_timestamp)
            assert (token_data[REFRESH_EXPIRATION_CLAIM] == (
                moment + override_refresh_lifespan).int_timestamp)
            assert token_data["id"] == the_dude.id

        moment = plummet.momentize('2018-08-14 09:08:39')
        with plummet.frozen_time(moment):
            header_dict = guard.pack_header_for_user(
                the_dude,
                duder="brief",
                el_duderino="not brief",
            )
            token_header = header_dict.get(DEFAULT_JWT_HEADER_NAME)
            assert token_header is not None
            token = token_header.replace(DEFAULT_JWT_HEADER_TYPE, "")
            token = token.strip()
            token_data = jwt.decode(
                token,
                guard.encode_key,
                algorithms=guard.allowed_algorithms,
            )
            assert token_data["iat"] == moment.int_timestamp
            assert (token_data["exp"] == (
                moment + DEFAULT_JWT_ACCESS_LIFESPAN).int_timestamp)
            assert (token_data[REFRESH_EXPIRATION_CLAIM] == (
                moment + DEFAULT_JWT_REFRESH_LIFESPAN).int_timestamp)
            assert token_data["id"] == the_dude.id
            assert token_data["rls"] == "admin,operator"
            assert token_data["duder"] == "brief"
            assert token_data["el_duderino"] == "not brief"
Exemple #18
0
    def test_encode_jwt_token(self, app, user_class, validating_user_class):
        """
        This test::
            * verifies that the encode_jwt_token correctly encodes jwt
              data based on a user instance.
            * verifies that if a user specifies an override for the access
              lifespan it is used in lieu of the instance's access_lifespan.
            * verifies that the access_lifespan cannot exceed the refresh
              lifespan.
            * ensures that if the user_class has the instance method
              validate(), it is called an any exceptions it raises are wrapped
              in an InvalidUserError
            * verifies that custom claims may be encoded in the token and
              validates that the custom claims do not collide with reserved
              claims
        """
        guard = Praetorian(app, user_class)
        the_dude = user_class(
            username='******',
            password=guard.hash_password('abides'),
            roles='admin,operator',
        )
        moment = pendulum.parse('2017-05-21 18:39:55')
        with freezegun.freeze_time(moment):
            token = guard.encode_jwt_token(the_dude)
            token_data = jwt.decode(
                token,
                guard.encode_key,
                algorithms=guard.allowed_algorithms,
            )
            assert token_data['iat'] == moment.int_timestamp
            assert token_data['exp'] == (
                moment + DEFAULT_JWT_ACCESS_LIFESPAN).int_timestamp
            assert token_data[REFRESH_EXPIRATION_CLAIM] == (
                moment + DEFAULT_JWT_REFRESH_LIFESPAN).int_timestamp
            assert token_data['id'] == the_dude.id
            assert token_data['rls'] == 'admin,operator'

        moment = pendulum.parse('2017-05-21 18:39:55')
        override_access_lifespan = pendulum.Duration(minutes=1)
        override_refresh_lifespan = pendulum.Duration(hours=1)
        with freezegun.freeze_time(moment):
            token = guard.encode_jwt_token(
                the_dude,
                override_access_lifespan=override_access_lifespan,
                override_refresh_lifespan=override_refresh_lifespan,
            )
            token_data = jwt.decode(
                token,
                guard.encode_key,
                algorithms=guard.allowed_algorithms,
            )
            assert token_data['iat'] == moment.int_timestamp
            assert token_data['exp'] == (
                moment + override_access_lifespan).int_timestamp
            assert token_data[REFRESH_EXPIRATION_CLAIM] == (
                moment + override_refresh_lifespan).int_timestamp
            assert token_data['id'] == the_dude.id
            assert token_data['rls'] == 'admin,operator'

        moment = pendulum.parse('2017-05-21 18:39:55')
        override_access_lifespan = pendulum.Duration(hours=1)
        override_refresh_lifespan = pendulum.Duration(minutes=1)
        with freezegun.freeze_time(moment):
            token = guard.encode_jwt_token(
                the_dude,
                override_access_lifespan=override_access_lifespan,
                override_refresh_lifespan=override_refresh_lifespan,
            )
            token_data = jwt.decode(
                token,
                guard.encode_key,
                algorithms=guard.allowed_algorithms,
            )
            assert token_data['iat'] == moment.int_timestamp
            assert token_data['exp'] == token_data[REFRESH_EXPIRATION_CLAIM]
            assert token_data[REFRESH_EXPIRATION_CLAIM] == (
                moment + override_refresh_lifespan).int_timestamp
            assert token_data['id'] == the_dude.id
            assert token_data['rls'] == 'admin,operator'

        validating_guard = Praetorian(app, validating_user_class)
        brandt = validating_user_class(
            username='******',
            password=guard.hash_password("can't watch"),
            is_active=True,
        )
        validating_guard.encode_jwt_token(brandt)
        brandt.is_active = False
        with pytest.raises(InvalidUserError) as err_info:
            validating_guard.encode_jwt_token(brandt)
        expected_message = 'The user is not valid or has had access revoked'
        assert expected_message in str(err_info.value)

        moment = pendulum.parse('2018-08-18 08:55:12')
        with freezegun.freeze_time(moment):
            token = guard.encode_jwt_token(
                the_dude,
                duder='brief',
                el_duderino='not brief',
            )
            token_data = jwt.decode(
                token,
                guard.encode_key,
                algorithms=guard.allowed_algorithms,
            )
            assert token_data['iat'] == moment.int_timestamp
            assert token_data['exp'] == (
                moment + DEFAULT_JWT_ACCESS_LIFESPAN).int_timestamp
            assert token_data[REFRESH_EXPIRATION_CLAIM] == (
                moment + DEFAULT_JWT_REFRESH_LIFESPAN).int_timestamp
            assert token_data['id'] == the_dude.id
            assert token_data['rls'] == 'admin,operator'
            assert token_data['duder'] == 'brief'
            assert token_data['el_duderino'] == 'not brief'

        with pytest.raises(ClaimCollisionError) as err_info:
            guard.encode_jwt_token(the_dude, exp='nice marmot')
        expected_message = 'custom claims collide'
        assert expected_message in str(err_info.value)
Exemple #19
0
DATABASE = os.getenv('DATABASE')
DATABASE_USERNAME = os.getenv('DATABASE_USER')
DATABASE_PASSWORD = os.getenv('DATABASE_PASSWORD')

app.config['SECRET_KEY'] = os.getenv('SECRET_KEY')
app.config['JWT_ACCESS_LIFESPAN'] = {'hours': 24}
app.config['JWT_REFRESH_LIFESPAN'] = {'days': 30}

# If we use heroku
if os.environ.get('DATABASE_URL') is not None:
    app.config['SQLALCHEMY_DATABASE_URI'] = os.environ.get('DATABASE_URL')
else:
    app.config['SQLALCHEMY_DATABASE_URI'] = f'postgresql+psycopg2://{DATABASE_USERNAME}:{DATABASE_PASSWORD}@localhost:5432/{DATABASE}'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True

db.init_app(app)
guard.init_app(app, User)

with app.app_context():
    db.create_all()
    if not db.session.query(User).filter_by(username='******').count():
        db.session.add(User(
          username='******',
          password=guard.hash_password('123abc'),
          roles = 'admin'
            ))
    db.session.commit()


import routes