Files
consentos/apps/api/src/services/auth.py
James Cottrill fbf26453f2 feat: initial public release
ConsentOS — a privacy-first cookie consent management platform.

Self-hosted, source-available alternative to OneTrust, Cookiebot, and
CookieYes. Full standards coverage (IAB TCF v2.2, GPP v1, Google
Consent Mode v2, GPC, Shopify Customer Privacy API), multi-tenant
architecture with role-based access, configuration cascade
(system → org → group → site → region), dark-pattern detection in
the scanner, and a tamper-evident consent record audit trail.

This is the initial public release. Prior development history is
retained internally.

See README.md for the feature list, architecture overview, and
quick-start instructions. Licensed under the Elastic Licence 2.0 —
self-host freely; do not resell as a managed service.
2026-04-14 09:18:18 +00:00

60 lines
1.6 KiB
Python

import uuid
from datetime import UTC, datetime, timedelta
import bcrypt
from jose import jwt
from src.config.settings import get_settings
def hash_password(password: str) -> str:
return bcrypt.hashpw(password.encode(), bcrypt.gensalt()).decode()
def verify_password(plain_password: str, hashed_password: str) -> bool:
return bcrypt.checkpw(plain_password.encode(), hashed_password.encode())
def create_access_token(
user_id: uuid.UUID,
organisation_id: uuid.UUID,
role: str,
email: str,
) -> str:
settings = get_settings()
now = datetime.now(UTC)
expire = now + timedelta(minutes=settings.jwt_access_token_expire_minutes)
payload = {
"sub": str(user_id),
"org_id": str(organisation_id),
"role": role,
"email": email,
"exp": expire,
"iat": now,
"type": "access",
}
return jwt.encode(payload, settings.jwt_secret_key, algorithm=settings.jwt_algorithm)
def create_refresh_token(
user_id: uuid.UUID,
organisation_id: uuid.UUID,
) -> str:
settings = get_settings()
now = datetime.now(UTC)
expire = now + timedelta(days=settings.jwt_refresh_token_expire_days)
payload = {
"sub": str(user_id),
"org_id": str(organisation_id),
"exp": expire,
"iat": now,
"type": "refresh",
}
return jwt.encode(payload, settings.jwt_secret_key, algorithm=settings.jwt_algorithm)
def decode_token(token: str) -> dict:
"""Decode and validate a JWT token. Raises JWTError on failure."""
settings = get_settings()
return jwt.decode(token, settings.jwt_secret_key, algorithms=[settings.jwt_algorithm])