Skip to content

Commit

Permalink
Add archive / unarchive support
Browse files Browse the repository at this point in the history
  • Loading branch information
mrchrisadams committed Oct 25, 2023
1 parent db655d9 commit aff5400
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 26 deletions.
29 changes: 29 additions & 0 deletions apps/accounts/migrations/0064_auto_20231025_1541.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Generated by Django 3.2.21 on 2023-10-25 15:41

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


class Migration(migrations.Migration):

dependencies = [
('accounts', '0063_provider_request_related_provider'),
]

operations = [
migrations.AddField(
model_name='datacentersupportingdocument',
name='archived',
field=models.BooleanField(default=False, editable=False, help_text='If this is checked, this document will not show up in any queries. Should not editable via the admin interface by non-staff users.'),
),
migrations.AddField(
model_name='hostingprovidersupportingdocument',
name='archived',
field=models.BooleanField(default=False, editable=False, help_text='If this is checked, this document will not show up in any queries. Should not editable via the admin interface by non-staff users.'),
),
migrations.AlterField(
model_name='hostingproviderstats',
name='hostingprovider',
field=models.OneToOneField(db_column='id_hp', on_delete=django.db.models.deletion.CASCADE, primary_key=True, serialize=False, to='accounts.hostingprovider'),
),
]
61 changes: 51 additions & 10 deletions apps/accounts/models/hosting.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ class ProviderService(tag_models.TaggedItemBase):
)



class Hostingprovider(models.Model):
archived = models.BooleanField(default=False)
country = CountryField(db_column="countrydomain")
Expand Down Expand Up @@ -306,6 +307,8 @@ class Hostingprovider(models.Model):
def __str__(self):
return self.name



@property
def users(self) -> models.QuerySet["User"]:
"""
Expand Down Expand Up @@ -351,14 +354,7 @@ def shared_secret(self) -> str:
except Hostingprovider.providersharedsecret.RelatedObjectDoesNotExist:
return None

@property
def public_supporting_evidence(self):
"""
Return the supporting evidence that has explictly been marked as public
by the users uploading it to the database
"""
return self.supporting_documents.filter(public=True).order_by("-valid_to")


@property
def evidence_expiry_date(self) -> typing.Optional[datetime.date]:
"""
Expand Down Expand Up @@ -470,9 +466,14 @@ def mark_as_pending_review(self, approval_request):
return False

# Queries
# set the return type to be a Queryset of the relevant model
# import queryset from django

def public_supporting_evidence(self) -> models.QuerySet["HostingproviderSupportingDocument"]:
"""
Return the supporting evidence that has explictly been marked as public
by the users uploading it to the database
"""
return self.supporting_documents.filter(public=True).order_by("-valid_to")


def active_ip_ranges(self) -> models.QuerySet["GreencheckIP"]:
"""
Expand Down Expand Up @@ -754,6 +755,14 @@ class AbstractSupportingDocument(models.Model):
"document/page in your entry in the green web directory."
),
)
archived = models.BooleanField(
default=False,
editable=False,
help_text=(
"If this is checked, this document will not show up in any queries. "
"Should not editable via the admin interface by non-staff users."
)
)

def __str__(self):
return f"{self.valid_from} - {self.title}"
Expand All @@ -780,12 +789,25 @@ class DatacenterSupportingDocument(AbstractSupportingDocument):
def parent(self):
return self.datacentre

class SupportingEvidenceManager(models.Manager):
"""
A manager to filter out archived items of supporting evidence
for a given provider
"""
def get_queryset(self):
return super().get_queryset().filter(archived=False)




class HostingProviderSupportingDocument(AbstractSupportingDocument):
"""
The subclass for hosting providers.
"""

objects = SupportingEvidenceManager()
objects_all = models.Manager()

hostingprovider = models.ForeignKey(
Hostingprovider,
db_column="id_hp",
Expand All @@ -795,6 +817,23 @@ class HostingProviderSupportingDocument(AbstractSupportingDocument):
# related_name="hostingprovider_evidence",
)

def archive(self) -> "HostingProviderSupportingDocument":
self.archived=True
self.save()
# TODO if we are using object storage, use the boto3 API to mark the
# file as no longer public

return self

def unarchive(self) -> "HostingProviderSupportingDocument":
self.archived=False
self.save()
# TODO if we are using object storage, use the boto3 API to mark the
# file as no longer public

return self


@property
def parent(self):
return self.hostingprovider
Expand All @@ -815,6 +854,8 @@ def link(self) -> str:
return self.url




class Certificate(models.Model):
energyprovider = models.CharField(max_length=255)
mainenergy_type = models.CharField(
Expand Down
43 changes: 31 additions & 12 deletions apps/accounts/models/provider_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from django.conf import settings
from django.core.exceptions import ValidationError

import rich
from django_countries.fields import CountryField
from taggit.managers import TaggableManager
from taggit import models as tag_models
Expand Down Expand Up @@ -192,21 +193,24 @@ def approve(self) -> Hostingprovider:
if self.provider:
hp = Hostingprovider.objects.get(pk=self.provider.id)



# delete related objects, they will be recreated with recent data
hp.services.clear()

for asn in hp.greencheckasn_set.all():
# TODO: decide about logging this change if it changes
# TODO: decide about logging this change if it changes
# the state the ASN
asn.archive()

for ip_range in hp.greencheckip_set.all():
# TODO: decide about logging this change if it changes
# TODO: decide about logging this change if it changes
# the state the ASN
ip_range.archive()

for doc in hp.supporting_documents.all():
doc.delete()
rich.print(doc)
doc.archive()

else:
hp = Hostingprovider.objects.create()
Expand Down Expand Up @@ -241,8 +245,10 @@ def approve(self) -> Hostingprovider:

# create related objects: ASNs
for asn in self.providerrequestasn_set.all():
if matching_inactive_asn := GreencheckASN.objects.filter(active=False, asn=asn.asn, hostingprovider=hp):
matching_inactive_asn.update(active=True)
if matching_inactive_asn := GreencheckASN.objects.filter(
active=False, asn=asn.asn, hostingprovider=hp
):
[inactive_asn.unarchive() for inactive_asn in matching_inactive_asn]
continue
try:
GreencheckASN.objects.create(
Expand All @@ -253,17 +259,18 @@ def approve(self) -> Hostingprovider:
f"Failed to approve the request `{self}` because the ASN '{asn}' already exists in the database"
) from e

# create related objects: new IP ranges, or activate existing ones
# create related objects: new IP ranges, or activate existing ones
# if inactive matching ones exist in the database
for ip_range in self.providerrequestiprange_set.all():
if matching_inactive_ip := GreencheckIp.objects.filter(active=False,
if matching_inactive_ip := GreencheckIp.objects.filter(
active=False,
ip_start=ip_range.start,
ip_end=ip_range.end,
hostingprovider=hp
):
matching_inactive_ip.update(active=True)
hostingprovider=hp,
):
[inactive_ip.unarchive() for inactive_ip in matching_inactive_ip]
continue

GreencheckIp.objects.create(
active=True,
ip_start=ip_range.start,
Expand All @@ -276,6 +283,19 @@ def approve(self) -> Hostingprovider:
# AbstractSupportingDocument does not accept null values for `url` and `attachment` fields
url = evidence.link or ""
attachment = evidence.file or ""


# assert HostingProviderSupportingDocument.objects_all.filter(archived=True)
if archived_evidence := HostingProviderSupportingDocument.objects_all.filter(
hostingprovider=hp,
title=evidence.title,
archived=True,
type=evidence.type,
public=evidence.public,
):
[archived_ev.unarchive() for archived_ev in archived_evidence]
continue

HostingProviderSupportingDocument.objects.create(
hostingprovider=hp,
title=evidence.title,
Expand Down Expand Up @@ -350,7 +370,6 @@ def clean(self) -> None:
if self.start and self.end:
validate_ip_range(self.start, self.end)



class ProviderRequestEvidence(models.Model):
"""
Expand Down
30 changes: 26 additions & 4 deletions apps/accounts/tests/test_provider_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -676,19 +676,42 @@ def test_approve_updates_existing_provider_without_deleting_supporting_evidence(
hostingprovider=hosting_provider_with_sample_user
)

assert original_evidence.id in [
evidence.id
for evidence in
hosting_provider_with_sample_user.supporting_documents.all()
]

# given: a provider request linked to an existing hosting provider
pr = ProviderRequestFactory.create(
services=faker.words(nb=4), provider=hosting_provider_with_sample_user
)
# and: a location
ProviderRequestLocationFactory.create(request=pr)
original_evidence = ProviderRequestEvidenceFactory.create(request=pr)
# and: a matching piece of supporting evidence
pr_original_evidence = ProviderRequestEvidenceFactory.create(
request=pr,
title=original_evidence.title,
description=original_evidence.description,
public=original_evidence.public,
type=original_evidence.type,
file=original_evidence.attachment,
link=original_evidence.url,
)

# when: the request is approved
result = pr.approve()
hp = models.Hostingprovider.objects.get(id=result.id)

pr_evidence_items = hp.supporting_documents.all()
updated_hp_evidence = hp.supporting_documents.all()

assert original_evidence.id in [evidence.id for evidence in pr_evidence_items]
import rich
for pr_ev in updated_hp_evidence:
rich.inspect(pr_ev)

rich.inspect(original_evidence)

assert original_evidence.id in [evidence.id for evidence in updated_hp_evidence]


@pytest.mark.django_db
Expand Down Expand Up @@ -1635,7 +1658,6 @@ def test_saving_changes_to_verification_request_from_hp_via_wizard(

@pytest.mark.django_db
@override_flag("provider_request", active=True)
@pytest.mark.only
def test_saving_changes_to_hp_with_new_verification_request(
client,
hosting_provider_with_sample_user,
Expand Down
18 changes: 18 additions & 0 deletions apps/greencheck/models/checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,15 @@ def archive(self) -> "GreencheckIp":
self.save()
return self

def unarchive(self) -> "GreencheckIp":
"""
Mark a GreencheckIp as inactive, as a softer alternative to deletion,
returning the Greencheck IP for further processing.
"""
self.active = True
self.save()
return self

def __str__(self):
return f"{self.ip_start} - {self.ip_end}"

Expand Down Expand Up @@ -396,6 +405,15 @@ def archive(self) -> "GreencheckASN":
self.save()
return self

def unarchive(self) -> "GreencheckASN":
"""
Mark a GreencheckASN as inactive, as a softer alternative to deletion,
returning the Greencheck ASN for further processing.
"""
self.active = True
self.save()
return self

def __str__(self):
active_state = "Inactive"
if self.active:
Expand Down

0 comments on commit aff5400

Please sign in to comment.