Skip to the content.

← Back to Activities Plugin

5.6.7 Authorization Entity Reference

Last Updated: December 3, 2025
Status: Complete
Scope: Activities Plugin - Authorization Entity

Comprehensive technical reference for the Authorization entity, covering data model, lifecycle management, relationships, and integration patterns with the temporal authorization system.

Table of Contents

Authorization Entity Overview

The Authorization entity represents a member’s request to participate in a specific activity within KMP. Authorizations implement temporal validation through ActiveWindowBaseEntity, providing time-bounded access control with automatic lifecycle management.

Core Responsibilities:

Location: plugins/Activities/src/Model/Entity/Authorization.php
Extends: App\Model\Entity\ActiveWindowBaseEntity
Table Class: Activities\Model\Table\AuthorizationsTable

Database Schema

Table: activities_authorizations

The Authorization entity maps to the activities_authorizations database table with the following structure:

Column Type Null Default Notes
id INT(11) NO Auto Primary key, auto-incrementing
member_id INT(11) NO   Foreign key to member requesting authorization
activity_id INT(11) NO   Foreign key to activity being authorized for
granted_member_role_id INT(11) YES NULL Foreign key to role granted upon approval
expires_on DATETIME YES NULL Authorization expiration date/time
start_on DATETIME YES NULL Authorization start date/time
created TIMESTAMP NO CURRENT Creation timestamp
approval_count INT(11) NO 0 Number of approvals received
status VARCHAR(20) NO ‘pending’ Current authorization status
revoked_reason VARCHAR(255) YES ’’ Reason for revocation if revoked
revoker_id INT(11) YES NULL Foreign key to member who revoked authorization
is_renewal TINYINT(1) NO 0 Flag indicating if this is a renewal request

Indexes:

Foreign Keys:

Notes:

Entity Properties

Core Identification Properties

id

member_id

activity_id

Temporal Properties

start_on

expires_on

Approval Workflow Properties

status

approval_count

Role Assignment Properties

granted_member_role_id

Revocation Properties

revoker_id

revoked_reason

Renewal Properties

is_renewal

Audit Properties

created

Authorization Status Constants

The authorization lifecycle is managed through distinct status values defined as class constants:

// From Authorization entity definition
const APPROVED_STATUS = "Approved";      // Authorization is active and valid
const PENDING_STATUS = "Pending";        // Authorization awaiting approval
const DENIED_STATUS = "Denied";          // Authorization request was rejected
const REVOKED_STATUS = "Revoked";        // Previously approved authorization was revoked
const EXPIRED_STATUS = "Expired";        // Authorization has passed expiration date
const RETRACTED_STATUS = "Retracted";    // Member retracted pending request

Status Lifecycle Overview

stateDiagram-v2
    [*] --> PENDING : Request Created
    PENDING --> APPROVED : All Required Approvals Received
    PENDING --> DENIED : Approval Denied
    PENDING --> EXPIRED : Expires Before Approval
    PENDING --> RETRACTED : Member Retracts Request
    APPROVED --> EXPIRED : Expiration Date Passed
    APPROVED --> REVOKED : Administrative Revocation
    DENIED --> [*]
    EXPIRED --> [*]
    REVOKED --> [*]
    RETRACTED --> [*]

Status Descriptions

PENDING (“Pending”)

APPROVED (“Approved”)

DENIED (“Denied”)

REVOKED (“Revoked”)

EXPIRED (“Expired”)

RETRACTED (“Retracted”)

Status Transition Rules

Automatic Transitions (by ActiveWindow/checkStatus):

Manual Transitions (by AuthorizationManager):

Relationships

Parent Relationships (belongsTo)

member

activity

member_role

revoked_by

Child Relationships (hasMany)

authorization_approvals

ActiveWindow Relationships

Through ActiveWindowBaseEntity inheritance, Authorization provides temporal query support:

Example:

// Find all currently valid authorizations
$currentAuths = $authorizationsTable->find('current')->toArray();

// Find upcoming authorizations starting soon
$upcomingAuths = $authorizationsTable->find('upcoming')->toArray();

// Get authorization history
$history = $authorizationsTable->find('previous')
    ->where(['member_id' => $memberId])
    ->toArray();

Mass Assignment Security

The Authorization entity uses CakePHP’s accessible field system to prevent mass assignment vulnerabilities while allowing legitimate field updates.

Accessible Fields

The following fields can be safely mass assigned through newEntity() or patchEntity():

Core Fields:

Relationship Management:

Protected Fields

The following fields are NOT accessible via mass assignment:

System Fields:

Audit Fields:

Authorization Lifecycle

Creation Phase (PENDING)

Trigger: Member requests authorization for activity

$authorization = $authorizationsTable->newEntity([
    'member_id' => $member->id,
    'activity_id' => $activity->id,
    'start_on' => FrozenDate::now(),
    'expires_on' => FrozenDate::now()->addYears(2),
    'status' => Authorization::PENDING_STATUS,
    'is_renewal' => false
]);
$authorizationsTable->save($authorization);

State:

Approval Phase (PENDING → APPROVED or DENIED)

Trigger: Approval workflow processes required approvers

Path A: Approval Granted

// When all required approvals received
$authorization->status = Authorization::APPROVED_STATUS;
$authorizationsTable->save($authorization);
// ActiveWindow automatically assigns role

Path B: Approval Denied

// When approval denied
$authorization->status = Authorization::DENIED_STATUS;
$authorizationsTable->save($authorization);
// Terminal state - no further action

State (Approved):

Active Phase (APPROVED)

Duration: From approval to expiration date

Automatic Expiration:

Manual Revocation:

$authorization->status = Authorization::REVOKED_STATUS;
$authorization->revoked_reason = "Member left organization";
$authorization->revoker_id = $revokingMemberId;
$authorizationsTable->save($authorization);
// Role automatically removed by ActiveWindow

Termination Phase (EXPIRED, REVOKED, DENIED, RETRACTED)

Terminal States:

Renewal Options:

Temporal Management

ActiveWindow Integration

Authorization extends ActiveWindowBaseEntity for automatic temporal lifecycle management:

Automatic Behaviors:

Key Methods:

// Check if authorization is currently active
$isActive = $authorization->isCurrent();  // Between start_on and expires_on

// Get time until expiration
$daysRemaining = $authorization->expires_on->diffInDays(
    new FrozenDate()
);

// Check if upcoming
$isUpcoming = $authorization->isUpcoming();  // start_on in future

// Check if in past
$isExpired = !$authorization->isCurrent() && 
             $authorization->expires_on < new FrozenDate();

Temporal Queries

// Find currently valid authorizations for member
$currentAuths = $authorizationsTable->find('current')
    ->where(['member_id' => $memberId])
    ->contain(['Activities'])
    ->toArray();

// Find expiring authorizations in next 30 days
$expiringAuths = $authorizationsTable->find()
    ->where([
        'status' => Authorization::APPROVED_STATUS,
        'expires_on >=' => FrozenDate::now(),
        'expires_on <=' => FrozenDate::now()->addDays(30)
    ])
    ->contain(['Members', 'Activities'])
    ->all();

// Get authorization history
$history = $authorizationsTable->find()
    ->where(['member_id' => $memberId, 'activity_id' => $activityId])
    ->orderBy(['created' => 'DESC'])
    ->all();

Usage Examples

Creating Authorization Requests

// Simple authorization request
$authorization = $authorizationsTable->newEntity([
    'member_id' => $member->id,
    'activity_id' => $activity->id,
    'start_on' => FrozenDate::now(),
    'expires_on' => FrozenDate::now()->addYears(2),
    'status' => Authorization::PENDING_STATUS
]);
$authorizationsTable->save($authorization);

// Renewal authorization
$authorization = $authorizationsTable->newEntity([
    'member_id' => $member->id,
    'activity_id' => $activity->id,
    'start_on' => $existing->expires_on->addDay(),
    'expires_on' => $existing->expires_on->addYears(2),
    'status' => Authorization::PENDING_STATUS,
    'is_renewal' => true
]);
$authorizationsTable->save($authorization);

Checking Current Authorizations

// Check if member has current authorization for activity
$currentAuth = $authorizationsTable->find('current')
    ->where([
        'member_id' => $member->id,
        'activity_id' => $activity->id,
        'status' => Authorization::APPROVED_STATUS
    ])
    ->first();

if ($currentAuth) {
    $daysRemaining = $currentAuth->expires_on->diffInDays(FrozenDate::now());
    echo "Authorization valid for {$daysRemaining} more days";
} else {
    echo "Member not authorized for this activity";
}

Handling Expiration

// Manual status check
$authorizationsTable->checkStatus();

// Get expired authorizations
$expiredAuths = $authorizationsTable->find()
    ->where(['status' => Authorization::EXPIRED_STATUS])
    ->contain(['Members', 'Activities'])
    ->all();

// Process expiration notifications
foreach ($expiredAuths as $auth) {
    if ($auth->expires_on->diffInDays(FrozenDate::now()) === 0) {
        // Send expiration notification
        $this->queueMail('Activities', 'authorizationExpired', 
            $auth->member->email_address, 
            ['activity' => $auth->activity->name]
        );
    }
}

Authorization Revocation

// Revoke authorization
$authorization = $authorizationsTable->get($id);
$authorization->status = Authorization::REVOKED_STATUS;
$authorization->revoked_reason = "Member removed from organization";
$authorization->revoker_id = $currentUserId;
$authorizationsTable->save($authorization);
// Role automatically removed by ActiveWindow

Approval Workflow Integration

// Get authorization with complete approval workflow
$authorization = $authorizationsTable->get($id, [
    'contain' => [
        'Members',
        'Activities',
        'AuthorizationApprovals' => [
            'Members',
            'sort' => ['created' => 'ASC']
        ]
    ]
]);

// Track approval progress
$totalRequired = $authorization->activity->num_required_authorizors;
$approvals = $authorization->authorization_approvals;
$pending = $approvals->where(function ($approval) {
    return $approval->responded_on === null;
});

$progress = [
    'total_required' => $totalRequired,
    'responses_received' => count($approvals) - count($pending),
    'pending_count' => count($pending),
    'complete' => $authorization->approval_count >= $totalRequired
];

Authorization Statistics

// Get authorization statistics for activity
$stats = $authorizationsTable->find()
    ->select([
        'activity_id',
        'status',
        'count' => $authorizationsTable->find()->func()->count('*')
    ])
    ->where(['activity_id' => $activityId])
    ->groupBy(['status'])
    ->toArray();

$summary = [
    'pending' => collect($stats)->where('status', Authorization::PENDING_STATUS)->first()['count'] ?? 0,
    'approved' => collect($stats)->where('status', Authorization::APPROVED_STATUS)->first()['count'] ?? 0,
    'denied' => collect($stats)->where('status', Authorization::DENIED_STATUS)->first()['count'] ?? 0,
    'expired' => collect($stats)->where('status', Authorization::EXPIRED_STATUS)->first()['count'] ?? 0,
    'revoked' => collect($stats)->where('status', Authorization::REVOKED_STATUS)->first()['count'] ?? 0
];

Source Files