Skip to content

Commit

Permalink
ci: release 3.15.0 (#265)
Browse files Browse the repository at this point in the history
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: Paul Bui-Quang <[email protected]>
Co-authored-by: hicham <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: AnddyAnddy <[email protected]>
Co-authored-by: anddy <[email protected]>
  • Loading branch information
6 people authored Sep 5, 2023
1 parent ed47e26 commit 7c053fc
Show file tree
Hide file tree
Showing 60 changed files with 1,369 additions and 1,029 deletions.
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
![image](https://img.shields.io/badge/Python-3.11-blue/?color=blue&logo=python&logoColor=9cf)
![image](https://img.shields.io/badge/Django-4.2-%2344b78b/?color=%2344b78b&logo=django&logoColor=green)
![image](https://img.shields.io/badge/Ruff-0.0.271-yellow/?color=yellow&logo=lightning&logoColor=yellow)

<!-- TABLE OF CONTENTS -->
<details open="open">
Expand Down
6 changes: 3 additions & 3 deletions accesses/accesses_alerts.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from django.db.models import Q, Count

from accesses.models import Access, Profile
from accesses.models.tools import q_is_valid_access
from admin_cohort.models import User
from admin_cohort.settings import EMAIL_SENDER_ADDRESS, MANUAL_SOURCE

Expand Down Expand Up @@ -46,10 +47,9 @@ def send_alert_email(user: User, days: int):
def send_access_expiry_alerts(days: int):
_logger.info("Checking expiring accesses")
expiry_date = date.today() + timedelta(days=days)
expiring_accesses = Access.objects.filter(Access.Q_is_valid() &
expiring_accesses = Access.objects.filter(q_is_valid_access() &
Q(profile__source=MANUAL_SOURCE) &
(Q(end_datetime__date=expiry_date) |
Q(manual_end_datetime__date=expiry_date)))\
Q(end_datetime__date=expiry_date))\
.values("profile")\
.annotate(total=Count("profile"))
for access in expiring_accesses:
Expand Down
582 changes: 223 additions & 359 deletions accesses/conf_perimeters.py

Large diffs are not rendered by default.

27 changes: 27 additions & 0 deletions accesses/migrations/0005_perimeter_level.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Generated by Django 4.1.7 on 2023-07-28 13:37

from django.db import migrations, models


trim_trailing_commas = "UPDATE accesses_perimeter SET above_levels_ids=TRIM(trailing ',' from above_levels_ids)"
set_level_aphp = "UPDATE accesses_perimeter SET level=1 WHERE parent_id IS NULL"
set_level_other_perimeters = """UPDATE accesses_perimeter SET level=array_length(string_to_array(above_levels_ids, ','), 1)+1
WHERE parent_id IS NOT NULL AND above_levels_ids IS NOT NULL"""


class Migration(migrations.Migration):

dependencies = [
('accesses', '0004_set_created_by_updated_by_for_accesses'),
]

operations = [
migrations.AddField(
model_name='perimeter',
name='level',
field=models.IntegerField(blank=True, null=True),
),
migrations.RunSQL(sql=trim_trailing_commas),
migrations.RunSQL(sql=set_level_aphp),
migrations.RunSQL(sql=set_level_other_perimeters),
]
29 changes: 29 additions & 0 deletions accesses/migrations/0006_unify_access_datetime_fields.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Generated by Django 4.1.7 on 2023-08-11 13:42

from django.db import migrations, models

unify_datetime_fields = """UPDATE accesses_access
SET start_datetime_new = COALESCE(manual_start_datetime, start_datetime),
end_datetime_new = COALESCE(manual_end_datetime, end_datetime)
"""


class Migration(migrations.Migration):

dependencies = [
('accesses', '0005_perimeter_level'),
]

operations = [
migrations.AddField(
model_name='access',
name='end_datetime_new',
field=models.DateTimeField(blank=True, null=True),
),
migrations.AddField(
model_name='access',
name='start_datetime_new',
field=models.DateTimeField(blank=True, null=True),
),
migrations.RunSQL(sql=unify_datetime_fields)
]
39 changes: 39 additions & 0 deletions accesses/migrations/0007_remove_access_end_datetime_and_more.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Generated by Django 4.1.7 on 2023-08-11 15:00

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('accesses', '0006_unify_access_datetime_fields'),
]

operations = [
migrations.RemoveField(
model_name='access',
name='end_datetime',
),
migrations.RemoveField(
model_name='access',
name='manual_end_datetime',
),
migrations.RemoveField(
model_name='access',
name='manual_start_datetime',
),
migrations.RemoveField(
model_name='access',
name='start_datetime',
),
migrations.RenameField(
model_name='access',
old_name='end_datetime_new',
new_name='end_datetime',
),
migrations.RenameField(
model_name='access',
old_name='start_datetime_new',
new_name='start_datetime',
),
]
28 changes: 28 additions & 0 deletions accesses/migrations/0008_count_users_on_perimeters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Generated by Django 4.1.7 on 2023-08-22 13:13

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('accesses', '0007_remove_access_end_datetime_and_more'),
]

operations = [
migrations.AddField(
model_name='perimeter',
name='count_allowed_users',
field=models.IntegerField(blank=True, default=0, null=True),
),
migrations.AddField(
model_name='perimeter',
name='count_allowed_users_above_levels',
field=models.IntegerField(blank=True, default=0, null=True),
),
migrations.AddField(
model_name='perimeter',
name='count_allowed_users_inferior_levels',
field=models.IntegerField(blank=True, default=0, null=True),
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 4.1.7 on 2023-08-25 14:25

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('accesses', '0008_count_users_on_perimeters'),
]

operations = [
migrations.AddField(
model_name='role',
name='right_read_admin_accesses_above_levels',
field=models.BooleanField(default=False),
),
]
8 changes: 3 additions & 5 deletions accesses/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from .role import Role
from .perimeter import Perimeter, get_all_perimeters_parents_queryset, get_all_level_children
from .perimeter import Perimeter
from .access import Access
from .profile import Profile
from .tools import get_user_valid_manual_accesses_queryset, intersect_queryset_criteria, build_data_rights,\
from .tools import get_user_valid_manual_accesses, intersect_queryset_criteria, build_data_rights,\
get_assignable_roles_on_perimeter, get_all_user_managing_accesses_on_perimeter, can_roles_manage_access,\
DataRight

Expand All @@ -11,9 +11,7 @@
"Access",
"Profile",
"Perimeter",
"get_user_valid_manual_accesses_queryset",
"get_all_perimeters_parents_queryset",
"get_all_level_children",
"get_user_valid_manual_accesses",
"intersect_queryset_criteria",
"build_data_rights",
"get_assignable_roles_on_perimeter",
Expand Down
73 changes: 21 additions & 52 deletions accesses/models/access.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
from __future__ import annotations

import datetime
from typing import List, Dict

from django.db import models
from django.db.models import CASCADE, Q, SET_NULL
from django.utils import timezone
from django.utils.datetime_safe import datetime
from django.db.models import CASCADE, SET_NULL
from django.utils.datetime_safe import date, datetime as dt

from accesses.models.perimeter import Perimeter
from accesses.models.profile import Profile
Expand All @@ -22,8 +23,6 @@ class Access(BaseModel):
source = models.TextField(blank=True, null=True, default=MANUAL_SOURCE)
start_datetime = models.DateTimeField(blank=True, null=True)
end_datetime = models.DateTimeField(blank=True, null=True)
manual_start_datetime = models.DateTimeField(blank=True, null=True)
manual_end_datetime = models.DateTimeField(blank=True, null=True)
created_by = models.ForeignKey(User, on_delete=SET_NULL, related_name='created_accesses', null=True, db_column="created_by")
updated_by = models.ForeignKey(User, on_delete=SET_NULL, related_name='updated_accesses', null=True, db_column="updated_by")

Expand All @@ -35,43 +34,23 @@ def save(self, *args, **kwargs):

@property
def is_valid(self):
today = datetime.now()
if self.actual_start_datetime is not None:
actual_start_datetime = datetime.combine(
self.actual_start_datetime.date()
if isinstance(self.actual_start_datetime, datetime) else
self.actual_start_datetime,
datetime.min
)
if actual_start_datetime > today:
return False
if self.actual_end_datetime is not None:
actual_end_datetime = datetime.combine(
self.actual_end_datetime.date()
if isinstance(self.actual_end_datetime, datetime)
else self.actual_end_datetime,
datetime.min
)
if actual_end_datetime <= today:
return False
return True

@classmethod
def Q_is_valid(cls) -> Q:
now = timezone.now()
q_actual_start_is_none = Q(start_datetime=None,
manual_start_datetime=None)
q_start_lte_now = ((Q(manual_start_datetime=None)
& Q(start_datetime__lte=now))
| Q(manual_start_datetime__lte=now))

q_actual_end_is_none = Q(end_datetime=None,
manual_end_datetime=None)
q_end_gte_now = ((Q(manual_end_datetime=None)
& Q(end_datetime__gte=now))
| Q(manual_end_datetime__gte=now))
return ((q_actual_start_is_none | q_start_lte_now)
& (q_actual_end_is_none | q_end_gte_now))
now = datetime.datetime.now(tz=datetime.timezone.utc)
valid = True
if self.start_datetime:
if isinstance(self.start_datetime, date):
start_datetime = dt.combine(self.start_datetime, dt.min)
else:
start_datetime = self.start_datetime
if start_datetime > now:
valid = False
if self.end_datetime:
if isinstance(self.end_datetime, date):
end_datetime = dt.combine(self.end_datetime, dt.min)
else:
end_datetime = self.end_datetime
if end_datetime <= now:
valid = False
return valid

@property
def care_site_id(self):
Expand All @@ -87,16 +66,6 @@ def care_site(self):
'care_site_source_value': self.perimeter.source_value,
} if self.perimeter else None

@property
def actual_start_datetime(self):
return self.start_datetime if self.manual_start_datetime is None \
else self.manual_start_datetime

@property
def actual_end_datetime(self):
return self.end_datetime if self.manual_end_datetime is None \
else self.manual_end_datetime

@property
def accesses_criteria_to_exclude(self) -> List[Dict]:
res = self.role.unreadable_rights
Expand Down
32 changes: 6 additions & 26 deletions accesses/models/perimeter.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from __future__ import annotations

import logging
from typing import List, Union

from django.db import models
from django.db.models import Q
Expand All @@ -22,11 +21,15 @@ class Perimeter(BaseModel):
short_name = models.TextField(blank=True, null=True)
type_source_value = models.TextField(blank=True, null=True)
parent = models.ForeignKey("accesses.perimeter", on_delete=models.CASCADE, related_name="children", null=True)
above_levels_ids = models.TextField(blank=True, null=True)
inferior_levels_ids = models.TextField(blank=True, null=True)
above_levels_ids = models.TextField(blank=True, null=True) # todo: make it ArrayField instead
inferior_levels_ids = models.TextField(blank=True, null=True) # todo: make it ArrayField instead
cohort_id = models.TextField(blank=True, null=True)
full_path = models.TextField(blank=True, null=True)
cohort_size = models.TextField(blank=True, null=True)
level = models.IntegerField(blank=True, null=True)
count_allowed_users = models.IntegerField(blank=True, null=True, default=0)
count_allowed_users_inferior_levels = models.IntegerField(blank=True, null=True, default=0)
count_allowed_users_above_levels = models.IntegerField(blank=True, null=True, default=0)

def __str__(self):
return f"[{self.id}] {self.name}"
Expand Down Expand Up @@ -93,26 +96,3 @@ def children_prefetch(cls, filtered_queryset: QuerySet = None) -> Prefetch:
filtered_queryset = filtered_queryset or cls.objects.all()
return Prefetch('children', queryset=filtered_queryset,
to_attr='prefetched_children')


def get_all_perimeters_parents_queryset(perims: List[Perimeter], ) -> QuerySet:
return Perimeter.objects.filter(join_qs([
p.all_parents_query() for p in perims
]))


def get_all_level_children(
perimeters_ids: Union[int, List[int]], strict: bool = False,
filtered_ids: List[str] = [], ids_only: bool = False
) -> List[Union[Perimeter, str]]:
qs = join_qs(
[Perimeter.objects.filter(
**{i * 'parent__' + 'id__in': perimeters_ids}
) for i in range(0 + strict, len(PERIMETERS_TYPES))]
)
if len(filtered_ids):
return qs.filter(id__in=filtered_ids)

if ids_only:
return [str(i[0]) for i in qs.values_list('id')]
return list(qs)
Loading

0 comments on commit 7c053fc

Please sign in to comment.