Skip to content

Commit f1862f8

Browse files
committed
refactor(authentication): enhance header usage and verification checks
- Allowed the use of the auth header from settings in `authentication.py`. - Improved handling of email and phone verification checks.
1 parent c138f59 commit f1862f8

File tree

2 files changed

+66
-39
lines changed

2 files changed

+66
-39
lines changed

django_appwrite/authentication.py

Lines changed: 9 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,19 @@
1-
from django.conf import settings
21
from rest_framework.authentication import BaseAuthentication
3-
from rest_framework.exceptions import AuthenticationFailed
4-
from django.contrib.auth import get_user_model, authenticate
5-
from appwrite.services.account import Account
62

7-
from django_appwrite.utilities import initialize_appwrite_client, get_appwrite_settings, log_error
8-
9-
User = get_user_model()
3+
from django_appwrite.utilities import get_appwrite_settings, extract_token, \
4+
get_appwrite_user_info, check_verification, get_or_create_django_user
105

116

127
class AppwriteAuthentication(BaseAuthentication):
138
def authenticate(self, request):
14-
# Extract the Appwrite token from the request headers
15-
auth_header = request.headers.get('Authorization')
16-
if not auth_header or not auth_header.startswith('Bearer '):
17-
return None # No authentication attempt
18-
19-
token = auth_header.split('Bearer ')[1]
20-
21-
# Verify the token with Appwrite
22-
client = initialize_appwrite_client()
23-
client.set_jwt(token)
24-
25-
try:
26-
user_info = Account(client).get()
27-
except Exception as e:
28-
if settings.DEBUG:
29-
log_error(e)
30-
raise AuthenticationFailed('Invalid Appwrite token or other Appwrite authentication issue.')
31-
329
appwrite_settings = get_appwrite_settings()
10+
token = extract_token(request, appwrite_settings)
3311

34-
email = appwrite_settings['prefix_email'] + user_info['email']
35-
password = settings.SECRET_KEY + user_info['$id']
36-
37-
username_field = getattr(User, 'USERNAME_FIELD', 'username')
38-
39-
# Get or create a corresponding Django user
40-
django_user = User.objects.filter(**{username_field: email}).first()
41-
if not django_user:
42-
User.objects.create_user(**{username_field: email, 'password': password})
12+
# Verify the token with Appwrite
13+
user_info = get_appwrite_user_info(token)
4314

44-
# Ensure the user can be authenticated with Django's system
45-
auth_user = authenticate(request, **{username_field: email, 'password': password})
46-
if not auth_user:
47-
raise AuthenticationFailed('The user could not be authenticated with Django.')
15+
# Check email and phone verification
16+
check_verification(user_info, appwrite_settings)
4817

49-
return auth_user, token
18+
# Authenticate or create Django user
19+
return get_or_create_django_user(request, user_info, appwrite_settings), token

django_appwrite/utilities.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
from django.conf import settings
2+
from django.contrib.auth import get_user_model, authenticate
23
from appwrite.client import Client
4+
from appwrite.services.account import Account
5+
from rest_framework.exceptions import AuthenticationFailed
6+
7+
User = get_user_model()
38

49

510
def get_appwrite_settings():
@@ -44,3 +49,55 @@ def log_error(e):
4449
import logging
4550
logger = logging.getLogger('django')
4651
logger.error('Error: ', e)
52+
53+
54+
def check_verification(user_info, appwrite_settings):
55+
if appwrite_settings['verify_email'] and not user_info['emailVerification']:
56+
raise AuthenticationFailed('Email not verified.')
57+
if appwrite_settings['verify_phone'] and not user_info['phoneVerification']:
58+
raise AuthenticationFailed('Phone not verified.')
59+
60+
61+
def get_or_create_django_user(request, user_info, appwrite_settings):
62+
email = appwrite_settings['prefix_email'] + user_info['email']
63+
password = settings.SECRET_KEY + user_info['$id']
64+
username_field = getattr(User, 'USERNAME_FIELD', 'username')
65+
66+
# Get or create a corresponding Django user
67+
django_user = User.objects.filter(**{username_field: email}).first()
68+
if not django_user:
69+
User.objects.create_user(**{username_field: email, 'password': password})
70+
71+
auth_user = authenticate(request, **{username_field: email, 'password': password})
72+
if not auth_user:
73+
raise AuthenticationFailed('The user could not be authenticated with Django.')
74+
75+
return auth_user
76+
77+
78+
def _log_error(message, exception=None):
79+
if settings.DEBUG:
80+
log_error(message)
81+
if exception:
82+
log_error(str(exception))
83+
84+
85+
def get_appwrite_user_info(token):
86+
client = initialize_appwrite_client()
87+
client.set_jwt(token)
88+
try:
89+
return Account(client).get()
90+
except Exception as e:
91+
_log_error(e)
92+
raise AuthenticationFailed('Invalid Appwrite token or other Appwrite authentication issue.')
93+
94+
95+
def extract_token(request, appwrite_settings):
96+
try:
97+
auth_header = request.headers.get(appwrite_settings['auth_header'])
98+
if not auth_header or 'Bearer ' not in auth_header:
99+
raise ValueError("Bearer token missing, make sure you're using the correct auth header.")
100+
return auth_header.split('Bearer ')[1]
101+
except (ValueError, IndexError) as e:
102+
_log_error('AppwriteAuthentication: cannot extract token from request headers.', e)
103+
return None

0 commit comments

Comments
 (0)