from django.contrib.auth.decorators import login_required from django.shortcuts import get_object_or_404, redirect, render from django.contrib import messages from django.core.exceptions import PermissionDenied from django.conf import settings from django.http import HttpResponse, HttpResponseBadRequest from django.views.decorators.http import require_POST from django.views.decorators.csrf import csrf_exempt from django.contrib.auth import authenticate, get_user_model from django.contrib.auth.views import LoginView, LogoutView from django.contrib.auth import login as auth_login from services.models import IPResource from djadhere.utils import get_active_filter from .forms import UserForm, ProfileForm from ipaddress import ip_address, IPv6Address from services.utils.ip_conversion import ipv6_to_ipv4 def login(request): def try_authenticate_from_ip(): x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR') if x_forwarded_for: ip = x_forwarded_for.split(',')[0] else: ip = request.META.get('REMOTE_ADDR') try: ip = ip_address(ip) except ValueError: return try: if type(ip) == IPv6Address: ip = ipv6_to_ipv4(ip) ip = IPResource.objects.get(ip=ip.exploded) except (IPResource.DoesNotExist, ValueError): return allocation = ip.allocations.filter(get_active_filter()).first() if not allocation: return user = allocation.service.adhesion.user if not user: # corporation return if user.is_superuser: # superusers must enter password return auth_login(request, user, backend='django.contrib.auth.backends.ModelBackend') if not request.session.get('disable-ip-based-login', False): try_authenticate_from_ip() # Même si l’auto-login a marché, on utilise LoginView qui fera la bonne redirection return LoginView.as_view(redirect_authenticated_user=True)(request) def logout(request): response = LogoutView.as_view()(request) # Définie *après* car le logout flush la session request.session['disable-ip-based-login'] = True return response @login_required def profile(request): user_form = UserForm(request.POST or None, instance=request.user) profile_form = ProfileForm(request.POST or None, instance=request.user.profile) forms = [user_form, profile_form] if request.method == 'POST' and all(form.is_valid() for form in forms): for form in forms: form.save() messages.success(request, 'Profil mis à jour avec succès !') return redirect('profile') return render(request, 'accounts/profile.html', { 'user_form': user_form, 'profile_form': profile_form, }) @require_POST @csrf_exempt def auth_api(request, token): # token could not be None due to url regex if token != getattr(settings, 'AUTH_API_TOKEN', None): raise PermissionDenied username = request.POST.get('username') if not username: return HttpResponseBadRequest() password = request.POST.get('password') if password: user = authenticate(username=username, password=password) if user is None: return HttpResponse('