Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: centralise linting across the project #1288

Merged
merged 7 commits into from
Jun 6, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
2 changes: 1 addition & 1 deletion SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Only the latest version is checked for security vulnerabilities.
This project deals with sensitive patient data and we do our very best to find security vulnerabilities and solve them as soon as possible,
We also aknowledge that our project is not perfect , since this is an open sourced initiative, I highly encourage you to go through this project and report any and all security issues you may find.

In case you do find a vulnerability, please do NOT create an issue or mention the Vulnerability anywhere in the project, instead please send an email at `vichuhari100@gmail.com` with a detailed report and possibly the steps to reproduce the issue.
In case you do find a vulnerability, please do NOT create an issue or mention the Vulnerability anywhere in the project, instead please send an email at `vichuhari100@gmail.com` with a detailed report and possibly the steps to reproduce the issue.
We will do our best to coorpeate and solve it.

Thank you for your time.
1 change: 0 additions & 1 deletion aws/backend.json
Original file line number Diff line number Diff line change
Expand Up @@ -209,4 +209,3 @@
"cpu": "256",
"volumes": []
}

7 changes: 6 additions & 1 deletion care/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
__version__ = "0.1.0"
__version_info__ = tuple([int(num) if num.isdigit() else num for num in __version__.replace("-", ".", 1).split(".")])
__version_info__ = tuple(
[
int(num) if num.isdigit() else num
for num in __version__.replace("-", ".", 1).split(".")
]
)
22 changes: 16 additions & 6 deletions care/audit_log/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,19 @@
from typing import List, NamedTuple

from django.conf import settings
from rest_framework.utils.encoders import JSONEncoder

from multiselectfield.db.fields import MSFList
from rest_framework.utils.encoders import JSONEncoder


def remove_non_member_fields(d: dict):
return {k: v for k, v in d.items() if not k.startswith("_")}


def instance_finder(v):
return isinstance(v, (list, dict, set, MSFList),)
return isinstance(
v,
(list, dict, set, MSFList),
)


def seperate_hashable_dict(d: dict):
Expand Down Expand Up @@ -44,7 +46,9 @@ def _make_search(item):
return Search(type="plain", value=splits[0])


def candidate_in_scope(candidate: str, scope: List, is_application: bool = False) -> bool:
def candidate_in_scope(
candidate: str, scope: List, is_application: bool = False
) -> bool:
"""
Check if the candidate string is valid with the scope supplied,
the scope should be list of search strings - that can be either
Expand Down Expand Up @@ -79,10 +83,16 @@ def candidate_in_scope(candidate: str, scope: List, is_application: bool = False

@lru_cache()
def exclude_model(model_name):
if candidate_in_scope(model_name, settings.AUDIT_LOG["globals"]["exclude"]["applications"], is_application=True):
if candidate_in_scope(
model_name,
settings.AUDIT_LOG["globals"]["exclude"]["applications"],
is_application=True,
):
return True

if candidate_in_scope(model_name, settings.AUDIT_LOG["models"]["exclude"]["models"]):
if candidate_in_scope(
model_name, settings.AUDIT_LOG["models"]["exclude"]["models"]
):
return True

return False
Expand Down
39 changes: 31 additions & 8 deletions care/audit_log/receivers.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,13 @@
logger = logging.getLogger(__name__)

Event = NamedTuple(
"Event", [("model", str), ("actor", AbstractUser), ("entity_id", Union[int, str]), ("changes", dict)],
"Event",
[
("model", str),
("actor", AbstractUser),
("entity_id", Union[int, str]),
("changes", dict),
],
)


Expand Down Expand Up @@ -53,13 +59,15 @@ def pre_save_signal(sender, instance, **kwargs) -> None:
# __dict__ is used on pre, therefore we need to create a function
# that uses __dict__ too, but returns nothing.

pre = lambda _: None
pre = lambda _: None # noqa: E731
operation = Operation.INSERT

changes = {}

if operation not in {Operation.INSERT, Operation.DELETE}:
old, new = remove_non_member_fields(pre.__dict__), remove_non_member_fields(instance.__dict__)
old, new = remove_non_member_fields(pre.__dict__), remove_non_member_fields(
instance.__dict__
)

try:
changes = dict(set(new.items()).difference(old.items()))
Expand All @@ -68,9 +76,17 @@ def pre_save_signal(sender, instance, **kwargs) -> None:
new_hashable, new_non_hashable = seperate_hashable_dict(new)

changes = dict(set(new_hashable.items()).difference(old_hashable.items()))
changes.update({k: v for k, v in new_non_hashable.items() if v != old_non_hashable.get(k)})

excluded_fields = settings.AUDIT_LOG["models"]["exclude"]["fields"].get(model_name, [])
changes.update(
{
k: v
for k, v in new_non_hashable.items()
if v != old_non_hashable.get(k)
}
)

excluded_fields = settings.AUDIT_LOG["models"]["exclude"]["fields"].get(
model_name, []
)
for field in excluded_fields:
if field in changes:
changes[field] = "xxx"
Expand All @@ -81,7 +97,12 @@ def pre_save_signal(sender, instance, **kwargs) -> None:

current_user = AuditLogMiddleware.get_current_user()

instance._meta.dal.event = Event(model=model_name, actor=current_user, entity_id=instance.pk, changes=changes)
instance._meta.dal.event = Event(
model=model_name,
actor=current_user,
entity_id=instance.pk,
changes=changes,
)


def _post_processor(instance, event: Optional[Event], operation: Operation):
Expand All @@ -104,7 +125,9 @@ def _post_processor(instance, event: Optional[Event], operation: Operation):
logger.warning(f"Failed to log {event}", exc_info=True)
return

logger.info(f"AUDIT_LOG::{request_id}|{actor}|{operation.value}|{model_name}|ID:{instance.pk}|{changes}")
logger.info(
f"AUDIT_LOG::{request_id}|{actor}|{operation.value}|{model_name}|ID:{instance.pk}|{changes}"
)


@receiver(post_save, weak=False)
Expand Down
12 changes: 9 additions & 3 deletions care/facility/api/serializers/ambulance.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,12 @@ class Meta:
class AmbulanceSerializer(serializers.ModelSerializer):
drivers = serializers.ListSerializer(child=AmbulanceDriverSerializer())

primary_district_object = DistrictSerializer(read_only=True, source="primary_district")
secondary_district_object = DistrictSerializer(read_only=True, source="secondary_district")
primary_district_object = DistrictSerializer(
read_only=True, source="primary_district"
)
secondary_district_object = DistrictSerializer(
read_only=True, source="secondary_district"
)
third_district_object = DistrictSerializer(read_only=True, source="third_district")

class Meta:
Expand All @@ -32,7 +36,9 @@ class Meta:
def validate(self, obj):
validated = super().validate(obj)
if not validated.get("price_per_km") and not validated.get("has_free_service"):
raise ValidationError("The ambulance must provide a price or be marked as free")
raise ValidationError(
"The ambulance must provide a price or be marked as free"
)
return validated

def create(self, validated_data):
Expand Down
1 change: 0 additions & 1 deletion care/facility/api/serializers/asset.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ def validate_qr_code_id(self, value):
return value

def validate(self, attrs):

user = self.context["request"].user
if "location" in attrs:
location = get_object_or_404(
Expand Down
2 changes: 0 additions & 2 deletions care/facility/api/serializers/daily_round.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@ class Meta:
exclude = ("deleted",)

def update(self, instance, validated_data):

instance.last_edited_by = self.context["request"].user

if instance.consultation.discharge_date:
Expand Down Expand Up @@ -162,7 +161,6 @@ def update_last_daily_round(self, daily_round_obj):
).generate()

def create(self, validated_data):

# Authorisation Checks

# Skip check for asset user
Expand Down
70 changes: 46 additions & 24 deletions care/facility/api/serializers/inventory.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from datetime import timedelta

from django.db import transaction
from django.db import IntegrityError, transaction
from django.db.models import F, Sum
from django.utils import timezone
from rest_framework import serializers
Expand Down Expand Up @@ -62,15 +62,16 @@ class Meta:

@transaction.atomic
def create(self, validated_data):

item = validated_data["item"]
unit = validated_data["unit"]
facility = validated_data["facility"]

try:
item.allowed_units.get(id=unit.id)
except:
raise serializers.ValidationError({"unit": [f"Item cannot be measured with unit"]})
except FacilityInventoryUnit.DoesNotExist:
raise serializers.ValidationError(
{"unit": ["Item cannot be measured with unit"]}
)

multiplier = 1

Expand All @@ -79,8 +80,10 @@ def create(self, validated_data):
multiplier = FacilityInventoryUnitConverter.objects.get(
from_unit=unit, to_unit=item.default_unit
).multiplier
except:
raise serializers.ValidationError({"item": [f"Please Ask Admin to Add Conversion Metrics"]})
except FacilityInventoryUnitConverter.DoesNotExist:
raise serializers.ValidationError(
{"item": ["Please Ask Admin to Add Conversion Metrics"]}
)

validated_data["created_by"] = self.context["request"].user

Expand All @@ -92,20 +95,30 @@ def create(self, validated_data):
current_quantity = multiplier * validated_data["quantity"]
validated_data["quantity_in_default_unit"] = abs(current_quantity)
try:
summary_obj = FacilityInventorySummary.objects.get(facility=facility, item=item)
current_quantity = summary_obj.quantity + (multiplier * validated_data["quantity"])
summary_obj.quantity = F("quantity") + (multiplier * validated_data["quantity"])
except:
summary_obj = FacilityInventorySummary.objects.get(
facility=facility, item=item
)
current_quantity = summary_obj.quantity + (
multiplier * validated_data["quantity"]
)
summary_obj.quantity = F("quantity") + (
multiplier * validated_data["quantity"]
)
except FacilityInventorySummary.DoesNotExist:
summary_obj = FacilityInventorySummary(
facility=facility, item=item, quantity=multiplier * validated_data["quantity"]
facility=facility,
item=item,
quantity=multiplier * validated_data["quantity"],
)

if current_quantity < 0:
raise serializers.ValidationError({"stock": [f"Stock not Available"]})
raise serializers.ValidationError({"stock": ["Stock not Available"]})

try:
current_min_quantity = FacilityInventoryMinQuantity.objects.get(facility=facility, item=item).min_quantity
except:
current_min_quantity = FacilityInventoryMinQuantity.objects.get(
facility=facility, item=item
).min_quantity
except FacilityInventoryMinQuantity.DoesNotExist:
pass

summary_obj.is_low = current_quantity < current_min_quantity
Expand All @@ -128,7 +141,11 @@ def set_burn_rate(facility, item):
yesterday = timezone.now() - timedelta(days=1)

previous_usage_log_sum = FacilityInventoryLog.objects.filter(
probable_accident=False, facility=facility, item=item, is_incoming=False, created_date__gte=yesterday
probable_accident=False,
facility=facility,
item=item,
is_incoming=False,
created_date__gte=yesterday,
).aggregate(Sum("quantity_in_default_unit"))

if previous_usage_log_sum:
Expand Down Expand Up @@ -176,35 +193,40 @@ def create(self, validated_data):
item = validated_data["item"]

if not item:
raise serializers.ValidationError({"item": [f"Item cannot be Null"]})
raise serializers.ValidationError({"item": ["Item cannot be Null"]})

try:
instance = super().create(validated_data)
except:
raise serializers.ValidationError({"item": [f"Item min quantity already set"]})
except IntegrityError:
raise serializers.ValidationError(
{"item": ["Item min quantity already set"]}
)

try:
summary_obj = FacilityInventorySummary.objects.get(facility=validated_data["facility"], item=item)
summary_obj = FacilityInventorySummary.objects.get(
facility=validated_data["facility"], item=item
)
summary_obj.is_low = summary_obj.quantity < validated_data["min_quantity"]
summary_obj.save()
except:
except FacilityInventorySummary.DoesNotExist:
pass

return instance

def update(self, instance, validated_data):

if "item" in validated_data:
if instance.item != validated_data["item"]:
raise serializers.ValidationError({"item": [f"Item cannot be Changed"]})
raise serializers.ValidationError({"item": ["Item cannot be Changed"]})

item = validated_data["item"]

try:
summary_obj = FacilityInventorySummary.objects.get(facility=instance.facility, item=item)
summary_obj = FacilityInventorySummary.objects.get(
facility=instance.facility, item=item
)
summary_obj.is_low = summary_obj.quantity < validated_data["min_quantity"]
summary_obj.save()
except:
except FacilityInventorySummary.DoesNotExist:
pass

return super().update(instance, validated_data)
Expand Down
13 changes: 7 additions & 6 deletions care/facility/api/serializers/notification.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
from django.db.models import F
from rest_framework import serializers


from care.facility.models.notification import Notification

from care.users.api.serializers.user import UserBaseMinimumSerializer
from config.serializers import ChoiceField


class NotificationSerializer(serializers.ModelSerializer):

id = serializers.UUIDField(source="external_id", read_only=True)

caused_by = UserBaseMinimumSerializer(read_only=True)
Expand All @@ -19,10 +15,15 @@ class NotificationSerializer(serializers.ModelSerializer):

class Meta:
model = Notification
exclude = ("deleted", "modified_date", "intended_for", "medium_sent", "external_id")
exclude = (
"deleted",
"modified_date",
"intended_for",
"medium_sent",
"external_id",
)
read_only_fields = (
"message",
"caused_objects",
"created_date",
)

Loading