Adds account permissioning system

Adds an account permissioning system to allow granular control over account access.

Introduces the ability to grant users specific permissions (read, submit_expense, manage) on individual accounts.  This includes support for hierarchical permission inheritance, where permissions on parent accounts cascade to child accounts.

Adds new API endpoints for managing account permissions, including granting, listing, and revoking permissions.

Integrates permission checks into existing endpoints, such as creating expense entries, to ensure that users only have access to the accounts they are authorized to use.

Fixes #33 - Implements role based access control
This commit is contained in:
padreug 2025-11-07 17:55:59 +01:00
parent 7f9cecefa1
commit 92c1649f3b
4 changed files with 617 additions and 3 deletions

View file

@ -273,3 +273,48 @@ class UserInfo(BaseModel):
user_id: str
is_equity_eligible: bool
equity_account_name: Optional[str] = None
class PermissionType(str, Enum):
"""Types of permissions for account access"""
READ = "read" # Can view account and its balance
SUBMIT_EXPENSE = "submit_expense" # Can submit expenses to this account
MANAGE = "manage" # Can modify account (admin level)
class AccountPermission(BaseModel):
"""Defines which accounts a user can access"""
id: str # Unique permission ID
user_id: str # User's wallet ID (from invoice key)
account_id: str # Account ID from accounts table
permission_type: PermissionType
granted_by: str # Admin user ID who granted permission
granted_at: datetime
expires_at: Optional[datetime] = None # Optional expiration
notes: Optional[str] = None # Admin notes about this permission
class CreateAccountPermission(BaseModel):
"""Create account permission"""
user_id: str
account_id: str
permission_type: PermissionType
expires_at: Optional[datetime] = None
notes: Optional[str] = None
class AccountWithPermissions(BaseModel):
"""Account with user-specific permission metadata"""
id: str
name: str
account_type: AccountType
description: Optional[str] = None
user_id: Optional[str] = None
created_at: datetime
# Only included when filter_by_user=true
user_permissions: Optional[list[PermissionType]] = None
inherited_from: Optional[str] = None # Parent account ID if inherited
# Hierarchical structure
parent_account: Optional[str] = None # Parent account name
level: Optional[int] = None # Depth in hierarchy (0 = top level)
has_children: Optional[bool] = None # Whether this account has sub-accounts