Skip to content

Commit

Permalink
feat: #31 resolve mypy errors ✨
Browse files Browse the repository at this point in the history
  - resolve all errors flagged by mypy
  - TODO: verify is authenticated is correct
  • Loading branch information
liquidiert committed Apr 18, 2024
1 parent 3dd9e52 commit 505bcaa
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 20 deletions.
4 changes: 2 additions & 2 deletions example/example/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []
ALLOWED_HOSTS: list[str] = []


# Application definition
Expand Down Expand Up @@ -141,7 +141,7 @@
PYCLOAK_FIRSTNAME_CLAIM = "given_name"
PYCLOAK_LASTNAME_CLAIM = "family_name"
PYCLOAK_EMAIL_CLAIM = "email"
PYCLOAK_STAFF_ROLES = []
PYCLOAK_STAFF_ROLES: list[str] = []
PYCLOAK_SUPERUSER_ROLES = ["uma_authorization"]
PYCLOAK_TOKENID_CLAIM = "jti"
PYCLOAK_SESSION_KEY = "_pycloak_token_id"
15 changes: 8 additions & 7 deletions pycloak/auth.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
from typing import List

from django.conf import settings
from django.contrib.auth import get_user_model
from django.contrib.auth.backends import ModelBackend
Expand All @@ -9,7 +7,9 @@


class JWTBackend(ModelBackend):
def authenticate(self, request, jwt_data: dict = None):
def authenticate(self, request, jwt_data: dict | None = None):
if jwt_data is None:
raise ValueError("jwt_data must be provided")
# 1. get/create/update user
username = self.get_username(request, jwt_data)
is_staff = self.get_is_staff(request, jwt_data)
Expand Down Expand Up @@ -39,7 +39,7 @@ def add_groups(self, request, jwt_data, user):
user.groups.set(Group.objects.filter(name__in=token_roles))

def get_username(self, request, jwt_data: dict) -> str:
return jwt_data[conf.USERNAME_CLAIM]
return str(jwt_data[conf.USERNAME_CLAIM])

def get_email(self, request, jwt_data: dict) -> str:
return jwt_data.get(conf.EMAIL_CLAIM, "") or ""
Expand All @@ -58,9 +58,10 @@ def get_is_superuser(self, request, jwt_data: dict) -> bool:
token_roles = self.get_roles(request, jwt_data)
return bool(set(conf.SUPERUSER_ROLES).intersection(token_roles))

def get_roles(self, request, jwt_data: dict) -> List[str]:
return self.get_realm_roles(request, jwt_data) + self.get_client_roles(
request, jwt_data
def get_roles(self, request, jwt_data: dict) -> list[str]:
return list(
self.get_realm_roles(request, jwt_data)
+ self.get_client_roles(request, jwt_data)
)

def get_realm_roles(self, request, jwt_data: dict):
Expand Down
2 changes: 1 addition & 1 deletion pycloak/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@


class _PycloakConfiguration:
DEFAULTS = {
DEFAULTS: dict = {
"ALGORITHM": None,
"AUDIENCE": None,
"PUBLIC_KEY": None, # can be exported from keyclaok realm
Expand Down
20 changes: 10 additions & 10 deletions pycloak/middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from cryptography.hazmat.primitives import serialization
from django.contrib.auth import authenticate, login, logout
from django.core.exceptions import ImproperlyConfigured, ValidationError
from django.http import HttpResponse
from django.http import HttpResponse, HttpRequest
from django.utils.deprecation import MiddlewareMixin
from jwt import ExpiredSignatureError, InvalidTokenError, decode

Expand All @@ -31,7 +31,7 @@ def process_request(self, request):
if not self.allow_default_login(request):
return HttpResponse(status=UNAUTHORIZED)

def process_token(self, request) -> bool:
def process_token(self, request: HttpRequest) -> bool:
"""
Return True if there is a logged in and authenticated user when this function returns
"""
Expand All @@ -52,7 +52,7 @@ def process_token(self, request) -> bool:
# no token, but accept other options of authentication
logger.warning("No jwt retrieved")
request.session.pop(conf.SESSION_KEY, None)
return request.user.is_authenticated
return bool(request.user.is_authenticated) # TODO: if this really always returns True, is this safe?

# 2. get payload from jwt
try:
Expand Down Expand Up @@ -128,12 +128,12 @@ def get_public_key(self, request):
return public_key

def get_audience(self, request) -> str:
return conf.AUDIENCE
return str(conf.AUDIENCE)

def get_algorithms(self, request) -> List[str]:
return [conf.ALGORITHM]

def get_bearer_token(self, request) -> str:
def get_bearer_token(self, request) -> str | None:
"""
Get the token from the Authorization header
depending on the configuration of the oauth2 proxy, this might be the jwt access_token or the id_token
Expand All @@ -145,7 +145,7 @@ def get_bearer_token(self, request) -> str:
return None
except (KeyError, ValueError, TypeError):
return None
return token
return str(token)

def get_jwt_from_request(self, request) -> str:
token_header = conf.TOKEN_HEADER
Expand All @@ -170,7 +170,7 @@ def get_data_from_jwt(self, request, jwt) -> dict:
options = {
"verify_signature": self.get_verify(request),
}
data = decode(
data: dict = decode(
jwt,
algorithms=self.get_algorithms(request),
key=self.get_public_key(request),
Expand All @@ -182,10 +182,10 @@ def get_data_from_jwt(self, request, jwt) -> dict:
return data

def allow_default_login(self, request) -> bool:
return conf.ALLOW_DEFAULT_LOGIN
return bool(conf.ALLOW_DEFAULT_LOGIN)

def get_token_id(self, request, jwt_data) -> str:
return jwt_data[conf.TOKENID_CLAIM]
def get_token_id(self, request, jwt_data: dict) -> str:
return str(jwt_data[conf.TOKENID_CLAIM])

def store_claim_on_user(self, request, user):
# store objects to save (user or related objects)
Expand Down

0 comments on commit 505bcaa

Please sign in to comment.