77
88from django .conf import settings
99from django .contrib .auth import get_user_model
10+ from django .contrib .auth import views as auth_views
1011from django .core .paginator import EmptyPage , PageNotAnInteger , Paginator
1112from django .db .models import QuerySet
1213from django .http import HttpResponseRedirect
@@ -311,31 +312,29 @@ def user_templates(request):
311312def user_profile (request ):
312313 """
313314 User profile view that supports both Hanko and Django auth.
315+
316+ When Hanko auth is enabled, redirects to Hanko's profile page so users
317+ manage their email/username there. Changes are synced back via middleware.
314318 """
315319 from django import forms
316320
317- user = None
318- hanko_user = None
319-
320- # Check Hanko authentication first
321+ # If Hanko auth is enabled, redirect to Hanko profile page
321322 if getattr (settings , 'AUTH_PROVIDER' , 'legacy' ) == 'hanko' :
322- if hasattr (request , 'hotosm' ) and request .hotosm .user :
323- hanko_user = request .hotosm .user
324- user = get_hanko_django_user (request )
323+ from urllib .parse import quote
324+ hanko_public_url = getattr (settings , 'HANKO_PUBLIC_URL' , '' ) or getattr (settings , 'HANKO_API_URL' , '' )
325+ site_url = getattr (settings , 'SITE_URL' , '/' )
326+ return_to = quote (site_url , safe = '' )
327+ return HttpResponseRedirect (f"{ hanko_public_url } /app/profile?return_to={ return_to } " )
325328
326- # Fall back to Django session auth
327- if not user and request .user .is_authenticated :
329+ user = None
330+
331+ # Legacy Django session auth
332+ if request .user .is_authenticated :
328333 user = request .user
329334
330- # Only redirect if no Hanko user AND no Django user
331- if not user and not hanko_user :
335+ if not user :
332336 return HttpResponseRedirect (reverse ('login' ))
333337
334- # Hanko-only users (no Django user) cannot access profile page
335- # Redirect them to the dashboard
336- if hanko_user and not user :
337- return HttpResponseRedirect (reverse ('user_dashboard' ))
338-
339338 # Simple form for profile
340339 class UserProfileForm (forms .ModelForm ):
341340 class Meta :
@@ -361,9 +360,32 @@ class Meta:
361360 context = {
362361 'object' : user ,
363362 'user' : user ,
364- 'hanko_user' : hanko_user ,
365363 'form' : form ,
366364 'providers' : providers ,
367365 }
368366
369367 return render (request , "auth/user_form.html" , context )
368+
369+
370+ class HankoAwareLoginView (auth_views .LoginView ):
371+ """
372+ Custom login view that checks for Hanko authentication.
373+
374+ If user is authenticated with Hanko, redirect to 'next' URL directly
375+ without showing the legacy login form.
376+ """
377+
378+ def dispatch (self , request , * args , ** kwargs ):
379+ # Check if Hanko auth is enabled and user is authenticated with Hanko
380+ if getattr (settings , 'AUTH_PROVIDER' , 'legacy' ) == 'hanko' :
381+ if hasattr (request , 'hotosm' ) and request .hotosm .user :
382+ # User is authenticated with Hanko - redirect to 'next' or dashboard
383+ next_url = request .GET .get ('next' ) or request .POST .get ('next' )
384+ if next_url :
385+ return HttpResponseRedirect (next_url )
386+ else :
387+ # Default to user dashboard
388+ return HttpResponseRedirect (reverse ('user_dashboard' ))
389+
390+ # Fall through to normal login view
391+ return super ().dispatch (request , * args , ** kwargs )
0 commit comments