Files
SKEEN-Proyecto/odoo-addons/skeen_plataforma/controllers/api_keys.py

126 lines
4.7 KiB
Python

# -*- coding: utf-8 -*-
"""CRUD de claves de API de terceros (Configuración -> API)."""
import json
from odoo import http
from odoo.http import request, Response
from odoo.addons.skeen_whatsapp.controllers.auth import require_role, require_perm
from odoo.addons.skeen_plataforma.models.api_key import SCOPES
BASE = '/skeen/frontend/v1'
def _json(data, status=200):
return Response(
json.dumps(data, default=str),
status=status,
mimetype='application/json',
headers={
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
},
)
def _body():
try:
raw = request.httprequest.get_data(as_text=True)
return json.loads(raw) if raw else {}
except Exception:
return {}
def _login():
return getattr(request.frontend_user, 'login', '') if hasattr(request, 'frontend_user') else ''
class SkeenApiKeysController(http.Controller):
@http.route(BASE + '/api_keys', type='http', auth='none',
methods=['GET', 'OPTIONS'], csrf=False)
@require_role('gerencia')
@require_perm('api.claves')
def list_api_keys(self, **kw):
try:
keys = request.env['skeen.api.key'].sudo().search([])
return _json({
'status': 'success',
'api_keys': [k.to_public_dict() for k in keys],
'scopes': [{'clave': c, 'label': l} for c, l in SCOPES],
})
except Exception as e:
return _json({'status': 'error', 'message': str(e)}, 500)
@http.route(BASE + '/api_keys', type='http', auth='none',
methods=['POST', 'OPTIONS'], csrf=False)
@require_role('gerencia')
@require_perm('api.claves')
def create_api_key(self, **kw):
try:
data = _body()
nombre = (data.get('name') or '').strip()
if not nombre:
return _json({'status': 'error', 'message': 'El nombre es obligatorio'}, 400)
key, raw = request.env['skeen.api.key'].sudo().generar({
'name': nombre,
'scopes': data.get('scopes') or [],
'vence': data.get('vence') or False,
'notas': data.get('notas') or '',
}, login=_login())
return _json({
'status': 'success',
'clave': raw, # se muestra UNA sola vez
'api_key': key.to_public_dict(),
'message': 'Guarda esta clave: no se volverá a mostrar.',
})
except Exception as e:
request.env.cr.rollback()
return _json({'status': 'error', 'message': str(e)}, 500)
@http.route(BASE + '/api_keys/<int:key_id>', type='http', auth='none',
methods=['PUT', 'OPTIONS'], csrf=False)
@require_role('gerencia')
@require_perm('api.claves')
def update_api_key(self, key_id, **kw):
try:
key = request.env['skeen.api.key'].sudo().browse(key_id)
if not key.exists():
return _json({'status': 'error', 'message': 'Clave no encontrada'}, 404)
data = _body()
vals = {}
if 'name' in data and (data.get('name') or '').strip():
vals['name'] = data['name'].strip()
if 'scopes' in data:
vals['scopes'] = json.dumps(key._normalizar_scopes(data.get('scopes') or []))
if 'activo' in data:
vals['activo'] = bool(data['activo'])
if 'vence' in data:
vals['vence'] = data.get('vence') or False
if 'notas' in data:
vals['notas'] = data.get('notas') or ''
if vals:
key.write(vals)
return _json({'status': 'success', 'api_key': key.to_public_dict()})
except Exception as e:
request.env.cr.rollback()
return _json({'status': 'error', 'message': str(e)}, 500)
@http.route(BASE + '/api_keys/<int:key_id>/revocar', type='http', auth='none',
methods=['POST', 'OPTIONS'], csrf=False)
@require_role('gerencia')
@require_perm('api.claves')
def revocar_api_key(self, key_id, **kw):
try:
key = request.env['skeen.api.key'].sudo().browse(key_id)
if not key.exists():
return _json({'status': 'error', 'message': 'Clave no encontrada'}, 404)
key.action_revocar(login=_login())
return _json({'status': 'success', 'message': 'Clave revocada.',
'api_key': key.to_public_dict()})
except Exception as e:
request.env.cr.rollback()
return _json({'status': 'error', 'message': str(e)}, 500)