gesmuni/laravel-auth-local

Local database authentication implementation for Gesmuni Auth System using Laravel Eloquent

Maintainers

Package info

gitlab.gitlab.videoatencion.com/gesmuni/php-laravel/laravel-auth-local.git

pkg:composer/gesmuni/laravel-auth-local

Statistics

Installs: 67

Dependents: 1

Suggesters: 0

1.1.0 2026-03-27 10:16 UTC

This package is not auto-updated.

Last update: 2026-05-08 11:11:46 UTC


README

Local database authentication implementation for Gesmuni Auth System using Laravel Eloquent

This package provides a Laravel-based implementation of the Gesmuni Auth System using Eloquent ORM. It implements all interfaces defined in gesmuni/laravel-auth-base for Local Mode operation, where the authentication system runs in-process with direct database access.

Features

  • Complete implementation of all 13 repository interfaces
  • LocalAuthQuery service for read-only authentication queries
  • LocalAuthAdmin service for full CRUD operations
  • Eloquent models with proper relationships
  • Database migrations for all 13 entities
  • Bootstrap seeder for system initialization
  • UUID-based primary keys for distributed compatibility
  • Group-based hierarchical authorization
  • Role and permission management per application namespace

Installation

1. Install via Composer

composer require gesmuni/laravel-auth-local

2. Publish and Run Migrations

php artisan vendor:publish --tag=gesmuni-auth-migrations
php artisan migrate

This will create 13 tables:

  • auth_actors
  • auth_roles
  • auth_permissions
  • auth_role_permissions
  • auth_app_users
  • auth_actor_roles
  • auth_app_data
  • auth_audit_logs
  • auth_refresh_tokens
  • auth_groups
  • auth_group_members
  • auth_group_roles
  • auth_app_registrations

3. Run Bootstrap Seeder

The seeder creates:

  • everyone system group (root of group tree)
  • 16 _auth.* system permissions
  • _auth.LocalAdmin system role with all auth permissions
  • Initial admin user
php artisan db:seed --class="Gesmuni\AuthLocal\Database\Seeders\AuthSystemSeeder"

You'll be prompted for the admin email and password during seeding.

Usage

Service Injection

The package registers two main services:

use Gesmuni\Auth\Base\Contracts\Services\AuthQuery;
use Gesmuni\Auth\Base\Contracts\Services\AuthAdmin;

class YourController
{
    public function __construct(
        private readonly AuthQuery $authQuery,
        private readonly AuthAdmin $authAdmin
    ) {}
}

Authentication

Validate Credentials

$result = $this->authQuery->validateCredentials('user@example.com', 'password');

if ($result->isSuccess()) {
    $actor = $result->actor;
    // Login successful
} else {
    // Login failed: $result->reason
}

Check Permissions

// Check single permission
if ($this->authQuery->hasPermission($actorId, '_auth.actor:create')) {
    // Actor can create actors
}

// Check any permission
if ($this->authQuery->hasAnyPermission($actorId, ['post:edit', 'post:delete'])) {
    // Actor has at least one of these permissions
}

// Check all permissions
if ($this->authQuery->hasAllPermissions($actorId, ['post:edit', 'post:publish'])) {
    // Actor has both permissions
}

Actor Management

Create Actor

use Gesmuni\Auth\Base\DTOs\Input\CreateActorInput;
use Gesmuni\Auth\Base\ValueObjects\ActorType;
use Gesmuni\Auth\Base\ValueObjects\ActorStatus;

$input = new CreateActorInput(
    type: ActorType::HUMAN,
    email: 'user@example.com',
    name: 'John Doe',
    password: 'secret123',  // Will be hashed automatically
    status: ActorStatus::ACTIVE,
    emailVerified: false
);

$actor = $this->authAdmin->createActor($input);

Update Actor

use Gesmuni\Auth\Base\DTOs\Input\UpdateActorInput;

$input = new UpdateActorInput(
    name: 'Jane Doe',
    email: 'jane@example.com',
    password: 'newsecret123'  // Optional, set to null to keep existing
);

$actor = $this->authAdmin->updateActor($actorId, $input);

Role Management

Create Role

use Gesmuni\Auth\Base\DTOs\Input\CreateRoleInput;

$input = new CreateRoleInput(
    name: 'Content Editor',
    slug: 'content_editor',
    description: 'Can create and edit content',
    isSystem: false
);

$role = $this->authAdmin->createRole($input);

Assign Permissions to Role

$this->authAdmin->assignPermissionsToRole(
    $roleId,
    [$permissionId1, $permissionId2, $permissionId3]
);

Assign Role to Actor

// In local mode, app_id is always null
$this->authAdmin->assignRoleToActor($actorId, null, $roleId);

Permission Management

Register Permissions

use Gesmuni\Auth\Base\DTOs\Input\CreatePermissionInput;

// Single permission
$input = new CreatePermissionInput(
    slug: 'blog.post:create',  // Format: namespace.resource:action
    name: 'Create Blog Posts',
    group: 'Blog',
    description: 'Allows creating new blog posts'
);

$permission = $this->authAdmin->registerPermission($input);

// Multiple permissions
$permissions = $this->authAdmin->registerPermissions([
    new CreatePermissionInput('blog.post:read', 'Read Posts', 'Blog'),
    new CreatePermissionInput('blog.post:update', 'Update Posts', 'Blog'),
    new CreatePermissionInput('blog.post:delete', 'Delete Posts', 'Blog'),
]);

List Permissions

// All permissions
$permissions = $this->authAdmin->listPermissions();

// Grouped by category
$permissionsByGroup = $this->authAdmin->listPermissionsByGroup();
// Returns: ['Blog' => [...], 'Users' => [...], ...]

Group Management

Create Group

use Gesmuni\Auth\Base\DTOs\Input\CreateGroupInput;

$input = new CreateGroupInput(
    name: 'Developers',
    parentId: $everyoneGroupId,  // Must have a parent (except 'everyone')
    description: 'Development team members'
);

$group = $this->authAdmin->createGroup($input);

Add Members to Group

$this->authAdmin->addMemberToGroup($actorId, $groupId);

Assign Role to Group

// All members inherit this role
$this->authAdmin->assignRoleToGroup($groupId, null, $roleId);

Get Effective Roles

// Returns direct roles + roles inherited from all groups
$roles = $this->authQuery->getActorEffectiveRoles($actorId);

Examples

The examples/ directory contains sample applications demonstrating how to use this package. These examples are excluded from the Composer distribution — to access them, clone the repository directly.

Minimal App

A minimal Laravel application with session-based authentication: login/logout, protected routes, and user info display with roles and permissions.

See examples/minimal-app/README.md for setup instructions.

Architecture

Local Mode

In Local Mode (app_id = 'local'):

  • The value 'local' is reserved for local mode operation
  • No AppRegistration required - the app is implicit
  • No explicit AppUser bindings - every actor is automatically a user
  • Roles and permissions are in the application's own namespace
  • Suitable for monoliths, small applications, and prototypes

Note: The original design used null for app_id in local mode, but this was changed to the reserved string 'local' to avoid issues with composite primary keys in SQL databases.

Entities

The system manages 13 entities:

  1. Actor - Users and applications with authentication
  2. Role - Container for permissions
  3. Permission - Atomic actions (namespace.resource:action)
  4. RolePermission - N:M relationship
  5. AppRegistration - Application namespaces (Service Mode)
  6. AppUser - Actor-to-app bindings
  7. ActorRole - Direct role assignments
  8. AppData - Per-actor key-value storage
  9. AuditLog - Operation audit trail
  10. RefreshToken - Token-based authentication
  11. Group - Hierarchical groups for role inheritance
  12. GroupMember - Actor membership in groups
  13. GroupRole - Role assignments to groups

Permission Resolution

An actor's effective permissions are the union of:

  1. Direct roles via ActorRole
  2. Group roles via GroupRole for all their groups
  3. Inherited roles from ancestor groups up the tree
Actor → Groups → Ancestor Groups → Roles → Permissions

Testing

Quick Start (SQLite - Default)

Run tests locally without Docker using SQLite in-memory database:

composer test
# or
vendor/bin/phpunit

This is the fastest and simplest way to run tests locally.

Testing with Docker (SQLite/MySQL/PostgreSQL)

For testing in a Docker environment, use Docker Compose. All CI/CD files are located in the ci-cd/ directory.

SQLite (default)

ci-cd/run-tests.sh

Or with Make:

cd ci-cd && make test

MySQL

ci-cd/run-tests.sh --mysql

PostgreSQL

ci-cd/run-tests.sh --postgres

Docker testing verifies compatibility with the same PHP version and extensions used in production.

Run Specific Tests

ci-cd/run-tests.sh tests/Feature/ActorRepositoryTest.php
ci-cd/run-tests.sh --filter=it_can_create_and_retrieve_an_actor

For more details about Docker testing, see ci-cd/TESTING.md

License

This project is licensed under the AGPL-3.0-or-later license.

Related Packages

Support

For issues and feature requests, please use the GitHub issue tracker.