+
{{ config.release }}
@@ -27,7 +27,7 @@
@@ -47,10 +47,11 @@
{{ br.last_update }} |
+ {% if perms.build.can_trigger %}onclick="click_refresh_projects(event, '{{ br.id }}')"{% endif %}
+ class="btn btn-primary" {% if not perms.build.can_trigger %}disabled="disabled"{% endif %}>Refresh projects
+ {% if perms.build.can_trigger %}onclick="click_delete(event, '{{ br.id }}')"{% endif %}
+ class="btn btn-danger" {% if not perms.build.can_trigger %}disabled="disabled"{% endif %}>Delete
|
{% endfor %}
@@ -64,7 +65,8 @@
diff --git a/release_dashboard/test/test_views.py b/release_dashboard/test/test_views.py
index 080510f..1931138 100644
--- a/release_dashboard/test/test_views.py
+++ b/release_dashboard/test/test_views.py
@@ -14,7 +14,9 @@
# with this prograproj. If not, see
.
from unittest.mock import patch
+from django.contrib.auth.models import Permission
from django.contrib.auth.models import User
+from django.contrib.contenttypes.models import ContentType
from django.test import override_settings
from django.test import TestCase
from django.urls import reverse
@@ -23,13 +25,26 @@ from build.models import BuildRelease
from repoapi.test.base import BaseTest
+def add_perm(user, model, codename):
+ ct = ContentType.objects.get_for_model(model)
+ perm = Permission.objects.get(content_type=ct, codename=codename)
+ user.user_permissions.add(perm)
+
+
class TestHotfix(TestCase):
def test_no_login(self):
res = self.client.get(reverse("release_dashboard:hotfix"))
self.assertNotEqual(res.status_code, 200)
+ def test_login_no_perm(self):
+ user = User.objects.create_user(username="test")
+ self.client.force_login(user)
+ res = self.client.get(reverse("release_dashboard:hotfix"))
+ self.assertEqual(res.status_code, 403)
+
def test_login_ok(self):
user = User.objects.create_user(username="test")
+ add_perm(user, BuildRelease, "can_trigger_hotfix")
self.client.force_login(user)
res = self.client.get(reverse("release_dashboard:hotfix"))
self.assertEqual(res.status_code, 200)
@@ -39,6 +54,7 @@ class TestHotfix(TestCase):
@patch("release_dashboard.views.get_branches")
def test_natural_sort(self, gb, gt):
user = User.objects.create_user(username="test")
+ add_perm(user, BuildRelease, "can_trigger_hotfix")
self.client.force_login(user)
gt.return_value = []
gb.return_value = [
@@ -77,8 +93,19 @@ class TestHotfixRelease(TestCase):
)
self.assertNotEqual(res.status_code, 200)
+ def test_login_no_perm(self):
+ user = User.objects.create_user(username="test")
+ self.client.force_login(user)
+ res = self.client.get(
+ reverse(
+ "release_dashboard:hotfix_release", args=["release-mr7.5.2"]
+ )
+ )
+ self.assertEqual(res.status_code, 403)
+
def test_login_ok(self):
user = User.objects.create_user(username="test")
+ add_perm(user, BuildRelease, "can_trigger_hotfix")
self.client.force_login(user)
res = self.client.get(
reverse(
@@ -89,6 +116,7 @@ class TestHotfixRelease(TestCase):
def test_no_mrXXX(self):
user = User.objects.create_user(username="test")
+ add_perm(user, BuildRelease, "can_trigger_hotfix")
self.client.force_login(user)
res = self.client.get(
reverse("release_dashboard:hotfix_release", args=["release-mr7.5"])
@@ -105,6 +133,7 @@ class TestHotfixRelease(TestCase):
def test_project_ok(self):
user = User.objects.create_user(username="test")
+ add_perm(user, BuildRelease, "can_trigger_hotfix")
self.client.force_login(user)
res = self.client.post(
reverse(
@@ -118,6 +147,7 @@ class TestHotfixRelease(TestCase):
def test_project_wrong(self):
user = User.objects.create_user(username="test")
+ add_perm(user, BuildRelease, "can_trigger_hotfix")
self.client.force_login(user)
res = self.client.post(
reverse(
diff --git a/release_dashboard/views/build.py b/release_dashboard/views/build.py
index 31c80aa..5660029 100644
--- a/release_dashboard/views/build.py
+++ b/release_dashboard/views/build.py
@@ -17,6 +17,8 @@ import uuid
import structlog
from django.contrib.auth.decorators import login_required
+from django.contrib.auth.decorators import permission_required
+from django.core.exceptions import PermissionDenied
from django.http import HttpResponseNotFound
from django.http import HttpResponseRedirect
from django.http import JsonResponse
@@ -52,6 +54,8 @@ def index(request):
def build_release(request, release):
release_config = ReleaseConfig(release)
if request.method == "POST":
+ if not request.user.has_perm("build.can_trigger"):
+ raise PermissionDenied()
release_uuid = uuid.uuid4()
BuildRelease.objects.create_build_release(release_uuid, release)
return HttpResponseRedirect(
@@ -77,6 +81,7 @@ def build_release(request, release):
@login_required
@require_http_methods(["POST"])
+@permission_required("build.can_trigger_hotfix", raise_exception=True)
def hotfix_build(request, branch, project):
if project not in settings.RELEASE_DASHBOARD_PROJECTS:
error = "repo:%s not valid" % project
@@ -104,6 +109,7 @@ def hotfix_build(request, branch, project):
@login_required
+@permission_required("build.can_trigger_hotfix", raise_exception=True)
def hotfix(request):
prj_list = _projects_versions(
settings.RELEASE_DASHBOARD_PROJECTS, regex_hotfix
@@ -114,6 +120,7 @@ def hotfix(request):
@login_required
@require_http_methods(["POST"])
+@permission_required("build.can_trigger_hotfix", raise_exception=True)
def hotfix_release_build(request, release, project):
release_config = ReleaseConfig(release)
if project not in release_config.projects:
@@ -138,6 +145,7 @@ def hotfix_release_build(request, release, project):
@login_required
+@permission_required("build.can_trigger_hotfix", raise_exception=True)
def hotfix_release(request, release):
release_config = ReleaseConfig(release)
if not regex_hotfix.match(release_config.branch):
@@ -164,6 +172,7 @@ def refresh_all(request):
return render(request, template, {"projects": projects})
+@login_required
@require_http_methods(["POST"])
def refresh(request, project):
res = gerrit_fetch_info.delay(project)
diff --git a/repoapi/migrations/0012_ldap_grp_perms.py b/repoapi/migrations/0012_ldap_grp_perms.py
new file mode 100644
index 0000000..0aab445
--- /dev/null
+++ b/repoapi/migrations/0012_ldap_grp_perms.py
@@ -0,0 +1,86 @@
+# Generated by Django 3.2.13 on 2022-06-14 16:12
+from django.contrib.auth.management import create_permissions
+from django.db import migrations
+
+
+def add_permissions(apps, schema_editor):
+ """ContentType table is populated after all the migrations applied"""
+ for app_config in apps.get_app_configs():
+ app_config.models_module = True
+ create_permissions(app_config, verbosity=0)
+ app_config.models_module = None
+
+
+def reverse_func(apps, schema_editor):
+ add_permissions(apps, schema_editor)
+ Group = apps.get_model("auth", "Group")
+ Permission = apps.get_model("auth", "Permission")
+ ContentType = apps.get_model("contenttypes", "ContentType")
+ db_alias = schema_editor.connection.alias
+
+ dev_grp = Group.objects.using(db_alias).get(name="dev")
+ devops_grp = Group.objects.using(db_alias).get(name="devops")
+
+ BuildRelease = apps.get_model("build", "BuildRelease")
+ ct = ContentType.objects.get_for_model(BuildRelease)
+
+ # these are the wrong ones!!
+ devops_grp.permissions.set(
+ [
+ Permission.objects.using(db_alias).get(
+ content_type=ct, codename="can_trigger_hotfix"
+ ),
+ ]
+ )
+ dev_grp.permissions.set(
+ [
+ Permission.objects.using(db_alias).get(
+ content_type=ct, codename="can_trigger"
+ ),
+ ]
+ )
+
+
+def forwards_func(apps, schema_editor):
+ add_permissions(apps, schema_editor)
+ Group = apps.get_model("auth", "Group")
+ Permission = apps.get_model("auth", "Permission")
+ ContentType = apps.get_model("contenttypes", "ContentType")
+ db_alias = schema_editor.connection.alias
+
+ dev_grp = Group.objects.using(db_alias).get(name="dev")
+ devops_grp = Group.objects.using(db_alias).get(name="devops")
+
+ BuildRelease = apps.get_model("build", "BuildRelease")
+ ct = ContentType.objects.get_for_model(BuildRelease)
+
+ perm_codenames = ["can_trigger", "can_trigger_hotfix"]
+ for perm in ("add", "change", "delete", "view"):
+ perm_codenames.append(f"{perm}_buildrelease")
+
+ perms = []
+ for codename in perm_codenames:
+ perm = Permission.objects.using(db_alias).get(
+ content_type=ct, codename=codename
+ )
+ perms.append(perm)
+ devops_grp.permissions.set(perms)
+
+ dev_grp.permissions.set(
+ [
+ Permission.objects.using(db_alias).get(
+ content_type=ct, codename="can_trigger_hotfix"
+ ),
+ ]
+ )
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("repoapi", "0011_ldap_groups"),
+ ]
+
+ operations = [
+ migrations.RunPython(forwards_func, reverse_func),
+ ]