Exemple #1
0
    def init_app(self, app, user_class, is_blacklisted=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: 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.
        """
        PraetorianError.require_condition(
            app.config.get('SECRET_KEY') is not None,
            "There must be a SECRET_KEY app config setting set",
        )

        possible_schemes = [
            'argon2',
            'bcrypt',
            'pbkdf2_sha512',
        ]
        self.pwd_ctx = CryptContext(
            default='pbkdf2_sha512',
            schemes=possible_schemes + ['plaintext'],
            deprecated=[],
        )

        self.hash_scheme = app.config.get('PRAETORIAN_HASH_SCHEME')
        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: {}",
            'PRAETORIAN_HASH_SCHEME',
            valid_schemes,
        )

        self.user_class = self._validate_user_class(user_class)
        self.is_blacklisted = is_blacklisted or (lambda t: False)

        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 = pendulum.Duration(**app.config.get(
            'JWT_ACCESS_LIFESPAN',
            DEFAULT_JWT_ACCESS_LIFESPAN,
        ))
        self.refresh_lifespan = pendulum.Duration(**app.config.get(
            'JWT_REFRESH_LIFESPAN',
            DEFAULT_JWT_REFRESH_LIFESPAN,
        ))
        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,
        )

        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
Exemple #2
0
    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