Page MenuHomeWickedGov Phorge

FilteredRequestTracker.php
No OneTemporary

Size
3 KB
Referenced Files
None
Subscribers
None

FilteredRequestTracker.php

<?php
namespace MediaWiki\Extension\CentralAuth;
use LogicException;
use MediaWiki\Auth\AuthManager;
use MediaWiki\Request\WebRequest;
use MWExceptionHandler;
/**
* A trivial service to track whether authentication providers have been filtered in the current
* request, used as shared state between SsoHookHandler (which does the filtering, and needs to
* know at the end of the authentication whether filtering was done, but can't easily preserve
* that information through a multi-request authentication process) and
* CentralAuthSsoPreAuthenticationProvider (which can use AuthManager to preserve state during an
* authentication flow).
* @see \MediaWiki\Extension\CentralAuth\Hooks\Handlers\SsoHookHandler
* @see \MediaWiki\Extension\CentralAuth\CentralAuthSsoPreAuthenticationProvider
*/
class FilteredRequestTracker {
private const SESSION_KEY = 'CentralAuth.filtered';
/** @var WebRequest|null The authentication request for which we disabled non-SUL3 local providers. */
private ?WebRequest $filteredRequest = null;
/**
* Mark the given request as using relaxed security due to the AuthManagerVerifyAuthentication hook.
* Note that on authentication requests this is called before the authentication process starts,
* and it can be called on non-authentication requests as well (initializing authentication
* providers is involved in e.g. skin logic).
*/
public function markRequestAsFiltered( WebRequest $request ): void {
$this->filteredRequest = $request;
}
/**
* Store filtered state in the authentication session. Must be invoked inside the
* authentication flow.
* @param AuthManager $authManager
*/
public function saveState( AuthManager $authManager ): void {
$arePreviousRequestsFiltered = $authManager->getAuthenticationSessionData( self::SESSION_KEY, false );
if ( !$arePreviousRequestsFiltered && $this->filteredRequest ) {
$authManager->setAuthenticationSessionData( self::SESSION_KEY, true );
} elseif ( $arePreviousRequestsFiltered && !$this->filteredRequest ) {
// TODO This is probably possible if the user manipulates request data mid-authentication;
// maybe we should prevent that in a cleaner way. For now just log. The session flag
// will stick, so security-wise the AuthManagerVerifyAuthentication hook will
// handle it correctly.
MWExceptionHandler::logException( new LogicException( 'Filter flag applied inconsistently' ) );
}
}
/**
* Check whether the current authentication flow is using relaxed security due to the
* AuthManagerVerifyAuthentication hook (invoked in either the current request or a subsequent
* authentication step).
*/
public function isCurrentAuthenticationFlowFiltered( AuthManager $authManager ): bool {
$arePreviousRequestsFiltered = $authManager->getAuthenticationSessionData( self::SESSION_KEY, false );
if ( $this->filteredRequest && $authManager->getRequest() !== $this->filteredRequest ) {
// Maybe a unit test where some but not all services got reset?
// Should not happen during real authentication.
MWExceptionHandler::logException( new LogicException(
'Request changed between AuthManagerFilterProviders and AuthManagerVerifyAuthentication' ) );
}
return $this->filteredRequest || $arePreviousRequestsFiltered;
}
/**
* Reset the state of the tracker.
* @internal For use in tests only
*/
public function reset(): void {
if ( !defined( 'MW_PHPUNIT_TEST' ) ) {
throw new LogicException( 'reset() is for testing only' );
}
$this->filteredRequest = null;
}
}

File Metadata

Mime Type
text/x-php
Expires
Sat, Oct 3, 08:48 (1 w, 4 d ago)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
5a/e6/9f12cb7418e619ff77b8eb5410d1
Default Alt Text
FilteredRequestTracker.php (3 KB)

Event Timeline