Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 22
0.00% covered (danger)
0.00%
0 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
Hooks
0.00% covered (danger)
0.00%
0 / 22
0.00% covered (danger)
0.00%
0 / 6
182
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
 onAuthManagerLoginAuthenticateAudit
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
56
 doSuccessfulLogin
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 doFailedLogin
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 onLocalUserCreated
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 onRecentChange_save
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/**
3 * @file
4 * @ingroup Extensions
5 */
6
7// phpcs:disable MediaWiki.NamingConventions.LowerCamelFunctionsName
8
9namespace LoginNotify;
10
11use MediaWiki\Auth\AuthenticationResponse;
12use MediaWiki\Auth\Hook\AuthManagerLoginAuthenticateAuditHook;
13use MediaWiki\Auth\Hook\LocalUserCreatedHook;
14use MediaWiki\Hook\RecentChange_saveHook;
15use MediaWiki\User\User;
16use MediaWiki\User\UserFactory;
17use RecentChange;
18
19class Hooks implements
20    AuthManagerLoginAuthenticateAuditHook,
21    LocalUserCreatedHook,
22    RecentChange_saveHook
23{
24    /** @var UserFactory */
25    private $userFactory;
26
27    public function __construct( UserFactory $userFactory ) {
28        $this->userFactory = $userFactory;
29    }
30
31    /**
32     * Hook for login auditing
33     *
34     * @param AuthenticationResponse $ret Is login successful?
35     * @param User|null $user User object on successful auth
36     * @param string|null $username Username for failed attempts.
37     * @param string[] $extraData
38     */
39    public function onAuthManagerLoginAuthenticateAudit(
40        $ret, $user, $username, $extraData
41    ) {
42        if ( !$user && $username !== null ) {
43            $user = $this->userFactory->newFromName( $username, UserFactory::RIGOR_USABLE );
44        }
45
46        if ( !$user ) {
47            return;
48        }
49
50        if ( $ret->status === AuthenticationResponse::PASS ) {
51            self::doSuccessfulLogin( $user );
52        } elseif (
53            $ret->status === AuthenticationResponse::FAIL
54            && $ret->message->getKey() !== 'login-throttled'
55        ) {
56            self::doFailedLogin( $user );
57        }
58        // Other statuses include Abstain, Redirect, or UI. We ignore such
59        // statuses.
60    }
61
62    /**
63     * Handle a successful login (clear the attempt counter, send a notice, and record the
64     * current IP address as known).
65     *
66     * @param User $user The user who logged in.
67     */
68    public static function doSuccessfulLogin( User $user ) {
69        $loginNotify = LoginNotify::getInstance();
70        $loginNotify->clearCounters( $user );
71        $loginNotify->sendSuccessNotice( $user );
72        $loginNotify->recordKnownWithCookie( $user );
73    }
74
75    /**
76     * Handle a failed login (record the failure).
77     *
78     * @param User $user The user that failed to log in.
79     */
80    public static function doFailedLogin( User $user ) {
81        $loginNotify = LoginNotify::getInstance();
82        $loginNotify->recordFailure( $user );
83    }
84
85    /**
86     * Hook handler for new account creation.
87     *
88     * Called immediately after a local user has been created and saved to the database
89     *
90     * @todo This still sets cookies if user creates account well logged in as someone else.
91     * @param User $user User created
92     * @param bool $autocreated Whether this was an auto-created account
93     */
94    public function onLocalUserCreated( $user, $autocreated ) {
95        if ( !$autocreated ) {
96            $loginNotify = LoginNotify::getInstance();
97            $loginNotify->recordKnownWithCookie( $user );
98        }
99    }
100
101    /**
102     * @param RecentChange $recentChange
103     */
104    public function onRecentChange_save( $recentChange ) {
105        $loginNotify = LoginNotify::getInstance();
106        $user = $this->userFactory->newFromUserIdentity( $recentChange->getPerformerIdentity() );
107        $loginNotify->recordKnown( $user );
108    }
109}