Skip to content

Commit

Permalink
updates permissions
Browse files Browse the repository at this point in the history
  • Loading branch information
saxix committed Oct 18, 2024
1 parent 41c0963 commit 9f4c737
Show file tree
Hide file tree
Showing 51 changed files with 773 additions and 3,377 deletions.
17 changes: 15 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -132,14 +132,16 @@ jobs:
LOCK_SHA=$(sha1sum uv.lock docker/bin/* docker/conf/* docker/Dockerfile | sha1sum | awk '{print $1}' | cut -c 1-8)
echo "checksum=$LOCK_SHA" >> "$GITHUB_ENV"
- run: |
- name: Build Test Image
run: |
docker build \
--target tests \
-t "unicef/hope-country-workspace:${{env.BRANCH}}-test-${{env.checksum}}" \
--cache-from "type=gha" \
--cache-to "type=gha,mode=max" \
-f docker/Dockerfile .
- run: |
- name: Run Test suite
run: |
docker run --rm \
--network host \
-e PYTHONPATH=/app/src \
Expand All @@ -158,3 +160,14 @@ jobs:
token: ${{ secrets.CODECOV_TOKEN }}
verbose: false
name: codecov-${{env.GITHUB_REF_NAME}}
- name: Build Distro
run: |
docker run --rm \
--network host \
-e PYTHONPATH=/app/src \
-e DATABASE_URL=${DATABASE_URL} \
-v "./src/:/app/src" \
-v "./tests:/app/tests" \
-v "./pytest.ini:/app/pytest.ini" \
-t "unicef/hope-country-workspace:${{env.BRANCH}}-test-${{env.checksum}}" \
pytest -c /app/pytest.ini tests/ -v --maxfail=5 --migrations --cov
1 change: 1 addition & 0 deletions src/country_workspace/config/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
"django.middleware.clickjacking.XFrameOptionsMiddleware",
# "unicef_security.middleware.UNICEFSocialAuthExceptionMiddleware",
"country_workspace.middleware.state.StateClearMiddleware",
"country_workspace.middleware.exception.ExceptionMiddleware",
)

AUTHENTICATION_BACKENDS = (
Expand Down
5 changes: 5 additions & 0 deletions src/country_workspace/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,8 @@

class RemoteError(Http404):
pass


class HttpErrorRedirect(Exception):
def __init__(self, url):
self.url = url
19 changes: 19 additions & 0 deletions src/country_workspace/middleware/exception.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import logging

from django.core.exceptions import PermissionDenied
from django.http import HttpRequest, HttpResponseRedirect
from django.shortcuts import render
from django.utils.deprecation import MiddlewareMixin

from country_workspace.exceptions import HttpErrorRedirect

logger = logging.getLogger(__name__)


class ExceptionMiddleware(MiddlewareMixin):
def process_exception(self, request: "HttpRequest", exception: Exception):
if isinstance(exception, (PermissionDenied,)):
return render(request, "403.html", {"message": "Permission denied"}, status=403)
if isinstance(exception, (HttpErrorRedirect,)):
return HttpResponseRedirect(exception.url)
raise exception
6 changes: 2 additions & 4 deletions src/country_workspace/middleware/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@
if TYPE_CHECKING:
from collections.abc import Callable

from country_workspace.types.http import AuthHttpRequest


logger = logging.getLogger(__name__)

Expand All @@ -21,7 +19,7 @@ def __init__(self, get_response: "Callable[[HttpRequest],HttpResponse]") -> None
self.get_response = get_response
self.handler = RequestHandler()

def __call__(self, request: "AuthHttpRequest") -> "HttpResponse":
def __call__(self, request: "HttpRequest") -> "HttpResponse":
state = self.handler.process_request(request)
with configure_scope() as scope:
scope.set_tag("state:cookie", state.tenant_cookie)
Expand All @@ -36,7 +34,7 @@ def __init__(self, get_response: "Callable[[HttpRequest],HttpResponse]") -> None
self.get_response = get_response
self.handler = RequestHandler()

def __call__(self, request: "AuthHttpRequest") -> "HttpResponse":
def __call__(self, request: "HttpRequest") -> "HttpResponse":
response = self.get_response(request)
self.handler.process_response(request, response)

Expand Down
6 changes: 5 additions & 1 deletion src/country_workspace/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Generated by Django 5.1.1 on 2024-10-16 08:55
# Generated by Django 5.1.2 on 2024-10-18 08:07

import django.contrib.auth.models
import django.contrib.auth.validators
Expand Down Expand Up @@ -192,6 +192,8 @@ class Migration(migrations.Migration):
("errors", models.JSONField(blank=True, default=dict, editable=False)),
("flex_fields", models.JSONField(blank=True, default=dict)),
("name", models.CharField(max_length=255, verbose_name="Name")),
("removed", models.BooleanField(default=False, verbose_name="Removed")),
("history", models.JSONField(blank=True, default=dict, editable=False)),
("last_modified", models.DateTimeField(auto_now=True)),
("system_fields", models.JSONField(blank=True, default=dict)),
("batch", models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to="country_workspace.batch")),
Expand All @@ -208,6 +210,8 @@ class Migration(migrations.Migration):
("errors", models.JSONField(blank=True, default=dict, editable=False)),
("flex_fields", models.JSONField(blank=True, default=dict)),
("name", models.CharField(max_length=255, verbose_name="Name")),
("removed", models.BooleanField(default=False, verbose_name="Removed")),
("history", models.JSONField(blank=True, default=dict, editable=False)),
("last_modified", models.DateTimeField(auto_now=True)),
("system_fields", models.JSONField(blank=True, default=dict)),
("batch", models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to="country_workspace.batch")),
Expand Down
8 changes: 6 additions & 2 deletions src/country_workspace/models/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,17 @@ class Validable(models.Model):
last_checked = models.DateTimeField(default=None, null=True, blank=True)
errors = models.JSONField(default=dict, blank=True, editable=False)
flex_fields = models.JSONField(default=dict, blank=True)
# country_office = models.ForeignKey("Office", on_delete=models.CASCADE, related_name="%(class)ss")
# program = models.ForeignKey("Program", on_delete=models.CASCADE, related_name="%(class)ss")

name = models.CharField(_("Name"), max_length=255)
removed = models.BooleanField(_("Removed"), default=False)
history = models.JSONField(default=dict, blank=True, editable=False)

class Meta:
abstract = True

def __str__(self) -> str:
return self.name or "%s %s" % (self._meta.verbose_name, self.id)

@cached_property
def checker(self) -> "DataChecker":
raise NotImplementedError
Expand Down
3 changes: 0 additions & 3 deletions src/country_workspace/models/household.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@ class Household(Validable, BaseModel):
class Meta:
verbose_name = "Household"

def __str__(self) -> str:
return self.name or "Household %s" % self.id

@cached_property
def checker(self) -> "DataChecker":
return self.program.household_checker
Expand Down
3 changes: 0 additions & 3 deletions src/country_workspace/models/individual.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@ class Individual(Validable, BaseModel):
household = models.ForeignKey(Household, on_delete=models.CASCADE, null=True, blank=True, related_name="members")
system_fields = models.JSONField(default=dict, blank=True)

def __str__(self) -> str:
return self.name

@cached_property
def checker(self) -> "DataChecker":
return self.program.individual_checker
Expand Down
5 changes: 3 additions & 2 deletions src/country_workspace/models/program.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,11 @@ def individuals(self):

def get_checker_for(self, m: Union[type[Validable], Validable]) -> DataChecker:
from country_workspace.models import Household, Individual
from country_workspace.workspaces.models import CountryHousehold, CountryIndividual

if isinstance(m, Household) or m == Household:
if isinstance(m, (Household, CountryHousehold)) or m in (Household, CountryHousehold):
return self.household_checker
elif isinstance(m, Individual) or m == Individual:
elif isinstance(m, (Individual, CountryIndividual)) or m in (Individual, CountryIndividual):
return self.individual_checker
else:
raise ValueError(m)
1 change: 0 additions & 1 deletion src/country_workspace/web/static/admin/hr.css

This file was deleted.

1 change: 0 additions & 1 deletion src/country_workspace/web/static/admin/hr.css.map

This file was deleted.

162 changes: 0 additions & 162 deletions src/country_workspace/web/static/admin/hr.scss

This file was deleted.

2 changes: 0 additions & 2 deletions src/country_workspace/web/static/d3.min.js

This file was deleted.

Loading

0 comments on commit 9f4c737

Please sign in to comment.