Skip to content

Commit

Permalink
MIJN-8594-bsn-nummer-niet-meer-tonen-alg-user-e-xperience (#124)
Browse files Browse the repository at this point in the history
* no BSN on prd + formatting

* README for Windows

* readability

* parent -> ouder

* prs -> persoon

* Check to server.py

* unused imports

* better naming

* remove print

* Add tests, fix environ var (#125)

---------

Co-authored-by: Tim van Oostrom <[email protected]>
  • Loading branch information
Anouk91 and timvanoostrom authored Jun 7, 2024
1 parent 2a2dc35 commit 790e0a0
Show file tree
Hide file tree
Showing 9 changed files with 338 additions and 246 deletions.
28 changes: 16 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
MKS API
=========
# MKS API

### Deze api levert de volgende data:

Expand All @@ -9,41 +8,46 @@ MKS API
- Overzicht ID kaarten en Paspoorten

### Local env
```
python -m venv venv
source venv/bin/activate
pip install -r requirements-root.txt

// Initialize

- `python -m venv venv`
- Mac: `source venv/bin/activate` Windows: `.\venv\Scripts\Activate.ps1` (in case of UnauthorizedAccess run `Set-ExecutionPolicy Unrestricted -Scope Process` beforehand)
- `pip install -r requirements-root.txt`

// unittest
python -m unittest
`python -m unittest`

// requirements.txt maken
make requirements
`make requirements`

// dev server
sh scripts/run-dev.sh
```
`sh scripts/run-dev.sh`

### Kenmerken

- Het bronsysteem is een soap/stuf api MKS, deze haalt gegevens uit de brp.
- Het bronsysteem wordt bevraagd op basis van een BSN of KVK nummer.
- De output van de api is JSON formaat.

### Dependencies

- Voeg de naam van de library/dependency toe aan requirements-root.txt
- Voer volgende commando uit: `make requirements`


### Development & testen

- Er is geen uitgebreide lokale set-up waarbij ontwikkeld kan worden op basis van een "draaiende" api. Dit zou gemaakt / geïmplementeerd moeten worden.
- Alle tests worden dichtbij de geteste functionaliteit opgeslagen. B.v `some_service.py` en wordt getest in `test_some_service.py`.

### CI/CD

- De applicatie wordt verpakt in een Docker container.
- Bouwen en deployen van de applicatie gebeurt in Github en Azure DevOps.

### Release to production

```
~ cd scripts
~ sh release.sh --minor [--major [--patch]]
```
```
4 changes: 4 additions & 0 deletions app/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@
IS_OT = IS_DEV or IS_TEST
IS_AZ = os.getenv("IS_AZ", False)

IS_SHOW_BSN_ENABLED = (
os.getenv("MKS_IS_SHOW_BSN_ENABLED", "false" if IS_PRODUCTION else "true") == "true"
)

# App constants
VERIFY_JWT_SIGNATURE = os.getenv("VERIFY_JWT_SIGNATURE", IS_AP)
REQUEST_TIMEOUT = 20 if IS_PRODUCTION else 30 # seconds
Expand Down
12 changes: 12 additions & 0 deletions app/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,15 @@ def get_request_template(name):
filename = os.path.join(SERVICES_DIR, f"{name}.jinja2")
with open(filename) as fp:
return Template(fp.read())


def remove_attr(input, attr):
if isinstance(input, dict):
for key in list(input.keys()):
if key == attr:
input.pop(key)
else:
remove_attr(input[key], attr)
if isinstance(input, list):
for list_item in input:
remove_attr(list_item, attr)
2 changes: 1 addition & 1 deletion app/model/gba.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"M": "Man",
"V": "Vrouw",
}
lookup_prsidb_soort_code = {
lookup_persoonidb_soort_code = {
1: "paspoort",
2: "europese identiteitskaart",
3: "toeristenkaart",
Expand Down
105 changes: 62 additions & 43 deletions app/model/stuf_02_04.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@
from collections import defaultdict
from datetime import date
from hashlib import sha256
from app.config import IS_PRODUCTION

# from config import IS_PRODUCTION
from bs4 import Tag, ResultSet
from dateutil.relativedelta import relativedelta
from app.helpers import encrypt

from app.model.gba import (
lookup_prsidb_soort_code,
lookup_persoonidb_soort_code,
lookup_geslacht,
lookup_gemeenten,
lookup_landen,
Expand All @@ -32,7 +34,7 @@
is_nil,
to_string_4x0,
set_indicatie_geboortedatum,
set_fields_with_attributes
set_fields_with_attributes,
)


Expand Down Expand Up @@ -77,7 +79,7 @@ def get_nationaliteiten(nationaliteiten: ResultSet):
def extract_persoon_data(persoon_tree: Tag):
result = {}

prs_fields = [
persoon_fields = [
{"name": "bsn-nummer", "parser": as_bsn, "save_as": "bsn"},
{"name": "geslachtsnaam", "parser": to_string},
{"name": "voornamen", "parser": to_string},
Expand All @@ -102,7 +104,7 @@ def extract_persoon_data(persoon_tree: Tag):
{"name": "aanduidingNaamgebruik", "parser": to_string},
]

prs_extra_fields = [
persoon_extra_fields = [
{"name": "aanduidingNaamgebruikOmschrijving", "parser": to_string},
{"name": "geboortelandnaam", "parser": to_string},
{"name": "geboorteplaatsnaam", "parser": to_string},
Expand All @@ -119,13 +121,17 @@ def extract_persoon_data(persoon_tree: Tag):
},
]

prs_fields_with_attrs = [
{"name": "geboortedatum", "parser": set_indicatie_geboortedatum, "save_as": "indicatieGeboortedatum"},
persoon_fields_with_attrs = [
{
"name": "geboortedatum",
"parser": set_indicatie_geboortedatum,
"save_as": "indicatieGeboortedatum",
},
]

set_fields(persoon_tree, prs_fields, result)
set_extra_fields(persoon_tree.extraElementen, prs_extra_fields, result)
set_fields_with_attributes(persoon_tree, prs_fields_with_attrs, result)
set_fields(persoon_tree, persoon_fields, result)
set_extra_fields(persoon_tree.extraElementen, persoon_extra_fields, result)
set_fields_with_attributes(persoon_tree, persoon_fields_with_attrs, result)

# vertrokken onbekend waarheen
result["vertrokkenOnbekendWaarheen"] = False
Expand All @@ -135,14 +141,13 @@ def extract_persoon_data(persoon_tree: Tag):
set_omschrijving_geslachtsaanduiding(result)
set_geboorteLandnaam(result)
set_geboorteplaatsNaam(result)

return result


def extract_kinderen_data(persoon_tree: Tag):
result = []

knd_fields = [
kind_fields = [
{"name": "bsn-nummer", "parser": as_bsn, "save_as": "bsn"},
{"name": "voornamen", "parser": to_string},
{"name": "voorvoegselGeslachtsnaam", "parser": to_string},
Expand All @@ -163,16 +168,20 @@ def extract_kinderen_data(persoon_tree: Tag):
{"name": "adellijkeTitelPredikaat", "parser": to_string},
]

knd_extra_fields = [
kind_extra_fields = [
{"name": "omschrijvingAdellijkeTitel", "parser": to_string},
{"name": "geboortelandnaam", "parser": to_string},
{"name": "geboorteplaatsnaam", "parser": to_string},
{"name": "omschrijvingGeslachtsaanduiding", "parser": to_string},
{"name": "opgemaakteNaam", "parser": to_string},
]

knd_fields_with_attrs = [
{"name": "geboortedatum", "parser": set_indicatie_geboortedatum, "save_as": "indicatieGeboortedatum"},
kind_fields_with_attrs = [
{
"name": "geboortedatum",
"parser": set_indicatie_geboortedatum,
"save_as": "indicatieGeboortedatum",
},
]

kinderen = persoon_tree.find_all("PRSPRSKND")
Expand All @@ -181,9 +190,9 @@ def extract_kinderen_data(persoon_tree: Tag):

for kind in kinderen:
result_kind = {}
set_fields(kind.PRS, knd_fields, result_kind)
set_extra_fields(kind.PRS, knd_extra_fields, result_kind)
set_fields_with_attributes(kind.PRS, knd_fields_with_attrs, result_kind)
set_fields(kind.PRS, kind_fields, result_kind)
set_extra_fields(kind.PRS, kind_extra_fields, result_kind)
set_fields_with_attributes(kind.PRS, kind_fields_with_attrs, result_kind)

set_omschrijving_geslachtsaanduiding(result_kind)
set_geboorteLandnaam(result_kind)
Expand All @@ -196,10 +205,10 @@ def extract_kinderen_data(persoon_tree: Tag):
return result


def extract_parents_data(persoon_tree: Tag):
def extract_ouders_data(persoon_tree: Tag):
result = []

parent_fields = [
ouder_fields = [
{"name": "bsn-nummer", "parser": as_bsn, "save_as": "bsn"},
{"name": "voornamen", "parser": to_string},
{"name": "voorvoegselGeslachtsnaam", "parser": to_string},
Expand All @@ -220,33 +229,37 @@ def extract_parents_data(persoon_tree: Tag):
{"name": "adellijkeTitelPredikaat", "parser": to_string},
]

parent_extra_fields = [
ouder_extra_fields = [
{"name": "omschrijvingAdellijkeTitel", "parser": to_string},
{"name": "geboortelandnaam", "parser": to_string},
{"name": "geboorteplaatsnaam", "parser": to_string},
{"name": "omschrijvingGeslachtsaanduiding", "parser": to_string},
{"name": "opgemaakteNaam", "parser": to_string},
]

parent_fields_with_attrs = [
{"name": "geboortedatum", "parser": set_indicatie_geboortedatum, "save_as": "indicatieGeboortedatum"},
ouder_fields_with_attrs = [
{
"name": "geboortedatum",
"parser": set_indicatie_geboortedatum,
"save_as": "indicatieGeboortedatum",
},
]

parents = persoon_tree.find_all("PRSPRSOUD")
if is_nil(parents):
ouders = persoon_tree.find_all("PRSPRSOUD")
if is_nil(ouders):
return []

for ouder in parents:
result_parent = {}
set_fields(ouder.PRS, parent_fields, result_parent)
set_extra_fields(ouder.PRS, parent_extra_fields, result_parent)
set_fields_with_attributes(ouder.PRS, parent_fields_with_attrs, result_parent)
for ouder in ouders:
result_ouder = {}
set_fields(ouder.PRS, ouder_fields, result_ouder)
set_extra_fields(ouder.PRS, ouder_extra_fields, result_ouder)
set_fields_with_attributes(ouder.PRS, ouder_fields_with_attrs, result_ouder)

set_omschrijving_geslachtsaanduiding(result_parent)
set_geboorteLandnaam(result_parent)
set_geboorteplaatsNaam(result_parent)
set_omschrijving_geslachtsaanduiding(result_ouder)
set_geboorteLandnaam(result_ouder)
set_geboorteplaatsNaam(result_ouder)

result.append(result_parent)
result.append(result_ouder)

result.sort(key=lambda x: x["geboortedatum"] or date.min)

Expand Down Expand Up @@ -292,7 +305,11 @@ def extract_verbintenis_data(persoon_tree: Tag):
]

partner_fields_with_attrs = [
{"name": "geboortedatum", "parser": set_indicatie_geboortedatum, "save_as": "indicatieGeboortedatum"},
{
"name": "geboortedatum",
"parser": set_indicatie_geboortedatum,
"save_as": "indicatieGeboortedatum",
},
]

verbintenissen = persoon_tree.find_all("PRSPRSHUW")
Expand All @@ -311,14 +328,16 @@ def extract_verbintenis_data(persoon_tree: Tag):

set_fields(verb.PRS, partner_fields, result_verbintenis["persoon"])
set_extra_fields(verb.PRS, partner_extra_fields, result_verbintenis["persoon"])
set_fields_with_attributes(verb.PRS, partner_fields_with_attrs, result_verbintenis["persoon"])
set_fields_with_attributes(
verb.PRS, partner_fields_with_attrs, result_verbintenis["persoon"]
)

set_omschrijving_geslachtsaanduiding(result_verbintenis["persoon"])

einde_verbintenis_code = verb.find("redenOntbinding").string
result_verbintenis[
"redenOntbindingOmschrijving"
] = lookup_reden_ontbinding_partner.get(einde_verbintenis_code, None)
result_verbintenis["redenOntbindingOmschrijving"] = (
lookup_reden_ontbinding_partner.get(einde_verbintenis_code, None)
)

result.append(result_verbintenis)

Expand Down Expand Up @@ -499,12 +518,12 @@ def extract_identiteitsbewijzen(persoon_tree: Tag):
continue

try:
result_id["documentType"] = lookup_prsidb_soort_code[type_number]
result_id["documentType"] = lookup_persoonidb_soort_code[type_number]
except Exception as e:
logging.info(f"unknown document type {type_number} {type(e)} {e}")
result_id[
"documentType"
] = f"onbekend type ({type_number})" # unknown doc type
result_id["documentType"] = (
f"onbekend type ({type_number})" # unknown doc type
)

hash = sha256()
hash.update(result_id["documentNummer"].encode())
Expand Down Expand Up @@ -559,7 +578,7 @@ def extract_data(persoon_tree: Tag):

if isAmsterdammer:
kinderen = extract_kinderen_data(persoon_tree)
ouders = extract_parents_data(persoon_tree)
ouders = extract_ouders_data(persoon_tree)
verbintenis = verbintenissen["verbintenis"]
verbintenis_historisch = verbintenissen["verbintenisHistorisch"]
identiteitsbewijzen = extract_identiteitsbewijzen(persoon_tree)
Expand Down
8 changes: 7 additions & 1 deletion app/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@
from app import auth
from app.config import (
IS_DEV,
IS_SHOW_BSN_ENABLED,
UpdatedJSONProvider,
get_application_insights_connection_string,
)
from app.helpers import decrypt, error_response_json, success_response_json
from app.helpers import decrypt, error_response_json, remove_attr, success_response_json
from app.service import mks_client_02_04, mks_client_hr
from app.service.adr_mks_client_02_04 import get_resident_count

Expand All @@ -27,6 +28,7 @@
app = Flask(__name__)
app.json = UpdatedJSONProvider(app)


FlaskInstrumentor.instrument_app(app)


Expand All @@ -36,6 +38,10 @@ def get_brp():
with tracer.start_as_current_span("/brp"):
user = auth.get_current_user()
brp = mks_client_02_04.get_0204(user["id"])

if not IS_SHOW_BSN_ENABLED:
remove_attr(brp, "bsn")

return success_response_json(brp)


Expand Down
Loading

0 comments on commit 790e0a0

Please sign in to comment.