Browse Source

Add environments models and views

David Burke 4 years ago
parent
commit
88795f4ecc

+ 0 - 0
environments/__init__.py


+ 16 - 0
environments/admin.py

@@ -0,0 +1,16 @@
+from django.contrib import admin
+from .models import Environment, EnvironmentProject
+
+
+class EnvironmentAdmin(admin.ModelAdmin):
+    pass
+
+
+admin.site.register(Environment, EnvironmentAdmin)
+
+
+class EnvironmentProjectAdmin(admin.ModelAdmin):
+    pass
+
+
+admin.site.register(EnvironmentProject, EnvironmentProjectAdmin)

+ 5 - 0
environments/apps.py

@@ -0,0 +1,5 @@
+from django.apps import AppConfig
+
+
+class EnvironmentsConfig(AppConfig):
+    name = 'environments'

+ 48 - 0
environments/migrations/0001_initial.py

@@ -0,0 +1,48 @@
+# Generated by Django 3.1.3 on 2020-11-15 21:19
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    initial = True
+
+    dependencies = [
+        ('projects', '0007_auto_20201026_2354'),
+        ('organizations_ext', '0009_organization_scrub_ip_addresses'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='Environment',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('name', models.CharField(max_length=256)),
+                ('created', models.DateTimeField(auto_now_add=True, db_index=True)),
+                ('organization', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='organizations_ext.organization')),
+            ],
+        ),
+        migrations.CreateModel(
+            name='EnvironmentProject',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('is_hidden', models.BooleanField()),
+                ('created', models.DateTimeField(auto_now_add=True, db_index=True)),
+                ('environment', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='environments.environment')),
+                ('project', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='projects.project')),
+            ],
+            options={
+                'unique_together': {('project', 'environment')},
+            },
+        ),
+        migrations.AddField(
+            model_name='environment',
+            name='projects',
+            field=models.ManyToManyField(through='environments.EnvironmentProject', to='projects.Project'),
+        ),
+        migrations.AlterUniqueTogether(
+            name='environment',
+            unique_together={('organization', 'name')},
+        ),
+    ]

+ 0 - 0
environments/migrations/__init__.py


+ 28 - 0
environments/models.py

@@ -0,0 +1,28 @@
+from django.db import models
+
+
+class EnvironmentProject(models.Model):
+    project = models.ForeignKey("projects.Project", on_delete=models.CASCADE)
+    environment = models.ForeignKey(
+        "environments.Environment", on_delete=models.CASCADE
+    )
+    is_hidden = models.BooleanField()
+    created = models.DateTimeField(auto_now_add=True, db_index=True)
+
+    class Meta:
+        unique_together = ("project", "environment")
+
+
+class Environment(models.Model):
+    name = models.CharField(max_length=256)
+    organization = models.ForeignKey(
+        "organizations_ext.Organization", on_delete=models.CASCADE
+    )
+    projects = models.ManyToManyField("projects.Project", through=EnvironmentProject)
+    created = models.DateTimeField(auto_now_add=True, db_index=True)
+
+    class Meta:
+        unique_together = ("organization", "name")
+
+    def __str__(self):
+        return self.name

+ 12 - 0
environments/permissions.py

@@ -0,0 +1,12 @@
+from organizations_ext.permissions import OrganizationPermission
+from projects.permissions import ProjectPermission
+
+
+class EnvironmentPermission(OrganizationPermission):
+    def get_user_scopes(self, obj, user):
+        return obj.organization.get_user_scopes(user)
+
+
+class EnvironmentProjectPermission(ProjectPermission):
+    def get_user_scopes(self, obj, user):
+        return obj.project.organization.get_user_scopes(user)

+ 17 - 0
environments/serializers.py

@@ -0,0 +1,17 @@
+from rest_framework import serializers
+from .models import Environment, EnvironmentProject
+
+
+class EnvironmentSerializer(serializers.ModelSerializer):
+    class Meta:
+        model = Environment
+        fields = ("id", "name")
+
+
+class EnvironmentProjectSerializer(serializers.ModelSerializer):
+    name = serializers.StringRelatedField(source="environment")
+    isHidden = serializers.BooleanField(source="is_hidden")
+
+    class Meta:
+        model = EnvironmentProject
+        fields = ("id", "name", "isHidden")

+ 0 - 0
environments/tests/__init__.py


+ 66 - 0
environments/tests/test_api_permissions.py

@@ -0,0 +1,66 @@
+from django.shortcuts import reverse
+from model_bakery import baker
+from glitchtip.test_utils.test_case import APIPermissionTestCase
+
+
+class EnvironmentAPIPermissionTests(APIPermissionTestCase):
+    def setUp(self):
+        self.create_user_org()
+        self.set_client_credentials(self.auth_token.token)
+        self.environment = baker.make(
+            "environments.Environment", organization=self.organization
+        )
+        self.list_url = reverse(
+            "organization-environments-list",
+            kwargs={"organization_slug": self.organization.slug},
+        )
+        self.detail_url = reverse(
+            "organization-environments-detail",
+            kwargs={
+                "organization_slug": self.organization.slug,
+                "pk": self.environment.pk,
+            },
+        )
+
+    def test_list(self):
+        self.assertGetReqStatusCode(self.list_url, 403)
+        self.auth_token.add_permission("org:read")
+        self.assertGetReqStatusCode(self.list_url, 200)
+
+    def test_retrieve(self):
+        self.assertGetReqStatusCode(self.detail_url, 403)
+        self.auth_token.add_permission("org:read")
+        self.assertGetReqStatusCode(self.detail_url, 200)
+
+
+class EnvironmentProjectAPIPermissionTests(APIPermissionTestCase):
+    def setUp(self):
+        self.create_user_org()
+        self.set_client_credentials(self.auth_token.token)
+        self.project = baker.make("projects.Project", organization=self.organization)
+        self.environment_project = baker.make(
+            "environments.EnvironmentProject",
+            environment__organization=self.organization,
+            project=self.project,
+        )
+        self.list_url = reverse(
+            "project-environments-list",
+            kwargs={"project_pk": f"{self.organization.slug}/{self.project.slug}"},
+        )
+        self.detail_url = reverse(
+            "project-environments-detail",
+            kwargs={
+                "project_pk": f"{self.organization.slug}/{self.project.slug}",
+                "pk": self.environment_project.pk,
+            },
+        )
+
+    def test_list(self):
+        self.assertGetReqStatusCode(self.list_url, 403)
+        self.auth_token.add_permission("project:read")
+        self.assertGetReqStatusCode(self.list_url, 200)
+
+    def test_retrieve(self):
+        self.assertGetReqStatusCode(self.detail_url, 403)
+        self.auth_token.add_permission("project:read")
+        self.assertGetReqStatusCode(self.detail_url, 200)

Some files were not shown because too many files changed in this diff