Commit Graph

4 Commits

Author SHA1 Message Date
m
8e65463130 feat: role-based permissions — owner/partner/associate/paralegal/secretary (P0) 2026-03-30 11:09:05 +02:00
m
0a0ec016d8 feat: role-based permissions (owner/partner/associate/paralegal/secretary)
Backend:
- auth/permissions.go: full permission matrix with RequirePermission/RequireRole
  middleware, CanEditCase, CanDeleteDocument helpers
- auth/context.go: add user role to request context
- auth/middleware.go: resolve role alongside tenant in auth flow
- auth/tenant_resolver.go: verify membership + resolve role for X-Tenant-ID
- handlers/case_assignments.go: CRUD for case-level user assignments
- handlers/tenant_handler.go: UpdateMemberRole, GetMe (/api/me) endpoints
- handlers/documents.go: permission-based delete (own vs all)
- router/router.go: permission-wrapped routes for all endpoints
- services/case_assignment_service.go: assign/unassign with tenant validation
- services/tenant_service.go: UpdateMemberRole with owner protection
- models/case_assignment.go: CaseAssignment model

Database:
- user_tenants.role: CHECK constraint (owner/partner/associate/paralegal/secretary)
- case_assignments table: case_id, user_id, role (lead/team/viewer)
- Migrated existing admin->partner, member->associate

Frontend:
- usePermissions hook: fetches /api/me, provides can() helper
- TeamSettings: 5-role dropdown, role change, permission-gated invite
- CaseAssignments: new component for case-level team management
- Sidebar: conditionally hides AI/Settings based on permissions
- Cases page: hides "Neue Akte" button for non-authorized roles
- Case detail: new "Mitarbeiter" tab for assignment management
2026-03-30 11:04:57 +02:00
m
c15d5b72f2 fix: critical security hardening — tenant isolation, CORS, error leaking, input validation
1. Tenant isolation bypass (CRITICAL): TenantResolver now verifies user
   has access to X-Tenant-ID via user_tenants lookup before setting context.
   Added VerifyAccess method to TenantLookup interface and TenantService.

2. Consolidated tenant resolution: Removed duplicate resolveTenant() from
   helpers.go and tenant resolution from auth middleware. TenantResolver is
   now the single source of truth. Deadlines and AI handlers use
   auth.TenantFromContext() instead of direct DB queries.

3. CalDAV credential masking: tenant settings responses now mask CalDAV
   passwords with "********" via maskSettingsPassword helper. Applied to
   GetTenant, ListTenants, and UpdateSettings responses.

4. CORS + security headers: New middleware/security.go with CORS
   (restricted to FRONTEND_ORIGIN) and security headers (X-Frame-Options,
   X-Content-Type-Options, HSTS, Referrer-Policy, X-XSS-Protection).

5. Internal error leaking: All writeError(w, 500, err.Error()) replaced
   with internalError() that logs via slog and returns generic "internal
   error" to client. Same for jsonError in tenant handler.

6. Input validation: Max length on title (500), description (10000),
   case_number (100), search (200). Pagination clamped to max 100.
   Content-Disposition filename sanitized against header injection.

Regression test added for tenant access denial (403 on unauthorized
X-Tenant-ID). All existing tests pass, go vet clean.
2026-03-30 11:01:14 +02:00
m
0b6bab8512 feat: add tenant + auth backend endpoints (Phase 1A)
Tenant management:
- POST /api/tenants — create tenant (creator becomes owner)
- GET /api/tenants — list tenants for authenticated user
- GET /api/tenants/:id — tenant details with access check
- POST /api/tenants/:id/invite — invite user by email (owner/admin)
- DELETE /api/tenants/:id/members/:uid — remove member
- GET /api/tenants/:id/members — list members

New packages:
- internal/services/tenant_service.go — CRUD on tenants + user_tenants
- internal/handlers/tenant_handler.go — HTTP handlers with auth checks
- internal/auth/tenant_resolver.go — X-Tenant-ID header middleware,
  defaults to user's first tenant for scoped routes

Authorization: owners/admins can invite and remove members. Cannot
remove the last owner. Users can remove themselves. TenantResolver
applies to resource routes (cases, deadlines, etc.) but not tenant
management routes.
2026-03-25 13:27:39 +01:00