63 lines
2.3 KiB
Python
63 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")
|