Skip to content

Commit

Permalink
Reconfigure access to run through our SitePermissions model (which is…
Browse files Browse the repository at this point in the history
… connected to a user's haztrak profile) versus the old RcraSitePermissions which was dependent on a user's RCRAInfo permissions

rename RcraSitePermission to RcraSitePermissions, add development fixtures, when syncing a user's RCRAInfo profile, it does not create new HaztrakSites (only RcraSites)
convert foreign key to HaztrakSite to RcraSite in the RcraSitePermission (makes sense when you write it our) now we will be implementing the Remote Signer policy into our application so access will be granted by a remote signer (or the Haztrak Admin)
rename 'Site' model to 'HaztrakSite' to distinguish it from the 'RcraSite' model
  • Loading branch information
dpgraham4401 committed Nov 8, 2023
1 parent 6461c5b commit 706f4be
Show file tree
Hide file tree
Showing 29 changed files with 233 additions and 138 deletions.
Binary file modified docs/guide/src/assets/erd.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions server/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
cache/
test_db
static/
.mypy_cache
8 changes: 4 additions & 4 deletions server/apps/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
from apps.sites.models import ( # type: ignore
Address,
Contact,
HaztrakSite,
RcraPhone,
RcraSite,
Site,
)
from apps.trak.models import ManifestPhone # type: ignore

Expand Down Expand Up @@ -202,15 +202,15 @@ def create_rcra_site(


@pytest.fixture
def site_factory(db, rcra_site_factory):
def haztrak_site_factory(db, rcra_site_factory):
"""Abstract factory for Haztrak Site model"""

def create_site(
rcra_site: Optional[RcraSite] = None,
name: Optional[str] = "my site name",
admin_rcrainfo_profile: Optional[RcraProfile] = None,
) -> Site:
return Site.objects.create(
) -> HaztrakSite:
return HaztrakSite.objects.create(
rcra_site=rcra_site or rcra_site_factory(),
name=name,
admin_rcrainfo_profile=admin_rcrainfo_profile,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Generated by Django 4.2.7 on 2023-11-08 21:29

from django.db import migrations


class Migration(migrations.Migration):
dependencies = [
("core", "0004_haztrakprofile_admin_rcrainfo_profile"),
]

operations = [
migrations.RemoveField(
model_name="haztrakprofile",
name="admin_rcrainfo_profile",
),
]
10 changes: 3 additions & 7 deletions server/apps/core/models.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from django.contrib.auth.models import AbstractUser
from django.db import models
from django.utils.functional import cached_property

from haztrak import settings

Expand Down Expand Up @@ -37,12 +36,9 @@ class Meta:
on_delete=models.CASCADE,
related_name="haztrak_profile",
)
admin_rcrainfo_profile = models.ForeignKey(
"RcraProfile",
on_delete=models.SET_NULL,
null=True,
default=None,
)

def __str__(self):
return f"{self.user.username}"


class RcraProfile(CoreBaseModel):
Expand Down
4 changes: 2 additions & 2 deletions server/apps/core/views/profile_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
HaztrakUserSerializer,
RcraProfileSerializer,
)
from apps.sites.tasks import sync_user_sites
from apps.sites.tasks import sync_user_rcrainfo_sites


class HaztrakUserView(RetrieveUpdateAPIView):
Expand Down Expand Up @@ -60,7 +60,7 @@ class RcraProfileSyncView(GenericAPIView):

def get(self, request: Request) -> Response:
try:
task: CeleryTask = sync_user_sites.delay(str(self.request.user))
task: CeleryTask = sync_user_rcrainfo_sites.delay(str(self.request.user))
return self.response({"task": task.id})
except RcraProfile.DoesNotExist as exc:
return self.response(data={"error": str(exc)}, status=status.HTTP_404_NOT_FOUND)
Expand Down
16 changes: 12 additions & 4 deletions server/apps/sites/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,14 @@

from apps.core.admin import HiddenListView
from apps.core.models import RcraProfile
from apps.sites.models import Address, Contact, RcraSite, RcraSitePermission, Site, SitePermissions
from apps.sites.models import (
Address,
Contact,
HaztrakSite,
RcraSite,
RcraSitePermissions,
SitePermissions,
)


@admin.register(RcraSite)
Expand All @@ -23,13 +30,13 @@ class SitePermissionAdmin(admin.ModelAdmin):
search_help_text = "Search by user or site"


@admin.register(Site)
@admin.register(HaztrakSite)
class SiteAdmin(admin.ModelAdmin):
list_display = ["__str__", "related_handler", "last_rcrainfo_manifest_sync"]
list_display_links = ["__str__", "related_handler"]

@admin.display(description="EPA Site")
def related_handler(self, site: Site) -> str:
def related_handler(self, site: HaztrakSite) -> str:
url = (
reverse("admin:sites_rcrasite_changelist")
+ "?"
Expand All @@ -39,8 +46,9 @@ def related_handler(self, site: Site) -> str:


class RcraSitePermissionInline(admin.TabularInline):
model = RcraSitePermission
model = RcraSitePermissions
extra = 0

ordering = ["site"]

def has_change_permission(self, request, obj=None):
Expand Down
17 changes: 17 additions & 0 deletions server/apps/sites/migrations/0006_rename_site_haztraksite.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Generated by Django 4.2.7 on 2023-11-08 20:19

from django.db import migrations


class Migration(migrations.Migration):
dependencies = [
("core", "0004_haztrakprofile_admin_rcrainfo_profile"),
("sites", "0005_rename_last_rcra_sync_site_last_rcrainfo_manifest_sync"),
]

operations = [
migrations.RenameModel(
old_name="Site",
new_name="HaztrakSite",
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Generated by Django 4.2.7 on 2023-11-08 20:48

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):
dependencies = [
("sites", "0006_rename_site_haztraksite"),
]

operations = [
migrations.AlterModelOptions(
name="rcrasitepermission",
options={
"ordering": ["site__epa_id"],
"verbose_name": "RCRA Site Permission",
},
),
migrations.AlterField(
model_name="rcrasitepermission",
name="site",
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to="sites.rcrasite"
),
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Generated by Django 4.2.7 on 2023-11-08 21:18

from django.db import migrations


class Migration(migrations.Migration):
dependencies = [
("core", "0004_haztrakprofile_admin_rcrainfo_profile"),
("sites", "0007_alter_rcrasitepermission_options_and_more"),
]

operations = [
migrations.RenameModel(
old_name="RcraSitePermission",
new_name="RcraSitePermissions",
),
]
10 changes: 8 additions & 2 deletions server/apps/sites/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
from ...core.models import RcraProfile
from .contact_models import Address, Contact, RcraPhone, RcraStates
from .site_models import RcraSite, RcraSitePermission, RcraSiteType, Role, Site, SitePermissions
from .site_models import (
HaztrakSite,
RcraSite,
RcraSitePermissions,
RcraSiteType,
Role,
SitePermissions,
)
26 changes: 11 additions & 15 deletions server/apps/sites/models/site_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

from apps.sites.models import Address, Contact
from apps.sites.models.contact_models import RcraPhone
from haztrak import settings

from .base_models import SitesBaseManager, SitesBaseModel

Expand All @@ -27,9 +26,7 @@ class RcraSiteType(models.TextChoices):


class RcraSiteManager(SitesBaseManager):
"""
Inter-model related functionality for RcraSite Model
"""
"""Inter-model related functionality for RcraSite Model"""

def __init__(self):
self.handler_data = None
Expand Down Expand Up @@ -172,12 +169,11 @@ def __str__(self):
return f"{self.epa_id}"


class Site(SitesBaseModel):
class HaztrakSite(SitesBaseModel):
"""
Haztrak Site model used to control access to RcraSite object.
Not to be confused with what are frequently called 'sites' in RCRAInfo, for that,
see the RcraSite model.
Haztrak Site is a cornerstone model that many other models rely on.
It wraps around RCRAInfo sites (AKA handlers, our RcraSite object). and adds
additional functionality and fields.
"""

class Meta:
Expand Down Expand Up @@ -237,7 +233,7 @@ class Meta:
related_name="site_permissions",
)
site = models.ForeignKey(
Site,
HaztrakSite,
on_delete=models.CASCADE,
)
emanifest = models.CharField(
Expand All @@ -254,10 +250,10 @@ def __str__(self):
return f"{self.profile.user}"


class RcraSitePermission(SitesBaseModel):
class RcraSitePermissions(SitesBaseModel):
"""
RCRAInfo Site Permissions per module connected to a user's RcraProfile
and the corresponding Site
and the corresponding HaztrakSite
"""

CERTIFIER = "Certifier"
Expand All @@ -272,10 +268,10 @@ class RcraSitePermission(SitesBaseModel):

class Meta:
verbose_name = "RCRA Site Permission"
ordering = ["site__rcra_site__epa_id"]
ordering = ["site__epa_id"]

site = models.ForeignKey(
Site,
RcraSite,
on_delete=models.CASCADE,
)
profile = models.ForeignKey(
Expand Down Expand Up @@ -308,7 +304,7 @@ class Meta:
)

def __str__(self):
return f"{self.profile.user}: {self.site.rcra_site.epa_id}"
return f"{self.profile.user}: {self.site.epa_id}"

def clean(self):
if self.site_manager:
Expand Down
10 changes: 5 additions & 5 deletions server/apps/sites/serializers/profile_ser.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from rest_framework import serializers
from rest_framework.exceptions import APIException, ValidationError

from apps.sites.models import RcraSitePermission, SitePermissions
from apps.sites.models import RcraSitePermissions, SitePermissions

from .base_ser import SitesBaseSerializer
from .site_ser import SiteSerializer
Expand All @@ -23,7 +23,7 @@ class Meta:

class RcraSitePermissionSerializer(SitesBaseSerializer):
"""
RcraSitePermission model serializer
RcraSitePermissions model serializer
We use this internally because it's easier to handle, using consistent naming,
Haztrak has a separate serializer for user permissions from RCRAInfo.
See RcraPermissionSerializer.
Expand Down Expand Up @@ -69,7 +69,7 @@ def to_representation(self, instance):
return representation

class Meta:
model = RcraSitePermission
model = RcraSitePermissions
fields = [
"epaSiteId",
"siteManagement",
Expand Down Expand Up @@ -108,7 +108,7 @@ def to_internal_value(self, data):

class RcraPermissionSerializer(RcraSitePermissionSerializer):
"""
RcraSitePermission model serializer specifically for reading a user's site permissions
RcraSitePermissions model serializer specifically for reading a user's site permissions
from RCRAInfo. It's not used for serializing, only deserializing permissions from RCRAinfo
"""

Expand Down Expand Up @@ -159,7 +159,7 @@ def to_internal_value(self, data):
raise ValidationError(f"malformed JSON: {exc}")

class Meta:
model = RcraSitePermission
model = RcraSitePermissions
fields = [
"siteId",
"name",
Expand Down
6 changes: 3 additions & 3 deletions server/apps/sites/serializers/site_ser.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from rest_framework import serializers

from apps.sites.models import RcraSite, Site
from apps.sites.models import HaztrakSite, RcraSite
from apps.sites.serializers import AddressSerializer, ContactSerializer, RcraPhoneSerializer

from .base_ser import SitesBaseSerializer
Expand Down Expand Up @@ -90,7 +90,7 @@ class Meta:

class SiteSerializer(SitesBaseSerializer):
"""
Site model serializer for JSON marshalling/unmarshalling
HaztrakSite model serializer for JSON marshalling/unmarshalling
"""

name = serializers.CharField(
Expand All @@ -101,5 +101,5 @@ class SiteSerializer(SitesBaseSerializer):
)

class Meta:
model = Site
model = HaztrakSite
fields = ["name", "handler"]
Loading

0 comments on commit 706f4be

Please sign in to comment.