Skip to content

Commit

Permalink
Merge pull request #192 from intuitem/CA-329-An-admin-can-remove-his-…
Browse files Browse the repository at this point in the history
…admin-permissions-and-even-delete-his-account

Return an error message when an admin try to delete the only admin account
  • Loading branch information
eric-intuitem authored Apr 5, 2024
2 parents 23d0fa4 + fba0bcb commit b6cda17
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 8 deletions.
22 changes: 21 additions & 1 deletion backend/core/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@

from django.db import models

from iam.models import User, RoleAssignment, Folder
from iam.models import User, UserGroup, RoleAssignment, Folder

User = get_user_model()

Expand Down Expand Up @@ -835,6 +835,26 @@ def get_queryset(self):
# TODO: Implement a proper filter for the queryset
return User.objects.all()

def update(self, request: Request, *args, **kwargs) -> Response:
user = self.get_object()
if user.is_admin() :
number_of_admin_users = User.get_admin_users().count()
admin_group = UserGroup.objects.get(name="BI-UG-ADM")
if number_of_admin_users == 1 :
new_user_groups = set(request.data["user_groups"])
if str(admin_group.pk) not in new_user_groups :
return Response({"error":"attemptToRemoveOnlyAdminUserGroup"},status=HTTP_403_FORBIDDEN)

return super().update(request, *args, **kwargs)

def destroy(self, request, *args, **kwargs):
user = self.get_object()
if user.is_admin() :
number_of_admin_users = User.get_admin_users().count()
if number_of_admin_users == 1 :
return Response({"error":"attemptToDeleteOnlyAdminAccountError"},status=HTTP_403_FORBIDDEN)

return super().destroy(request,*args,**kwargs)

class UserGroupViewSet(BaseModelViewSet):
"""
Expand Down
8 changes: 6 additions & 2 deletions backend/iam/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,6 @@ def get_user_groups(user):
user_group_list.append(user_group)
return user_group_list


class UserManager(BaseUserManager):
use_in_migrations = True

Expand Down Expand Up @@ -291,7 +290,6 @@ def create_superuser(self, email, password=None, **extra_fields):
UserGroup.objects.get(name="BI-UG-ADM").user_set.add(superuser)
return superuser


class User(AbstractBaseUser, AbstractBaseModel, FolderMixin):
"""a user is a principal corresponding to a human"""

Expand Down Expand Up @@ -471,6 +469,12 @@ def permissions(self):
def set_username(self, username):
self.email = username

@staticmethod
def get_admin_users() -> List[Self] :
return User.objects.filter(user_groups__name="BI-UG-ADM")

def is_admin(self) -> bool :
return self.user_groups.filter(name="BI-UG-ADM").exists()

class Role(NameDescriptionMixin, FolderMixin):
"""A role is a list of permissions"""
Expand Down
4 changes: 3 additions & 1 deletion frontend/messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -495,5 +495,7 @@
"invalidLibraryFileError": "Invalid library file. Please make sure the format is correct.",
"taintedFormMessage": "Do you want to leave this page? Changes you made may not be saved.",
"riskScenariosStatus": "Risk scenarios status",
"onlineDocs": "Online documentation"
"onlineDocs": "Online documentation",
"attemptToDeleteOnlyAdminAccountError": "You can't delete the only admin account of your application.",
"attemptToRemoveOnlyAdminUserGroup": "You can't remove the only admin user of the application from the admin user group."
}
4 changes: 3 additions & 1 deletion frontend/messages/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -492,5 +492,7 @@
"invalidLibraryFileError": "Fichier de bibliothèque invalide. Veuillez vérifier le format du fichier.",
"taintedFormMessage": "Voulez-vous vraiment quitter cette page ? Toutes les données non enregistrées seront perdues.",
"riskScenariosStatus": "Statut des scénarios de risque",
"onlineDocs": "Documentation en ligne"
"onlineDocs": "Documentation en ligne",
"attemptToDeleteOnlyAdminAccountError": "Vous ne pouvez pas supprimer votre unique compte administrateur de l'application.",
"attemptToRemoveOnlyAdminUserGroup": "Vous ne pouvez pas retirer le seul compte administrateur de l'application du groupe des administrateurs."
}
4 changes: 3 additions & 1 deletion frontend/src/lib/utils/locales.ts
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,9 @@ export function localItems(languageTag: string): LocalItems {
highSOK: m.highSOK({ languageTag: languageTag }),
libraryImportError: m.libraryImportError({ languageTag: languageTag }),
libraryAlreadyExistsError: m.libraryAlreadyImportedError({ languageTag: languageTag }),
invalidLibraryFileError: m.invalidLibraryFileError({ languageTag: languageTag })
invalidLibraryFileError: m.invalidLibraryFileError({ languageTag: languageTag }),
attemptToDeleteOnlyAdminAccountError: m.attemptToDeleteOnlyAdminAccountError({ languageTag: languageTag }),
attemptToRemoveOnlyAdminUserGroup: m.attemptToRemoveOnlyAdminUserGroup({ languageTag: languageTag })
};
return LOCAL_ITEMS;
}
4 changes: 4 additions & 0 deletions frontend/src/routes/(app)/[model=urlmodel]/+page.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,10 @@ export const actions: Actions = {
if (!res.ok) {
const response = await res.json();
console.log(response);
if (response.error) {
setFlash({ type: 'error', message: localItems(languageTag())[response.error] }, event);
return fail(403, { form: deleteForm });
}
if (response.non_field_errors) {
setError(deleteForm, 'non_field_errors', response.non_field_errors);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ export const actions: Actions = {
if (!res.ok) {
const response = await res.json();
console.error('server response:', response);
if (response.error) {
setFlash({ type: 'error', message: response.error }, event);
return fail(403, { form: form });
}
if (response.non_field_errors) {
setError(form, 'non_field_errors', response.non_field_errors);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ import { BASE_API_URL } from '$lib/utils/constants';
import { UserEditSchema } from '$lib/utils/schemas';
import { setError, superValidate } from 'sveltekit-superforms/server';
import type { PageServerLoad } from './$types';
import { redirect, type Actions } from '@sveltejs/kit';
import { fail } from 'assert';
import { redirect, fail, type Actions } from '@sveltejs/kit';
import { getModelInfo } from '$lib/utils/crud';
import { setFlash } from 'sveltekit-flash-message/server';
import * as m from '$paraglide/messages';
import { languageTag } from '$paraglide/runtime';
import { localItems } from '$lib/utils/locales';

export const load: PageServerLoad = async ({ params, fetch }) => {
const URLModel = 'users';
Expand Down Expand Up @@ -58,6 +59,10 @@ export const actions: Actions = {
if (!res.ok) {
const response = await res.json();
console.error('server response:', response);
if (response.error) {
setFlash({ type: 'error', message: localItems(languageTag())[response.error] }, event);
return fail(403, { form: form });
}
if (response.non_field_errors) {
setError(form, 'non_field_errors', response.non_field_errors);
}
Expand Down

0 comments on commit b6cda17

Please sign in to comment.