# OAuth Propagation
* adds user propagation without django-simple-sso
This commit is contained in:
7
user/views/__init__.py
Normal file
7
user/views/__init__.py
Normal file
@@ -0,0 +1,7 @@
|
||||
"""
|
||||
Author: Michel Peltriaux
|
||||
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
|
||||
Contact: ksp-servicestelle@sgdnord.rlp.de
|
||||
Created on: 10.05.24
|
||||
|
||||
"""
|
||||
69
user/views/propagate.py
Normal file
69
user/views/propagate.py
Normal file
@@ -0,0 +1,69 @@
|
||||
"""
|
||||
Author: Michel Peltriaux
|
||||
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
|
||||
Contact: ksp-servicestelle@sgdnord.rlp.de
|
||||
Created on: 10.05.24
|
||||
|
||||
"""
|
||||
import base64
|
||||
import hashlib
|
||||
import json
|
||||
|
||||
from cryptography.fernet import Fernet
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.http import HttpRequest, JsonResponse
|
||||
from django.utils.decorators import method_decorator
|
||||
from django.views import View
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
|
||||
from konova.sub_settings.sso_settings import OAUTH_CLIENT_ID
|
||||
from user.models import User
|
||||
|
||||
|
||||
class PropagateUserView(View):
|
||||
""" Receives user data to be stored in db
|
||||
|
||||
Used if new user gets access to application and needs to be created in application before first login (e.g.
|
||||
proper rights management)
|
||||
|
||||
"""
|
||||
|
||||
@method_decorator(csrf_exempt)
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
def post(self, request: HttpRequest, *args, **kwargs):
|
||||
# Decrypt
|
||||
encrypted_body = request.body
|
||||
hash = hashlib.md5()
|
||||
hash.update(OAUTH_CLIENT_ID.encode("utf-8"))
|
||||
key = base64.urlsafe_b64encode(hash.hexdigest().encode("utf-8"))
|
||||
fernet = Fernet(key)
|
||||
body = fernet.decrypt(encrypted_body).decode("utf-8")
|
||||
body = json.loads(body)
|
||||
|
||||
try:
|
||||
status = "updated"
|
||||
user = User.objects.get(username=body.get('username'))
|
||||
# Update user data, excluding some changes
|
||||
skipable_attrs = {
|
||||
"username",
|
||||
"is_staff",
|
||||
"is_superuser",
|
||||
}
|
||||
for _attr, _val in body.items():
|
||||
if _attr in skipable_attrs:
|
||||
continue
|
||||
setattr(user, _attr, _val)
|
||||
except ObjectDoesNotExist:
|
||||
user = User(**body)
|
||||
status = "created"
|
||||
user.set_unusable_password()
|
||||
user.save()
|
||||
|
||||
data = {
|
||||
"success": True,
|
||||
"status": status
|
||||
}
|
||||
|
||||
return JsonResponse(data)
|
||||
237
user/views/views.py
Normal file
237
user/views/views.py
Normal file
@@ -0,0 +1,237 @@
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.urls import reverse
|
||||
|
||||
from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER
|
||||
from konova.utils.mailer import Mailer
|
||||
from konova.utils.message_templates import FORM_INVALID
|
||||
from user.forms.modals.team import NewTeamModalForm, EditTeamModalForm, RemoveTeamModalForm, LeaveTeamModalForm
|
||||
from user.forms.modals.user import UserContactForm
|
||||
from user.forms.team import TeamDataForm
|
||||
from user.forms.user import UserNotificationForm, UserAPITokenForm
|
||||
from user.models import User, Team
|
||||
from django.http import HttpRequest, Http404
|
||||
from django.shortcuts import render, redirect, get_object_or_404
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from konova.contexts import BaseContext
|
||||
from konova.decorators import any_group_check, default_group_required, login_required_modal
|
||||
|
||||
|
||||
@login_required
|
||||
@any_group_check
|
||||
def index_view(request: HttpRequest):
|
||||
""" Renders the user's data index view
|
||||
|
||||
Args:
|
||||
request ():
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
template = "user/index.html"
|
||||
context = {
|
||||
"user": request.user,
|
||||
TAB_TITLE_IDENTIFIER: _("User settings"),
|
||||
}
|
||||
context = BaseContext(request, context).context
|
||||
return render(request, template, context)
|
||||
|
||||
|
||||
@login_required
|
||||
@any_group_check
|
||||
def notifications_view(request: HttpRequest):
|
||||
""" Renders the notifications settings view
|
||||
|
||||
Args:
|
||||
request ():
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
template = "user/notifications.html"
|
||||
user = request.user
|
||||
|
||||
form = UserNotificationForm(user=user, data=request.POST or None)
|
||||
if request.method == "POST":
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
messages.success(
|
||||
request,
|
||||
_("Notifications edited")
|
||||
)
|
||||
return redirect("user:index")
|
||||
elif request.method == "GET":
|
||||
# Implicit
|
||||
pass
|
||||
else:
|
||||
raise NotImplementedError
|
||||
|
||||
context = {
|
||||
"user": user,
|
||||
"form": form,
|
||||
TAB_TITLE_IDENTIFIER: _("User notifications"),
|
||||
}
|
||||
context = BaseContext(request, context).context
|
||||
return render(request, template, context)
|
||||
|
||||
|
||||
@login_required
|
||||
@default_group_required
|
||||
def api_token_view(request: HttpRequest):
|
||||
""" Handles the request for user api frontend settings
|
||||
|
||||
Args:
|
||||
request (HttpRequest): The incoming request
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
template = "user/token.html"
|
||||
user = request.user
|
||||
form = UserAPITokenForm(request.POST or None, instance=user)
|
||||
if request.method == "POST":
|
||||
if form.is_valid():
|
||||
token = form.save()
|
||||
messages.info(request, _("New token generated. Administrators need to validate."))
|
||||
mailer = Mailer()
|
||||
mailer.send_mail_verify_api_token(user)
|
||||
return redirect("user:api-token")
|
||||
else:
|
||||
messages.error(request, FORM_INVALID, extra_tags="danger")
|
||||
elif request.method != "GET":
|
||||
raise NotImplementedError
|
||||
context = {
|
||||
"user": user,
|
||||
"form": form,
|
||||
TAB_TITLE_IDENTIFIER: _("User API token"),
|
||||
}
|
||||
context = BaseContext(request, context).context
|
||||
return render(request, template, context)
|
||||
|
||||
|
||||
@login_required_modal
|
||||
@login_required
|
||||
def contact_view(request: HttpRequest, id: str):
|
||||
""" Renders contact modal view of a users contact data
|
||||
|
||||
Args:
|
||||
request (HttpRequest): The incoming request
|
||||
id (str): The user's id
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
user = get_object_or_404(User, id=id)
|
||||
form = UserContactForm(request.POST or None, instance=user, request=request)
|
||||
template = "modal/modal_form.html"
|
||||
context = {
|
||||
"form": form,
|
||||
}
|
||||
context = BaseContext(request, context).context
|
||||
return render(
|
||||
request,
|
||||
template,
|
||||
context
|
||||
)
|
||||
|
||||
|
||||
@login_required_modal
|
||||
@login_required
|
||||
def data_team_view(request: HttpRequest, id: str):
|
||||
""" Renders team data
|
||||
|
||||
Args:
|
||||
request (HttpRequest): The incoming request
|
||||
id (str): The team's id
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
team = get_object_or_404(Team, id=id)
|
||||
form = TeamDataForm(request.POST or None, instance=team, request=request)
|
||||
template = "modal/modal_form.html"
|
||||
context = {
|
||||
"form": form,
|
||||
}
|
||||
context = BaseContext(request, context).context
|
||||
return render(
|
||||
request,
|
||||
template,
|
||||
context
|
||||
)
|
||||
|
||||
|
||||
@login_required
|
||||
def index_team_view(request: HttpRequest):
|
||||
template = "user/team/index.html"
|
||||
user = request.user
|
||||
context = {
|
||||
"teams": user.shared_teams,
|
||||
"tab_title": _("Teams"),
|
||||
}
|
||||
context = BaseContext(request, context).context
|
||||
return render(request, template, context)
|
||||
|
||||
|
||||
@login_required_modal
|
||||
@login_required
|
||||
def new_team_view(request: HttpRequest):
|
||||
form = NewTeamModalForm(request.POST or None, request=request)
|
||||
return form.process_request(
|
||||
request,
|
||||
_("New team added"),
|
||||
redirect_url=reverse("user:team-index")
|
||||
)
|
||||
|
||||
|
||||
@login_required_modal
|
||||
@login_required
|
||||
def edit_team_view(request: HttpRequest, id: str):
|
||||
team = get_object_or_404(Team, id=id)
|
||||
user_is_admin = team.is_user_admin(request.user)
|
||||
if not user_is_admin:
|
||||
raise Http404()
|
||||
form = EditTeamModalForm(request.POST or None, instance=team, request=request)
|
||||
return form.process_request(
|
||||
request,
|
||||
_("Team edited"),
|
||||
redirect_url=reverse("user:team-index")
|
||||
)
|
||||
|
||||
|
||||
@login_required_modal
|
||||
@login_required
|
||||
def remove_team_view(request: HttpRequest, id: str):
|
||||
team = get_object_or_404(Team, id=id)
|
||||
user_is_admin = team.is_user_admin(request.user)
|
||||
if not user_is_admin:
|
||||
raise Http404()
|
||||
form = RemoveTeamModalForm(request.POST or None, instance=team, request=request)
|
||||
return form.process_request(
|
||||
request,
|
||||
_("Team removed"),
|
||||
redirect_url=reverse("user:team-index")
|
||||
)
|
||||
|
||||
|
||||
@login_required_modal
|
||||
@login_required
|
||||
def leave_team_view(request: HttpRequest, id: str):
|
||||
team = get_object_or_404(Team, id=id)
|
||||
user = request.user
|
||||
|
||||
is_user_team_member = team.users.filter(id=user.id).exists()
|
||||
if not is_user_team_member:
|
||||
messages.info(
|
||||
request,
|
||||
_("You are not a member of this team")
|
||||
)
|
||||
return redirect("user:team-index")
|
||||
|
||||
form = LeaveTeamModalForm(request.POST or None, instance=team, request=request)
|
||||
return form.process_request(
|
||||
request,
|
||||
_("Left Team"),
|
||||
redirect_url=reverse("user:team-index")
|
||||
)
|
||||
Reference in New Issue
Block a user