⬅️ Back to Controller Overview

Security Endpoints Matrix

Authorization Overview

This document maps roles to endpoints across all controllers. Use this matrix to understand who can access what.

Key Principles: - ADMIN = Full access (creation, modification, deletion, reporting) - USER = Read & limited write (own data, standard operations) - PUBLIC = Unauthenticated demo mode (read-only where @appProperties.demoReadonly) - AUTHENTICATED = Any logged-in user (role-agnostic operations)


Role Definitions

graph LR AUTH["Authentication Layer"] AUTH --> ADMIN["ROLE_ADMIN
Full Platform Access"] AUTH --> USER["ROLE_USER
Standard Operations"] AUTH --> PUBLIC["PUBLIC
Demo Mode"] AUTH --> NONE["UNAUTHENTICATED
No Access"] ADMIN --> A1["Create/Edit/Delete"] ADMIN --> A2["Analytics Reports"] ADMIN --> A3["Audit Trails"] USER --> U1["Create/Edit Own Items"] USER --> U2["View Analytics"] USER --> U3["Read Audit Trails"] PUBLIC --> P1["Read-Only (if enabled)"] NONE --> N1["Not Accessible"] style ADMIN fill:#ffcdd2 style USER fill:#fff9c4 style PUBLIC fill:#c8e6c9 style NONE fill:#eeeeee

Supplier Controller Authorization

Endpoint Method Public USER ADMIN Notes
/api/suppliers GET βœ… βœ… βœ… List all suppliers (paginated)
/api/suppliers/{id} GET βœ… βœ… βœ… Get supplier by ID
/api/suppliers POST ❌ ❌ βœ… Create supplier (ADMIN only)
/api/suppliers/{id} PUT ❌ ❌ βœ… Update supplier (ADMIN only)
/api/suppliers/{id} DELETE ❌ ❌ βœ… Soft delete supplier (ADMIN only)
/api/suppliers/count GET βœ… βœ… βœ… Count suppliers
/api/suppliers/search GET βœ… βœ… βœ… Search suppliers by name

Authorization Annotations

// READ (Public allowed in demo mode)
@PreAuthorize("isAuthenticated() or @appProperties.demoReadonly")

// CREATE/UPDATE/DELETE (ADMIN only)
@PreAuthorize("hasRole('ADMIN')")

Inventory Item Controller Authorization

Endpoint Method Public USER ADMIN Notes
/api/items GET βœ… βœ… βœ… List all items (paginated)
/api/items/{id} GET βœ… βœ… βœ… Get item details
/api/items POST ❌ ❌ βœ… Create item (ADMIN only)
/api/items/{id} PUT ❌ ❌ βœ… Update item (ADMIN only)
/api/items/{id} DELETE ❌ ❌ βœ… Soft delete item (ADMIN only)
/api/items/{id}/update-stock PATCH ❌ ❌ βœ… Update stock quantity (ADMIN only)
/api/items/count GET βœ… βœ… βœ… Count items
/api/items/search GET βœ… βœ… βœ… Search items by name

Authorization Pattern

// READ operations
@PreAuthorize("isAuthenticated() or @appProperties.demoReadonly")

// WRITE operations (stock updates, creation)
@PreAuthorize("hasRole('ADMIN')")

Critical: Stock updates (PATCH /api/items/{id}/update-stock) require ADMIN role and create audit trail entries via StockHistory.


Stock History Controller Authorization

Endpoint Method Public USER ADMIN Notes
/api/stock-history GET βœ… βœ… βœ… List all stock changes
/api/stock-history/{id} GET βœ… βœ… βœ… Get specific change entry
/api/stock-history/by-item/{itemId} GET βœ… βœ… βœ… Changes for one item
/api/stock-history/by-supplier/{supplierId} GET βœ… βœ… βœ… Changes for one supplier

Authorization Pattern

// ALL operations (Read-only audit trail)
@PreAuthorize("isAuthenticated() or @appProperties.demoReadonly")

Note: Stock History is immutable read-only audit trail. No write operations exposed.


Authentication Controller Authorization

Endpoint Method Public USER ADMIN Notes
/api/me GET ❌ βœ… βœ… Get current user profile
/api/logout POST ❌ βœ… βœ… Invalidate session

Authorization Pattern

// User profile & logout (Authenticated only)
@PreAuthorize("isAuthenticated()")

OAuth2 Flow: - GET /api/me triggers auto-authentication if not logged in - POST /api/logout clears cookies and redirects to home


Analytics Controller Authorization

Endpoint Method Public USER ADMIN Notes
/api/analytics/dashboard-summary GET βœ… βœ… βœ… KPI dashboard
/api/analytics/financial-summary GET βœ… βœ… βœ… P&L and inventory metrics
/api/analytics/stock-value GET βœ… βœ… βœ… Time series data
/api/analytics/stock-per-supplier GET βœ… βœ… βœ… Supplier distribution
/api/analytics/trends/price GET βœ… βœ… βœ… Price trends over time
/api/analytics/trends/monthly-movement GET βœ… βœ… βœ… Monthly activity
/api/analytics/low-stock-items GET βœ… βœ… βœ… Items below reorder level
/api/analytics/update-frequency GET βœ… βœ… βœ… Item activity analysis

Authorization Pattern

// All analytics endpoints (Read-only)
@PreAuthorize("isAuthenticated() or @appProperties.demoReadonly")

Feature: Analytics are safe for public demo mode (no sensitive data mutation).


Consolidated Access Matrix

╔══════════════════════════════════╦═══════╦══════╦═══════╗
β•‘ Controller Group                 β•‘ PUBLICβ•‘ USER β•‘ ADMIN β•‘
╠══════════════════════════════════╬═══════╬══════╬═══════╣
β•‘ SUPPLIER - List/Get              β•‘   βœ…  β•‘  βœ…  β•‘  βœ…   β•‘
β•‘ SUPPLIER - Create/Update/Delete  β•‘   ❌  β•‘  ❌  β•‘  βœ…   β•‘
β•‘ INVENTORY - List/Get             β•‘   βœ…  β•‘  βœ…  β•‘  βœ…   β•‘
β•‘ INVENTORY - Create/Update/Delete β•‘   ❌  β•‘  ❌  β•‘  βœ…   β•‘
β•‘ INVENTORY - Update Stock         β•‘   ❌  β•‘  ❌  β•‘  βœ…   β•‘
β•‘ STOCK HISTORY - All              β•‘   βœ…  β•‘  βœ…  β•‘  βœ…   β•‘
β•‘ ANALYTICS - All                  β•‘   βœ…  β•‘  βœ…  β•‘  βœ…   β•‘
β•‘ AUTH - Get Profile/Logout        β•‘   ❌  β•‘  βœ…  β•‘  βœ…   β•‘
β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•©β•β•β•β•β•β•β•β•©β•β•β•β•β•β•β•©β•β•β•β•β•β•β•β•

Demo Mode Behavior

When appProperties.demoReadonly = true:

// Public reads allowed
@PreAuthorize("isAuthenticated() or @appProperties.demoReadonly")

// Actual behavior:
if (demoReadonly) {
    // βœ… GET requests β†’ Allowed
    // ❌ POST/PUT/PATCH/DELETE β†’ Blocked (throws DemoModeException)
}

Use Cases: - Public dashboards (analytics) - Preview environments - Sandboxes for training


Security Validation Checklist

Before deploying:

β˜‘ ADMIN roles assigned only to trusted users (via APP_ADMIN_EMAILS)
β˜‘ OAuth2 configured (ClientId, ClientSecret in environment)
β˜‘ HTTPS enabled in production (secure cookies)
β˜‘ Session timeout configured (15–30 minutes)
β˜‘ CSRF protection enabled (Spring Security default)
β˜‘ Demo mode disabled in production (@appProperties.demoReadonly = false)
β˜‘ Audit logging enabled (StockHistory captures all writes)
β˜‘ Rate limiting configured (if using Spring Cloud)

Role Assignment Logic

ADMIN Role Assignment

// From AuthController.java
if (APP_ADMIN_EMAILS.contains(user.getEmail())) {
    grantRole("ROLE_ADMIN");
    // Full platform access
} else {
    grantRole("ROLE_USER");
    // Read + limited write access
}

Configuration: Set via environment variable:

APP_ADMIN_EMAILS=admin@company.com,ops@company.com

Summary

Role Access Level Typical Users Use Case
PUBLIC Read-only Unauthenticated demo visitors Dashboards, demo environments
USER Read + Limited Write Employees, staff Daily operations, item viewing
ADMIN Full CRUD Managers, ops team System configuration, creation, deletion

Default: Users logged in via OAuth2 get ROLE_USER. Admins require email in APP_ADMIN_EMAILS.


⬅️ Back to Controller Overview