views.py 3.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. from django.contrib.auth.decorators import login_required
  2. from django.shortcuts import get_object_or_404, redirect, render
  3. from django.contrib import messages
  4. from django.core.exceptions import PermissionDenied
  5. from django.conf import settings
  6. from django.http import HttpResponse, HttpResponseBadRequest
  7. from django.views.decorators.http import require_POST
  8. from django.views.decorators.csrf import csrf_exempt
  9. from django.contrib.auth import authenticate, get_user_model
  10. from django.contrib.auth.views import LoginView, LogoutView
  11. from django.contrib.auth import login as auth_login
  12. from services.models import IPResource
  13. from djadhere.utils import get_active_filter
  14. from .forms import UserForm, ProfileForm
  15. from ipaddress import ip_address, IPv6Address
  16. from services.utils.ip_conversion import ipv6_to_ipv4
  17. def login(request):
  18. def try_authenticate_from_ip():
  19. x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
  20. if x_forwarded_for:
  21. ip = x_forwarded_for.split(',')[0]
  22. else:
  23. ip = request.META.get('REMOTE_ADDR')
  24. try:
  25. ip = ip_address(ip)
  26. except ValueError:
  27. return
  28. try:
  29. if type(ip) == IPv6Address:
  30. ip = ipv6_to_ipv4(ip)
  31. ip = IPResource.objects.get(ip=ip.exploded)
  32. except (IPResource.DoesNotExist, ValueError):
  33. return
  34. allocation = ip.allocations.filter(get_active_filter()).first()
  35. if not allocation:
  36. return
  37. user = allocation.service.adhesion.user
  38. if not user: # corporation
  39. return
  40. if user.is_superuser: # superusers must enter password
  41. return
  42. auth_login(request, user, backend='django.contrib.auth.backends.ModelBackend')
  43. if not request.session.get('disable-ip-based-login', False):
  44. try_authenticate_from_ip()
  45. # Même si l’auto-login a marché, on utilise LoginView qui fera la bonne redirection
  46. return LoginView.as_view(redirect_authenticated_user=True)(request)
  47. def logout(request):
  48. response = LogoutView.as_view()(request)
  49. # Définie *après* car le logout flush la session
  50. request.session['disable-ip-based-login'] = True
  51. return response
  52. @login_required
  53. def profile(request):
  54. user_form = UserForm(request.POST or None, instance=request.user)
  55. profile_form = ProfileForm(request.POST or None, instance=request.user.profile)
  56. forms = [user_form, profile_form]
  57. if request.method == 'POST' and all(form.is_valid() for form in forms):
  58. for form in forms:
  59. form.save()
  60. messages.success(request, 'Profil mis à jour avec succès !')
  61. return redirect('profile')
  62. return render(request, 'accounts/profile.html', {
  63. 'user_form': user_form,
  64. 'profile_form': profile_form,
  65. })
  66. @require_POST
  67. @csrf_exempt
  68. def auth_api(request, token):
  69. # token could not be None due to url regex
  70. if token != getattr(settings, 'AUTH_API_TOKEN', None):
  71. raise PermissionDenied
  72. username = request.POST.get('username')
  73. if not username:
  74. return HttpResponseBadRequest()
  75. password = request.POST.get('password')
  76. if password:
  77. user = authenticate(username=username, password=password)
  78. if user is None:
  79. return HttpResponse('<h1>401 Unauthorized</h1>', status=401)
  80. else:
  81. user = get_object_or_404(get_user_model(), username=username)
  82. required_groups = request.POST.get('groups')
  83. if required_groups and not user.is_superuser: # skip groups check for superusers
  84. required_groups = set(required_groups.split(' '))
  85. user_groups = set(map(lambda g: g.name, user.groups.all()))
  86. if required_groups - user_groups:
  87. return HttpResponse('<h1>401 Unauthorized</h1>', status=401)
  88. return HttpResponse()