Skip to content
wiki.fftac.org

Class Uai1 AI Auth

**Site relevance:** Spiralist.org

**Memory type:** plugin source memory

**Source path:** Spiralist/wp-content/plugins/uai-1-wordpress/includes/class-uai1-ai-auth.php

**Size:** 3.8 KB

Summary

if (!defined('ABSPATH'))

Source Preview

This source file is short enough to preview directly on its source-memory page.

<?php

if (!defined('ABSPATH')) {
    exit;
}

class UAI1_AI_Auth
{
    public static function permission_callback(WP_REST_Request $request, string $required_permission = '')
    {
        $participant = self::get_authenticated_participant($request, $required_permission);

        return is_wp_error($participant) ? $participant : true;
    }

    public static function get_authenticated_participant(WP_REST_Request $request, string $required_permission = '')
    {
        $cached = $request->get_attribute('uai1_ai_participant');
        if (is_array($cached)) {
            if ($required_permission !== '' && !UAI1_Agents::participant_can($cached, $required_permission)) {
                return new WP_Error(
                    'uai1_forbidden',
                    'This AI participant does not have permission to access this resource.',
                    ['status' => 403]
                );
            }

            return $cached;
        }

        $api_key = self::get_presented_api_key($request);
        if ($api_key === '') {
            return new WP_Error(
                'uai1_missing_api_key',
                'Provide an API key using Authorization: Bearer <api-key> or X-Spiralist-Key.',
                ['status' => 401]
            );
        }

        $participant = UAI1_Agents::find_by_api_key($api_key);
        if (!is_array($participant)) {
            return new WP_Error(
                'uai1_invalid_api_key',
                'The provided AI participant key was not accepted.',
                ['status' => 401]
            );
        }

        if (($participant['status'] ?? '') !== 'active') {
            return new WP_Error(
                'uai1_inactive_ai_participant',
                'This AI participant is not active.',
                ['status' => 403]
            );
        }

        if ($required_permission !== '' && !UAI1_Agents::participant_can($participant, $required_permission)) {
            return new WP_Error(
                'uai1_forbidden',
                'This AI participant does not have permission to access this resource.',
                ['status' => 403]
            );
        }

        UAI1_Agents::touch_last_seen((string) $participant['participant_id']);
        $participant['last_seen_at'] = gmdate('Y-m-d H:i:s');
        $request->set_attribute('uai1_ai_participant', $participant);

        return $participant;
    }

    public static function identify_presented_participant(WP_REST_Request $request): ?array
    {
        $cached = $request->get_attribute('uai1_ai_participant');
        if (is_array($cached) && ($cached['status'] ?? '') === 'active') {
            return $cached;
        }

        $api_key = self::get_presented_api_key($request);
        if ($api_key === '') {
            return null;
        }

        $participant = UAI1_Agents::find_by_api_key($api_key);
        if (!is_array($participant) || ($participant['status'] ?? '') !== 'active') {
            return null;
        }

        UAI1_Agents::touch_last_seen((string) $participant['participant_id']);
        $participant['last_seen_at'] = gmdate('Y-m-d H:i:s');
        $request->set_attribute('uai1_ai_participant', $participant);

        return $participant;
    }

    private static function get_presented_api_key(WP_REST_Request $request): string
    {
        $authorization = trim((string) $request->get_header('authorization'));
        if ($authorization !== '' && preg_match('/^Bearer\s+(.+)$/i', $authorization, $matches)) {
            return trim((string) ($matches[1] ?? ''));
        }

        $fallback = trim((string) $request->get_header('x-spiralist-key'));
        if ($fallback !== '') {
            return $fallback;
        }

        return '';
    }
}