Failed Conditions
Pull Request — newinternal (#527)
by Simon
16:02 queued 05:59
created

AuthenticationManager::authenticate()   A

Complexity

Conditions 5
Paths 8

Size

Total Lines 35

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
nc 8
nop 3
dl 0
loc 35
rs 9.0488
c 0
b 0
f 0
1
<?php
2
/******************************************************************************
3
 * Wikipedia Account Creation Assistance tool                                 *
4
 *                                                                            *
5
 * All code in this file is released into the public domain by the ACC        *
6
 * Development Team. Please see team.json for a list of contributors.         *
7
 ******************************************************************************/
8
9
namespace Waca\Security;
10
11
use PDO;
12
use Waca\DataObjects\User;
13
use Waca\Helpers\HttpHelper;
14
use Waca\PdoDatabase;
15
use Waca\Security\CredentialProviders\ICredentialProvider;
16
use Waca\Security\CredentialProviders\PasswordCredentialProvider;
17
use Waca\Security\CredentialProviders\YubikeyCredentialProvider;
18
use Waca\SiteConfiguration;
19
20
class AuthenticationManager
21
{
22
    const AUTH_OK = 1;
23
    const AUTH_FAIL = 2;
24
    const AUTH_REQUIRE_NEXT_STAGE = 3;
25
    private $typeMap = array();
26
    /**
27
     * @var PdoDatabase
28
     */
29
    private $database;
30
31
    /**
32
     * AuthenticationManager constructor.
33
     *
34
     * @param PdoDatabase       $database
35
     * @param SiteConfiguration $siteConfiguration
36
     * @param HttpHelper        $httpHelper
37
     */
38
    public function __construct(PdoDatabase $database, SiteConfiguration $siteConfiguration, HttpHelper $httpHelper)
0 ignored issues
show
Unused Code introduced by
The parameter $httpHelper is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
39
    {
40
        // setup providers
41
        $this->typeMap['password'] = new PasswordCredentialProvider($database, $siteConfiguration);
42
        $this->database = $database;
43
    }
44
45
    public function authenticate(User $user, $data, $stage)
46
    {
47
        $sql = 'SELECT type FROM credential WHERE user = :user AND factor = :stage';
48
        $statement = $this->database->prepare($sql);
49
        $statement->execute(array(':user' => $user->getId(), ':stage' => $stage));
50
        $options = $statement->fetchAll(PDO::FETCH_COLUMN);
51
52
        $sql = 'SELECT count(DISTINCT factor) FROM credential WHERE user = :user AND factor > :stage';
53
        $statement = $this->database->prepare($sql);
54
        $statement->execute(array(':user' => $user->getId(), ':stage' => $stage));
55
        $requiredFactors = $statement->fetchColumn();
56
57
        // prep the correct OK response based on how many factors are ahead of this one
58
        $success = self::AUTH_OK;
59
        if ($requiredFactors > 0) {
60
            $success = self::AUTH_REQUIRE_NEXT_STAGE;
61
        }
62
63
        foreach ($options as $type) {
64
            if (!isset($this->typeMap[$type])) {
65
                // does this type have a credentialProvider registered?
66
                continue;
67
            }
68
69
            /** @var ICredentialProvider $credentialProvider */
70
            $credentialProvider = $this->typeMap[$type];
71
            if ($credentialProvider->authenticate($user, $data)) {
72
                return $success;
73
            }
74
        }
75
76
        // We've iterated over all the available providers for this stage.
77
        // They all hate you.
78
        return self::AUTH_FAIL;
79
    }
80
}