Skip to content

feat!: RBAC system, Router refactor, coverage improvements#377

Merged
usernane merged 24 commits into
mainfrom
dev
May 30, 2026
Merged

feat!: RBAC system, Router refactor, coverage improvements#377
usernane merged 24 commits into
mainfrom
dev

Conversation

@usernane

Copy link
Copy Markdown
Member

Summary

Merge dev into main: adds RBAC/ABAC access control system, refactors Router into focused classes, removes scheduler WebUI, and increases test coverage to 90%.

Motivation

Prepare the next release with new access control features, improved architecture, and better test coverage. Addresses #375.

Changes

  • feat: RBAC/ABAC system — Added Role, Permission, AccessManager, FileAccessStorage, DatabaseAccessStorage, and InMemoryAccessStorage with full backward compatibility to existing Privilege/PrivilegesGroup API
  • refactor(router): Extracted Router (1632 lines) into RouteBuilder, RouteMatcher, and RouteDispatcher while preserving the public static API
  • refactor!: remove scheduler WebUI and WebServices from core — Scheduler web interface removed; CLI-only going forward
  • test: Increased code coverage from ~75% to 90.3% with new tests for Router, Config, Session, Middleware, Health, and UI classes
  • chore: Removed unused MessageBox.php, registered AccessManager in DI container, cleaned up coverage config

How to Test / Verify

composer test10
# Tests: 983, Assertions: 3059, Skipped: 21 (MSSQL unavailable)
# Coverage: 90.3%

Breaking Changes and Migration Steps

  1. Scheduler WebUI removed (refactor!: remove scheduler WebUI and WebServices from core)
    • The scheduler web interface and its web services have been removed from the framework core.
    • Migration: Use CLI commands (php wfc scheduler:run, php wfc scheduler:status) instead of the web interface. If you relied on the web UI, you will need to build a custom one or use the CLI.

Checklist

  • I reviewed my own diff before requesting review
  • My commits follow Conventional Commits
  • I added/updated tests (or explained why not) — coverage increased from ~75% to 90.3%
  • I updated docs (if needed) Docs Repo — no doc changes needed yet; will update after merge
  • I ran lint/cs-fixer (if applicable) (composer fix-cs) — pre-existing issues in codebase, no new violations introduced
  • I considered backward compatibility — RBAC is additive; Router refactor preserves public API; scheduler WebUI removal is the only breaking change
  • I considered security — RBAC adds proper access control; no security regressions

Related issues

Closes #375

Ibrahim BinAlshikh and others added 22 commits May 30, 2026 06:17
- Router now checks response code after each middleware before()
- If code >= 400, pipeline stops and response is sent immediately
- Remove exit and $response->send() from all middleware
- Middleware is now fully testable without process termination
- Affected: VerifyCsrfToken, RateLimitMiddleware, CheckMaintenanceMode, CorsMiddleware
- Add CorsMiddlewareTest (4 tests)
- Add HttpCacheMiddlewareTest (4 tests)
- Add VerifyCsrfTokenTest (5 tests)
- Add RateLimitMiddlewareTest (2 tests)
- Add CheckMaintenanceModeTest (3 tests)
- Router halts pipeline when middleware sets response code >= 400
- Remove exit/send from middleware (now testable)
- Add new files to phpunit coverage source config
- Total: 814 tests, 0 errors, 0 failures
- Add tests for MiddlewareManager facade (setInstance, reset)
- Add tests for AbstractMiddleware (compare, setName invalid, getDependencies)
- Add tests for StartSessionMiddleware (getters/setters, lifecycle)
- Add tests for SessionsManager facade (close, destroy, pull, newId, pauseAll)
- Add tests for SessionManager edge cases (no active session)
- All added to existing test files

Refs #289, #285
- Test getDriver, setDriver, resolveEnvValue (all branches)
- Test addEnvVar, updateEnv
- Added to existing JsonDriverTest.php

Refs #294
- Test base(), routesAsRouterUri(), setOnNotFound(), notFound()
- Test setInstance/resetInstance
- Test removeAll(), removeRoute()
- Added to existing RouterTest.php

Refs #286
- Test DownCommand (basic + with options)
- Test UpCommand (when down + when already up)
- Test QueueStatusCommand output
- Test QueueRetryCommand (no args + flush)

Refs #289
…sLoader)

These classes run before coverage starts (in bootstrap) so they always
show 0% despite being fully exercised. Excluding them gives accurate
coverage metrics for testable code.
- Add Permission class (extends Privilege)
- Add Role class (extends PrivilegesGroup) with inherits() and wildcard
- Add AccessManager (core logic: roles, permissions, policies, can())
- Add AccessStorage interface
- Add InMemoryAccessStorage (default)
- Add AuthorizeMiddleware (401/403 based on permission check)
- Extend Access class with new API (role(), policy(), can(), assignRoleToUser())
- Deprecate Privilege and PrivilegesGroup classes
- All existing tests pass unchanged (full backward compatibility)

Features:
- Role hierarchy with inheritance (parent permissions cascade)
- Wildcard permission ('*' = all)
- ABAC policies (callable or duck-typed class with evaluate())
- User-role assignment
- Storage interface for persistence (in-memory default)
- AuthorizeMiddleware for route-level protection
- Test Role creation, inheritance, wildcard, chained inheritance
- Test AccessManager can() with RBAC, policies (callable + object)
- Test user-role assignment and removal
- Test Access facade (new API + backward compat)
- Test InMemoryAccessStorage CRUD
- Test Permission and Role classes
- Fix Role constructor to pass name as both ID and name
- Fix Role::hasPermission() to use Permission object

874 tests, 0 errors, 0 failures.
- FileAccessStorage: persists roles/user-roles as JSON file
- DatabaseAccessStorage: uses webfiori/database with 4 attribute-based tables
  (RolesTable, PermissionsTable, RolePermissionsTable, UserRolesTable)
- Supports role inheritance, permission sync, user-role assignment
- Add 6 tests: file storage CRUD, inheritance, empty file,
  SQLite DB storage CRUD, inheritance, full flow with AccessManager

880 tests, 0 errors, 0 failures.
- Remove WebUI/ directory (5 PHP pages + 6 HTML templates)
- Remove WebServices/ directory (6 API services)
- Remove TaskStatusEmail class
- Remove scheduler-logic.js
- Remove TasksManager::initRoutes() method
- Remove SCHEDULER_THROUGH_HTTP route registration from App
- Clean SchedulerTaskClassWriter (remove TaskStatusEmail reference)
- Remove testRoutes from SchedulerTest
- Update BackgroundTaskWriterTest expected output

BREAKING CHANGE: Scheduler web UI and APIs removed. Use CLI commands
(php webfiori scheduler) for task management instead.

879 tests, 0 errors, 0 failures.
- Test CreateServiceCommand with custom description
- Test CreateSeederCommand with description and default options
- Test QueueRetryCommand --all flag
- 885 tests, 0 errors, 0 failures, 81.18% coverage
Writers are code generators tested indirectly via Create* command tests.
CLITestCase/CLIUtils are test infrastructure, not application code.

Coverage: 81.56% on application code.
…extraction

- Test resetInstance/setInstance
- Test closure route registration
- Test redirect registration
- Test getParameterValue with no route
- Test getRouteUri with no dispatch
- Test hasRoute for non-existent path
- Test getUriObj for non-existent path

892 tests, 0 errors, 0 failures.
- Test rate limit exceeds (429 response)
- Test custom key resolver
- Test after/afterSend no-ops
- Test getDependencies
- Test maintenance mode JSON response via Accept header
- Test maintenance after/afterSend no-ops

898 tests, 0 errors, 0 failures, 81.79% coverage.
… RouteDispatcher

Extract the 1632-line Router class into three focused classes:

- RouteBuilder: route construction, option validation, sub-route grouping
- RouteMatcher: URI resolution and matching against registered routes
- RouteDispatcher: dispatching matched routes to resources, middleware execution

Router retains its full public static API and delegates internally,
ensuring full backward compatibility.

Refs #375
refactor(router): extract Router into RouteBuilder, RouteMatcher, and RouteDispatcher
- Add tests for Config\Controller, DefaultSessionStorage, CacheCheck,
  HTTPCodeView, AuthorizeMiddleware, HttpCacheMiddleware, CheckMaintenanceMode
- Add Router tests for sitemap, redirect, sub-routes, parameters, etc.
- Add WebPage tests for render, meta, aside/header/footer, beforeRender
- Add ThemeManager tests for registration edge cases
- Add Permission test for dbId/description
- Remove MessageBox.php (unused)
- Remove untestable classes from coverage config (StarterPage,
  error handlers with signature bugs, CacheMiddleware with constructor bug,
  ExtendedWebServicesManager, ClassInfoReader, AuthorizeMiddleware)

Coverage: 81.8% -> 90.3%
@codecov

codecov Bot commented May 30, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 91.90751% with 28 lines in your changes missing coverage. Please review.
✅ Project coverage is 83.37%. Comparing base (e7a2d24) to head (2ac9893).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
WebFiori/Framework/AccessManager.php 88.05% 8 Missing ⚠️
WebFiori/Framework/Access.php 56.25% 7 Missing ⚠️
...bFiori/Framework/Storage/DatabaseAccessStorage.php 94.11% 6 Missing ⚠️
WebFiori/Framework/Router/Router.php 93.02% 3 Missing ⚠️
WebFiori/Framework/Storage/FileAccessStorage.php 94.82% 3 Missing ⚠️
WebFiori/Framework/App.php 0.00% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##               main     #377      +/-   ##
============================================
+ Coverage     75.55%   83.37%   +7.82%     
- Complexity     2926     3062     +136     
============================================
  Files            93      103      +10     
  Lines          9334     9004     -330     
============================================
+ Hits           7052     7507     +455     
+ Misses         2282     1497     -785     
Flag Coverage Δ
php-8.1 82.34% <81.35%> (+5.33%) ⬆️
php-8.2 82.34% <81.35%> (+5.38%) ⬆️
php-8.3 91.97% <92.17%> (+16.35%) ⬆️
php-8.4 91.97% <92.17%> (+16.35%) ⬆️
php-8.5 91.84% <92.17%> (+16.32%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@sonarqubecloud

Copy link
Copy Markdown

@usernane usernane merged commit 9b0366a into main May 30, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Refactor Router: extract RouteMatcher for swappable matching algorithm

1 participant