Failed Conditions
Push — newinternal ( b66232...216d62 )
by Simon
16:33 queued 06:35
created

CredentialProviderBase::deleteCredential()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 1
dl 0
loc 29
rs 9.456
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\CredentialProviders;
10
11
use Waca\DataObjects\Credential;
12
use Waca\DataObjects\User;
13
use Waca\PdoDatabase;
14
use Waca\SiteConfiguration;
15
16
abstract class CredentialProviderBase implements ICredentialProvider
17
{
18
    /**
19
     * @var PdoDatabase
20
     */
21
    private $database;
22
    /**
23
     * @var SiteConfiguration
24
     */
25
    private $configuration;
26
    /** @var string */
27
    private $type;
28
29
    /**
30
     * CredentialProviderBase constructor.
31
     *
32
     * @param PdoDatabase       $database
33
     * @param SiteConfiguration $configuration
34
     * @param string            $type
35
     */
36
    public function __construct(PdoDatabase $database, SiteConfiguration $configuration, $type)
37
    {
38
        $this->database = $database;
39
        $this->configuration = $configuration;
40
        $this->type = $type;
41
    }
42
43
    /**
44
     * @param int  $userId
45
     *
46
     * @param bool $disabled
47
     *
48
     * @return Credential
0 ignored issues
show
Documentation introduced by
Should the return type not be Credential|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
49
     */
50
    protected function getCredentialData($userId, $disabled = false)
51
    {
52
        $sql = 'SELECT * FROM credential WHERE type = :t AND user = :u';
53
        $parameters = array(
54
            ':u' => $userId,
55
            ':t' => $this->type
56
        );
57
58
        if($disabled !== null) {
59
            $sql .= ' AND disabled = :d';
60
            $parameters[':d'] = $disabled ? 1 : 0;
61
        }
62
63
        $statement = $this->database->prepare($sql);
64
        $statement->execute($parameters);
65
66
        /** @var Credential $obj */
67
        $obj = $statement->fetchObject(Credential::class);
68
69
        if ($obj === false) {
70
            return null;
71
        }
72
73
        $obj->setDatabase($this->database);
74
75
        $statement->closeCursor();
76
77
        return $obj;
78
    }
79
80
    /**
81
     * @return PdoDatabase
82
     */
83
    public function getDatabase()
84
    {
85
        return $this->database;
86
    }
87
88
    /**
89
     * @return SiteConfiguration
90
     */
91
    public function getConfiguration()
92
    {
93
        return $this->configuration;
94
    }
95
96
    public function deleteCredential(User $user) {
97
        // get this factor
98
        $statement = $this->database->prepare('SELECT * FROM credential WHERE user = :user AND type = :type');
99
        $statement->execute(array(':user' => $user->getId(), ':type' => $this->type));
100
        /** @var Credential $credential */
101
        $credential = $statement->fetchObject(Credential::class);
102
        $credential->setDatabase($this->database);
103
        $statement->closeCursor();
104
105
        $stage = $credential->getFactor();
106
107
        $statement = $this->database->prepare('SELECT COUNT(*) FROM credential WHERE user = :user AND factor = :factor');
108
        $statement->execute(array(':user' => $user->getId(), ':factor' => $stage));
109
        $alternates = $statement->fetchColumn();
110
        $statement->closeCursor();
111
112
        if($alternates <= 1) {
113
            // decrement the factor for every stage above this
114
            $sql = 'UPDATE credential SET factor = factor - 1 WHERE user = :user AND factor > :factor';
115
            $statement = $this->database->prepare($sql);
116
            $statement->execute(array(':user' => $user->getId(), ':factor' => $stage));
117
        }
118
        else {
119
            // There are other auth factors at this point. Don't renumber the factors just yet.
120
        }
121
122
        // delete this credential.
123
        $credential->delete();
124
    }
125
126
    /**
127
     * @param User $user
128
     *
129
     * @return Credential
130
     */
131
    protected function createNewCredential(User $user)
132
    {
133
        $credential = new Credential();
134
        $credential->setDatabase($this->getDatabase());
135
        $credential->setUserId($user->getId());
136
        $credential->setType($this->type);
137
138
        return $credential;
139
    }
140
141
    /**
142
     * @param int $userId
143
     *
144
     * @return bool
145
     */
146
    public function userIsEnrolled($userId) {
147
        $cred = $this->getCredentialData($userId);
148
149
        return $cred !== null;
150
    }
151
}