Package: helsinki-profile-gdpr-api
Helsinki profile GDPR APIDjango app for implementing Helsinki profile GDPR API.This library will allow a service using Helsinki profile to implement the GDPR
functionality required byopen-city-profilebackend.Installationpip install helsinki-profile-gdpr-apiUsageAuthentication needs to be configured for the requireddjango-heluserModel which is to be used for GDPR operations should inheritSerializableMixinand
include the requiredserialize_fieldsproperty.Define the following settings in your Django configuration.SettingExampleDescriptionGDPR_API_MODEL"youths.YouthProfile"GDPR profile model in the formapp_label.model_name. model_name is case-insensitive.GDPR_API_QUERY_SCOPE"jassariapi.gdprquery"API scope required for the query operation.GDPR_API_DELETE_SCOPE"jassariapi.gdprdelete"API scope required for the delete operation.Add the GDPR API urls into your url config:urlpatterns=[...path("gdpr-api/",include("helsinki_gdpr.urls")),]ConfigurabilityThe configuration above is the minimum needed. With those the app uses the default behaviour.
The app can also be configured in various ways if the default behaviour is not appropriate.Setting the URL patternIf GDPR API URLs are setup as explained in the Usage section above, the GDPR URL pattern isgdpr-api/v1/profiles/<uuid:pk>. The first part (gdpr-api/) can be set freely in the URL config. The
rest (v1/profiles/<uuid:pk>) can be controlled with theGDPR_API_URL_PATTERNsetting. It can be set to
for exampleusers/<uuid:user_id>/gdpr. There needs to beexactly onenamed parameter in the URL
pattern. Its type needs to beuuid, name can be chosen freely.Searching the model instanceBy default theGDPR_API_MODELis searched with its primary key, something like this:fromdjango.appsimportappsfromdjango.confimportsettingsmodel=apps.get_model(settings.GDPR_API_MODEL)# The `id` is extracted from the request's URLobj=model.objects.get(pk=id)Ifpkis not the correct field lookup to use, set the settingGDPR_API_MODEL_LOOKUPto the correct
value, for exampleuser__uuid.If changing the field lookup that way doesn't solve the model instance searching, it's also possible to
set theGDPR_API_MODEL_LOOKUPsetting to an import path to a function, for examplemyapp.gdpr.get_model_instance. The function gets called whenever the GDPR API is accessed and the model
instance is needed. The function gets two arguments, the model class specified by theGDPR_API_MODELsetting and the id from the GDPR API request's path. The function must return an instance of the model
specified by theGDPR_API_MODELsetting, if an instance is found. If no instance is found, then the
function must either returnNoneor raise aDoesNotExistexception of the model.Obtaining a User model instanceIt's required that aUsermodel instance can be obtained from the GDPR API model instance specified by
theGDPR_API_MODELsetting. By default the GDPR API model instance'suserattribute is tried. If that
doesn't work, it's possible to configure a function that will provide theUserinstance. This is
achieved by setting the import path of the function to theGDPR_API_USER_PROVIDERsetting, for examplemyapp.gdpr.get_user. The function gets the GDPR API model instance as an argument.Controlling how data deletion is performedBy default the GDPR delete operation deletes theGDPR_API_MODELinstance and the relatedUserinstance. If that procedure isn't sufficient for the project, it's possible to override the data deletion
operation. This is achieved by setting theGDPR_API_DELETERsetting to an import path to a function, for
examplemyapp.gdpr.delete_data. The function gets two arguments, theGDPR_API_MODELinstance and a
boolean value indicating if this is a dry run or not.The function gets called within a database transaction, which gets automatically rolled back if it's a dry
run operation. Thus the function is free to do database modifications even in the dry run case. All
changes get rolled back afterwards. If it's not a dry run case, then the transaction is committed and all
changes to the database are persisted.If the data deletion isn't allowed, the function has two ways to indicate this:Return ahelsinki_gdpr.types.ErrorResponseinstance. This allows also communicating the reasons
why the deletion isn't allowed.Raise adjango.db.DatabaseErrorexception.DevelopmentIt's good to use a Python virtual environment:$> python -m venv venv
$> source ./venv/bin/activateInstall development dependencies:$> pip install -r requirements-dev.txtRun tests:$> pytestCode formatThis project usesblack,flake8andisortfor code formatting and quality checking. Project follows the basic black config, without any modifications.Basicblackcommands:To letblackdo its magic:black .To see which filesblackwould change:black --check .pre-commitcan be used to install and run all the formatting tools as git hooks
automatically before a commit.