From afd5c39889fd49ac377767d08be3866f7a4eb60b Mon Sep 17 00:00:00 2001 From: Pelayo Torres Date: Thu, 9 May 2024 14:23:02 +0200 Subject: [PATCH 1/4] Helper service --- .../core/apiinvokerenrolmentdetails.py | 2 +- .../api_invoker_management/db/db.py | 1 - .../config.yaml | 10 +- .../api_provider_management/db/db.py | 1 - .../config.yaml | 9 - services/docker-compose-capif.yml | 25 ++- services/helper/Dockerfile | 16 ++ services/helper/config.yaml | 18 ++ services/helper/helper_service/__init__.py | 0 services/helper/helper_service/__main__.py | 68 ++++++ services/helper/helper_service/certs/.gitkeep | 0 services/helper/helper_service/config.py | 20 ++ .../controllers/helper_controller.py | 115 ++++++++++ .../helper_service/core/helper_operations.py | 204 ++++++++++++++++++ services/helper/helper_service/db/db.py | 45 ++++ services/helper/requirements.txt | 8 + services/nginx/nginx.conf | 13 ++ .../core/register_operations.py | 10 +- 18 files changed, 538 insertions(+), 27 deletions(-) create mode 100644 services/helper/Dockerfile create mode 100644 services/helper/config.yaml create mode 100644 services/helper/helper_service/__init__.py create mode 100644 services/helper/helper_service/__main__.py create mode 100644 services/helper/helper_service/certs/.gitkeep create mode 100644 services/helper/helper_service/config.py create mode 100644 services/helper/helper_service/controllers/helper_controller.py create mode 100644 services/helper/helper_service/core/helper_operations.py create mode 100644 services/helper/helper_service/db/db.py create mode 100644 services/helper/requirements.txt 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 dc186e4..2d43af2 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 5bfcd0b..638cc80 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 e208a78..2a14561 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 bb08025..a67e2ea 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 8de29a4..7d1899a 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 f667d8c..d05518f 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 0000000..2bc3b33 --- /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 0000000..46e5801 --- /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 0000000..e69de29 diff --git a/services/helper/helper_service/__main__.py b/services/helper/helper_service/__main__.py new file mode 100644 index 0000000..833284b --- /dev/null +++ b/services/helper/helper_service/__main__.py @@ -0,0 +1,68 @@ +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 0000000..e69de29 diff --git a/services/helper/helper_service/config.py b/services/helper/helper_service/config.py new file mode 100644 index 0000000..d04bd1a --- /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 0000000..995d335 --- /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 0000000..aed9da5 --- /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 0000000..9820a92 --- /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 0000000..c5a4f37 --- /dev/null +++ b/services/helper/requirements.txt @@ -0,0 +1,8 @@ +python_dateutil >= 2.6.0 +setuptools >= 21.0.0 +Flask >= 2.0.3 +pymongo == 4.0.1 +flask_jwt_extended +pyopenssl +pyyaml +requests diff --git a/services/nginx/nginx.conf b/services/nginx/nginx.conf index d30ded7..ec70d57 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 a8fee91..1eb6b07 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: -- GitLab From 29660fcf62e0496fa60e33fb02a8d06a1083b305 Mon Sep 17 00:00:00 2001 From: Pelayo Torres Date: Wed, 22 May 2024 11:06:30 +0200 Subject: [PATCH 2/4] Setup fixed versions --- services/helper/requirements.txt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/services/helper/requirements.txt b/services/helper/requirements.txt index c5a4f37..68d82b2 100644 --- a/services/helper/requirements.txt +++ b/services/helper/requirements.txt @@ -1,8 +1,8 @@ -python_dateutil >= 2.6.0 -setuptools >= 21.0.0 -Flask >= 2.0.3 +python_dateutil == 2.9.0.post0 +setuptools == 68.2.2 +Flask == 3.0.3 pymongo == 4.0.1 -flask_jwt_extended -pyopenssl -pyyaml -requests +flask_jwt_extended == 4.6.0 +pyopenssl == 24.1.0 +pyyaml == 6.0.1 +requests == 2.32.2 -- GitLab From b9ca1f231229f8dabf7490639c9d3e92033be8ad Mon Sep 17 00:00:00 2001 From: torrespel Date: Wed, 22 May 2024 09:09:32 +0000 Subject: [PATCH 3/4] Update config.py --- services/helper/helper_service/config.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/services/helper/helper_service/config.py b/services/helper/helper_service/config.py index d04bd1a..444a232 100644 --- a/services/helper/helper_service/config.py +++ b/services/helper/helper_service/config.py @@ -3,18 +3,18 @@ import os #Config class to get config class Config: - def __init__(self): - self.cached = 0 - self.file="./config.yaml" - self.my_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() + 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 + def get_config(self): + return self.my_config -- GitLab From 936bf13be61ce7f8ac3415bf76b019fc771f43b7 Mon Sep 17 00:00:00 2001 From: Pelayo Torres Date: Wed, 22 May 2024 12:45:01 +0200 Subject: [PATCH 4/4] commit --- services/helper/helper_service/__main__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/services/helper/helper_service/__main__.py b/services/helper/helper_service/__main__.py index 833284b..69411aa 100644 --- a/services/helper/helper_service/__main__.py +++ b/services/helper/helper_service/__main__.py @@ -6,7 +6,6 @@ from .config import Config import json import requests - app = Flask(__name__) config = Config().get_config() -- GitLab