summaryrefslogtreecommitdiff
path: root/wsgitools/authentication.py
diff options
context:
space:
mode:
authorHelmut Grohne <helmut@subdivi.de>2020-04-13 21:30:34 +0200
committerHelmut Grohne <helmut@subdivi.de>2023-06-18 23:16:57 +0200
commita41066b413489b407b9d99174af697563ad680b9 (patch)
tree2f08f9e886e13a7500d1eb527e30737d961deab6 /wsgitools/authentication.py
parent4d52eaa4801df3f3169df8e58758bcccf22dc4de (diff)
downloadwsgitools-a41066b413489b407b9d99174af697563ad680b9.tar.gz
add type hints to all of the code
In order to use type hint syntax, we need to bump the minimum Python version to 3.7 and some of the features such as Literal and Protocol are opted in when a sufficiently recent Python is available. This does not make all of the code pass type checking with mypy. A number of typing issues remain, but the output of mypy becomes something one can read through. In adding type hints, a lot of epydoc @type annotations are removed as redundant. This update also adopts black-style line breaking.
Diffstat (limited to 'wsgitools/authentication.py')
-rw-r--r--wsgitools/authentication.py43
1 files changed, 25 insertions, 18 deletions
diff --git a/wsgitools/authentication.py b/wsgitools/authentication.py
index c076d7f..345a0ae 100644
--- a/wsgitools/authentication.py
+++ b/wsgitools/authentication.py
@@ -1,3 +1,9 @@
+import typing
+
+from wsgitools.internal import (
+ Environ, HeaderList, OptExcInfo, StartResponse, WriteCallback, WsgiApp
+)
+
__all__ = []
class AuthenticationRequired(Exception):
@@ -15,28 +21,24 @@ class AuthenticationMiddleware:
@cvar authorization_method: the implemented Authorization method. It will
be verified against Authorization headers. Subclasses must define this
attribute.
- @type authorization_method: str
"""
- authorization_method = None
- def __init__(self, app):
+ authorization_method: typing.ClassVar[str]
+ def __init__(self, app: WsgiApp):
"""
@param app: is a WSGI application.
"""
assert self.authorization_method is not None
self.app = app
- def authenticate(self, auth, environ):
+ def authenticate(self, auth: str, environ: Environ) -> Environ:
"""Try to authenticate a request. The Authorization header is examined
and checked agains the L{authorization_method} before being passed to
this method. This method must either raise an AuthenticationRequired
instance or return a dictionary explaining what was successfully
authenticated.
- @type auth: str
@param auth: is the part of the Authorization header after the method
- @type environ: {str: object}
@param environ: is the environment passed with a WSGI request
- @rtype: {str: object}
@returns: a dictionary that provides a key "user" listing the
authenticated username as a string. It may also provide the key
"outheaders" with a [(str, str)] value to extend the response
@@ -45,11 +47,10 @@ class AuthenticationMiddleware:
"""
raise NotImplementedError
- def __call__(self, environ, start_response):
- """wsgi interface
-
- @type environ: {str: object}
- """
+ def __call__(
+ self, environ: Environ, start_response: StartResponse
+ ) -> typing.Iterable[bytes]:
+ """wsgi interface"""
assert isinstance(environ, dict)
try:
try:
@@ -70,7 +71,9 @@ class AuthenticationMiddleware:
assert "user" in result
environ["REMOTE_USER"] = result["user"]
if "outheaders" in result:
- def modified_start_response(status, headers, exc_info=None):
+ def modified_start_response(
+ status: str, headers: HeaderList, exc_info: OptExcInfo = None
+ ) -> WriteCallback:
assert isinstance(headers, list)
headers.extend(result["outheaders"])
return start_response(status, headers, exc_info)
@@ -78,22 +81,26 @@ class AuthenticationMiddleware:
modified_start_response = start_response
return self.app(environ, modified_start_response)
- def www_authenticate(self, exception):
+ def www_authenticate(
+ self, exception: AuthenticationRequired
+ ) -> typing.Tuple[str, str]:
"""Generates a WWW-Authenticate header. Subclasses must implement this
method.
- @type exception: L{AuthenticationRequired}
@param exception: reason for generating the header
- @rtype: (str, str)
@returns: the header as (part_before_colon, part_after_colon)
"""
raise NotImplementedError
- def authorization_required(self, environ, start_response, exception):
+ def authorization_required(
+ self,
+ environ: Environ,
+ start_response: StartResponse,
+ exception: AuthenticationRequired,
+ ) -> typing.Iterable[bytes]:
"""Generate an error page after failed authentication. Apart from the
exception parameter, this method behaves like a WSGI application.
- @type exception: L{AuthenticationRequired}
@param exception: reason for the authentication failure
"""
status = "401 Authorization required"