def test_refresh_jwt_token(self, app, db, user_class): """ This test verifies that the refresh_jwt_token properly generates a refreshed jwt token. It ensures that a token who's access permission has not expired may not be refreshed. It also ensures that a token who's access permission has expired must not have an expired refresh permission for a new token to be issued """ guard = Praetorian(app, user_class) the_dude = user_class( username='******', password=guard.encrypt_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') .add_timedelta(DEFAULT_JWT_ACCESS_LIFESPAN) .add(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['rf_exp'] == ( moment + DEFAULT_JWT_REFRESH_LIFESPAN ).int_timestamp assert new_token_data['id'] == the_dude.id assert new_token_data['rls'] == 'admin,operator'
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.encrypt_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') + pendulum.Duration(**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 + pendulum.Duration(**DEFAULT_JWT_ACCESS_LIFESPAN)).int_timestamp assert new_token_data['rf_exp'] == (moment + pendulum.Duration( **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') + pendulum.Duration(**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['rf_exp'] expiring_interval = (pendulum.Duration(**DEFAULT_JWT_ACCESS_LIFESPAN) + pendulum.Duration(minutes=1)) validating_guard = Praetorian(app, validating_user_class) brandt = validating_user_class( username='******', password=guard.encrypt_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 = (pendulum.Duration(**DEFAULT_JWT_ACCESS_LIFESPAN) + pendulum.Duration(minutes=1)) guard = Praetorian(app, user_class) bunny = user_class( username='******', password=guard.encrypt_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') + pendulum.Duration(**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 + pendulum.Duration(**DEFAULT_JWT_ACCESS_LIFESPAN)).int_timestamp assert new_token_data['rf_exp'] == (moment + pendulum.Duration( **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'