feat: update auth logic
This commit is contained in:
@@ -7,15 +7,3 @@ class ILegalEntityRepository(ABC):
|
|||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def get_by_user_id(self, user_id: str) -> LegalEntityEntity | None:
|
async def get_by_user_id(self, user_id: str) -> LegalEntityEntity | None:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
async def get_by_id(self, organization_id: str) -> LegalEntityEntity:
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
async def list_all(self, *, limit: int, offset: int) -> list[LegalEntityEntity]:
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
async def count_all(self) -> int:
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
from src.application.commands.organization_commands import (
|
from src.application.commands.organization_commands import GetOrganizationCommand
|
||||||
GetOrganizationCommand,
|
|
||||||
ListOrganizationsCommand,
|
|
||||||
)
|
|
||||||
from src.application.commands.organization_wallet_commands import (
|
from src.application.commands.organization_wallet_commands import (
|
||||||
GetOrganizationMnemonicCommand,
|
GetOrganizationMnemonicCommand,
|
||||||
GetOrganizationSecretKeysCommand,
|
GetOrganizationSecretKeysCommand,
|
||||||
|
|||||||
@@ -1,28 +1,17 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from src.application.abstractions import IUnitOfWork
|
from src.application.abstractions import IUnitOfWork
|
||||||
|
from src.application.commands.legal_entity_guard import require_legal_entity
|
||||||
from src.application.contracts import ILogger
|
from src.application.contracts import ILogger
|
||||||
from src.application.domain.entities.legal_entity import LegalEntityEntity
|
from src.application.domain.entities.legal_entity import LegalEntityEntity
|
||||||
from src.infrastructure.database.decorators import transactional
|
from src.infrastructure.database.decorators import transactional
|
||||||
|
|
||||||
|
|
||||||
class ListOrganizationsCommand:
|
|
||||||
def __init__(self, unit_of_work: IUnitOfWork, logger: ILogger):
|
|
||||||
self._unit_of_work = unit_of_work
|
|
||||||
self._logger = logger
|
|
||||||
|
|
||||||
@transactional
|
|
||||||
async def __call__(self, *, limit: int = 50, offset: int = 0) -> tuple[list[LegalEntityEntity], int]:
|
|
||||||
items = await self._unit_of_work.legal_entity_repository.list_all(limit=limit, offset=offset)
|
|
||||||
total = await self._unit_of_work.legal_entity_repository.count_all()
|
|
||||||
return items, total
|
|
||||||
|
|
||||||
|
|
||||||
class GetOrganizationCommand:
|
class GetOrganizationCommand:
|
||||||
def __init__(self, unit_of_work: IUnitOfWork, logger: ILogger):
|
def __init__(self, unit_of_work: IUnitOfWork, logger: ILogger):
|
||||||
self._unit_of_work = unit_of_work
|
self._unit_of_work = unit_of_work
|
||||||
self._logger = logger
|
self._logger = logger
|
||||||
|
|
||||||
@transactional
|
@transactional
|
||||||
async def __call__(self, organization_id: str) -> LegalEntityEntity:
|
async def __call__(self, user_id: str) -> LegalEntityEntity:
|
||||||
return await self._unit_of_work.legal_entity_repository.get_by_id(organization_id)
|
return await require_legal_entity(user_id, self._unit_of_work)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from src.application.abstractions import IUnitOfWork
|
from src.application.abstractions import IUnitOfWork
|
||||||
|
from src.application.commands.legal_entity_guard import require_legal_entity
|
||||||
from src.application.contracts import ILogger
|
from src.application.contracts import ILogger
|
||||||
from src.application.domain.entities.legal_entity import LegalEntityEntity
|
from src.application.domain.entities.legal_entity import LegalEntityEntity
|
||||||
from src.application.domain.entities.organization_wallet import OrganizationWalletEntity
|
from src.application.domain.entities.organization_wallet import OrganizationWalletEntity
|
||||||
@@ -20,9 +21,9 @@ class ListOrganizationWalletsCommand:
|
|||||||
self._logger = logger
|
self._logger = logger
|
||||||
|
|
||||||
@transactional
|
@transactional
|
||||||
async def __call__(self, organization_id: str) -> list[OrganizationWalletEntity]:
|
async def __call__(self, user_id: str) -> list[OrganizationWalletEntity]:
|
||||||
await self._unit_of_work.legal_entity_repository.get_by_id(organization_id)
|
org = await require_legal_entity(user_id, self._unit_of_work)
|
||||||
return await self._unit_of_work.organization_wallet_repository.list_by_organization(organization_id)
|
return await self._unit_of_work.organization_wallet_repository.list_by_organization(org.id)
|
||||||
|
|
||||||
|
|
||||||
class GetOrganizationMnemonicCommand:
|
class GetOrganizationMnemonicCommand:
|
||||||
@@ -31,14 +32,14 @@ class GetOrganizationMnemonicCommand:
|
|||||||
self._logger = logger
|
self._logger = logger
|
||||||
|
|
||||||
@transactional
|
@transactional
|
||||||
async def __call__(self, organization_id: str) -> str:
|
async def __call__(self, user_id: str) -> str:
|
||||||
org = await self._require_wallets_org(organization_id)
|
org = await self._require_wallets_org(user_id)
|
||||||
if not is_crypto_ready():
|
if not is_crypto_ready():
|
||||||
raise ServiceUnavailableException(message='Crypto service not ready')
|
raise ServiceUnavailableException(message='Crypto service not ready')
|
||||||
return decrypt_mnemonic(org.encrypted_mnemonic or '')
|
return decrypt_mnemonic(org.encrypted_mnemonic or '')
|
||||||
|
|
||||||
async def _require_wallets_org(self, organization_id: str) -> LegalEntityEntity:
|
async def _require_wallets_org(self, user_id: str) -> LegalEntityEntity:
|
||||||
org = await self._unit_of_work.legal_entity_repository.get_by_id(organization_id)
|
org = await require_legal_entity(user_id, self._unit_of_work)
|
||||||
if not org.encrypted_mnemonic:
|
if not org.encrypted_mnemonic:
|
||||||
raise NotFoundException(message='Wallets not created for organization')
|
raise NotFoundException(message='Wallets not created for organization')
|
||||||
return org
|
return org
|
||||||
@@ -50,15 +51,15 @@ class GetOrganizationSecretKeysCommand:
|
|||||||
self._logger = logger
|
self._logger = logger
|
||||||
|
|
||||||
@transactional
|
@transactional
|
||||||
async def __call__(self, organization_id: str) -> list[DerivedSecretKey]:
|
async def __call__(self, user_id: str) -> list[DerivedSecretKey]:
|
||||||
org = await self._require_wallets_org(organization_id)
|
org = await self._require_wallets_org(user_id)
|
||||||
if not is_crypto_ready():
|
if not is_crypto_ready():
|
||||||
raise ServiceUnavailableException(message='Crypto service not ready')
|
raise ServiceUnavailableException(message='Crypto service not ready')
|
||||||
mnemonic = decrypt_mnemonic(org.encrypted_mnemonic or '')
|
mnemonic = decrypt_mnemonic(org.encrypted_mnemonic or '')
|
||||||
return derive_all_private_keys(mnemonic)
|
return derive_all_private_keys(mnemonic)
|
||||||
|
|
||||||
async def _require_wallets_org(self, organization_id: str) -> LegalEntityEntity:
|
async def _require_wallets_org(self, user_id: str) -> LegalEntityEntity:
|
||||||
org = await self._unit_of_work.legal_entity_repository.get_by_id(organization_id)
|
org = await require_legal_entity(user_id, self._unit_of_work)
|
||||||
if not org.encrypted_mnemonic:
|
if not org.encrypted_mnemonic:
|
||||||
raise NotFoundException(message='Wallets not created for organization')
|
raise NotFoundException(message='Wallets not created for organization')
|
||||||
return org
|
return org
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
from src.application.domain.dto.token import AccessTokenPayload, AdminAuthContext, AuthContext
|
from src.application.domain.dto.token import AccessTokenPayload, AuthContext
|
||||||
from src.application.domain.dto.keys import JwtPublicKey, JwtPublicKeySet
|
from src.application.domain.dto.keys import JwtPublicKey, JwtPublicKeySet
|
||||||
@@ -4,8 +4,7 @@ from pydantic import BaseModel
|
|||||||
class AccessTokenPayload(BaseModel):
|
class AccessTokenPayload(BaseModel):
|
||||||
sub: str
|
sub: str
|
||||||
type: str
|
type: str
|
||||||
sid: str | None = None
|
sid: str
|
||||||
role: str | None = None
|
|
||||||
iat: int
|
iat: int
|
||||||
nbf: int
|
nbf: int
|
||||||
exp: int
|
exp: int
|
||||||
@@ -17,8 +16,3 @@ class AuthContext(BaseModel):
|
|||||||
user_id: str
|
user_id: str
|
||||||
sid: str
|
sid: str
|
||||||
token: AccessTokenPayload
|
token: AccessTokenPayload
|
||||||
|
|
||||||
|
|
||||||
class AdminAuthContext(BaseModel):
|
|
||||||
admin_user_id: str
|
|
||||||
role: str
|
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from sqlalchemy import func, select
|
from sqlalchemy import select
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
from sqlalchemy.exc import SQLAlchemyError
|
from sqlalchemy.exc import SQLAlchemyError
|
||||||
|
|
||||||
from src.application.abstractions.repositories.i_legal_entity_repository import ILegalEntityRepository
|
from src.application.abstractions.repositories.i_legal_entity_repository import ILegalEntityRepository
|
||||||
from src.application.contracts import ILogger
|
from src.application.contracts import ILogger
|
||||||
from src.application.domain.entities.legal_entity import LegalEntityEntity
|
from src.application.domain.entities.legal_entity import LegalEntityEntity
|
||||||
from src.application.domain.exceptions import InternalException, NotFoundException
|
from src.application.domain.exceptions import InternalException
|
||||||
from src.infrastructure.database.models.legal_entity import LegalEntityModel
|
from src.infrastructure.database.models.legal_entity import LegalEntityModel
|
||||||
|
|
||||||
|
|
||||||
@@ -52,39 +52,3 @@ class LegalEntityRepository(ILegalEntityRepository):
|
|||||||
self._logger.exception(str(exc))
|
self._logger.exception(str(exc))
|
||||||
raise InternalException(message=f'Database error: {exc}') from exc
|
raise InternalException(message=f'Database error: {exc}') from exc
|
||||||
|
|
||||||
async def get_by_id(self, organization_id: str) -> LegalEntityEntity:
|
|
||||||
try:
|
|
||||||
stmt = select(LegalEntityModel).where(LegalEntityModel.id == organization_id)
|
|
||||||
result = await self._session.execute(stmt)
|
|
||||||
model = result.scalar_one_or_none()
|
|
||||||
if model is None:
|
|
||||||
raise NotFoundException(message='Organization not found')
|
|
||||||
return self._to_entity(model)
|
|
||||||
except NotFoundException:
|
|
||||||
raise
|
|
||||||
except SQLAlchemyError as exc:
|
|
||||||
self._logger.exception(str(exc))
|
|
||||||
raise InternalException(message=f'Database error: {exc}') from exc
|
|
||||||
|
|
||||||
async def list_all(self, *, limit: int, offset: int) -> list[LegalEntityEntity]:
|
|
||||||
try:
|
|
||||||
stmt = (
|
|
||||||
select(LegalEntityModel)
|
|
||||||
.order_by(LegalEntityModel.created_at.desc())
|
|
||||||
.limit(limit)
|
|
||||||
.offset(offset)
|
|
||||||
)
|
|
||||||
result = await self._session.execute(stmt)
|
|
||||||
return [self._to_entity(m) for m in result.scalars().all()]
|
|
||||||
except SQLAlchemyError as exc:
|
|
||||||
self._logger.exception(str(exc))
|
|
||||||
raise InternalException(message=f'Database error: {exc}') from exc
|
|
||||||
|
|
||||||
async def count_all(self) -> int:
|
|
||||||
try:
|
|
||||||
stmt = select(func.count()).select_from(LegalEntityModel)
|
|
||||||
result = await self._session.execute(stmt)
|
|
||||||
return int(result.scalar_one())
|
|
||||||
except SQLAlchemyError as exc:
|
|
||||||
self._logger.exception(str(exc))
|
|
||||||
raise InternalException(message=f'Database error: {exc}') from exc
|
|
||||||
|
|||||||
@@ -23,8 +23,7 @@ class JwtService(IJwtService):
|
|||||||
return AccessTokenPayload(
|
return AccessTokenPayload(
|
||||||
sub=str(payload['sub']),
|
sub=str(payload['sub']),
|
||||||
type='access',
|
type='access',
|
||||||
sid=str(payload['sid']) if payload.get('sid') else None,
|
sid=str(payload['sid']),
|
||||||
role=str(payload['role']) if payload.get('role') else None,
|
|
||||||
iat=int(payload['iat']),
|
iat=int(payload['iat']),
|
||||||
nbf=int(payload['nbf']),
|
nbf=int(payload['nbf']),
|
||||||
exp=int(payload['exp']),
|
exp=int(payload['exp']),
|
||||||
@@ -84,9 +83,9 @@ class JwtService(IJwtService):
|
|||||||
options=options,
|
options=options,
|
||||||
)
|
)
|
||||||
|
|
||||||
if 'sid' not in payload and 'role' not in payload:
|
if 'sid' not in payload:
|
||||||
self._logger.warning(f'JWT missing sid or role claim kid={kid}')
|
self._logger.warning(f'JWT missing sid claim kid={kid}')
|
||||||
raise ApplicationException(status_code=401, message='Missing token claim: sid or role')
|
raise ApplicationException(status_code=401, message='Missing token claim: sid')
|
||||||
|
|
||||||
if 'type' not in payload:
|
if 'type' not in payload:
|
||||||
self._logger.warning(f'JWT missing type claim kid={kid}')
|
self._logger.warning(f'JWT missing type claim kid={kid}')
|
||||||
|
|||||||
@@ -1,47 +0,0 @@
|
|||||||
from fastapi import Depends, Request
|
|
||||||
from fastapi.security.utils import get_authorization_scheme_param
|
|
||||||
|
|
||||||
from src.application.contracts import IJwtService
|
|
||||||
from src.application.domain.dto import AdminAuthContext
|
|
||||||
from src.application.domain.exceptions import ForbiddenException, UnauthorizedException
|
|
||||||
from src.presentation.dependencies.security import get_jwt_service
|
|
||||||
|
|
||||||
|
|
||||||
def _extract_bearer_token(request: Request) -> str | None:
|
|
||||||
auth = request.headers.get('Authorization')
|
|
||||||
if not auth:
|
|
||||||
return None
|
|
||||||
scheme, param = get_authorization_scheme_param(auth)
|
|
||||||
if scheme.lower() == 'bearer' and param:
|
|
||||||
return param
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
async def require_admin_access(
|
|
||||||
request: Request,
|
|
||||||
jwt_service: IJwtService = Depends(get_jwt_service),
|
|
||||||
) -> AdminAuthContext:
|
|
||||||
token = _extract_bearer_token(request)
|
|
||||||
if not token:
|
|
||||||
raise UnauthorizedException(message='Authorization Bearer token required')
|
|
||||||
|
|
||||||
payload = await jwt_service.decode_access_token(token)
|
|
||||||
if payload.type != 'access':
|
|
||||||
raise UnauthorizedException(message='Invalid token type')
|
|
||||||
|
|
||||||
role = payload.role
|
|
||||||
if not role:
|
|
||||||
raise UnauthorizedException(message='Token missing role')
|
|
||||||
|
|
||||||
return AdminAuthContext(admin_user_id=payload.sub, role=role)
|
|
||||||
|
|
||||||
|
|
||||||
def require_admin_role(*allowed_roles: str):
|
|
||||||
allowed = set(allowed_roles)
|
|
||||||
|
|
||||||
async def dependency(auth: AdminAuthContext = Depends(require_admin_access)) -> AdminAuthContext:
|
|
||||||
if auth.role not in allowed:
|
|
||||||
raise ForbiddenException(message='Insufficient permissions')
|
|
||||||
return auth
|
|
||||||
|
|
||||||
return dependency
|
|
||||||
@@ -7,7 +7,6 @@ from src.application.commands import (
|
|||||||
GetOrganizationSecretKeysCommand,
|
GetOrganizationSecretKeysCommand,
|
||||||
GetPurchaseRequestCommand,
|
GetPurchaseRequestCommand,
|
||||||
ListOrganizationWalletsCommand,
|
ListOrganizationWalletsCommand,
|
||||||
ListOrganizationsCommand,
|
|
||||||
ListPurchaseRequestsCommand,
|
ListPurchaseRequestsCommand,
|
||||||
)
|
)
|
||||||
from src.application.contracts import ILogger
|
from src.application.contracts import ILogger
|
||||||
@@ -36,13 +35,6 @@ def get_get_purchase_request_command(
|
|||||||
return GetPurchaseRequestCommand(unit_of_work=unit_of_work, logger=logger)
|
return GetPurchaseRequestCommand(unit_of_work=unit_of_work, logger=logger)
|
||||||
|
|
||||||
|
|
||||||
def get_list_organizations_command(
|
|
||||||
logger: ILogger = Depends(get_logger),
|
|
||||||
unit_of_work: IUnitOfWork = Depends(get_unit_of_work),
|
|
||||||
) -> ListOrganizationsCommand:
|
|
||||||
return ListOrganizationsCommand(unit_of_work=unit_of_work, logger=logger)
|
|
||||||
|
|
||||||
|
|
||||||
def get_get_organization_command(
|
def get_get_organization_command(
|
||||||
logger: ILogger = Depends(get_logger),
|
logger: ILogger = Depends(get_logger),
|
||||||
unit_of_work: IUnitOfWork = Depends(get_unit_of_work),
|
unit_of_work: IUnitOfWork = Depends(get_unit_of_work),
|
||||||
|
|||||||
@@ -1,24 +1,21 @@
|
|||||||
from fastapi import APIRouter, Depends, Query
|
from fastapi import APIRouter, Depends
|
||||||
|
|
||||||
from src.application.commands import (
|
from src.application.commands import (
|
||||||
GetOrganizationCommand,
|
GetOrganizationCommand,
|
||||||
GetOrganizationMnemonicCommand,
|
GetOrganizationMnemonicCommand,
|
||||||
GetOrganizationSecretKeysCommand,
|
GetOrganizationSecretKeysCommand,
|
||||||
ListOrganizationWalletsCommand,
|
ListOrganizationWalletsCommand,
|
||||||
ListOrganizationsCommand,
|
|
||||||
)
|
)
|
||||||
from src.application.domain.dto import AdminAuthContext
|
from src.application.domain.dto import AuthContext
|
||||||
from src.presentation.decorators.admin_auth import require_admin_access, require_admin_role
|
from src.presentation.decorators.auth import require_access_token
|
||||||
from src.presentation.dependencies.commands import (
|
from src.presentation.dependencies.commands import (
|
||||||
get_get_organization_command,
|
get_get_organization_command,
|
||||||
get_get_organization_mnemonic_command,
|
get_get_organization_mnemonic_command,
|
||||||
get_get_organization_secret_keys_command,
|
get_get_organization_secret_keys_command,
|
||||||
get_list_organization_wallets_command,
|
get_list_organization_wallets_command,
|
||||||
get_list_organizations_command,
|
|
||||||
)
|
)
|
||||||
from src.presentation.schemas.organization import (
|
from src.presentation.schemas.organization import (
|
||||||
MnemonicResponse,
|
MnemonicResponse,
|
||||||
OrganizationListResponse,
|
|
||||||
OrganizationResponse,
|
OrganizationResponse,
|
||||||
SecretKeyResponse,
|
SecretKeyResponse,
|
||||||
WalletResponse,
|
WalletResponse,
|
||||||
@@ -33,57 +30,39 @@ from src.presentation.serializers.organization import (
|
|||||||
organizations_router = APIRouter(prefix='/organizations', tags=['organizations'])
|
organizations_router = APIRouter(prefix='/organizations', tags=['organizations'])
|
||||||
|
|
||||||
|
|
||||||
@organizations_router.get('', response_model=OrganizationListResponse)
|
@organizations_router.get('', response_model=OrganizationResponse)
|
||||||
async def list_organizations(
|
|
||||||
limit: int = Query(default=50, ge=1, le=200),
|
|
||||||
offset: int = Query(default=0, ge=0),
|
|
||||||
auth: AdminAuthContext = Depends(require_admin_access),
|
|
||||||
command: ListOrganizationsCommand = Depends(get_list_organizations_command),
|
|
||||||
):
|
|
||||||
items, total = await command(limit=limit, offset=offset)
|
|
||||||
return OrganizationListResponse(
|
|
||||||
items=[organization_to_response(x) for x in items],
|
|
||||||
total=total,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@organizations_router.get('/{organization_id}', response_model=OrganizationResponse)
|
|
||||||
async def get_organization(
|
async def get_organization(
|
||||||
organization_id: str,
|
auth: AuthContext = Depends(require_access_token),
|
||||||
auth: AdminAuthContext = Depends(require_admin_access),
|
|
||||||
command: GetOrganizationCommand = Depends(get_get_organization_command),
|
command: GetOrganizationCommand = Depends(get_get_organization_command),
|
||||||
):
|
):
|
||||||
org = await command(organization_id)
|
org = await command(auth.user_id)
|
||||||
return organization_to_response(org)
|
return organization_to_response(org)
|
||||||
|
|
||||||
|
|
||||||
@organizations_router.get('/{organization_id}/wallets', response_model=list[WalletResponse])
|
@organizations_router.get('/wallets', response_model=list[WalletResponse])
|
||||||
async def list_organization_wallets(
|
async def list_organization_wallets(
|
||||||
organization_id: str,
|
auth: AuthContext = Depends(require_access_token),
|
||||||
auth: AdminAuthContext = Depends(require_admin_access),
|
|
||||||
command: ListOrganizationWalletsCommand = Depends(get_list_organization_wallets_command),
|
command: ListOrganizationWalletsCommand = Depends(get_list_organization_wallets_command),
|
||||||
):
|
):
|
||||||
wallets = await command(organization_id)
|
wallets = await command(auth.user_id)
|
||||||
return [wallet_to_response(w) for w in wallets]
|
return [wallet_to_response(w) for w in wallets]
|
||||||
|
|
||||||
|
|
||||||
@organizations_router.get('/{organization_id}/wallets/mnemonic', response_model=MnemonicResponse)
|
@organizations_router.get('/wallets/mnemonic', response_model=MnemonicResponse)
|
||||||
async def get_organization_mnemonic(
|
async def get_organization_mnemonic(
|
||||||
organization_id: str,
|
auth: AuthContext = Depends(require_access_token),
|
||||||
auth: AdminAuthContext = Depends(require_admin_role('compliance', 'superadmin')),
|
|
||||||
command: GetOrganizationMnemonicCommand = Depends(get_get_organization_mnemonic_command),
|
command: GetOrganizationMnemonicCommand = Depends(get_get_organization_mnemonic_command),
|
||||||
):
|
):
|
||||||
mnemonic = await command(organization_id)
|
mnemonic = await command(auth.user_id)
|
||||||
return mnemonic_to_response(mnemonic)
|
return mnemonic_to_response(mnemonic)
|
||||||
|
|
||||||
|
|
||||||
@organizations_router.get('/{organization_id}/wallets/secret-keys', response_model=list[SecretKeyResponse])
|
@organizations_router.get('/wallets/secret-keys', response_model=list[SecretKeyResponse])
|
||||||
async def get_organization_secret_keys(
|
async def get_organization_secret_keys(
|
||||||
organization_id: str,
|
auth: AuthContext = Depends(require_access_token),
|
||||||
auth: AdminAuthContext = Depends(require_admin_role('compliance', 'superadmin')),
|
|
||||||
command: GetOrganizationSecretKeysCommand = Depends(get_get_organization_secret_keys_command),
|
command: GetOrganizationSecretKeysCommand = Depends(get_get_organization_secret_keys_command),
|
||||||
):
|
):
|
||||||
keys = await command(organization_id)
|
keys = await command(auth.user_id)
|
||||||
return [
|
return [
|
||||||
secret_key_to_response(
|
secret_key_to_response(
|
||||||
chain=k.chain,
|
chain=k.chain,
|
||||||
|
|||||||
@@ -27,11 +27,6 @@ class OrganizationResponse(BaseModel):
|
|||||||
updated_at: str | None
|
updated_at: str | None
|
||||||
|
|
||||||
|
|
||||||
class OrganizationListResponse(BaseModel):
|
|
||||||
items: list[OrganizationResponse]
|
|
||||||
total: int
|
|
||||||
|
|
||||||
|
|
||||||
class WalletResponse(BaseModel):
|
class WalletResponse(BaseModel):
|
||||||
id: str
|
id: str
|
||||||
chain: str
|
chain: str
|
||||||
|
|||||||
Reference in New Issue
Block a user