fief_client.integrations.flask

Flask integration.

  1"""Flask integration."""
  2
  3import uuid
  4from functools import wraps
  5from typing import Callable, Optional
  6
  7from flask import g, request
  8
  9from fief_client import (
 10    Fief,
 11    FiefAccessTokenACRTooLow,
 12    FiefAccessTokenExpired,
 13    FiefAccessTokenInfo,
 14    FiefAccessTokenInvalid,
 15    FiefAccessTokenMissingScope,
 16    FiefACR,
 17    FiefUserInfo,
 18)
 19from fief_client.client import FiefAccessTokenMissingPermission
 20
 21
 22class FiefAuthError(Exception):
 23    """
 24    Base error for FiefAuth integration.
 25    """
 26
 27
 28class FiefAuthUnauthorized(FiefAuthError):
 29    """
 30    Request unauthorized error.
 31
 32    This error is raised when using the `authenticated` or `current_user` decorator
 33    but the request is not authenticated.
 34
 35    You should implement an `errorhandler` to define the behavior of your server when
 36    this happens.
 37
 38    **Example:**
 39
 40    ```py
 41    @app.errorhandler(FiefAuthUnauthorized)
 42    def fief_unauthorized_error(e):
 43        return "", 401
 44    ```
 45    """
 46
 47
 48class FiefAuthForbidden(FiefAuthError):
 49    """
 50    Request forbidden error.
 51
 52    This error is raised when using the `authenticated` or `current_user` decorator
 53    but the access token doesn't match the list of scopes, permissions or minimum ACR level.
 54
 55    You should implement an `errorhandler` to define the behavior of your server when
 56    this happens.
 57
 58    **Example:**
 59
 60    ```py
 61    @app.errorhandler(FiefAuthForbidden)
 62    def fief_forbidden_error(e):
 63        return "", 403
 64    ```
 65    """
 66
 67
 68TokenGetter = Callable[[], Optional[str]]
 69"""Type of a function that can be used to retrieve a token."""
 70
 71UserInfoCacheGetter = Callable[[uuid.UUID], Optional[FiefUserInfo]]
 72"""
 73Type of a function that can be used to retrieve user information from a cache.
 74
 75Read more: https://docs.fief.dev/integrate/python/flask/#web-application-example
 76"""
 77
 78UserInfoCacheSetter = Callable[[uuid.UUID, FiefUserInfo], None]
 79"""
 80Type of a function that can be used to store user information in a cache.
 81
 82Read more: https://docs.fief.dev/integrate/python/flask/#web-application-example
 83"""
 84
 85
 86def get_authorization_scheme_token(*, scheme: str = "bearer") -> TokenGetter:
 87    """
 88    Return a `TokenGetter` function to retrieve a token from the `Authorization` header of an HTTP request.
 89
 90    :param scheme: Scheme of the token. Defaults to `bearer`.
 91    """
 92
 93    def _get_authorization_scheme_token():
 94        authorization = request.headers.get("Authorization")
 95        if authorization is None:
 96            return None
 97        parts = authorization.split()
 98        if len(parts) != 2 or parts[0].lower() != scheme.lower():
 99            return None
100        return parts[1]
101
102    return _get_authorization_scheme_token
103
104
105def get_cookie(cookie_name: str) -> TokenGetter:
106    """
107    Return a `TokenGetter` function to retrieve a token from a `Cookie` of an HTTP request.
108
109    :param cookie_name: Name of the cookie.
110    """
111
112    def _get_cookie():
113        return request.cookies.get(cookie_name)
114
115    return _get_cookie
116
117
118class FiefAuth:
119    """
120    Helper class to integrate Fief authentication with Flask.
121
122    **Example:**
123
124    ```py
125    from fief_client import Fief
126    from fief_client.integrations.flask import (
127        FiefAuth,
128        get_authorization_scheme_token,
129    )
130    from flask import Flask, g
131
132    fief = Fief(
133        "https://example.fief.dev",
134        "YOUR_CLIENT_ID",
135        "YOUR_CLIENT_SECRET",
136    )
137
138    auth = FiefAuth(fief, get_authorization_scheme_token())
139
140    app = Flask(__name__)
141    ```
142    """
143
144    def __init__(
145        self,
146        client: Fief,
147        token_getter: TokenGetter,
148        *,
149        get_userinfo_cache: Optional[UserInfoCacheGetter] = None,
150        set_userinfo_cache: Optional[UserInfoCacheSetter] = None,
151    ) -> None:
152        """
153        :param client: Instance of a `fief_client.Fief` client.
154        :param token_getter: Function to retrieve a token.
155        It should follow the `TokenGetter` type.
156        :param get_userinfo_cache: Optional function to retrieve user information from a cache.
157        Otherwise, the Fief API will always be reached when requesting user information.
158        It should follow the `UserInfoCacheGetter` type.
159        :param set_userinfo_cache: Optional function to store user information in a cache.
160        It should follow the `UserInfoCacheSetter` type.
161        """
162        self.client = client
163        self.token_getter = token_getter
164        self.get_userinfo_cache = get_userinfo_cache
165        self.set_userinfo_cache = set_userinfo_cache
166
167    def authenticated(
168        self,
169        *,
170        optional: bool = False,
171        scope: Optional[list[str]] = None,
172        acr: Optional[FiefACR] = None,
173        permissions: Optional[list[str]] = None,
174    ):
175        """
176        Decorator to check if a request is authenticated.
177
178        If the request is authenticated, the `g` object will have an `access_token_info` property,
179        of type `fief_client.FiefAccessTokenInfo`.
180
181        :param optional: If `False` and the request is not authenticated,
182        a `FiefAuthUnauthorized` error will be raised.
183        :param scope: Optional list of scopes required.
184        If the access token lacks one of the required scope, a `FiefAuthForbidden` error will be raised.
185        :param acr: Optional minimum ACR level required.
186        If the access token doesn't meet the minimum level, a `FiefAuthForbidden` error will be raised.
187        Read more: https://docs.fief.dev/going-further/acr/
188        :param permissions: Optional list of permissions required.
189        If the access token lacks one of the required permission, a `FiefAuthForbidden` error will be raised.
190
191        **Example**
192
193        ```py
194        @app.get("/authenticated")
195        @auth.authenticated()
196        def get_authenticated():
197            return g.access_token_info
198        ```
199        """
200
201        def _authenticated(f):
202            @wraps(f)
203            def decorated_function(*args, **kwargs):
204                token = self.token_getter()
205                if token is None:
206                    if optional:
207                        g.access_token_info = None
208                        return f(*args, **kwargs)
209                    raise FiefAuthUnauthorized()
210
211                try:
212                    info = self.client.validate_access_token(
213                        token,
214                        required_scope=scope,
215                        required_acr=acr,
216                        required_permissions=permissions,
217                    )
218                except (FiefAccessTokenInvalid, FiefAccessTokenExpired) as e:
219                    if optional:
220                        g.access_token_info = None
221                        return f(*args, **kwargs)
222                    raise FiefAuthUnauthorized() from e
223                except (
224                    FiefAccessTokenMissingScope,
225                    FiefAccessTokenACRTooLow,
226                    FiefAccessTokenMissingPermission,
227                ) as e:
228                    raise FiefAuthForbidden() from e
229
230                g.access_token_info = info
231
232                return f(*args, **kwargs)
233
234            return decorated_function
235
236        return _authenticated
237
238    def current_user(
239        self,
240        *,
241        optional: bool = False,
242        scope: Optional[list[str]] = None,
243        acr: Optional[FiefACR] = None,
244        permissions: Optional[list[str]] = None,
245        refresh: bool = False,
246    ):
247        """
248        Decorator to check if a user is authenticated.
249
250        If the request is authenticated, the `g` object will have a `user` property,
251        of type `fief_client.FiefUserInfo`.
252
253        :param optional: If `False` and the request is not authenticated,
254        a `FiefAuthUnauthorized` error will be raised.
255        :param scope: Optional list of scopes required.
256        If the access token lacks one of the required scope, a `FiefAuthForbidden` error will be raised.
257        :param acr: Optional minimum ACR level required.
258        If the access token doesn't meet the minimum level, a `FiefAuthForbidden` error will be raised.
259        Read more: https://docs.fief.dev/going-further/acr/
260        :param permissions: Optional list of permissions required.
261        If the access token lacks one of the required permission, a `FiefAuthForbidden` error will be raised.
262        :param refresh: If `True`, the user information will be refreshed from the Fief API.
263        Otherwise, the cache will be used.
264
265        **Example**
266
267        ```py
268        @app.get("/current-user")
269        @auth.current_user()
270        def get_current_user():
271            user = g.user
272            return f"<h1>You are authenticated. Your user email is {user['email']}</h1>"
273        ```
274        """
275
276        def _current_user(f):
277            @wraps(f)
278            @self.authenticated(
279                optional=optional, scope=scope, acr=acr, permissions=permissions
280            )
281            def decorated_function(*args, **kwargs):
282                access_token_info: Optional[FiefAccessTokenInfo] = g.access_token_info
283
284                if access_token_info is None and optional:
285                    g.user = None
286                    return f(*args, **kwargs)
287
288                assert access_token_info is not None
289
290                userinfo = None
291                if self.get_userinfo_cache is not None:
292                    userinfo = self.get_userinfo_cache(access_token_info["id"])
293
294                if userinfo is None or refresh:
295                    userinfo = self.client.userinfo(access_token_info["access_token"])
296
297                    if self.set_userinfo_cache is not None:
298                        self.set_userinfo_cache(access_token_info["id"], userinfo)
299
300                g.user = userinfo
301
302                return f(*args, **kwargs)
303
304            return decorated_function
305
306        return _current_user
307
308
309__all__ = [
310    "FiefAuth",
311    "FiefAuthError",
312    "FiefAuthUnauthorized",
313    "FiefAuthForbidden",
314    "TokenGetter",
315    "UserInfoCacheGetter",
316    "UserInfoCacheSetter",
317    "get_authorization_scheme_token",
318    "get_cookie",
319]
class FiefAuth:
119class FiefAuth:
120    """
121    Helper class to integrate Fief authentication with Flask.
122
123    **Example:**
124
125    ```py
126    from fief_client import Fief
127    from fief_client.integrations.flask import (
128        FiefAuth,
129        get_authorization_scheme_token,
130    )
131    from flask import Flask, g
132
133    fief = Fief(
134        "https://example.fief.dev",
135        "YOUR_CLIENT_ID",
136        "YOUR_CLIENT_SECRET",
137    )
138
139    auth = FiefAuth(fief, get_authorization_scheme_token())
140
141    app = Flask(__name__)
142    ```
143    """
144
145    def __init__(
146        self,
147        client: Fief,
148        token_getter: TokenGetter,
149        *,
150        get_userinfo_cache: Optional[UserInfoCacheGetter] = None,
151        set_userinfo_cache: Optional[UserInfoCacheSetter] = None,
152    ) -> None:
153        """
154        :param client: Instance of a `fief_client.Fief` client.
155        :param token_getter: Function to retrieve a token.
156        It should follow the `TokenGetter` type.
157        :param get_userinfo_cache: Optional function to retrieve user information from a cache.
158        Otherwise, the Fief API will always be reached when requesting user information.
159        It should follow the `UserInfoCacheGetter` type.
160        :param set_userinfo_cache: Optional function to store user information in a cache.
161        It should follow the `UserInfoCacheSetter` type.
162        """
163        self.client = client
164        self.token_getter = token_getter
165        self.get_userinfo_cache = get_userinfo_cache
166        self.set_userinfo_cache = set_userinfo_cache
167
168    def authenticated(
169        self,
170        *,
171        optional: bool = False,
172        scope: Optional[list[str]] = None,
173        acr: Optional[FiefACR] = None,
174        permissions: Optional[list[str]] = None,
175    ):
176        """
177        Decorator to check if a request is authenticated.
178
179        If the request is authenticated, the `g` object will have an `access_token_info` property,
180        of type `fief_client.FiefAccessTokenInfo`.
181
182        :param optional: If `False` and the request is not authenticated,
183        a `FiefAuthUnauthorized` error will be raised.
184        :param scope: Optional list of scopes required.
185        If the access token lacks one of the required scope, a `FiefAuthForbidden` error will be raised.
186        :param acr: Optional minimum ACR level required.
187        If the access token doesn't meet the minimum level, a `FiefAuthForbidden` error will be raised.
188        Read more: https://docs.fief.dev/going-further/acr/
189        :param permissions: Optional list of permissions required.
190        If the access token lacks one of the required permission, a `FiefAuthForbidden` error will be raised.
191
192        **Example**
193
194        ```py
195        @app.get("/authenticated")
196        @auth.authenticated()
197        def get_authenticated():
198            return g.access_token_info
199        ```
200        """
201
202        def _authenticated(f):
203            @wraps(f)
204            def decorated_function(*args, **kwargs):
205                token = self.token_getter()
206                if token is None:
207                    if optional:
208                        g.access_token_info = None
209                        return f(*args, **kwargs)
210                    raise FiefAuthUnauthorized()
211
212                try:
213                    info = self.client.validate_access_token(
214                        token,
215                        required_scope=scope,
216                        required_acr=acr,
217                        required_permissions=permissions,
218                    )
219                except (FiefAccessTokenInvalid, FiefAccessTokenExpired) as e:
220                    if optional:
221                        g.access_token_info = None
222                        return f(*args, **kwargs)
223                    raise FiefAuthUnauthorized() from e
224                except (
225                    FiefAccessTokenMissingScope,
226                    FiefAccessTokenACRTooLow,
227                    FiefAccessTokenMissingPermission,
228                ) as e:
229                    raise FiefAuthForbidden() from e
230
231                g.access_token_info = info
232
233                return f(*args, **kwargs)
234
235            return decorated_function
236
237        return _authenticated
238
239    def current_user(
240        self,
241        *,
242        optional: bool = False,
243        scope: Optional[list[str]] = None,
244        acr: Optional[FiefACR] = None,
245        permissions: Optional[list[str]] = None,
246        refresh: bool = False,
247    ):
248        """
249        Decorator to check if a user is authenticated.
250
251        If the request is authenticated, the `g` object will have a `user` property,
252        of type `fief_client.FiefUserInfo`.
253
254        :param optional: If `False` and the request is not authenticated,
255        a `FiefAuthUnauthorized` error will be raised.
256        :param scope: Optional list of scopes required.
257        If the access token lacks one of the required scope, a `FiefAuthForbidden` error will be raised.
258        :param acr: Optional minimum ACR level required.
259        If the access token doesn't meet the minimum level, a `FiefAuthForbidden` error will be raised.
260        Read more: https://docs.fief.dev/going-further/acr/
261        :param permissions: Optional list of permissions required.
262        If the access token lacks one of the required permission, a `FiefAuthForbidden` error will be raised.
263        :param refresh: If `True`, the user information will be refreshed from the Fief API.
264        Otherwise, the cache will be used.
265
266        **Example**
267
268        ```py
269        @app.get("/current-user")
270        @auth.current_user()
271        def get_current_user():
272            user = g.user
273            return f"<h1>You are authenticated. Your user email is {user['email']}</h1>"
274        ```
275        """
276
277        def _current_user(f):
278            @wraps(f)
279            @self.authenticated(
280                optional=optional, scope=scope, acr=acr, permissions=permissions
281            )
282            def decorated_function(*args, **kwargs):
283                access_token_info: Optional[FiefAccessTokenInfo] = g.access_token_info
284
285                if access_token_info is None and optional:
286                    g.user = None
287                    return f(*args, **kwargs)
288
289                assert access_token_info is not None
290
291                userinfo = None
292                if self.get_userinfo_cache is not None:
293                    userinfo = self.get_userinfo_cache(access_token_info["id"])
294
295                if userinfo is None or refresh:
296                    userinfo = self.client.userinfo(access_token_info["access_token"])
297
298                    if self.set_userinfo_cache is not None:
299                        self.set_userinfo_cache(access_token_info["id"], userinfo)
300
301                g.user = userinfo
302
303                return f(*args, **kwargs)
304
305            return decorated_function
306
307        return _current_user

Helper class to integrate Fief authentication with Flask.

Example:

from fief_client import Fief
from fief_client.integrations.flask import (
    FiefAuth,
    get_authorization_scheme_token,
)
from flask import Flask, g

fief = Fief(
    "https://example.fief.dev",
    "YOUR_CLIENT_ID",
    "YOUR_CLIENT_SECRET",
)

auth = FiefAuth(fief, get_authorization_scheme_token())

app = Flask(__name__)
FiefAuth( client: fief_client.Fief, token_getter: Callable[[], Optional[str]], *, get_userinfo_cache: Optional[Callable[[uuid.UUID], Optional[fief_client.FiefUserInfo]]] = None, set_userinfo_cache: Optional[Callable[[uuid.UUID, fief_client.FiefUserInfo], NoneType]] = None)
145    def __init__(
146        self,
147        client: Fief,
148        token_getter: TokenGetter,
149        *,
150        get_userinfo_cache: Optional[UserInfoCacheGetter] = None,
151        set_userinfo_cache: Optional[UserInfoCacheSetter] = None,
152    ) -> None:
153        """
154        :param client: Instance of a `fief_client.Fief` client.
155        :param token_getter: Function to retrieve a token.
156        It should follow the `TokenGetter` type.
157        :param get_userinfo_cache: Optional function to retrieve user information from a cache.
158        Otherwise, the Fief API will always be reached when requesting user information.
159        It should follow the `UserInfoCacheGetter` type.
160        :param set_userinfo_cache: Optional function to store user information in a cache.
161        It should follow the `UserInfoCacheSetter` type.
162        """
163        self.client = client
164        self.token_getter = token_getter
165        self.get_userinfo_cache = get_userinfo_cache
166        self.set_userinfo_cache = set_userinfo_cache
Parameters
  • client: Instance of a fief_client.Fief client.
  • token_getter: Function to retrieve a token. It should follow the TokenGetter type.
  • get_userinfo_cache: Optional function to retrieve user information from a cache. Otherwise, the Fief API will always be reached when requesting user information. It should follow the UserInfoCacheGetter type.
  • set_userinfo_cache: Optional function to store user information in a cache. It should follow the UserInfoCacheSetter type.
client
token_getter
get_userinfo_cache
set_userinfo_cache
def authenticated( self, *, optional: bool = False, scope: Optional[list[str]] = None, acr: Optional[fief_client.FiefACR] = None, permissions: Optional[list[str]] = None):
168    def authenticated(
169        self,
170        *,
171        optional: bool = False,
172        scope: Optional[list[str]] = None,
173        acr: Optional[FiefACR] = None,
174        permissions: Optional[list[str]] = None,
175    ):
176        """
177        Decorator to check if a request is authenticated.
178
179        If the request is authenticated, the `g` object will have an `access_token_info` property,
180        of type `fief_client.FiefAccessTokenInfo`.
181
182        :param optional: If `False` and the request is not authenticated,
183        a `FiefAuthUnauthorized` error will be raised.
184        :param scope: Optional list of scopes required.
185        If the access token lacks one of the required scope, a `FiefAuthForbidden` error will be raised.
186        :param acr: Optional minimum ACR level required.
187        If the access token doesn't meet the minimum level, a `FiefAuthForbidden` error will be raised.
188        Read more: https://docs.fief.dev/going-further/acr/
189        :param permissions: Optional list of permissions required.
190        If the access token lacks one of the required permission, a `FiefAuthForbidden` error will be raised.
191
192        **Example**
193
194        ```py
195        @app.get("/authenticated")
196        @auth.authenticated()
197        def get_authenticated():
198            return g.access_token_info
199        ```
200        """
201
202        def _authenticated(f):
203            @wraps(f)
204            def decorated_function(*args, **kwargs):
205                token = self.token_getter()
206                if token is None:
207                    if optional:
208                        g.access_token_info = None
209                        return f(*args, **kwargs)
210                    raise FiefAuthUnauthorized()
211
212                try:
213                    info = self.client.validate_access_token(
214                        token,
215                        required_scope=scope,
216                        required_acr=acr,
217                        required_permissions=permissions,
218                    )
219                except (FiefAccessTokenInvalid, FiefAccessTokenExpired) as e:
220                    if optional:
221                        g.access_token_info = None
222                        return f(*args, **kwargs)
223                    raise FiefAuthUnauthorized() from e
224                except (
225                    FiefAccessTokenMissingScope,
226                    FiefAccessTokenACRTooLow,
227                    FiefAccessTokenMissingPermission,
228                ) as e:
229                    raise FiefAuthForbidden() from e
230
231                g.access_token_info = info
232
233                return f(*args, **kwargs)
234
235            return decorated_function
236
237        return _authenticated

Decorator to check if a request is authenticated.

If the request is authenticated, the g object will have an access_token_info property, of type fief_client.FiefAccessTokenInfo.

Parameters
  • optional: If False and the request is not authenticated, a FiefAuthUnauthorized error will be raised.
  • scope: Optional list of scopes required. If the access token lacks one of the required scope, a FiefAuthForbidden error will be raised.
  • acr: Optional minimum ACR level required. If the access token doesn't meet the minimum level, a FiefAuthForbidden error will be raised. Read more: https://docs.fief.dev/going-further/acr/
  • permissions: Optional list of permissions required. If the access token lacks one of the required permission, a FiefAuthForbidden error will be raised.

Example

@app.get("/authenticated")
@auth.authenticated()
def get_authenticated():
    return g.access_token_info
def current_user( self, *, optional: bool = False, scope: Optional[list[str]] = None, acr: Optional[fief_client.FiefACR] = None, permissions: Optional[list[str]] = None, refresh: bool = False):
239    def current_user(
240        self,
241        *,
242        optional: bool = False,
243        scope: Optional[list[str]] = None,
244        acr: Optional[FiefACR] = None,
245        permissions: Optional[list[str]] = None,
246        refresh: bool = False,
247    ):
248        """
249        Decorator to check if a user is authenticated.
250
251        If the request is authenticated, the `g` object will have a `user` property,
252        of type `fief_client.FiefUserInfo`.
253
254        :param optional: If `False` and the request is not authenticated,
255        a `FiefAuthUnauthorized` error will be raised.
256        :param scope: Optional list of scopes required.
257        If the access token lacks one of the required scope, a `FiefAuthForbidden` error will be raised.
258        :param acr: Optional minimum ACR level required.
259        If the access token doesn't meet the minimum level, a `FiefAuthForbidden` error will be raised.
260        Read more: https://docs.fief.dev/going-further/acr/
261        :param permissions: Optional list of permissions required.
262        If the access token lacks one of the required permission, a `FiefAuthForbidden` error will be raised.
263        :param refresh: If `True`, the user information will be refreshed from the Fief API.
264        Otherwise, the cache will be used.
265
266        **Example**
267
268        ```py
269        @app.get("/current-user")
270        @auth.current_user()
271        def get_current_user():
272            user = g.user
273            return f"<h1>You are authenticated. Your user email is {user['email']}</h1>"
274        ```
275        """
276
277        def _current_user(f):
278            @wraps(f)
279            @self.authenticated(
280                optional=optional, scope=scope, acr=acr, permissions=permissions
281            )
282            def decorated_function(*args, **kwargs):
283                access_token_info: Optional[FiefAccessTokenInfo] = g.access_token_info
284
285                if access_token_info is None and optional:
286                    g.user = None
287                    return f(*args, **kwargs)
288
289                assert access_token_info is not None
290
291                userinfo = None
292                if self.get_userinfo_cache is not None:
293                    userinfo = self.get_userinfo_cache(access_token_info["id"])
294
295                if userinfo is None or refresh:
296                    userinfo = self.client.userinfo(access_token_info["access_token"])
297
298                    if self.set_userinfo_cache is not None:
299                        self.set_userinfo_cache(access_token_info["id"], userinfo)
300
301                g.user = userinfo
302
303                return f(*args, **kwargs)
304
305            return decorated_function
306
307        return _current_user

Decorator to check if a user is authenticated.

If the request is authenticated, the g object will have a user property, of type fief_client.FiefUserInfo.

Parameters
  • optional: If False and the request is not authenticated, a FiefAuthUnauthorized error will be raised.
  • scope: Optional list of scopes required. If the access token lacks one of the required scope, a FiefAuthForbidden error will be raised.
  • acr: Optional minimum ACR level required. If the access token doesn't meet the minimum level, a FiefAuthForbidden error will be raised. Read more: https://docs.fief.dev/going-further/acr/
  • permissions: Optional list of permissions required. If the access token lacks one of the required permission, a FiefAuthForbidden error will be raised.
  • refresh: If True, the user information will be refreshed from the Fief API. Otherwise, the cache will be used.

Example

@app.get("/current-user")
@auth.current_user()
def get_current_user():
    user = g.user
    return f"<h1>You are authenticated. Your user email is {user['email']}</h1>"
class FiefAuthError(builtins.Exception):
23class FiefAuthError(Exception):
24    """
25    Base error for FiefAuth integration.
26    """

Base error for FiefAuth integration.

class FiefAuthUnauthorized(FiefAuthError):
29class FiefAuthUnauthorized(FiefAuthError):
30    """
31    Request unauthorized error.
32
33    This error is raised when using the `authenticated` or `current_user` decorator
34    but the request is not authenticated.
35
36    You should implement an `errorhandler` to define the behavior of your server when
37    this happens.
38
39    **Example:**
40
41    ```py
42    @app.errorhandler(FiefAuthUnauthorized)
43    def fief_unauthorized_error(e):
44        return "", 401
45    ```
46    """

Request unauthorized error.

This error is raised when using the authenticated or current_user decorator but the request is not authenticated.

You should implement an errorhandler to define the behavior of your server when this happens.

Example:

@app.errorhandler(FiefAuthUnauthorized)
def fief_unauthorized_error(e):
    return "", 401
class FiefAuthForbidden(FiefAuthError):
49class FiefAuthForbidden(FiefAuthError):
50    """
51    Request forbidden error.
52
53    This error is raised when using the `authenticated` or `current_user` decorator
54    but the access token doesn't match the list of scopes, permissions or minimum ACR level.
55
56    You should implement an `errorhandler` to define the behavior of your server when
57    this happens.
58
59    **Example:**
60
61    ```py
62    @app.errorhandler(FiefAuthForbidden)
63    def fief_forbidden_error(e):
64        return "", 403
65    ```
66    """

Request forbidden error.

This error is raised when using the authenticated or current_user decorator but the access token doesn't match the list of scopes, permissions or minimum ACR level.

You should implement an errorhandler to define the behavior of your server when this happens.

Example:

@app.errorhandler(FiefAuthForbidden)
def fief_forbidden_error(e):
    return "", 403
TokenGetter = typing.Callable[[], typing.Optional[str]]

Type of a function that can be used to retrieve a token.

UserInfoCacheGetter = typing.Callable[[uuid.UUID], typing.Optional[fief_client.FiefUserInfo]]

Type of a function that can be used to retrieve user information from a cache.

Read more: https://docs.fief.dev/integrate/python/flask/#web-application-example

UserInfoCacheSetter = typing.Callable[[uuid.UUID, fief_client.FiefUserInfo], NoneType]

Type of a function that can be used to store user information in a cache.

Read more: https://docs.fief.dev/integrate/python/flask/#web-application-example

def get_authorization_scheme_token(*, scheme: str = 'bearer') -> Callable[[], Optional[str]]:
 87def get_authorization_scheme_token(*, scheme: str = "bearer") -> TokenGetter:
 88    """
 89    Return a `TokenGetter` function to retrieve a token from the `Authorization` header of an HTTP request.
 90
 91    :param scheme: Scheme of the token. Defaults to `bearer`.
 92    """
 93
 94    def _get_authorization_scheme_token():
 95        authorization = request.headers.get("Authorization")
 96        if authorization is None:
 97            return None
 98        parts = authorization.split()
 99        if len(parts) != 2 or parts[0].lower() != scheme.lower():
100            return None
101        return parts[1]
102
103    return _get_authorization_scheme_token

Return a TokenGetter function to retrieve a token from the Authorization header of an HTTP request.

Parameters
  • scheme: Scheme of the token. Defaults to bearer.