Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 47
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
CampaignsSecondaryAuthenticationProvider
0.00% covered (danger)
0.00%
0 / 47
0.00% covered (danger)
0.00%
0 / 4
306
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getAuthenticationRequests
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
20
 beginSecondaryAuthentication
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 beginSecondaryAccountCreation
0.00% covered (danger)
0.00%
0 / 37
0.00% covered (danger)
0.00%
0 / 1
132
1<?php
2
3namespace MediaWiki\Extension\Campaigns;
4
5use MediaWiki\Auth\AbstractSecondaryAuthenticationProvider;
6use MediaWiki\Auth\AuthenticationRequest;
7use MediaWiki\Auth\AuthenticationResponse;
8use MediaWiki\Auth\AuthManager;
9use MediaWiki\Extension\CentralAuth\SharedDomainUtils;
10use MediaWiki\Extension\EventLogging\EventLogging;
11use MediaWiki\MediaWikiServices;
12use MediaWiki\Registration\ExtensionRegistry;
13use MediaWiki\Session\SessionManager;
14use MediaWiki\User\TempUser\TempUserConfig;
15use MobileContext;
16
17/**
18 * Log user creations to EventLogging, including the parameter "campaign" that
19 * was set on account creation form link if one was present.
20 */
21class CampaignsSecondaryAuthenticationProvider
22    extends AbstractSecondaryAuthenticationProvider {
23
24    public function __construct( private readonly TempUserConfig $tempUserConfig ) {
25    }
26
27    /** @inheritDoc */
28    public function getAuthenticationRequests( $action, array $options ) {
29        if ( $action === AuthManager::ACTION_CREATE ) {
30            $useCampaignField = !isset( $options['username'] ) ||
31                ( $this->tempUserConfig->isEnabled() && $this->tempUserConfig->isTempName( $options['username'] ) );
32
33            return [ new CampaignsAuthenticationRequest(
34                $this->manager->getRequest(),
35                $useCampaignField
36            ) ];
37        }
38
39        return [];
40    }
41
42    /** @inheritDoc */
43    public function beginSecondaryAuthentication( $user, array $reqs ) {
44        return AuthenticationResponse::newAbstain();
45    }
46
47    /** @inheritDoc */
48    public function beginSecondaryAccountCreation( $user, $creator, array $reqs ) {
49        $req = AuthenticationRequest::getRequestByClass(
50            $reqs, CampaignsAuthenticationRequest::class
51        );
52
53        $request = $this->manager->getRequest();
54        $userId = $user->getId();
55        $creatorUserId = $creator->getId();
56
57        // MediaWiki allows existing users to create accounts on behalf
58        // of others. In such cases the ID of the newly-created user and
59        // the ID of the user making this web request are different.
60        $isSelfMade = ( $userId && $userId === $creatorUserId ) || !$creatorUserId;
61
62        $displayMobile = ExtensionRegistry::getInstance()->isLoaded( 'MobileFrontend' ) &&
63            MobileContext::singleton()->shouldDisplayMobileView();
64
65        $sul3Enabled = false;
66        if ( ExtensionRegistry::getInstance()->isLoaded( 'CentralAuth' ) ) {
67            // Check if we're in SUL3 mode or not and notify event schema.
68            /** @var SharedDomainUtils $sharedDomainUtils */
69            $sharedDomainUtils = MediaWikiServices::getInstance()
70                ->getService( 'CentralAuth.SharedDomainUtils' );
71            $sul3Enabled = $sharedDomainUtils->isSul3Enabled( $request );
72        }
73
74        // Default of -1 for wikis which don't have hCaptcha loaded
75        $hCaptchaScore = -1;
76        if ( ExtensionRegistry::getInstance()->isLoaded( 'hCaptcha' ) ) {
77            // get() may return null if no score was returned by the hCaptcha api, or otherwise not inserted
78            // on the ConfirmEdit side.
79            // Make sure we still default to using -1 as value outside range potentially returned by
80            // hCaptcha (0.00-1.00), and something that would be acceptable to the event schema.
81            $hCaptchaScore = SessionManager::getGlobalSession()->get( 'hCaptcha-score', -1 );
82        }
83
84        $event = [
85            'userId' => $userId,
86            'userName' => $user->getName(),
87            'isSelfMade' => $isSelfMade,
88            'campaign' => $req ? $req->campaign : '',
89            'displayMobile' => $displayMobile,
90            // @todo: Remove these unused fields when they're no longer required by the schema.
91            'token' => '',
92            'userBuckets' => '',
93            'isApi' => defined( 'MW_API' ),
94            'sul3Enabled' => $sul3Enabled,
95            'hCaptchaScore' => $hCaptchaScore,
96        ];
97
98        $returnTo = $request->getVal( 'returnto', $req ? $req->returnTo : null );
99        if ( $returnTo !== null ) {
100            $event[ 'returnTo' ] = $returnTo;
101        }
102
103        $returnToQuery = $request->getVal( 'returntoquery', $req ? $req->returnToQuery : null );
104        if ( $returnToQuery !== null ) {
105            $event[ 'returnToQuery' ] = $returnToQuery;
106        }
107
108        // This has been migrated to an Event Platform schema; schema revision is no longer used
109        // in this call. Versioned schema URI is set in extension.json.
110        EventLogging::logEvent( 'ServerSideAccountCreation', -1, $event );
111
112        return AuthenticationResponse::newPass();
113    }
114}