62 lines
2.3 KiB
Python
62 lines
2.3 KiB
Python
from django.contrib.auth import views as auth_views
|
||||
|
|
from django.contrib.auth.decorators import login_required
|
|||
|
|
from django.http import HttpResponse, HttpResponseForbidden, HttpResponseRedirect
|
|||
|
|
from django.shortcuts import get_object_or_404, render
|
|||
|
|
from django.urls import reverse_lazy
|
|||
|
|
from django.views.decorators.http import require_GET
|
|||
|
|
|
|||
|
|
from .models import AccessLog, Resource
|
|||
|
|
from .services import get_available_resources, issue_resource_token, user_can_access_resource
|
|||
|
|
|
|||
|
|
|
|||
|
|
class PortalLoginView(auth_views.LoginView):
|
|||
|
|
template_name = "portal/login.html"
|
|||
|
|
redirect_authenticated_user = True
|
|||
|
|
|
|||
|
|
def get_success_url(self):
|
|||
|
|
# Если пользователь пришёл по прямой ссылке на ресурс (?next=/group/resource/),
|
|||
|
|
# HAProxy направил его на портал для логина — после успеха возвращаем туда же.
|
|||
|
|
next_url = self.request.POST.get("next") or self.request.GET.get("next")
|
|||
|
|
return next_url or reverse_lazy("dashboard")
|
|||
|
|
|
|||
|
|
|
|||
|
|
@login_required
|
|||
|
|
def dashboard(request):
|
|||
|
|
resources = get_available_resources(request.user)
|
|||
|
|
return render(request, "portal/dashboard.html", {"resources": resources})
|
|||
|
|
|
|||
|
|
|
|||
|
|
@login_required
|
|||
|
|
@require_GET
|
|||
|
|
def open_resource(request, group_slug: str, resource_slug: str):
|
|||
|
|
resource = get_object_or_404(
|
|||
|
|
Resource, group__ad_group_name=group_slug, slug=resource_slug, is_active=True
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
if not user_can_access_resource(request.user, resource):
|
|||
|
|
return HttpResponseForbidden("Доступ к этому ресурсу не предоставлен вашей AD-группе.")
|
|||
|
|
|
|||
|
|
AccessLog.objects.create(
|
|||
|
|
user=request.user,
|
|||
|
|
resource=resource,
|
|||
|
|
ip_address=request.META.get("REMOTE_ADDR"),
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
token = issue_resource_token(request.user, resource)
|
|||
|
|
|
|||
|
|
response = HttpResponseRedirect(resource.path)
|
|||
|
|
response.set_cookie(
|
|||
|
|
key="resource_token",
|
|||
|
|
value=token,
|
|||
|
|
max_age=60, # HAProxy снимет cookie на первом же запросе к backend'у
|
|||
|
|
path=resource.path, # cookie видна только на пути конкретного ресурса
|
|||
|
|
secure=True,
|
|||
|
|
httponly=True,
|
|||
|
|
samesite="Lax",
|
|||
|
|
)
|
|||
|
|
return response
|
|||
|
|
|
|||
|
|
|
|||
|
|
@require_GET
|
|||
|
|
def healthz(request):
|
|||
|
|
return HttpResponse("ok")
|