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

@ -391,3 +391,64 @@ async def m010_user_equity_status(db):
WHERE is_equity_eligible = TRUE;
"""
)
async def m011_account_permissions(db):
"""
Create account_permissions table for granular account access control.
Allows admins to grant specific permissions (read, submit_expense, manage) to users for specific accounts.
Supports hierarchical permission inheritance (permissions on parent accounts cascade to children).
"""
await db.execute(
f"""
CREATE TABLE account_permissions (
id TEXT PRIMARY KEY,
user_id TEXT NOT NULL,
account_id TEXT NOT NULL,
permission_type TEXT NOT NULL,
granted_by TEXT NOT NULL,
granted_at TIMESTAMP NOT NULL DEFAULT {db.timestamp_now},
expires_at TIMESTAMP,
notes TEXT,
FOREIGN KEY (account_id) REFERENCES accounts (id)
);
"""
)
# Index for looking up permissions by user
await db.execute(
"""
CREATE INDEX idx_account_permissions_user_id ON account_permissions (user_id);
"""
)
# Index for looking up permissions by account
await db.execute(
"""
CREATE INDEX idx_account_permissions_account_id ON account_permissions (account_id);
"""
)
# Composite index for checking specific user+account permissions
await db.execute(
"""
CREATE INDEX idx_account_permissions_user_account
ON account_permissions (user_id, account_id);
"""
)
# Index for finding permissions by type
await db.execute(
"""
CREATE INDEX idx_account_permissions_type ON account_permissions (permission_type);
"""
)
# Index for finding expired permissions
await db.execute(
"""
CREATE INDEX idx_account_permissions_expires
ON account_permissions (expires_at)
WHERE expires_at IS NOT NULL;
"""
)