Page MenuHomePhabricator

LDAPGroups and LDAPUserInfo: UserLoggedIn hook not frequent enough
Closed, ResolvedPublic

Description

The UserLoggedIn hook is almost never called when authenticated via Auth_remoteuser. The session may last for month. Therefore changes in groups or user info will not be synced for a long time.

Proposal: Use UserLoadAfterLoadFromSession hook.

Here is an example of an implementation that was created to hotfix this issue:

$GLOBALS['wgHooks']['UserLoadAfterLoadFromSession'][] = function( $user ) {
	$webRequest = RequestContext::getMain()->getRequest();
	$session = $webRequest->getSession();
	$sessionDataKey = 'ldap-data-sync-last';

	$lastSyncTS = $session->get( $sessionDataKey, null );
	$nextSyncTS = $lastSyncTS + 1 * 60 * 60;
	$nowTS = time();

	if( $nowTS >= $nextSyncTS ) {
		$session->set( $sessionDataKey, $nowTS );

		$domain = 'XYZ';
		$domainConfigFactory = \MediaWiki\Extension\LDAPProvider\DomainConfigFactory::getInstance();
		$ldapClient = MediaWiki\Extension\LDAPProvider\ClientFactory::getInstance()->getForDomain( $domain );
		$ldapGroupsDomainConfig = $domainConfigFactory->factory(
			$domain,
			MediaWiki\Extension\LDAPGroups\Config::DOMAINCONFIG_SECTION
		);
		$ldapUserInfoDomainConfig = $domainConfigFactory->factory(
			$domain,
			MediaWiki\Extension\LDAPUserInfo\Config::DOMAINCONFIG_SECTION
		);
		$config = MediaWiki\MediaWikiServices::getInstance()->getMainConfig();

		//Here comes the code of the UserLoggedIn-Handlers of LDAPGroups and LDAPUserInfo
		//LDAPGroups
		$process = new \MediaWiki\Extension\LDAPGroups\GroupSyncProcess(
			$user,
			$ldapGroupsDomainConfig,
			$ldapClient,
			$config->get( 'LDAPGroupsSyncMechanismRegistry' )
		);
		$process->run();

		//LDAPUserInfo
		$userInfo = $ldapClient->getUserInfo( $user->getName() );
		$attributesMap = $ldapUserInfoDomainConfig->get( MediaWiki\Extension\LDAPUserInfo\Config::ATTRIBUTES_MAP );
		$modifierRegistry = $config->get( 'LDAPUserInfoModifierRegistry' );

		foreach ( $attributesMap as $modifierKey => $ldapAttribute ) {
			if ( !isset( $userInfo[$ldapAttribute] ) ) {
				continue;
			}

			$origModifierKey = $modifierKey;
			if ( !isset( $modifierRegistry[$modifierKey] ) ) {
				// "property.gender" --> "property.*"
				$modifierKey = preg_replace( '#^(.*?)\..*?#', '$1.*', $modifierKey );
				if ( !isset( $modifierRegistry[$modifierKey] ) ) {
					continue;
				}
			}
			$factoryCallback = $modifierRegistry[$modifierKey];
			$modifier = call_user_func_array(
				$factoryCallback,
				[
					$origModifierKey,
					$ldapUserInfoDomainConfig
				]
			);
			if ( $modifier instanceof MediaWiki\Extension\LDAPUserInfo\IUserInfoModifier === false ) {
				continue;
			}

			$status = $modifier->modifyUserInfo( $user, $userInfo[$ldapAttribute] );
		}

		$user->saveSettings();
	}

	return true;
};

Event Timeline

Osnard created this task.Apr 9 2019, 7:05 AM
Restricted Application added a subscriber: Aklapper. · View Herald TranscriptApr 9 2019, 7:05 AM
Osnard triaged this task as High priority.Apr 9 2019, 7:06 AM
Osnard updated the task description. (Show Details)

This worked and synch'd the LDAP groups, but needed one adjustment:
replace

$config = MediaWiki\MediaWikiServices::getInstance()->getMainConfig();

with

$config = new GlobalVarConfig();
Osnard reassigned this task from Osnard to Intracomof.Apr 17 2019, 6:02 AM
Osnard moved this task from Backlog to Doing on the LDAP-Extensions board.

@Intracomof Can you please check how things behave if the user is not logged in?

Osnard closed this task as Resolved.Apr 30 2019, 1:59 PM
Osnard moved this task from Doing to Done on the LDAP-Extensions board.