Issues (186)

CredentialProviders/CredentialProviderBase.php (2 issues)

Severity
1
<?php
2
/******************************************************************************
3
 * Wikipedia Account Creation Assistance tool                                 *
4
 * ACC Development Team. Please see team.json for a list of contributors.     *
5
 *                                                                            *
6
 * This is free and unencumbered software released into the public domain.    *
7
 * Please see LICENSE.md for the full licencing statement.                    *
8
 ******************************************************************************/
9
10
namespace Waca\Security\CredentialProviders;
11
12
use Waca\DataObjects\Credential;
13
use Waca\DataObjects\User;
14
use Waca\PdoDatabase;
15
use Waca\SiteConfiguration;
16
17
abstract class CredentialProviderBase implements ICredentialProvider
18
{
19
    /**
20
     * @var PdoDatabase
21
     */
22
    private $database;
23
    /**
24
     * @var SiteConfiguration
25
     */
26
    private $configuration;
27
    /** @var string */
28
    private $type;
29
30
    /**
31
     * CredentialProviderBase constructor.
32
     *
33
     * @param PdoDatabase       $database
34
     * @param SiteConfiguration $configuration
35
     * @param string            $type
36
     */
37
    public function __construct(PdoDatabase $database, SiteConfiguration $configuration, $type)
38
    {
39
        $this->database = $database;
40
        $this->configuration = $configuration;
41
        $this->type = $type;
42
    }
43
44
    /**
45
     * @param int  $userId
46
     *
47
     * @param bool $disabled
48
     *
49
     * @return Credential
50
     */
51
    protected function getCredentialData($userId, $disabled = false)
52
    {
53
        $sql = 'SELECT * FROM credential WHERE type = :t AND user = :u';
54
        $parameters = array(
55
            ':u' => $userId,
56
            ':t' => $this->type
57
        );
58
59
        if ($disabled !== null) {
0 ignored issues
show
The condition $disabled !== null is always true.
Loading history...
60
            $sql .= ' AND disabled = :d';
61
            $parameters[':d'] = $disabled ? 1 : 0;
62
        }
63
64
        $statement = $this->database->prepare($sql);
65
        $statement->execute($parameters);
66
67
        /** @var Credential $obj */
68
        $obj = $statement->fetchObject(Credential::class);
69
70
        if ($obj === false) {
0 ignored issues
show
The condition $obj === false is always false.
Loading history...
71
            return null;
72
        }
73
74
        $obj->setDatabase($this->database);
75
76
        $statement->closeCursor();
77
78
        return $obj;
79
    }
80
81
    /**
82
     * @return PdoDatabase
83
     */
84
    public function getDatabase()
85
    {
86
        return $this->database;
87
    }
88
89
    /**
90
     * @return SiteConfiguration
91
     */
92
    public function getConfiguration()
93
    {
94
        return $this->configuration;
95
    }
96
97
    public function deleteCredential(User $user)
98
    {
99
        // get this factor
100
        $statement = $this->database->prepare('SELECT * FROM credential WHERE user = :user AND type = :type');
101
        $statement->execute(array(':user' => $user->getId(), ':type' => $this->type));
102
        /** @var Credential $credential */
103
        $credential = $statement->fetchObject(Credential::class);
104
        $credential->setDatabase($this->database);
105
        $statement->closeCursor();
106
107
        $stage = $credential->getFactor();
108
109
        $statement = $this->database->prepare('SELECT COUNT(*) FROM credential WHERE user = :user AND factor = :factor');
110
        $statement->execute(array(':user' => $user->getId(), ':factor' => $stage));
111
        $alternates = $statement->fetchColumn();
112
        $statement->closeCursor();
113
114
        if ($alternates <= 1) {
115
            // decrement the factor for every stage above this
116
            $sql = 'UPDATE credential SET factor = factor - 1 WHERE user = :user AND factor > :factor';
117
            $statement = $this->database->prepare($sql);
118
            $statement->execute(array(':user' => $user->getId(), ':factor' => $stage));
119
        }
120
        else {
121
            // There are other auth factors at this point. Don't renumber the factors just yet.
122
        }
123
124
        // delete this credential.
125
        $credential->delete();
126
    }
127
128
    /**
129
     * @param User $user
130
     *
131
     * @return Credential
132
     */
133
    protected function createNewCredential(User $user)
134
    {
135
        $credential = new Credential();
136
        $credential->setDatabase($this->getDatabase());
137
        $credential->setUserId($user->getId());
138
        $credential->setType($this->type);
139
140
        return $credential;
141
    }
142
143
    /**
144
     * @param int $userId
145
     *
146
     * @return bool
147
     */
148
    public function userIsEnrolled($userId)
149
    {
150
        $cred = $this->getCredentialData($userId);
151
152
        return $cred !== null;
153
    }
154
}