Repository navigation
Release 0.2.0 - #1
Open
GuilhermeBarile wants to merge 217 commits into
Open
GuilhermeBarile wants to merge 217 commits into
GuilhermeBarile wants to merge 217 commits into
Conversation
Run user updates, role creation, and role membership replacement in one DB transaction so failures cannot leave partial changes. Add SQLite regression coverage that injects a membership insert failure and asserts that user fields, role definitions, and assignments roll back.
Delete relation rows only for entries marked auth_owned=true, preserving application-owned association data even when used for authorization. Document the opt-in for bundled delegations and add deletion regressions covering both Auth-owned and application-owned relation tables.
Refresh roles and lifecycle status before global, delegated, and resource permissions, invalidating stale sessions for suspended or deleted users. Preserve false/empty-list unauthenticated return semantics and include regression tests for role revocation, suspension, and account deletion.
7 tasks
Require a plain DELETE /api/users/{id} for account deletion and return
404 for unknown or incomplete subresource paths rather than deleting users.
Cover unsupported paths, valid user deletion and credential-only deletion
with regression tests; correct the previous unauthenticated delete test.
Only overwrite the stored BasicAuth credential profile when update_credential receives a non-null value, matching DBAuth's established semantics. Keep null defaults for new credentials and verify that login, null updates, and explicit profile replacements behave correctly.
Use the MySQL 8 utf8mb4_0900_bin collation for credential UID and provider columns in the existing Phinx migration. This prevents case-insensitive or trailing-space-insensitive matching of distinct external provider subjects. Verify column collations and actual credential lookup/uniqueness on MySQL 8.0 and 8.4, and document existing-schema migration considerations.
… tokens Restrict anonymous password recovery to independently verified credentials for every configured recovery provider, including local. Prefer the first verified matching channel rather than an unverified match, avoid rotating reset tokens for unverified accounts, and keep uniform anonymous responses. Cover BasicAuth and DBAuth behavior in regression tests and document existing-account migration requirements.
Update password hash, reset-token digest and expiration together in a single DBAuth UPDATE, and apply the same behavior in BasicAuth. Cover direct password changes and authenticated password-change routes with SQLite, in-memory and MySQL regressions. Document reset-link invalidation in the README and changelog.
Add DBAuth with_admin_mutation using db->transaction() and a stable role-row write lock, then reload the target and enforce the invariant within the same transaction before deletes, demotions, or suspensions. Protect PUT disabled_at as well as the suspend action. Add tests for all mutation paths and stale-count interleaving, and document the invariant and limits of direct DBAuth writes.
…ssions Use an authenticated non-target account for self-protection checks in new administrator mutation tests, matching the existing controller tests.
…lete Remove the with_admin_mutation abstraction from Auth, DBAuth and UserController. Use the existing db->transaction() calls in DBAuth update/delete for shared-role locking and fresh active-admin checks. Skip the lock for ordinary user updates and account activation. Protect direct DBAuth mutations, retain provider-neutral controller validation, and extend regression coverage.
Existing session revalidation tests must not demote, suspend or delete the only active administrator now that DBAuth enforces the invariant for direct update/delete calls. Keep a separate active administrator so those tests focus on session invalidation.
Create a second active admin before exercising role removal so the integration test verifies role syncing without violating the new DBAuth final-admin invariant. Assert that the demoted user loses the role while the backup retains it, and adjust remaining user count.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Release 0.2.0
This is a breaking rewrite of the package compared with
master/ 0.1.x. It introduces a provider-based auth architecture, database-backed roles and relations, OAuth/session hardening, a reusable user-management API, and modern CI/test coverage.No automatic data migration or backward compatibility is provided. Existing 0.1.x applications must follow the documented manual migration and rollout procedure in docs/UPGRADING-0.2.0.md.
Breaking changes
>=8.2(previously>=5.3).Objectiveweb\Authis now an abstract provider contract instead of a PDO-backed concrete implementation.Authhas been removed.Objectiveweb\Auth\DBAuthand usesobjectiveweb/db ^0.8.0.BasicAuthis now a complete in-memory provider for tests/dev/small setups.Objectiveweb\Auth\AuthControllerwas replaced by controllers underObjectiveweb\Auth\Controller\*.PasswordMismatchExceptionwas removed; authentication failures use the current auth/user exception model.src/password.php) was removed.Objectiveweb\Auth\.provider+uid).Provider architecture
DBAuth
Added
DBAuthas the database-backed provider:disabled_at;token_expires_at/ configurable TTL;user_context_callback;objectiveweb/db;DB::table()-backed query pagination/counting/sorting with nativeCollectionresults;GROUP_CONCAT.BasicAuth
Added a full in-memory provider implementing the same practical contract as
DBAuth:Collectionreturn contract asDBAuth, plus user updates;Authentication and session security
Session IDs are regenerated when authentication is established.
Password and OAuth login share the same session-establishment path.
Suspended users cannot authenticate.
Existing sessions are revalidated so role/lifecycle changes take effect on protected requests.
Public user payloads are centrally sanitized so password hashes, reset tokens and token-expiry internals are not exposed.
Registration, reset, query, invitation callbacks and duplicate-credential errors now return sanitized user data.
Password-reset tokens are stored as indexed SHA-256 digests of high-entropy one-time tokens and support expiration.
Password-reset token consumption is atomic: compare-and-swap updates the password and clears the token in one conditional statement.
Password login returns a generic HTTP 401 for missing identities, incorrect passwords and suspended accounts, reducing username enumeration.
Each provider credential has separate verification state and expiring, single-use hashed tokens. OAuth associations are verified only with provider-specific proof.
Anonymous password-recovery responses are indistinguishable for known and unknown UIDs; recovery callbacks are delivery-only and cannot alter the response.
Authenticated password changes require the existing password, verified through the provider; passwordless/OAuth-only accounts must use an independently verified reset or reauthentication flow.
Authenticated password changes require session-bound CSRF via
X-CSRF-Tokenand JSON HTTP requests.Logout redirects reject external, scheme-relative, backslash and control-character forms before ending the session.
Random token generation now uses cryptographically secure randomness.
user_context_callbackloads a sanitized user's application context at login and recomputes it on session revalidation.Authorization
Added role- and relation-based authorization:
Auth::ANONYMOUS,AUTHENTICATEDandALLaccess markers;RequireRolerouter middleware;user_can()checks for global roles, delegated users and arbitrary resource relations;User-management API
Added
Objectiveweb\Auth\Controller\UserController, protected by theadminrole, with support for:Objectiveweb\DB\Collection;Management hardening includes:
provider/profileare rejected on normal user updates;Auth controller
The new
Objectiveweb\Auth\Controller\AuthControllerseparates authentication concerns from admin user management and supports:/path, never//hostor external URLs);OAuth
Added/reworked
OAuthControllerwith:oauth-real-providersCI job installs optional League Google/Facebook packages and runs actual provider authorization, PKCE, mocked-HTTP token/userinfo exchange, first-time account choice, returning login, explicit linking, and negative state/token-error cases. No live provider credentials are used;getId()andtoArray()are assumed; name, avatar and email hints use safe optional getters with validated profile-field fallbacks. Invalid/missing data is ignored, without changing provider-subject verification or account-linking rules;OAuthController::postLink($provider)returningauthorization_url; ordinary sign-in never silently attaches new credentials or confirms pending links;examples/oauth-account-choice.htmlwith configurable same-origin redirect and application-routedgetPendingAccount,postCreateAccount,postExistingAccount,postCancelPendingAccountendpoints;redirectUrifor every provider, validated before login, linking and token exchange (HTTPS, or explicitly configured HTTP loopback for local development);HTTP_HOST,HTTP_X_FORWARDED_PROTO, or arbitrary request paths;Database schema and migrations
Added bundled Phinx migrations for the default DBAuth model:
user;user_credentials;role;user_roles;delegations.The default user schema includes:
disabled_at;Credential schema includes provider/UID identity, profile, token, verification expiration/verified timestamp, last-login and creation fields. The credential-verification migration is included.
Migrations intentionally use logical table names and remain compatible with application-level Phinx/database prefixes.
Correctness fixes
GROUP_CONCAT.Tooling and dependencies
objectiveweb/db ^0.8.0.objectiveweb/router ^3.0as a development dependency for controller/middleware compatibility testing.composer validate --strict.CI and tests
GitHub Actions now runs:
release.ymlon pull requests: PHP 8.2, Composer--no-dev, runtime autoload/authentication smoke tests, and an isolated consumer installation of the v0.2.0 candidate via a copied Composer path package;Collection-based DBAuth queries.The test suite now includes dedicated coverage for:
Collectionquery pagination/search.NOT NULLon composite primary keys), migrated schema constraints, and authentication/credential flows.Release documentation and migration
Documentation
README was rewritten for the 0.2.0 architecture and now documents:
managed_relationsto application-owned associations plususer_context_callback;Collectionlist responses, pagination metadata and CSRF requirements.Deferred to a later release
Rate limiting is intentionally not implemented in 0.2.0. Applications must enforce login, registration, recovery, reset-token and credential-verification throttling at a trusted reverse proxy, gateway, WAF or middleware. Do not use SQL rate-limit tables or per-request application database counters. The future pluggable implementation is tracked in #2.