126 lines
4.7 KiB
Python
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)
|