def test_duration_from_string_fails(self): """ This test verifies that the duration_from_string method raises a ConfiguationError exception if there was a problem parsing the string """ with pytest.raises(ConfigurationError): duration_from_string('12x1y1z') with pytest.raises(ConfigurationError): duration_from_string('')
def test_duration_from_string_success(self): """ This test verifies that the duration_from_string method can be used to parse a duration from a string with expected formats """ expected_duration = pendulum.duration(days=12, hours=1, seconds=1) computed_duration = duration_from_string('12d1h1s') assert computed_duration == expected_duration expected_duration = pendulum.duration(months=1, hours=2, minutes=3) computed_duration = duration_from_string('1 Month 2 Hours 3 minutes') assert computed_duration == expected_duration expected_duration = pendulum.duration(days=1, minutes=2, seconds=3) computed_duration = duration_from_string('1day,2min,3sec') assert computed_duration == expected_duration expected_duration = pendulum.duration(months=1, minutes=2) computed_duration = duration_from_string('1mo,2m') assert computed_duration == expected_duration
def init_app( self, app=None, user_class=None, token_store_class=None, is_blacklisted=None, encode_jwt_token_hook=None, refresh_jwt_token_hook=None, ): """ Initializes the Praetorian extension :param: app: The flask app to bind this extension to :param: user_class: The class used to interact with user data :param: token_store_class: The class used to interact with token store data :param: is_blacklisted: A method that may optionally be used to check the token against a blacklist when access or refresh is requested should take the jti for the token to check as a single argument. Returns True if the jti is blacklisted, False otherwise. By default, always returns False. :param encode_jwt_token_hook: A method that may optionally be called right before an encoded jwt is generated. Should take payload_parts which contains the ingredients for the jwt. :param refresh_jwt_token_hook: A method that may optionally be called right before an encoded jwt is refreshed. Should take payload_parts which contains the ingredients for the jwt. """ PraetorianError.require_condition( app.config.get('SECRET_KEY') is not None, "There must be a SECRET_KEY app config setting set", ) self.roles_disabled = app.config.get( 'PRAETORIAN_ROLES_DISABLED', DEFAULT_ROLES_DISABLED, ) self.hash_autoupdate = app.config.get( 'PRAETORIAN_HASH_AUTOUPDATE', DEFAULT_HASH_AUTOUPDATE, ) self.hash_autotest = app.config.get( 'PRAETORIAN_HASH_AUTOTEST', DEFAULT_HASH_AUTOTEST, ) self.pwd_ctx = CryptContext( schemes=app.config.get( 'PRAETORIAN_HASH_ALLOWED_SCHEMES', DEFAULT_HASH_ALLOWED_SCHEMES, ), default=app.config.get( 'PRAETORIAN_HASH_SCHEME', DEFAULT_HASH_SCHEME, ), deprecated=app.config.get( 'PRAETORIAN_HASH_DEPRECATED_SCHEMES', DEFAULT_HASH_DEPRECATED_SCHEMES, ), ) valid_schemes = self.pwd_ctx.schemes() PraetorianError.require_condition( self.hash_scheme in valid_schemes or self.hash_scheme is None, "If {} is set, it must be one of the following schemes: {}".format( 'PRAETORIAN_HASH_SCHEME', valid_schemes, ), ) self.user_class = self._validate_user_class(user_class) #self.token_class = self._validate_token_class(token_class) self.token_store_class = token_store_class self.is_blacklisted = is_blacklisted or (lambda t: False) self.encode_jwt_token_hook = encode_jwt_token_hook self.refresh_jwt_token_hook = refresh_jwt_token_hook self.encode_key = app.config['SECRET_KEY'] self.allowed_algorithms = app.config.get( 'JWT_ALLOWED_ALGORITHMS', DEFAULT_JWT_ALLOWED_ALGORITHMS, ) self.encode_algorithm = app.config.get( 'JWT_ALGORITHM', DEFAULT_JWT_ALGORITHM, ) self.access_lifespan = app.config.get( 'JWT_ACCESS_LIFESPAN', DEFAULT_JWT_ACCESS_LIFESPAN, ) self.refresh_lifespan = app.config.get( 'JWT_REFRESH_LIFESPAN', DEFAULT_JWT_REFRESH_LIFESPAN, ) self.reset_lifespan = app.config.get( 'JWT_RESET_LIFESPAN', DEFAULT_JWT_RESET_LIFESPAN, ) self.jwt_places = app.config.get( 'JWT_PLACES', DEFAULT_JWT_PLACES, ) self.cookie_name = app.config.get( 'JWT_COOKIE_NAME', DEFAULT_JWT_COOKIE_NAME, ) self.header_name = app.config.get( 'JWT_HEADER_NAME', DEFAULT_JWT_HEADER_NAME, ) self.header_type = app.config.get( 'JWT_HEADER_TYPE', DEFAULT_JWT_HEADER_TYPE, ) self.user_class_validation_method = app.config.get( 'USER_CLASS_VALIDATION_METHOD', DEFAULT_USER_CLASS_VALIDATION_METHOD, ) self.confirmation_template = app.config.get( 'PRAETORIAN_CONFIRMATION_TEMPLATE', DEFAULT_CONFIRMATION_TEMPLATE, ) self.confirmation_uri = app.config.get('PRAETORIAN_CONFIRMATION_URI', ) self.confirmation_sender = app.config.get( 'PRAETORIAN_CONFIRMATION_SENDER', ) self.confirmation_subject = app.config.get( 'PRAETORIAN_CONFIRMATION_SUBJECT', DEFAULT_CONFIRMATION_SUBJECT, ) self.reset_template = app.config.get( 'PRAETORIAN_RESET_TEMPLATE', DEFAULT_RESET_TEMPLATE, ) self.reset_uri = app.config.get('PRAETORIAN_RESET_URI', ) self.reset_sender = app.config.get('PRAETORIAN_RESET_SENDER', ) self.reset_subject = app.config.get( 'PRAETORIAN_RESET_SUBJECT', DEFAULT_RESET_SUBJECT, ) if isinstance(self.access_lifespan, dict): self.access_lifespan = pendulum.duration(**self.access_lifespan) elif isinstance(self.access_lifespan, str): self.access_lifespan = duration_from_string(self.access_lifespan) ConfigurationError.require_condition( isinstance(self.access_lifespan, datetime.timedelta), "access lifespan was not configured", ) if isinstance(self.refresh_lifespan, dict): self.refresh_lifespan = pendulum.duration(**self.refresh_lifespan) if isinstance(self.refresh_lifespan, str): self.refresh_lifespan = duration_from_string(self.refresh_lifespan) ConfigurationError.require_condition( isinstance(self.refresh_lifespan, datetime.timedelta), "refresh lifespan was not configured", ) if not app.config.get('DISABLE_PRAETORIAN_ERROR_HANDLER'): app.register_error_handler( PraetorianError, PraetorianError.build_error_handler(), ) self.is_testing = app.config.get('TESTING', False) if not hasattr(app, 'extensions'): app.extensions = {} app.extensions['praetorian'] = self return app