Authenticators
Default authenticators.
BasicAuth
aegis.authenticators.basic.BasicAuth
Base authenticator for Basic authentication.
Authenticator is set-up by setup()
.
The class implements aegis.authenticators.base.BaseAuth
.
User should never instantiate the class but create a new class that
inherits and overrides required variables and methods.
user_id
, password
and authenticate
is forced to override.
Arguments:
-
me_endpoint
- User information endpoint URI. Default route is/me
. -
auth_endpoint
- End-point URI for authenticating the user. If user sends aPOST
request to this end-point it triggers theauthenticate
method. Default route isNone
since we do not need an authentication end-point in Basic authentication. -
user_id: str
- The key name to retain the user ID when the token is decoded. Default value isuser_id
. -
password: str
- The key name to retain the password when the token is decoded. Default value ispassword
.
Methods:
-
decode(jwt_token: str, verify=True) -> dict
Decode basic token and return user's id and password as a dict.
Exceptions:
InvalidTokenException
will be raised ifbase64.b64decode
fails to decode the token.
-
get_permissions(request: web.Request)
Get the user from the request and return user's permissions.
-
authenticate(self, request: web.Request) -> Dict[str, Any]
Return JSON serializable user. This is an abstract method and should be overridden.
-
classmethod
setup(app, name='authenticator')
Set-up the authenticator.
JWTAuth
aegis.authenticators.jwt.JWTAuth
Base authenticator for JSON Web Token authentication.
Authenticator is set-up by :meth:setup
.
The class implements :class:aegis.authenticators.base.BaseAuth
.
User should never instantiate the class but create a new class that
inherits and overrides required variables and methods.
:attr:jwt_secret
and :meth:authenticator
is forced to override.
Arguments:
-
jwt_secret: str
- The secret key for encoding and decoding unique tokens. -
duration: int
- Access token expiration limit. Default limit is25_000
. -
jwt_algorithm: str
- The algorithm that will be used to generate the tokens. Default algorithm isHS256
. -
refresh_token: bool
- The flag that activates the refresh token feature. Default value isFalse
. -
refresh_endpoint: str
- Token refreshing endpoint URI. Default route is/auth/refresh
.
Methods:
-
decode(jwt_token: str, verify=True) -> dict
Decode the given token and return as a
dict
. Raise validation exceptions if verify is set toTrue
.Exceptions:
-
InvalidTokenException
will be raised if PyJWT fails to decode the access token. -
TokenExpiredException
will be raised if access token has expired.
-
-
encode(payload: dict) -> str
Encode given payload and return as a string.
-
get_permissions(request: web.Request)
Get the user from the request and return user's permissions.
-
authenticate(self, request: web.Request) -> Dict[str, Any]
Return JSON serializable user. This is an abstract method and should be overridden.
-
classmethod
setup(app, name='authenticator')
Set-up the authenticator.
BaseAuth
aegis.authenticators.base.BaseAuth
Abstract base authenticator. User can implement new authenticators based on their needs.
Arguments:
-
me_endpoint
- User information endpoint URI. Default route is/me
. -
auth_endpoint
- End-point URI for authenticating the user. If user sends aPOST
request to this end-point it triggers the :meth:authenticate
method. Default route is/auth
.
Methods:
-
check_permissions(user_scopes, required_scopes, algorithm='any') -> bool
Check whether user's permissions matches with required permissions to reach to the end-point.
By default check_permissions uses the
any
algorithm opens the end-point for any user who has any of the required permissions.We can use other pre-defined algorithms.
algorithm='all'
opens the end-point to users who has all of the required permissions. End-point will also be open for users with more permissions than its required withall
algorithm.If you want to open the end-point for the users who have exactly the same permissions with the end-point` you can use the
algorithm='exact'
. -
abstractmethod
decode(jwt_token: str, verify=True) -> dict
Decode token and return user credentials as a dict.
This is an abstract method and should be overridden.
-
abstractmethod
get_permissions(request: web.Request)
Decode token and return user credentials as a dict.
This is an abstract method and should be overridden.
-
abstractmethod
authenticate(self, request: web.Request) -> Dict[str, Any]
Return JSON serializable user.
This is an abstract method and should be overridden.
-
classmethod
setup(app, name='authenticator')
Set-up the authenticator.
MockAuthenticator
aegis.test_utils.MockAuthenticator
MockAuthenticator has an almost identical API to default authenticator classes. You can use this authenticator in your unit tests to bypass the authentication logic.
class AppTestCase(AioHTTPTestCase):
async def get_application(self):
app = create_app()
MockAuthenticator.setup(app)
return app
By calling the setup method, MockAuthenticator will mock the authenticator
that you have been using in your app. MockAuthenticator is almost the
same with the previous authenticator. In addition, it also has some
extra features to bypass
the authentication system.
Arguments:
user
- Injected test user. Default isNone
.
Methods:
-
bypass_auth(user: dict)
bypass_auth
might be the only method you will ever need to control the authentication logic. It is acontextmanager
. So you can disable the permission control multiple times in your test suite. To use thebypass_auth
, we first need to reach to our mocked authenticator instance, and then, we can manipulate the authentication control by calling thebypass_auth
method with a test user.
@unittest_run_loop
async def test_protected_route_without_credentials(self):
mocked_authenticator = self.app["authenticator"]
mock_user = {"permissions": ("user",)}
with mocked_authenticator.bypass_auth(user=mock_user):
resp = await self.client.request("GET", "/")
assert resp.status == 200
resp = await self.client.request("GET", "/")
assert resp.status == 401
- classmethod
setup(app)
Set-up the authenticator with mocked features.
class AppTestCase(AioHTTPTestCase):
async def get_application(self):
app = create_app()
MockAuthenticator.setup(app)
return app