Completed
Pull Request — master (#2)
by Tharanga
02:31
created

MysqliThirdPartyStorageRepository::remove()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 2
dl 0
loc 6
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * @author Tharanga Kothalawala <[email protected]>
4
 * @date 30-12-2018
5
 */
6
7
namespace TSK\SSO\Storage;
8
9
use TSK\SSO\AppUser\AppUser;
10
use TSK\SSO\Storage\Exception\DataCannotBeStoredException;
11
use TSK\SSO\ThirdParty\CommonAccessToken;
12
use TSK\SSO\ThirdParty\ThirdPartyUser;
13
use mysqli;
14
15
/**
16
 * @codeCoverageIgnore
17
 * @package TSK\SSO\Storage
18
 *
19
 * This will connect to a MySQL database using the php-mysql driver to persist vendor data.
20
 */
21
class MysqliThirdPartyStorageRepository implements ThirdPartyStorageRepository
22
{
23
    /**
24
     * @var mysqli
25
     */
26
    private $dbConnection;
27
28
    /**
29
     * @var string
30
     */
31
    private $table;
32
33
    /**
34
     * @param mysqli $dbConnection
35
     * @param string $table name of the table in the MySQL database
36
     */
37
    public function __construct(mysqli $dbConnection, $table = 'thirdparty_connections')
38
    {
39
        $this->dbConnection = $dbConnection;
40
        $this->table = $table;
41
    }
42
43
    /**
44
     * Returns a mapped full user record for a given vendor email address or null.
45
     *
46
     * @param string $emailAddress email address used within the given vendor system
47
     * @param string|null $vendorName [optional] name of the third party vendor for vendor filtering
48
     * @return MappedUser|null
49
     */
50
    public function getUser($emailAddress, $vendorName = null)
51
    {
52
        if (is_null($vendorName)) {
53
            $stmt = $this->dbConnection->prepare(<<<SQL
54
                SELECT
55
                    `app_user_id`, `vendor_name`, `vendor_email`, `vendor_access_token`, `vendor_data`
56
                FROM `{$this->table}`
57
                WHERE
58
                    `vendor_email` = ?
59
                LIMIT 1
60
SQL
61
            );
62
            $stmt->bind_param('s', $emailAddress);
63
        } else {
64
            $stmt = $this->dbConnection->prepare(<<<SQL
65
                SELECT
66
                    `app_user_id`, `vendor_name`, `vendor_email`, `vendor_access_token`, `vendor_data`
67
                FROM `{$this->table}`
68
                WHERE
69
                    `vendor_email` = ?
70
                    AND `vendor_name` = ?
71
                LIMIT 1
72
SQL
73
            );
74
            $stmt->bind_param('ss', $emailAddress, $vendorName);
75
        }
76
77
        $stmt->execute();
78
        $stmt->bind_result($appUserId, $vendor, $vendorEmail, $vendorToken, $vendorData);
79
        $stmt->fetch();
80
        $stmt->close();
81
        if (empty($appUserId)) {
82
            return null;
83
        }
84
85
        return new MappedUser($appUserId, $vendor, $vendorEmail, $vendorToken, $vendorData);
86
    }
87
88
    /**
89
     * Returns any vendor MappedUser list for a given Application user.
90
     *
91
     * @param AppUser $appUser
92
     * @return MappedUser[]
93
     */
94
    public function getByAppUser(AppUser $appUser)
95
    {
96
        $stmt = $this->dbConnection->prepare(<<<SQL
97
                SELECT
98
                    `app_user_id`, `vendor_name`, `vendor_email`, `vendor_access_token`, `vendor_data`
99
                FROM `{$this->table}`
100
                WHERE
101
                    `app_user_id` = ?
102
SQL
103
        );
104
        $appUserId = $appUser->id();
105
        if (is_numeric($appUserId)) {
106
            $stmt->bind_param('i', $appUserId);
107
        } else {
108
            $stmt->bind_param('s', $appUserId);
109
        }
110
111
        $vendor, $vendorEmail, $vendorToken, $vendorData = null;
0 ignored issues
show
Bug introduced by
A parse error occurred: Syntax error, unexpected ',' on line 111 at column 15
Loading history...
112
        $connections = array();
113
        if ($stmt->execute() &&
114
            $stmt->store_result() &&
115
            $stmt->bind_result($appUserId, $vendor, $vendorEmail, $vendorToken, $vendorData)
116
        ) {
117
            while ($stmt->fetch()) {
118
                $connections[] = new MappedUser(
119
                    $appUserId,
120
                    $vendor,
121
                    $vendorEmail,
122
                    $vendorToken,
123
                    $vendorData
124
                );
125
            }
126
127
            $stmt->fetch();
128
            $stmt->close();
129
        }
130
131
        return $connections;
132
    }
133
134
    /**
135
     * @param AppUser $appUser
136
     * @param ThirdPartyUser $thirdPartyUser
137
     * @param CommonAccessToken $accessToken
138
     * @throws DataCannotBeStoredException
139
     */
140
    public function save(
141
        AppUser $appUser,
142
        ThirdPartyUser $thirdPartyUser,
143
        CommonAccessToken $accessToken
144
    ) {
145
        $sql = <<<SQL
146
INSERT INTO `{$this->table}`
147
(
148
    `app_user_id`,
149
    `vendor_name`,
150
    `vendor_email`,
151
    `vendor_access_token`,
152
    `vendor_data`,
153
    `created_at`
154
)
155
VALUES
156
(
157
    ?, ?, ?, ?, ?, NOW()
158
)
159
ON DUPLICATE KEY UPDATE
160
    `vendor_access_token` = VALUES(`vendor_access_token`),
161
    `vendor_data` = VALUES(`vendor_data`),
162
    `updated_at` = NOW()
163
SQL;
164
165
        $vendorData = json_encode($thirdPartyUser->toArray());
166
        $appUserId = $appUser->id();
167
        $vendorName = $accessToken->vendor();
168
        $vendorEmail = $thirdPartyUser->email();
169
        $vendorToken = $accessToken->token();
170
171
        $stmt = $this->dbConnection->prepare($sql);
172
        $stmt->bind_param('sssss', $appUserId, $vendorName, $vendorEmail, $vendorToken, $vendorData);
173
        $saved = $stmt->execute();
174
        if (!$saved) {
175
            throw new DataCannotBeStoredException(
176
                sprintf("Couldn't save the third party user data. Error : %s", $this->dbConnection->error)
177
            );
178
        }
179
    }
180
181
    /**
182
     * Use this to clean the storage after revoking access to a third party for example.
183
     *
184
     * @param string $emailAddress email address used within the given vendor system
185
     * @param string $vendorName name of the third party where the given email belongs to
186
     * @return bool
187
     */
188
    public function remove($emailAddress, $vendorName)
189
    {
190
        $sql = "DELETE FROM `{$this->table}` WHERE `vendor_email` = ? AND `vendor_name` = ? LIMIT 1";
191
        $stmt = $this->dbConnection->prepare($sql);
192
        $stmt->bind_param("ss", $emailAddress, $vendorName);
193
        $stmt->execute();
194
    }
195
}
196