"""This file and its contents are licensed under the Apache License 2.0. Please see the included NOTICE for copyright information and LICENSE for a copy of the license.
|
"""
|
import logging
|
from urllib.parse import quote
|
|
from core.feature_flags import flag_set
|
from core.middleware import enforce_csrf_checks
|
from core.utils.common import load_func
|
from django.conf import settings
|
from django.contrib import auth
|
from django.contrib.auth.decorators import login_required
|
from django.core.exceptions import PermissionDenied
|
from django.shortcuts import redirect, render, reverse
|
from django.utils.http import url_has_allowed_host_and_scheme
|
from organizations.forms import OrganizationSignupForm
|
from organizations.models import Organization
|
from rest_framework.authtoken.models import Token
|
from users import forms
|
from users.functions import login, proceed_registration
|
|
logger = logging.getLogger()
|
|
|
@login_required
|
def logout(request):
|
auth.logout(request)
|
|
if settings.LOGOUT_REDIRECT_URL:
|
return redirect(settings.LOGOUT_REDIRECT_URL)
|
|
if settings.HOSTNAME:
|
redirect_url = settings.HOSTNAME
|
if not redirect_url.endswith('/'):
|
redirect_url += '/'
|
return redirect(redirect_url)
|
return redirect('/')
|
|
|
@enforce_csrf_checks
|
def user_signup(request):
|
"""Sign up page"""
|
user = request.user
|
next_page = request.GET.get('next')
|
token = request.GET.get('token')
|
|
# checks if the URL is a safe redirection.
|
if not next_page or not url_has_allowed_host_and_scheme(url=next_page, allowed_hosts=request.get_host()):
|
if flag_set('fflag_all_feat_dia_1777_ls_homepage_short', user):
|
next_page = reverse('main')
|
else:
|
next_page = reverse('projects:project-index')
|
|
user_form = forms.UserSignupForm()
|
organization_form = OrganizationSignupForm()
|
|
if user.is_authenticated:
|
return redirect(next_page)
|
|
# make a new user
|
if request.method == 'POST':
|
organization = Organization.objects.first()
|
if settings.DISABLE_SIGNUP_WITHOUT_LINK is True:
|
if not (token and organization and token == organization.token):
|
raise PermissionDenied()
|
else:
|
if token and organization and token != organization.token:
|
raise PermissionDenied()
|
|
user_form = forms.UserSignupForm(request.POST)
|
organization_form = OrganizationSignupForm(request.POST)
|
|
if user_form.is_valid():
|
redirect_response = proceed_registration(request, user_form, organization_form, next_page)
|
if redirect_response:
|
return redirect_response
|
|
if flag_set('fflag_feat_front_lsdv_e_297_increase_oss_to_enterprise_adoption_short'):
|
return render(
|
request,
|
'users/new-ui/user_signup.html',
|
{
|
'user_form': user_form,
|
'organization_form': organization_form,
|
'next': quote(next_page),
|
'token': token,
|
'found_us_options': forms.FOUND_US_OPTIONS,
|
'elaborate': forms.FOUND_US_ELABORATE,
|
},
|
)
|
|
return render(
|
request,
|
'users/user_signup.html',
|
{
|
'user_form': user_form,
|
'organization_form': organization_form,
|
'next': quote(next_page),
|
'token': token,
|
},
|
)
|
|
|
@enforce_csrf_checks
|
def user_login(request):
|
"""Login page"""
|
user = request.user
|
next_page = request.GET.get('next')
|
|
# checks if the URL is a safe redirection.
|
if not next_page or not url_has_allowed_host_and_scheme(url=next_page, allowed_hosts=request.get_host()):
|
if flag_set('fflag_all_feat_dia_1777_ls_homepage_short', user):
|
next_page = reverse('main')
|
else:
|
next_page = reverse('projects:project-index')
|
|
login_form = load_func(settings.USER_LOGIN_FORM)
|
form = login_form()
|
|
if user.is_authenticated:
|
return redirect(next_page)
|
|
if request.method == 'POST':
|
form = login_form(request.POST)
|
if form.is_valid():
|
user = form.cleaned_data['user']
|
login(request, user, backend='django.contrib.auth.backends.ModelBackend')
|
if form.cleaned_data['persist_session'] is not True:
|
# Set the session to expire when the browser is closed
|
request.session['keep_me_logged_in'] = False
|
request.session.set_expiry(0)
|
|
# user is organization member
|
org_pk = Organization.find_by_user(user).pk
|
user.active_organization_id = org_pk
|
user.save(update_fields=['active_organization'])
|
return redirect(next_page)
|
|
if flag_set('fflag_feat_front_lsdv_e_297_increase_oss_to_enterprise_adoption_short'):
|
return render(request, 'users/new-ui/user_login.html', {'form': form, 'next': quote(next_page)})
|
|
return render(request, 'users/user_login.html', {'form': form, 'next': quote(next_page)})
|
|
|
@login_required
|
def user_account(request, sub_path=None):
|
"""
|
Handle user account view and profile updates.
|
|
This view displays the user's profile information and allows them to update
|
it. It requires the user to be authenticated and have an active organization
|
or an organization_pk in the session.
|
|
Args:
|
request (HttpRequest): The request object.
|
sub_path (str, optional): A sub-path parameter for potential URL routing.
|
Defaults to None.
|
|
Returns:
|
HttpResponse: Renders the user account template with user profile form,
|
or redirects to 'main' if no active organization is found,
|
or redirects back to user-account after successful profile update.
|
|
Notes:
|
- Authentication is required (enforced by @login_required decorator)
|
- Retrieves the user's API token for display in the template
|
- Form validation happens on POST requests
|
"""
|
user = request.user
|
|
if user.active_organization is None and 'organization_pk' not in request.session:
|
return redirect(reverse('main'))
|
|
form = forms.UserProfileForm(instance=user)
|
token = Token.objects.get(user=user)
|
|
if request.method == 'POST':
|
form = forms.UserProfileForm(request.POST, instance=user)
|
if form.is_valid():
|
form.save()
|
return redirect(reverse('user-account'))
|
|
return render(
|
request,
|
'users/user_account.html',
|
{'settings': settings, 'user': user, 'user_profile_form': form, 'token': token},
|
)
|