Newer
Older
wordpress-ojs-pugin / includes / class-oidc-bridge.php
<?php
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

class WP_OJS_SSO_OIDC_Bridge {

    private static $instance = null;

    public static function instance() {
        if ( null === self::$instance ) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    private function __construct() {
        add_filter( 'oidc_registered_clients', [ $this, 'register_client' ] );
        add_filter( 'oidc_user_claims', [ $this, 'add_claims' ], 10, 2 );
        add_filter( 'oidc_minimal_capability', [ $this, 'minimal_capability' ] );
    }

    /**
     * Abbassa la capability minima richiesta dal plugin OpenID Connect Server
     * al livello di Sottoscrittore (`read`), in modo che qualsiasi utente
     * WordPress autenticato possa completare il flusso SSO verso OJS.
     *
     * L'effettivo accesso ai contenuti riservati (es. Issue 36) resta
     * governato dal claim `subscription_active` e dal meta utente
     * `ojs_subscription_active` gestiti dall'amministratore.
     */
    public function minimal_capability( $capability ) {
        return 'read';
    }

    public function register_client( $clients ) {
        $opts = WP_OJS_SSO_Plugin::get_option();

        $client_id = $opts['client_id'] ?? '';
        if ( empty( $client_id ) ) {
            return $clients;
        }

        $clients[ $client_id ] = [
            'name'         => 'OJS Journal',
            'secret'       => $opts['client_secret'] ?? '',
            'redirect_uri' => $opts['redirect_uri'] ?? '',
            'grant_types'  => [ 'authorization_code' ],
            'scope'        => 'openid profile email',
        ];

        return $clients;
    }

    public function add_claims( $claims, $user ) {
        $opts       = WP_OJS_SSO_Plugin::get_option();
        $meta_key   = $opts['user_meta_key'] ?? 'ojs_subscription_active';
        $claim_name = $opts['claim_name'] ?? 'subscription_active';

        if ( ! empty( $user->user_email ) ) {
            $claims['email']          = $user->user_email;
            $claims['email_verified'] = true;
        }

        if ( ! empty( $user->user_login ) && empty( $claims['preferred_username'] ) ) {
            $claims['preferred_username'] = $user->user_login;
        }

        if ( empty( $claims['given_name'] ) && ! empty( $user->first_name ) ) {
            $claims['given_name'] = $user->first_name;
        }
        if ( empty( $claims['family_name'] ) && ! empty( $user->last_name ) ) {
            $claims['family_name'] = $user->last_name;
        }

        if ( ! empty( $claim_name ) && preg_match( '/^[a-z_][a-z0-9_]*$/', $claim_name ) ) {
            $claims[ $claim_name ] = (bool) get_user_meta( $user->ID, $meta_key, true );
        }

        return $claims;
    }
}