As a developer, we have to secure the exposed endpoints (APIs) according the desired permission rules.
...
in openimis-be-claim_py/claim/app.py: DEFAULT_CFG = { [...] "gql_query_claims_perms": ["111001"],
[...] } ... and check it via standard django permission in openimis-be-claim_py/claim/schema.py: def resolve_claims(self, info, **kwargs): if not info.context.user.has_perms(ClaimConfig.gql_query_claims_perms): raise PermissionDenied(_("unauthorized")) [...] |
---|
We recommend (and this is what is in place in reference modules such as claims,...) to enforce the fine-grained security in django model itslef (overriding the 'get_query' method). This ensures that security applies whatever endpoint technology (GraphQL, FHIR, ...) is exposing it.
...
in openimis-be-claim_py/claim/models.py: class Claim(core_models.VersionedModel): id = models.AutoField(db_column='ClaimID', primary_key=True) [...]
@classmethod def get_queryset(cls, queryset, user): queryset = Claim.filter_queryset(queryset) # GraphQL calls with an info object while Rest calls with the user itself if isinstance(user, ResolveInfo): user = user.context.user if settings.ROW_SECURITY and user.is_anonymous: return queryset.filter(id=-1) if settings.ROW_SECURITY: # TechnicalUsers don't have health_facility_id attribute if hasattr(user._u, 'health_facility_id') and user._u.health_facility_id: return queryset.filter( health_facility_id=user._u.health_facility_id ) else: dist = UserDistrict.get_user_districts(user._u) return queryset.filter( health_facility__location_id__in=[l.location_id for l in dist] ) return queryset |
---|
For finer (rule-based) grained security (object-level) the django-rules module has been configured and is readily available for use (declaring predicates,...). It is however not already used at the time of writing.