diff --git a/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/apiinvokerenrolmentdetails.py b/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/apiinvokerenrolmentdetails.py index dc186e4da140c450eb8573cf4911c17a4c023eb8..2d43af2e22ae37fe2be82f15ca4a7ff560553f61 100644 --- a/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/apiinvokerenrolmentdetails.py +++ b/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/apiinvokerenrolmentdetails.py @@ -84,7 +84,7 @@ class InvokerManagementOperations(Resource): invoker_dict["username"]=username invoker_dict["uuid"]=uuid - mycol.insert_one(apiinvokerenrolmentdetail.to_dict()) + mycol.insert_one(invoker_dict) current_app.logger.debug("Invoker inserted in database") current_app.logger.debug("Netapp onboarded sucessfuly") diff --git a/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/db/db.py b/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/db/db.py index 5bfcd0b1f8539727cd9d821f466e69db220f67c1..638cc80e7f1b8e2e5e8e50165f4100fce5383920 100644 --- a/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/db/db.py +++ b/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/db/db.py @@ -16,7 +16,6 @@ class MongoDatabse(): self.config = Config().get_config() self.db = self.__connect() self.invoker_enrolment_details = self.config['mongo']['col'] - self.capif_users = self.config['mongo']['capif_users_col'] self.service_col = self.config['mongo']["service_col"] self.certs_col = self.config['mongo']['certs_col'] diff --git a/services/TS29222_CAPIF_API_Invoker_Management_API/config.yaml b/services/TS29222_CAPIF_API_Invoker_Management_API/config.yaml index e208a78ccfe2a48d16071e149b36575ba865e4d7..2a14561d485ebb8a81779e988a54b31f9c894fbb 100644 --- a/services/TS29222_CAPIF_API_Invoker_Management_API/config.yaml +++ b/services/TS29222_CAPIF_API_Invoker_Management_API/config.yaml @@ -3,20 +3,12 @@ mongo: { 'password': 'example', 'db': 'capif', 'col': 'invokerdetails', - 'capif_users_col': "user", 'certs_col': "certs", 'service_col': 'serviceapidescriptions', 'host': 'mongo', 'port': "27017" } -mongo_register: { - 'user': 'root', - 'password': 'example', - 'db': 'capif_users', - 'col': 'user', - 'host': 'mongo_register', - 'port': '27017' -} + ca_factory: { "url": "vault", "port": "8200", diff --git a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/db/db.py b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/db/db.py index bb080252efefbb51854ca37dd2cf5e6ebee8d41c..a67e2ea8412dedb818ce8352e7d91357c55a590d 100644 --- a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/db/db.py +++ b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/db/db.py @@ -17,7 +17,6 @@ class MongoDatabse(): self.config = Config().get_config() self.db = self.__connect() self.provider_enrolment_details = self.config['mongo']['col'] - self.capif_users = self.config['mongo']['capif_users'] self.certs_col = self.config['mongo']['certs_col'] def get_col_by_name(self, name): diff --git a/services/TS29222_CAPIF_API_Provider_Management_API/config.yaml b/services/TS29222_CAPIF_API_Provider_Management_API/config.yaml index 8de29a4385fffc05236cae4a9e72f9490969e47f..7d1899ab7a860fa1a6a0390f5fa4cf85271dc434 100644 --- a/services/TS29222_CAPIF_API_Provider_Management_API/config.yaml +++ b/services/TS29222_CAPIF_API_Provider_Management_API/config.yaml @@ -4,19 +4,10 @@ mongo: { 'db': 'capif', 'col': 'providerenrolmentdetails', 'certs_col': "certs", - 'capif_users': 'user', 'host': 'mongo', 'port': "27017" } -mongo_register: { - 'user': 'root', - 'password': 'example', - 'db': 'capif_users', - 'col': 'user', - 'host': 'mongo_register', - 'port': '27017' -} ca_factory: { "url": "vault", diff --git a/services/docker-compose-capif.yml b/services/docker-compose-capif.yml index f667d8c2999ac6ca304cafd621dc3ba2df32a074..d05518fade9fe04878556652d9518fefa9aa55b2 100644 --- a/services/docker-compose-capif.yml +++ b/services/docker-compose-capif.yml @@ -11,6 +11,30 @@ services: - $PWD/redis.conf:/usr/local/etc/redis/redis.conf environment: - REDIS_REPLICATION_MODE=master + + + helper: + build: + context: ./helper + expose: + - "8080" + container_name: helper + restart: unless-stopped + volumes: + - ./helper:/usr/src/app + extra_hosts: + - host.docker.internal:host-gateway + - fluent-bit:host-gateway + - otel-collector:host-gateway + - vault:host-gateway + environment: + - CAPIF_HOSTNAME=${CAPIF_HOSTNAME} + - CONTAINER_NAME=helper + - VAULT_HOSTNAME=vault + - VAULT_ACCESS_TOKEN=dev-only-token + - VAULT_PORT=8200 + depends_on: + - nginx access-control-policy: build: TS29222_CAPIF_Access_Control_Policy_API @@ -30,7 +54,6 @@ services: depends_on: - redis - nginx - api-invoker-management: build: diff --git a/services/helper/Dockerfile b/services/helper/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..2bc3b3390f4d6d7f5879af105f65308e7a5d8263 --- /dev/null +++ b/services/helper/Dockerfile @@ -0,0 +1,16 @@ +FROM public.ecr.aws/o2v4a8t6/opencapif/python:3-alpine + +RUN mkdir -p /usr/src/app +WORKDIR /usr/src/app + +COPY requirements.txt /usr/src/app/requirements.txt + +RUN apk add -U --no-cache gcc build-base linux-headers ca-certificates libffi-dev libressl-dev libxslt-dev +RUN pip3 install --no-cache-dir -r requirements.txt +RUN apk add openssl curl redis + +COPY . /usr/src/app + +EXPOSE 8080 + +CMD ["python3", "-m", "helper_service"] diff --git a/services/helper/config.yaml b/services/helper/config.yaml new file mode 100644 index 0000000000000000000000000000000000000000..46e5801bef78265a4d572d2a59f9628814dfafb5 --- /dev/null +++ b/services/helper/config.yaml @@ -0,0 +1,18 @@ +mongo: { + 'user': 'root', + 'password': 'example', + 'db': 'capif', + 'invoker_col': 'invokerdetails', + 'provider_col': 'providerenrolmentdetails', + 'col_services': "serviceapidescriptions", + 'col_security': "security", + 'col_event': "eventsdetails", + 'host': 'mongo', + 'port': "27017" +} + +ca_factory: { + "url": "vault", + "port": "8200", + "token": "dev-only-token" +} diff --git a/services/helper/helper_service/__init__.py b/services/helper/helper_service/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/services/helper/helper_service/__main__.py b/services/helper/helper_service/__main__.py new file mode 100644 index 0000000000000000000000000000000000000000..69411aafd2bde2eef90de3c33047ac594dbdc035 --- /dev/null +++ b/services/helper/helper_service/__main__.py @@ -0,0 +1,67 @@ +from flask import Flask +import logging +from .controllers.helper_controller import helper_routes +from OpenSSL.crypto import PKey, TYPE_RSA, X509Req, dump_certificate_request, FILETYPE_PEM, dump_privatekey +from .config import Config +import json +import requests + +app = Flask(__name__) +config = Config().get_config() + +# Create a superadmin CSR and keys +key = PKey() +key.generate_key(TYPE_RSA, 2048) +req = X509Req() +req.get_subject().O = 'OCF helper' +req.get_subject().OU = 'helper' +req.get_subject().L = 'Madrid' +req.get_subject().ST = 'Madrid' +req.get_subject().C = 'ES' +req.get_subject().emailAddress = 'helper@tid.es' +req.set_pubkey(key) +req.sign(key, 'sha256') + +csr_request = dump_certificate_request(FILETYPE_PEM, req) +private_key = dump_privatekey(FILETYPE_PEM, key) + +# Save superadmin private key +key_file = open("helper_service/certs/superadmin.key", 'wb+') +key_file.write(bytes(private_key)) +key_file.close() + +# Request superadmin certificate +url = 'http://{}:{}/v1/pki_int/sign/my-ca'.format(config["ca_factory"]["url"], config["ca_factory"]["port"]) +headers = {'X-Vault-Token': f"{config["ca_factory"]["token"]}"} +data = { + 'format':'pem_bundle', + 'ttl': '43000h', + 'csr': csr_request, + 'common_name': "superadmin" +} + +response = requests.request("POST", url, headers=headers, data=data, verify = False) +superadmin_cert = json.loads(response.text)['data']['certificate'] + +# Save the superadmin certificate +cert_file = open("helper_service/certs/superadmin.crt", 'wb') +cert_file.write(bytes(superadmin_cert, 'utf-8')) +cert_file.close() + +url = f"http://{config['ca_factory']['url']}:{config['ca_factory']['port']}/v1/secret/data/ca" +headers = { + + 'X-Vault-Token': config['ca_factory']['token'] +} +response = requests.request("GET", url, headers=headers, verify = False) + +ca_root = json.loads(response.text)['data']['data']['ca'] +cert_file = open("helper_service/certs/ca_root.crt", 'wb') +cert_file.write(bytes(ca_root, 'utf-8')) +cert_file.close() + +app.register_blueprint(helper_routes) +app.logger.setLevel(logging.DEBUG) + +if __name__ == '__main__': + app.run(host='0.0.0.0', port=8080, debug=True) \ No newline at end of file diff --git a/services/helper/helper_service/certs/.gitkeep b/services/helper/helper_service/certs/.gitkeep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/services/helper/helper_service/config.py b/services/helper/helper_service/config.py new file mode 100644 index 0000000000000000000000000000000000000000..444a23201168fceb276fa44b81f2417d8fc2afa6 --- /dev/null +++ b/services/helper/helper_service/config.py @@ -0,0 +1,20 @@ +import yaml +import os + +#Config class to get config +class Config: + def __init__(self): + self.cached = 0 + self.file="./config.yaml" + self.my_config = {} + + stamp = os.stat(self.file).st_mtime + if stamp != self.cached: + self.cached = stamp + f = open(self.file) + self.my_config = yaml.safe_load(f) + f.close() + + def get_config(self): + return self.my_config + diff --git a/services/helper/helper_service/controllers/helper_controller.py b/services/helper/helper_service/controllers/helper_controller.py new file mode 100644 index 0000000000000000000000000000000000000000..995d33590d5b6b32cb14961ed60e1d35463109a9 --- /dev/null +++ b/services/helper/helper_service/controllers/helper_controller.py @@ -0,0 +1,115 @@ +#!/usr/bin/env python3 + +from flask import Blueprint, request, current_app, jsonify +from ..core.helper_operations import HelperOperations +from ..config import Config + +config = Config().get_config() + +helper_routes = Blueprint("helper_routes", __name__) +helper_operation = HelperOperations() + +@helper_routes.route("/helper/getInvokers", methods=["GET"]) +def getInvokers(): + uuid = request.args.get('uuid') + invoker_id = request.args.get('api_invoker_id') + page_size = request.args.get('page_size') + page = request.args.get('page') + sort_order = request.args.get('sort_order') + if page_size: + page_size = int(page_size) + if page_size < 0: + return jsonify(message="The value of the page_size parameter must be greater than 0"), 400 + if page: + page = int(page) + if page < 0: + return jsonify(message="The value of the page parameter must be greater than 0"), 400 + + current_app.logger.debug(f"uuid: {uuid}, invoker_id: {invoker_id}, page: {page}, page_size: {page_size}, sort_order: {sort_order}") + + return helper_operation.get_invokers(uuid, invoker_id, page, page_size, sort_order) + +@helper_routes.route("/helper/getProviders", methods=["GET"]) +def getProviders(): + uuid = request.args.get('uuid') + provider_id = request.args.get('api_prov_dom_id') + page_size = request.args.get('page_size') + page = request.args.get('page') + sort_order = request.args.get('sort_order') + + if page_size: + page_size = int(page_size) + if page_size < 0: + return jsonify(message="The value of the page_size parameter must be greater than 0"), 400 + if page: + page = int(page) + if page < 0: + return jsonify(message="The value of the page parameter must be greater than 0"), 400 + + current_app.logger.debug(f"uuid: {uuid}, provider_id: {provider_id}, page: {page}, page_size: {page_size}, sort_order: {sort_order}") + + return helper_operation.get_providers(uuid, provider_id, page, page_size, sort_order) + + +@helper_routes.route("/helper/getServices", methods=["GET"]) +def getServices(): + service_id = request.args.get('service_id') + apf_id = request.args.get('apf_id') + api_name = request.args.get('api_name') + page_size = request.args.get('page_size') + page = request.args.get('page') + sort_order = request.args.get('sort_order') + if page_size: + page_size = int(page_size) + if page_size < 0: + return jsonify(message="The value of the page_size parameter must be greater than 0"), 400 + if page: + page = int(page) + if page < 0: + return jsonify(message="The value of the page parameter must be greater than 0"), 400 + + current_app.logger.debug(f"service_id: {service_id}, apf_id: {apf_id}, api_name: {api_name}, page: {page}, page_size: {page_size}, sort_order: {sort_order}") + + return helper_operation.get_services(service_id, apf_id, api_name, page, page_size, sort_order) + +@helper_routes.route("/helper/getSecurity", methods=["GET"]) +def getSecurity(): + invoker_id = request.args.get('invoker_id') + page_size = request.args.get('page_size') + page = request.args.get('page') + if page_size: + page_size = int(page_size) + if page_size < 0: + return jsonify(message="The value of the page_size parameter must be greater than 0"), 400 + if page: + page = int(page) + if page < 0: + return jsonify(message="The value of the page parameter must be greater than 0"), 400 + + current_app.logger.debug(f"invoker_id: {invoker_id}, page: {page}, page_size: {page_size} ") + + return helper_operation.get_security(invoker_id, page, page_size) + +@helper_routes.route("/helper/getEvents", methods=["GET"]) +def getEvents(): + subscriber_id = request.args.get('subscriber_id') + subscription_id = request.args.get('subscription_id') + page_size = request.args.get('page_size') + page = request.args.get('page') + if page_size: + page_size = int(page_size) + if page_size < 0: + return jsonify(message="The value of the page_size parameter must be greater than 0"), 400 + if page: + page = int(page) + if page < 0: + return jsonify(message="The value of the page parameter must be greater than 0"), 400 + + current_app.logger.debug(f"subscriber_id: {subscriber_id}, subscription_id: {subscription_id}, page: {page}, page_size: {page_size} ") + + return helper_operation.get_events(subscriber_id, subscription_id, page, page_size) + + +@helper_routes.route("/helper/deleteEntities/", methods=["DELETE"]) +def deleteUserEntities(uuid): + return helper_operation.remove_entities(uuid) diff --git a/services/helper/helper_service/core/helper_operations.py b/services/helper/helper_service/core/helper_operations.py new file mode 100644 index 0000000000000000000000000000000000000000..aed9da5ab74357632681679f0b99883b9f4746a7 --- /dev/null +++ b/services/helper/helper_service/core/helper_operations.py @@ -0,0 +1,204 @@ +from flask import jsonify, current_app +import pymongo +from ..db.db import MongoDatabse +from ..config import Config +import requests +import os + +class HelperOperations: + + def __init__(self): + self.db = MongoDatabse() + self.mimetype = 'application/json' + self.config = Config().get_config() + + def get_invokers(self, uuid, invoker_id, page, page_size, sort_order): + current_app.logger.debug(f"Getting the invokers") + invoker_col = self.db.get_col_by_name(self.db.invoker_col) + + total_invokers = invoker_col.count_documents({}) + + filter = {} + if uuid: + filter["uuid"]=uuid + if invoker_id: + filter["api_invoker_id"]=invoker_id + + sort_direction = pymongo.DESCENDING if sort_order == "desc" else pymongo.ASCENDING + + if page_size and page: + index = (page - 1) * page_size + documents = invoker_col.find(filter,{"_id":0}).sort("onboarding_date", sort_direction).skip(index).limit(page_size) + pages = (total_invokers + page_size - 1) // page_size + else: + documents = invoker_col.find(filter,{"_id":0}).sort("onboarding_date", sort_direction) + pages = 1 + + list_invokers= list(documents) + long = len(list_invokers) + + return jsonify(message="Invokers returned successfully", + invokers=list_invokers, + total = total_invokers, + long = long, + totalPages = pages, + sortOrder = sort_order), 200 + + + def get_providers(self, uuid, provider_id, page, page_size, sort_order): + current_app.logger.debug(f"Getting the providers") + provider_col = self.db.get_col_by_name(self.db.provider_col) + + total_providers = provider_col.count_documents({}) + + filter = {} + if uuid: + filter["uuid"]=uuid + if provider_id: + filter["api_prov_dom_id"]=provider_id + + sort_direction = pymongo.DESCENDING if sort_order == "desc" else pymongo.ASCENDING + + if page_size and page: + index = (page - 1) * page_size + documents = provider_col.find(filter,{"_id":0}).sort("onboarding_date", sort_direction).skip(index).limit(page_size) + pages = (total_providers + page_size - 1) // page_size + else: + documents = provider_col.find(filter,{"_id":0}).sort("onboarding_date", sort_direction) + pages = 1 + + list_providers = list(documents) + long = len(list_providers) + + return jsonify(message="Providers returned successfully", + providers=list_providers, + total = total_providers, + long = long, + totalPages = pages, + sortOrder = sort_order), 200 + + def get_services(self, service_id, apf_id, api_name, page, page_size, sort_order): + current_app.logger.debug(f"Getting the services") + service_col = self.db.get_col_by_name(self.db.services_col) + + total_services = service_col.count_documents({}) + + filter = {} + if service_id: + filter["api_id"]=service_id + if apf_id: + filter["apf_id"]=apf_id + if api_name: + filter["api_name"]=api_name + + sort_direction = pymongo.DESCENDING if sort_order == "desc" else pymongo.ASCENDING + + if page_size and page: + index = (page - 1) * page_size + documents = service_col.find(filter,{"_id":0}).sort("onboarding_date", sort_direction).skip(index).limit(page_size) + pages = (total_services + page_size - 1) // page_size + else: + documents = service_col.find(filter,{"_id":0}).sort("onboarding_date", sort_direction) + pages = 1 + + list_services= list(documents) + long = len(list_services) + + return jsonify(message="Services returned successfully", + services=list_services, + total = total_services, + long = long, + totalPages = pages, + sortOrder = sort_order), 200 + + def get_security(self, invoker_id, page, page_size): + current_app.logger.debug(f"Getting the security context") + security_col = self.db.get_col_by_name(self.db.security_context_col) + + total_security = security_col.count_documents({}) + + filter = {} + + if invoker_id: + filter["api_invoker_id"]=invoker_id + + if page_size and page: + index = (page - 1) * page_size + documents = security_col.find(filter,{"_id":0}).skip(index).limit(page_size) + pages = (total_security + page_size - 1) // page_size + else: + documents = security_col.find(filter,{"_id":0}) + pages = 1 + + list_security= list(documents) + long = len(list_security) + + return jsonify(message="Security context returned successfully", + security=list_security, + total = total_security, + long = long, + totalPages = pages), 200 + + def get_events(self, subscriber_id, subscription_id, page, page_size): + current_app.logger.debug(f"Getting the events") + events_col = self.db.get_col_by_name(self.db.events) + + total_events = events_col.count_documents({}) + + filter = {} + + if subscriber_id: + filter["subscriber_id"]=subscriber_id + if subscription_id: + filter["subscription_id"]=subscription_id + + if page_size and page: + index = (page - 1) * page_size + documents = events_col.find(filter,{"_id":0}).skip(index).limit(page_size) + pages = (total_events + page_size - 1) // page_size + else: + documents = events_col.find(filter,{"_id":0}) + pages = 1 + + list_events= list(documents) + long = len(list_events) + + return jsonify(message="Events returned successfully", + events=list_events, + total = total_events, + long = long, + totalPages = pages), 200 + + def remove_entities(self, uuid): + + current_app.logger.debug(f"Removing entities for uuid: {uuid}") + invoker_col = self.db.get_col_by_name(self.db.invoker_col) + provider_col = self.db.get_col_by_name(self.db.provider_col) + + try: + if invoker_col.count_documents({'uuid':uuid}) == 0 and provider_col.count_documents({'uuid':uuid}) == 0: + current_app.logger.debug(f"No entities found for uuid: {uuid}") + return jsonify(message=f"No entities found for uuid: {uuid}"), 204 + + for invoker in invoker_col.find({'uuid':uuid}, {"_id":0}): + current_app.logger.debug(f"Removing Invoker: {invoker["api_invoker_id"]}") + url = 'https://{}/api-invoker-management/v1/onboardedInvokers/{}'.format(os.getenv('CAPIF_HOSTNAME'), invoker["api_invoker_id"]) + requests.request("DELETE", url, cert=( + '/usr/src/app/helper_service/certs/superadmin.crt', '/usr/src/app/helper_service/certs/superadmin.key'), verify='/usr/src/app/helper_service/certs/ca_root.crt') + + for provider in provider_col.find({'uuid':uuid}, {"_id":0}): + current_app.logger.debug(f"Removing Provider: {provider["api_prov_dom_id"]}") + url = 'https://{}/api-provider-management/v1/registrations/{}'.format(os.getenv('CAPIF_HOSTNAME'), provider["api_prov_dom_id"]) + + requests.request("DELETE", url, cert=( + '/usr/src/app/helper_service/certs/superadmin.crt', '/usr/src/app/helper_service/certs/superadmin.key'), verify='/usr/src/app/helper_service/certs/ca_root.crt') + except Exception as e: + current_app.logger.debug(f"Error deleting user entities: {e}") + jsonify(message=f"Error deleting user entities: {e}"), 500 + + current_app.logger.debug(f"User entities removed successfully") + return jsonify(message="User entities removed successfully"), 200 + + + + diff --git a/services/helper/helper_service/db/db.py b/services/helper/helper_service/db/db.py new file mode 100644 index 0000000000000000000000000000000000000000..9820a92705e4c73151ffa216bab58b7d0cb866c0 --- /dev/null +++ b/services/helper/helper_service/db/db.py @@ -0,0 +1,45 @@ +import time +from pymongo import MongoClient +from pymongo.errors import AutoReconnect +from ..config import Config +from bson.codec_options import CodecOptions + +class MongoDatabse(): + + def __init__(self): + self.config = Config().get_config() + self.db = self.__connect() + self.invoker_col = self.config['mongo']['invoker_col'] + self.provider_col = self.config['mongo']['provider_col'] + self.services_col = self.config['mongo']['col_services'] + self.security_context_col = self.config['mongo']['col_security'] + self.events = self.config['mongo']['col_event'] + + + def get_col_by_name(self, name): + return self.db[name].with_options(codec_options=CodecOptions(tz_aware=True)) + + def __connect(self, max_retries=3, retry_delay=1): + + retries = 0 + + while retries < max_retries: + try: + uri = f"mongodb://{self.config['mongo']['user']}:{self.config['mongo']['password']}@" \ + f"{self.config['mongo']['host']}:{self.config['mongo']['port']}" + + + client = MongoClient(uri) + mydb = client[self.config['mongo']['db']] + mydb.command("ping") + return mydb + except AutoReconnect: + retries += 1 + print(f"Reconnecting... Retry {retries} of {max_retries}") + time.sleep(retry_delay) + return None + + def close_connection(self): + if self.db.client: + self.db.client.close() + diff --git a/services/helper/requirements.txt b/services/helper/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..68d82b28cd3fcc11703f52df02a7340086b90d33 --- /dev/null +++ b/services/helper/requirements.txt @@ -0,0 +1,8 @@ +python_dateutil == 2.9.0.post0 +setuptools == 68.2.2 +Flask == 3.0.3 +pymongo == 4.0.1 +flask_jwt_extended == 4.6.0 +pyopenssl == 24.1.0 +pyyaml == 6.0.1 +requests == 2.32.2 diff --git a/services/nginx/nginx.conf b/services/nginx/nginx.conf index d30ded7b2eb1863cc072284e1f6c5727bf849ef1..ec70d576977be2d61f633f8888ff392d60f1b322 100644 --- a/services/nginx/nginx.conf +++ b/services/nginx/nginx.conf @@ -12,6 +12,10 @@ http { default ""; ~(^|,)CN=(?[^,]+) $CN; } + map "$request_method:$uri:$ssl_client_s_dn_cn" $helper_error_message { + default 'SUCCESS'; + "~*(GET|DELETE):.*:(?!(superadmin))(.*)" '{"status":401, "title":"Unauthorized" ,"detail":"Role not authorized for this API route", "cause":"User role must be superadmin"}'; + } map "$request_method:$uri:$ssl_client_s_dn_cn" $invoker_error_message { default 'SUCCESS'; "~*(PUT|DELETE):.*:(?!(INV|superadmin))(.*)" '{"status":401, "title":"Unauthorized" ,"detail":"Role not authorized for this API route", "cause":"User role must be invoker"}'; @@ -163,6 +167,15 @@ http { proxy_pass http://access-control-policy:8080; } + location /helper { + if ( $helper_error_message != SUCCESS ) { + add_header Content-Type 'application/problem+json'; + return 401 $helper_error_message; + } + proxy_set_header X-SSL-Client-Cert $ssl_client_cert; + proxy_pass http://helper:8080; + } + } } diff --git a/services/register/register_service/core/register_operations.py b/services/register/register_service/core/register_operations.py index a8fee919900a1e36962f4e7f0b8b0cb257b1f5f2..1eb6b0775acc8319d15d3b2456280d420b1f5c58 100644 --- a/services/register/register_service/core/register_operations.py +++ b/services/register/register_service/core/register_operations.py @@ -3,7 +3,7 @@ from flask_jwt_extended import create_access_token from ..db.db import MongoDatabse from datetime import datetime from ..config import Config -import base64 +import requests import uuid class RegisterOperations: @@ -61,11 +61,11 @@ class RegisterOperations: mycol = self.db.get_col_by_name(self.db.capif_users) try: - mycol.delete_one({"uuid": uuid}) - - # Request to the helper to delete invokers and providers - + url = f"https://capifcore/helper/deleteEntities/{uuid}" + requests.delete(url, cert=("register_service/certs/superadmin.crt", "register_service/certs/superadmin.key"), verify="register_service/certs/ca_root.crt") + + mycol.delete_one({"uuid": uuid}) return jsonify(message="User removed successfully"), 204 except Exception as e: