Commit c4429b7d authored by guillecxb's avatar guillecxb
Browse files

working

parent 7ef2c167
Loading
Loading
Loading
Loading
+20 −3
Original line number Diff line number Diff line
from flask import Flask
from flask import Flask, request, make_response
from OpenSSL.crypto import PKey, TYPE_RSA, X509Req, dump_certificate_request, FILETYPE_PEM, dump_privatekey
from flask_jwt_extended import JWTManager
from .configs.config import Config
@@ -11,13 +11,24 @@ from .controllers.providers_controller import providers_routes
from .controllers.users_controller import users_routes
from .controllers.apis_controller import apis_routes
from .controllers.login import access_routes
from .controllers.configuration_controller import configuration_routes
from flask_cors import CORS

# Create Flask app
app = Flask(__name__)

# Configurar CORS para todas las rutas
CORS(app, resources={r"/api/*": {"origins": "http://localhost:3001"}})
# Configurar CORS correctamente
CORS(app, supports_credentials=True, allow_headers=["Content-Type", "Authorization"])

# Manejo global de preflight OPTIONS
@app.before_request
def handle_preflight():
    if request.method == "OPTIONS":
        res = make_response("", 200)
        res.headers["Access-Control-Allow-Origin"] = "*"
        res.headers["Access-Control-Allow-Methods"] = "GET, POST, PATCH, PUT, DELETE, OPTIONS"
        res.headers["Access-Control-Allow-Headers"] = "Content-Type, Authorization"
        return res

# Register blueprints (routes)
app.register_blueprint(backoffice_routes, url_prefix="/api")
@@ -26,11 +37,17 @@ app.register_blueprint(invokers_routes, url_prefix="/api/invokers")
app.register_blueprint(providers_routes, url_prefix="/api/providers")
app.register_blueprint(apis_routes, url_prefix="/api/apis")
app.register_blueprint(users_routes, url_prefix="/api/users")
app.register_blueprint(configuration_routes, url_prefix="/api")

@app.route("/api/options", methods=["OPTIONS"])
def handle_options():
    return "", 200


# @app.route("/api/configuration", methods=["OPTIONS"])
# def handle_options_conf():
#     return "", 200

# Configure JWT
app.config["JWT_SECRET_KEY"] = "super-secret"
jwt = JWTManager(app)
+161 −0
Original line number Diff line number Diff line
#!/usr/bin/env python3

from flask import Blueprint, jsonify
from ..core.operations import Operations
from flask_jwt_extended import jwt_required, get_jwt_identity
from flask_cors import cross_origin
import requests
from flask import request, make_response
import jsonschema
from jsonschema import validate, ValidationError


# create blueprint backoffice_routes
configuration_routes = Blueprint("configuration_routes", __name__)
operations = Operations()   # create operations object -> operations.py


@cross_origin()
@configuration_routes.route("/configuration", methods=["GET"])
@jwt_required()
def get_configuration():
    return operations.get_configuration()


@configuration_routes.route("/configuration/update-param", methods=["PATCH", "OPTIONS"])
@cross_origin()
@jwt_required()
def update_configuration_param():
    if request.method == "OPTIONS":
        return make_response("", 200)
    
    data = request.json
    param_path = data.get("param_path")
    new_value = data.get("new_value")

    if not param_path or new_value is None:
        return jsonify({"error": "param_path y new_value son requeridos"}), 400

    return operations.update_configuration_param(param_path, new_value)


@configuration_routes.route("/configuration/replace-config", methods=["PUT"])
@cross_origin()
@jwt_required()
def replace_configuration():
    """ Reemplaza toda la configuración con una nueva, verificando su estructura """
    new_config = request.json

    if not new_config:
        return jsonify({"error": "La nueva configuración no puede estar vacía"}), 400

    # Verificar estructura general
    required_keys = ["config_name", "version", "description", "settings"]
    for key in required_keys:
        if key not in new_config:
            return jsonify({"error": f"Falta la clave requerida: {key}"}), 400

    if not isinstance(new_config["settings"], dict) or not new_config["settings"]:
        return jsonify({"error": "'settings' debe ser un objeto con al menos una categoría"}), 400

    return operations.replace_configuration(new_config)


@configuration_routes.route("/configuration/add-category", methods=["POST"])
@cross_origin()
@jwt_required()
def add_new_category():
    """Añade una nueva categoría dentro de 'settings'."""
    data = request.json
    category_name = data.get("category_name")
    category_values = data.get("category_values")

    if not category_name or not category_values:
        return jsonify({"error": "category_name y category_values son requeridos"}), 400
    
    return operations.add_new_category(category_name, category_values)


@configuration_routes.route("/configuration/add-config-setting", methods=["PATCH"])
@cross_origin()
@jwt_required()
def add_new_config_setting():
    """Añade un nuevo parámetro dentro de una categoría en 'settings'."""
    data = request.json
    param_path = data.get("param_path")
    new_value = data.get("new_value")
    
    if not param_path or new_value is None:
        return jsonify({"error": "param_path y new_value son requeridos"}), 400
    
    return operations.add_new_config_setting(param_path, new_value)




### REGISTER CONFIGURATION ###

@cross_origin()
@configuration_routes.route("/configuration/register", methods=["GET"])
@jwt_required()
def get_register_configuration():
    """ Obtiene la configuración del register """
    return operations.get_register_configuration()


@cross_origin()
@configuration_routes.route("/configuration/register/update-param", methods=["PATCH"])
@jwt_required()
def update_register_configuration_param():
    """ Actualiza un único parámetro en la configuración del register """
    data = request.json
    param_path = data.get("param_path")
    new_value = data.get("new_value")

    if not param_path or new_value is None:
        return jsonify({"error": "param_path y new_value son requeridos"}), 400

    return operations.update_register_configuration_param(param_path, new_value)


@cross_origin()
@configuration_routes.route("/configuration/register/replace-config", methods=["PUT"])
@jwt_required()
def replace_register_configuration():
    """ Reemplaza toda la configuración del register con una nueva """
    new_config = request.json

    if not new_config:
        return jsonify({"error": "La nueva configuración no puede estar vacía"}), 400

    return operations.replace_register_configuration(new_config)


@cross_origin()
@configuration_routes.route("/configuration/register/add-category-config", methods=["POST"])
@jwt_required()
def add_new_config_regsiter_category():
    """Añade una nueva categoría dentro de 'settings' en el register."""
    data = request.json
    category_name = data.get("category_name")
    category_values = data.get("category_values")

    if not category_name or not category_values:
        return jsonify({"error": "category_name y category_values son requeridos"}), 400
    
    return operations.add_new_config_register_category(category_name, category_values)


@cross_origin()
@configuration_routes.route("/configuration/register/add-config-param-setting", methods=["PATCH"])
@jwt_required()
def add_new_config_register_setting():
    """Añade un nuevo parámetro dentro de una categoría en 'settings' en el register."""
    data = request.json
    param_path = data.get("param_path")
    new_value = data.get("new_value")
    
    if not param_path or new_value is None:
        return jsonify({"error": "param_path y new_value son requeridos"}), 400
    
    return operations.add_new_config_register_setting(param_path, new_value)
 No newline at end of file
+397 −0
Original line number Diff line number Diff line
@@ -895,3 +895,400 @@ class Operations:
        except requests.exceptions.RequestException as e:
            # Manejar errores de solicitud y devolver el mensaje de error
            return jsonify({"Error when retrieving number of APIs": str(e)}), 500
        

    
    def get_configuration(self):
        # Construimos la URL para la solicitud
        url = "https://{}/helper/getConfiguration".format(os.getenv('CAPIF_HOSTNAME'))

        try:
            # Realizamos la solicitud con los certificados y verificación del CA
            response = requests.get(url, verify="newcerts/ca_root.crt", cert=("newcerts/superadmin.crt", "newcerts/superadmin.key"))
            response.raise_for_status()  # Lanza una excepción si hay un error HTTP

            # Extraemos el JSON de la respuesta
            config_data = response.json()

            # Transformamos el JSON para devolverlo en un formato más manejable si es necesario
            transformed_data = {
                "configuration_name": config_data.get("config_name", ""),
                "description": config_data.get("description", ""),
                "settings": config_data.get("settings", {}),
                "version": config_data.get("version", "")
            }

            # Devolvemos los datos transformados
            return jsonify(transformed_data), response.status_code

        except requests.exceptions.RequestException as e:
            # Manejo de errores en caso de fallos en la solicitud
            return jsonify({"error": str(e)}), 500
        

    def update_configuration_param(self, param_path, new_value):
        """ Actualiza un único parámetro de la configuración """
        url = "https://{}/helper/updateConfigParam".format(os.getenv('CAPIF_HOSTNAME'))
        payload = {
            "param_path": param_path,
            "new_value": new_value
        }

        try:
            response = requests.patch(
                url,
                json=payload,
                verify="newcerts/ca_root.crt",
                cert=("newcerts/superadmin.crt", "newcerts/superadmin.key")
            )
            response.raise_for_status()
            return jsonify(response.json()), response.status_code

        except requests.exceptions.RequestException as e:
            return jsonify({"error": str(e)}), 500

    def replace_configuration(self, new_config):
        """ Reemplaza toda la configuración con una nueva """
        url = "https://{}/helper/replaceConfiguration".format(os.getenv('CAPIF_HOSTNAME'))

        try:
            response = requests.put(
                url,
                json=new_config,
                verify="newcerts/ca_root.crt",
                cert=("newcerts/superadmin.crt", "newcerts/superadmin.key")
            )
            response.raise_for_status()
            return jsonify(response.json()), response.status_code

        except requests.exceptions.RequestException as e:
            return jsonify({"error": str(e)}), 500
        

    def add_new_category(self, category_name, category_values):
        """Añade una nueva categoría de parámetros en 'settings'."""
        url = "https://{}/helper/addNewConfiguration".format(os.getenv('CAPIF_HOSTNAME'))
        payload = {
            "category_name": category_name,
            "category_values": category_values
        }
        
        try:
            response = requests.post(
                url,
                json=payload,
                verify="newcerts/ca_root.crt",
                cert=("newcerts/superadmin.crt", "newcerts/superadmin.key")
            )
            response.raise_for_status()
            return jsonify(response.json()), response.status_code
        except requests.exceptions.RequestException as e:
            return jsonify({"error": str(e)}), 500

    def add_new_config_setting(self, param_path, new_value):
        """Añade un nuevo parámetro en una categoría dentro de 'settings'."""
        url = "https://{}/helper/addNewConfigSetting".format(os.getenv('CAPIF_HOSTNAME'))
        payload = {
            "param_path": param_path,
            "new_value": new_value
        }
        
        try:
            response = requests.patch(
                url,
                json=payload,
                verify="newcerts/ca_root.crt",
                cert=("newcerts/superadmin.crt", "newcerts/superadmin.key")
            )
            response.raise_for_status()
            return jsonify(response.json()), response.status_code
        except requests.exceptions.RequestException as e:
            return jsonify({"error": str(e)}), 500
        

    
    ### REGISTER CONFIGURATION ###

    def get_register_configuration(self):
        """ Retrieve the current register configuration """

        def login():
            """ Obtain access token from register service """
            try:
                url = "https://{}/login".format(os.getenv('REGISTER_HOSTNAME'))

                print(f"DEBUG: Register login URL -> {url}", file=sys.stderr, flush=True)
                # print(f"DEBUG: Login response body: {response.text}", file=sys.stderr, flush=True)

                # print(f"DEBUG: Register login URL -> {url}")
                response = requests.post(
                    url,
                    auth=HTTPBasicAuth(self.username, self.password),
                    verify=False
                )
                print(f"DEBUG: Login response body: {response.text}", file=sys.stderr, flush=True)
                print(f"DEBUG: Login response body: {response}", file=sys.stderr, flush=True)
                if response.status_code == 200:
                    json_response = response.json()
                    access_token = json_response.get("access_token")
                    return access_token
            except requests.exceptions.RequestException as e:
                return None
            return None

        def fetch_configuration(token):
            """ Fetch register configuration using the access token """
            headers = {"Authorization": f"Bearer {token}"}
            try:
                url = "https://{}/configuration".format(os.getenv('REGISTER_HOSTNAME'))
                response = requests.get(url, headers=headers, verify=False)
                return response
            except requests.exceptions.RequestException as e:
                return None

        try:
            # Step 1: Get access token
            access_token = login()
            if not access_token:
                return jsonify({"error": "Unable to login and get access token"}), 401
            
            # Step 2: Fetch register configuration
            response = fetch_configuration(access_token)
            if response is None:
                return jsonify({"error": "Failed to connect to configuration endpoint"}), 500

            # Step 3: Return response
            if response.headers.get('Content-Type') == 'application/json':
                return jsonify(response.json()), response.status_code
            else:
                return (response.content, response.status_code, response.headers.items())

        except requests.exceptions.RequestException as e:
            return jsonify({"error": f"Error when fetching register configuration: {str(e)}"}), 500
        

    
    def update_register_configuration_param(self, param_path, new_value):
        """ Update a single parameter in the register configuration """

        def login():
            """ Obtain access token from register service """
            try:
                url = "https://{}/login".format(os.getenv('REGISTER_HOSTNAME'))
                print(f"DEBUG: Register login URL -> {url}", file=sys.stderr, flush=True)
                
                response = requests.post(
                    url,
                    auth=HTTPBasicAuth(self.username, self.password),
                    verify=False
                )
                
                print(f"DEBUG: Login response body: {response.text}", file=sys.stderr, flush=True)

                if response.status_code == 200:
                    json_response = response.json()
                    access_token = json_response.get("access_token")
                    return access_token
            except requests.exceptions.RequestException as e:
                print(f"ERROR: Failed to login -> {e}", file=sys.stderr, flush=True)
                return None
            return None

        def patch_configuration(token):
            """ Send PATCH request to update a single config parameter """
            headers = {
                "Authorization": f"Bearer {token}",
                "Content-Type": "application/json"
            }
            payload = {
                "param_path": param_path,
                "new_value": new_value
            }
            try:
                url = "https://{}/configuration".format(os.getenv('REGISTER_HOSTNAME'))
                response = requests.patch(url, json=payload, headers=headers, verify=False)
                return response
            except requests.exceptions.RequestException as e:
                print(f"ERROR: Failed to update config -> {e}", file=sys.stderr, flush=True)
                return None

        try:
            # Step 1: Get access token
            access_token = login()
            if not access_token:
                return jsonify({"error": "Unable to login and get access token"}), 401
            
            # Step 2: Send PATCH request to update the configuration
            response = patch_configuration(access_token)
            if response is None:
                return jsonify({"error": "Failed to connect to configuration endpoint"}), 500

            # Step 3: Return response
            if response.headers.get('Content-Type') == 'application/json':
                return jsonify(response.json()), response.status_code
            else:
                return (response.content, response.status_code, response.headers.items())

        except requests.exceptions.RequestException as e:
            return jsonify({"error": f"Error when updating register configuration: {str(e)}"}), 500
        


    def replace_register_configuration(self, new_config):
        """Replace the entire register configuration"""

        def login():
            """Obtain access token from register service"""
            try:
                url = "https://{}/login".format(os.getenv('REGISTER_HOSTNAME'))

                print(f"DEBUG: Register login URL -> {url}", file=sys.stderr, flush=True)
                response = requests.post(
                    url,
                    auth=HTTPBasicAuth(self.username, self.password),
                    verify=False
                )
                print(f"DEBUG: Login response body: {response.text}", file=sys.stderr, flush=True)
                
                if response.status_code == 200:
                    json_response = response.json()
                    return json_response.get("access_token")
            except requests.exceptions.RequestException as e:
                print(f"ERROR: Failed to login -> {str(e)}", file=sys.stderr, flush=True)
                return None
            return None

        def replace_configuration(token):
            """Replace the register configuration"""
            headers = {
                "Authorization": f"Bearer {token}",
                "Content-Type": "application/json"
            }
            try:
                url = "https://{}/configuration".format(os.getenv('REGISTER_HOSTNAME'))
                response = requests.put(url, json=new_config, headers=headers, verify=False)
                return response
            except requests.exceptions.RequestException as e:
                print(f"ERROR: Failed to replace configuration -> {str(e)}", file=sys.stderr, flush=True)
                return None

        try:
            # Step 1: Get access token
            access_token = login()
            if not access_token:
                return jsonify({"error": "Unable to login and get access token"}), 401
            
            # Step 2: Replace register configuration
            response = replace_configuration(access_token)
            if response is None:
                return jsonify({"error": "Failed to connect to configuration endpoint"}), 500

            # Step 3: Return response
            if response.headers.get('Content-Type') == 'application/json':
                return jsonify(response.json()), response.status_code
            else:
                return (response.content, response.status_code, response.headers.items())

        except requests.exceptions.RequestException as e:
            return jsonify({"error": f"Error when replacing register configuration: {str(e)}"}), 500
        



    def add_new_config_register_category(self, category_name, category_values):
        """Añade una nueva categoría de parámetros en 'settings' en el register."""
        def login():
            try:
                url = "https://{}/login".format(os.getenv('REGISTER_HOSTNAME'))
                response = requests.post(
                    url,
                    auth=HTTPBasicAuth(self.username, self.password),
                    verify=False
                )
                if response.status_code == 200:
                    return response.json().get("access_token")
            except requests.exceptions.RequestException as e:
                return None
            return None

        def post_category(token):
            headers = {
                "Authorization": f"Bearer {token}",
                "Content-Type": "application/json"
            }
            payload = {
                "category_name": category_name,
                "category_values": category_values
            }
            try:
                url = "https://{}/configuration/addNewCategory".format(os.getenv('REGISTER_HOSTNAME'))
                response = requests.post(url, json=payload, headers=headers, verify=False)
                return response
            except requests.exceptions.RequestException as e:
                return None

        try:
            access_token = login()
            if not access_token:
                return jsonify({"error": "Unable to login and get access token"}), 401
            
            response = post_category(access_token)
            if response is None:
                return jsonify({"error": "Failed to connect to configuration endpoint"}), 500
            
            if response.headers.get('Content-Type') == 'application/json':
                return jsonify(response.json()), response.status_code
            else:
                return (response.content, response.status_code, response.headers.items())
        except requests.exceptions.RequestException as e:
            return jsonify({"error": f"Error when adding category: {str(e)}"}), 500


    def add_new_config_register_setting(self, param_path, new_value):
        """Añade un nuevo parámetro en una categoría dentro de 'settings' en el register."""
        def login():
            try:
                url = "https://{}/login".format(os.getenv('REGISTER_HOSTNAME'))
                response = requests.post(
                    url,
                    auth=HTTPBasicAuth(self.username, self.password),
                    verify=False
                )
                if response.status_code == 200:
                    return response.json().get("access_token")
            except requests.exceptions.RequestException as e:
                return None
            return None

        def patch_config_setting(token):
            headers = {
                "Authorization": f"Bearer {token}",
                "Content-Type": "application/json"
            }
            payload = {
                "param_path": param_path,
                "new_value": new_value
            }
            try:
                url = "https://{}/configuration/addNewParamConfigSetting".format(os.getenv('REGISTER_HOSTNAME'))
                response = requests.patch(url, json=payload, headers=headers, verify=False)
                return response
            except requests.exceptions.RequestException as e:
                return None

        try:
            access_token = login()
            if not access_token:
                return jsonify({"error": "Unable to login and get access token"}), 401
            
            response = patch_config_setting(access_token)
            if response is None:
                return jsonify({"error": "Failed to connect to configuration endpoint"}), 500
            
            if response.headers.get('Content-Type') == 'application/json':
                return jsonify(response.json()), response.status_code
            else:
                return (response.content, response.status_code, response.headers.items())
        except requests.exceptions.RequestException as e:
            return jsonify({"error": f"Error when adding config setting: {str(e)}"}), 500
            
 No newline at end of file
+33 −33

File changed.

Preview size limit exceeded, changes collapsed.

+50 −50

File changed.

Preview size limit exceeded, changes collapsed.

Loading