From 7e859e32879fed7704a55ed1591fafe9fffd3709 Mon Sep 17 00:00:00 2001 From: Mahbub Ul Alam Date: Wed, 20 Nov 2024 14:33:00 +0100 Subject: [PATCH 01/17] SS-1112 Enforce unique project names by owner (#251) --- projects/views.py | 29 +++++++++++++++++++++++++- templates/projects/project_create.html | 5 ++--- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/projects/views.py b/projects/views.py index 170a8a76..c7ac1321 100644 --- a/projects/views.py +++ b/projects/views.py @@ -5,6 +5,7 @@ import requests as r from django.apps import apps from django.conf import settings as django_settings +from django.contrib import messages from django.contrib.auth import get_user_model from django.contrib.auth.decorators import login_required from django.core.exceptions import FieldDoesNotExist @@ -387,7 +388,9 @@ def get(self, request): template = arr[0] if len(arr) > 0 else None - context = {"template": template} + context = { + "template": template, + } return render( request=request, @@ -407,6 +410,30 @@ def post(self, request, *args, **kwargs): name = request.POST.get("name", "default")[:200] description = request.POST.get("description", "") + # Ensure no duplicate project name for the common user + + project_name_already_exists = ( + Project.objects.filter( + owner=request.user, + name=name, + ) + .exclude(status="deleted") + .exists() + ) + + if project_name_already_exists and not request.user.is_superuser: + pre_selected_template = request.GET.get("template") + template = ProjectTemplate.objects.filter(name=pre_selected_template).first() + context = {"template": template} + logger.error("A project with name '" + name + "' already exists.") + + messages.error( + request, + "Project cannot be created because a project with name '" + name + "' already exists.", + ) + + return render(request, self.template_name, context) + # Try to create database project object. try: project = Project.objects.create_project( diff --git a/templates/projects/project_create.html b/templates/projects/project_create.html index f02e01d1..6ba3369c 100644 --- a/templates/projects/project_create.html +++ b/templates/projects/project_create.html @@ -4,17 +4,16 @@ {% block content %} {% include "breadcrumbs/bc_project_create.html" %} +{% include 'common/flash_messages.html' %}
+

New project

Provide details about your new project.

- - -
{% if template %} From 1b83c5e785f37eb7fd7e6d0ace8f74ba832b7728 Mon Sep 17 00:00:00 2001 From: Arnold Kochari Date: Thu, 21 Nov 2024 11:01:18 +0100 Subject: [PATCH 02/17] SS-1126 Remove access to project after deletion (#253) --- apps/views.py | 5 ++++- projects/views.py | 14 +++++++++++++- templates/projects/partials/app_templates.html | 10 ---------- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/apps/views.py b/apps/views.py index e241ce0c..f55dc039 100644 --- a/apps/views.py +++ b/apps/views.py @@ -5,7 +5,7 @@ from django.contrib.auth import get_user_model from django.core.exceptions import PermissionDenied from django.db import transaction -from django.http import HttpResponseForbidden, JsonResponse +from django.http import HttpResponse, HttpResponseForbidden, JsonResponse from django.shortcuts import HttpResponseRedirect, render, reverse from django.utils.decorators import method_decorator from django.views import View @@ -221,6 +221,9 @@ def get(self, request, project, app_slug, app_id=None): project_slug = project project = Project.objects.get(slug=project_slug) + if request.user.is_superuser and project.status == "deleted": + return HttpResponse("This project has been deleted by the user.") + form = self.get_form(request, project, app_slug, app_id) if form is None or not getattr(form, "is_valid", False): diff --git a/projects/views.py b/projects/views.py index c7ac1321..27d03a48 100644 --- a/projects/views.py +++ b/projects/views.py @@ -21,7 +21,7 @@ from django.utils.decorators import method_decorator from django.views import View from guardian.decorators import permission_required_or_403 -from guardian.shortcuts import assign_perm, remove_perm +from guardian.shortcuts import assign_perm, get_users_with_perms, remove_perm from apps.app_registry import APP_REGISTRY from apps.models import BaseAppInstance @@ -87,6 +87,9 @@ def settings(request, project_slug): Q(slug=project_slug), ).first() + if request.user.is_superuser and project.status == "deleted": + return HttpResponse("This project has been deleted by the user.") + try: User._meta.get_field("is_user") platform_users = User.objects.filter( @@ -489,6 +492,10 @@ class DetailsView(View): def get(self, request, project_slug): project = Project.objects.get(slug=project_slug) + + if request.user.is_superuser and project.status == "deleted": + return HttpResponse("This project has been deleted by the user.") + resources = [] app_ids = [] if request.user.is_superuser: @@ -569,6 +576,11 @@ def delete(request, project_slug): project = Project.objects.filter(slug=project_slug).first() logger.info("SCHEDULING DELETION OF ALL INSTALLED APPS") + # remove permissions to see this project + users_with_permission = get_users_with_perms(project) + for user in users_with_permission: + remove_perm("can_view_project", user, project) + # set the status to 'deleted' project.status = "deleted" project.save() delete_project.delay(project.pk) diff --git a/templates/projects/partials/app_templates.html b/templates/projects/partials/app_templates.html index fddc7f4e..5f21b4b7 100644 --- a/templates/projects/partials/app_templates.html +++ b/templates/projects/partials/app_templates.html @@ -25,19 +25,9 @@
{{ app.name }}
{% if can_create %} - - {% if "Serv" in app.name or app.name == "Python Model Deployment" %} - Create - {% else %} - Create - - {% endif %} - - {% else %}