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

MIJN-8594-bsn-nummer-niet-meer-tonen-alg-user-e-xperience #124

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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