Commit f7a83208 authored by Jorge Moratinos's avatar Jorge Moratinos
Browse files

First review

parent 4bd5e02e
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -4,9 +4,9 @@ RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

COPY requirements.txt /usr/src/app/requirements.txt
COPY backoffice_service/certs2/ca_root.crt /etc/ssl/certs/
COPY backoffice_service/certs2/superadmin.crt /etc/ssl/certs/
COPY backoffice_service/certs2/superadmin.key /etc/ssl/private/
# COPY backoffice_service/certs2/ca_root.crt /etc/ssl/certs/
# COPY backoffice_service/certs2/superadmin.crt /etc/ssl/certs/
# COPY backoffice_service/certs2/superadmin.key /etc/ssl/private/

RUN apk add -U --no-cache gcc build-base linux-headers ca-certificates libffi-dev libressl-dev libxslt-dev
RUN pip3 install --upgrade --no-cache-dir -r requirements.txt
@@ -15,8 +15,8 @@ RUN apk add jq
RUN apk add curl
RUN apk add redis

# Copiar el script generate_certs.py
COPY backoffice_service/generate_certs.py /usr/src/app/generate_certs.py
# # Copiar el script generate_certs.py
# COPY backoffice_service/generate_certs.py /usr/src/app/generate_certs.py

COPY . /usr/src/app

+38 −31
Original line number Diff line number Diff line
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
import json
import requests
import os
from cryptography import x509
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.x509.oid import NameOID
from .controllers.default_controller import backoffice_routes
from .controllers.invokers_controller import invokers_routes
from .controllers.providers_controller import providers_routes
@@ -17,10 +20,10 @@ from flask_cors import CORS
# Create Flask app
app = Flask(__name__)

# Configurar CORS correctamente
# Configure CORS correctly
CORS(app, supports_credentials=True, allow_headers=["Content-Type", "Authorization"])

# Manejo global de preflight OPTIONS
# Global handling for preflight OPTIONS requests
@app.before_request
def handle_preflight():
    if request.method == "OPTIONS":
@@ -52,36 +55,40 @@ def handle_options():
app.config["JWT_SECRET_KEY"] = "super-secret"
jwt = JWTManager(app)

# create public/PRIVATE key
key = PKey()
key.generate_key(TYPE_RSA, 2048)
# create public/private key
key = rsa.generate_private_key(public_exponent=65537, key_size=2048)

# Generate CSR
req = X509Req()

req.get_subject().O = 'Telefonica I+D'
req.get_subject().OU = 'Innovation'
req.get_subject().L = 'Madrid'
req.get_subject().ST = 'Madrid'
req.get_subject().C = 'ES'
req.get_subject().emailAddress = 'inno@tid.es'
req.set_pubkey(key)
req.sign(key, 'sha256')

# Get CSR
csr_request = dump_certificate_request(FILETYPE_PEM, req)
subject = x509.Name([
    x509.NameAttribute(NameOID.ORGANIZATION_NAME, 'Telefonica I+D'),
    x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, 'Innovation'),
    x509.NameAttribute(NameOID.LOCALITY_NAME, 'Madrid'),
    x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, 'Madrid'),
    x509.NameAttribute(NameOID.COUNTRY_NAME, 'ES'),
    x509.NameAttribute(NameOID.EMAIL_ADDRESS, 'inno@tid.es'),
])
csr_request = (
    x509.CertificateSigningRequestBuilder()
    .subject_name(subject)
    .sign(key, hashes.SHA256())
    .public_bytes(serialization.Encoding.PEM)
)

# Get private key
private_key = dump_privatekey(FILETYPE_PEM, key)
private_key = key.private_bytes(
    encoding=serialization.Encoding.PEM,
    format=serialization.PrivateFormat.PKCS8,
    encryption_algorithm=serialization.NoEncryption(),
)

# Leer variable de entorno para determinar si se carga desde Vault o desde variables de entorno
# Read environment variable to determine whether to load from Vault or from environment variables
LOAD_FROM_VAULT = os.getenv('LOAD_FROM_VAULT', 'true').lower() == 'true'

# Ensure the certs directory exists
os.makedirs('newcerts', exist_ok=True)

if LOAD_FROM_VAULT:
    # Cargar certificados desde Vault
    # Load certificates from Vault
    print(f"Using Vault token: {os.getenv('VAULT_TOKEN')}")

    # Get ca.cert from Vault
@@ -90,7 +97,7 @@ if LOAD_FROM_VAULT:
    headers = {'X-Vault-Token': os.getenv('VAULT_TOKEN')}
    response = requests.request("GET", url, headers=headers, verify=False)

    # Imprimir el contenido completo de la respuesta para inspección
    # Print the full response content for inspection
    print("Response from Vault (ca.cert request):")
    print(response)

@@ -106,7 +113,7 @@ if LOAD_FROM_VAULT:
    data = {
        'format': 'pem_bundle',
        'ttl': '43000h',
        'csr': csr_request,
        'csr': csr_request.decode('utf-8'),
        'common_name': "superadmin"
    }
    response = requests.request("POST", url, headers=headers, data=data, verify=False)
@@ -123,24 +130,24 @@ if LOAD_FROM_VAULT:
    certification_file.close()

else:
    # Cargar certificados desde variables de entorno
    # Load certificates from environment variables
    ca_cert = os.getenv('CA_CERT')
    private_key_content = os.getenv('PRIVATE_KEY')
    backoffice_cert_content = os.getenv('BACKOFFICE_CERT')

    if not ca_cert or not private_key_content or not backoffice_cert_content:
        print("Error: Las variables de entorno CA_CERT, PRIVATE_KEY y BACKOFFICE_CERT deben estar definidas")
        print("Error: Environment variables CA_CERT, PRIVATE_KEY, and BACKOFFICE_CERT must be defined")
        exit(1)

    # Guardar el certificado CA
    # Save the CA certificate
    with open('newcerts/ca_root.crt', 'wb+') as ca_file:
        ca_file.write(ca_cert.replace('\\n', '\n').encode('utf-8'))

    # Guardar la clave privada
    # Save the private key
    with open('newcerts/superadmin.key', 'wb+') as private_key_file:
        private_key_file.write(private_key_content.replace('\\n', '\n').encode('utf-8'))

    # Guardar el certificado de backoffice
    # Save the backoffice certificate
    with open('newcerts/superadmin.crt', 'wb+') as certification_file:
        certification_file.write(backoffice_cert_content.replace('\\n', '\n').encode('utf-8'))

+18 −15
Original line number Diff line number Diff line
@@ -19,17 +19,19 @@ def login():
    print("username: ", username)
    print("password: ", password)

    if username != "superadmin" or password != "LzVgyRxi":
    # Check if the username and password are correct
    # TODO: Implement proper authentication mechanism (e.g., check against a database)
    if username != "superadmin" or password != "admin":
        print("Bad username or password") 
        return jsonify({"msg": "Bad username or password"}), 401

    # Configurar la expiración del token a 24 horas
    # Configure token expiration to 24 hours
    # expires = timedelta(hours=8)
    # expires_refresh = timedelta(days=30)

     # Configurar la expiración del token de acceso a 5 minutos
     # Configure access token expiration to 5 minutes
    expires = timedelta(minutes=120)
    # Configurar la expiración del token de refresco a 10 minutos
    # Configure refresh token expiration to 10 minutes
    expires_refresh = timedelta(minutes=240)

    # identity is a data that can be serialized in json -> username = superadmin
@@ -47,15 +49,16 @@ def refresh():

    current_user = get_jwt_identity()

    # Configurar la expiración del nuevo token de acceso a 8 horas
    # Configure new access token expiration to 8 hours
    expires = timedelta(hours=8)
    new_access_token = create_access_token(identity=current_user, expires_delta=expires)

    return jsonify(access_token=new_access_token)

# al hacer F5 en la página, si hay un JWT en las cookies tienes que saber si ese JWT es válido, y traerte los datos del usuario que te puedan interesar del backend
# 401 si el token no es válido, para que el front lo refresque
# 200 si es válido
# when pressing F5 on the page, if there is a JWT in cookies, you must verify whether that JWT is valid
# and fetch any user data from the backend that may be relevant
# 401 if the token is not valid, so the frontend can refresh it
# 200 if it is valid
@cross_origin()
@access_routes.route('/auth/me', methods=["GET", "OPTIONS"])
@jwt_required()
@@ -63,8 +66,8 @@ def authme():
    if request.method == "OPTIONS":
        return jsonify(message="CORS options OK"), 200

    # Puedes obtener la identidad del usuario del token con get_jwt_identity()
    # You can get the user identity from the token with get_jwt_identity()
    current_user = get_jwt_identity()

    # Si llegamos aquí, el token es válido, así que puedes devolver 200 OK
    return jsonify(message="Token válido", user=current_user), 200
    # If we get here, the token is valid, so you can return 200 OK
    return jsonify(message="Valid token", user=current_user), 200
+25 −17
Original line number Diff line number Diff line
import os
import json
import requests
from OpenSSL.crypto import PKey, TYPE_RSA, X509Req, dump_certificate_request, dump_privatekey, FILETYPE_PEM
from cryptography import x509
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.x509.oid import NameOID

# Configure JWT (dummy example, not used in this script)
JWT_SECRET_KEY = "super-secret"

# create public/PRIVATE key
key = PKey()
key.generate_key(TYPE_RSA, 2048)
# create public/private key
key = rsa.generate_private_key(public_exponent=65537, key_size=2048)

# Generate CSR
req = X509Req()
req.get_subject().O = 'Telefonica I+D'
req.get_subject().OU = 'Innovation'
req.get_subject().L = 'Madrid'
req.get_subject().ST = 'Madrid'
req.get_subject().C = 'ES'
req.get_subject().emailAddress = 'inno@tid.es'
req.set_pubkey(key)
req.sign(key, 'sha256')

# Get CSR
csr_request = dump_certificate_request(FILETYPE_PEM, req)
subject = x509.Name([
    x509.NameAttribute(NameOID.ORGANIZATION_NAME, 'Telefonica I+D'),
    x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, 'Innovation'),
    x509.NameAttribute(NameOID.LOCALITY_NAME, 'Madrid'),
    x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, 'Madrid'),
    x509.NameAttribute(NameOID.COUNTRY_NAME, 'ES'),
    x509.NameAttribute(NameOID.EMAIL_ADDRESS, 'inno@tid.es'),
])
csr_request = (
    x509.CertificateSigningRequestBuilder()
    .subject_name(subject)
    .sign(key, hashes.SHA256())
    .public_bytes(serialization.Encoding.PEM)
)

# Get private key
private_key = dump_privatekey(FILETYPE_PEM, key)
private_key = key.private_bytes(
    encoding=serialization.Encoding.PEM,
    format=serialization.PrivateFormat.PKCS8,
    encryption_algorithm=serialization.NoEncryption(),
)

# Get ca.cert from vault
VAULT_HOSTNAME = os.getenv('VAULT_HOSTNAME')
+34 −34
Original line number Diff line number Diff line
-----BEGIN CERTIFICATE-----
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
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
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
-----END CERTIFICATE-----
Loading