Completed
Push — master ( df062e...3563b3 )
by Tharanga
02:22
created

PdoThirdPartyStorageRepository::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 2
dl 0
loc 4
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 PDOException;
14
use PDO;
15
16
/**
17
 * @codeCoverageIgnore
18
 * @package TSK\SSO\Storage
19
 *
20
 * This will connect to a MySQL database using the php-pdo driver to persist vendor data.
21
 */
22
class PdoThirdPartyStorageRepository implements ThirdPartyStorageRepository
23
{
24
    /**
25
     * @var PDO
26
     */
27
    private $dbConnection;
28
29
    /**
30
     * @var string
31
     */
32
    private $table;
33
34
    /**
35
     * @param PDO $dbConnection
36
     * @param string $table name of the table in the MySQL database
37
     */
38
    public function __construct(PDO $dbConnection, $table = 'thirdparty_connections')
39
    {
40
        $this->dbConnection = $dbConnection;
41
        $this->table = $table;
42
    }
43
44
    /**
45
     * Returns a mapped full user record for a given vendor email address or null.
46
     *
47
     * @param string $emailAddress email address used within the given vendor system
48
     * @param string|null $vendorName [optional] name of the third party vendor for vendor filtering
49
     * @return MappedUser|null
50
     */
51
    public function getUser($emailAddress, $vendorName = null)
52
    {
53
        if (is_null($vendorName)) {
54
            $sql = "SELECT * FROM `{$this->table}` WHERE `vendor_email` = :email LIMIT 1";
55
            $stmt = $this->dbConnection->prepare($sql);
56
        } else {
57
            $sql = "SELECT * FROM `{$this->table}` WHERE `vendor_email` = :email AND `vendor_name` = :vendor LIMIT 1";
58
            $stmt = $this->dbConnection->prepare($sql);
59
            $stmt->bindParam(':vendor', $vendorName, PDO::PARAM_STR);
60
        }
61
62
        $stmt->bindParam(':email', $emailAddress, PDO::PARAM_STR);
63
        $stmt->execute();
64
65
        $userMap = $stmt->fetch(PDO::FETCH_ASSOC);
66
        if (empty($userMap)) {
67
            return null;
68
        }
69
70
        return new MappedUser(
71
            $userMap['app_user_id'],
72
            $userMap['vendor_name'],
73
            $userMap['vendor_email'],
74
            $userMap['vendor_access_token'],
75
            $userMap['vendor_data']
76
        );
77
    }
78
79
    /**
80
     * Returns any vendor MappedUser list for a given Application user.
81
     *
82
     * @param AppUser $appUser
83
     * @return MappedUser[]
84
     */
85
    public function getByAppUser(AppUser $appUser)
86
    {
87
        $stmt = $this->dbConnection->prepare("SELECT * FROM `{$this->table}` WHERE `app_user_id` = :appUserId");
88
        $appUserId = $appUser->id();
89
        $stmt->bindParam(':appUserId', $appUserId, is_numeric($appUserId) ? PDO::PARAM_STR : PDO::PARAM_INT);
90
        $stmt->execute();
91
92
        $connections = array();
93
        while ($mappedUser = $stmt->fetch(PDO::FETCH_ASSOC)) {
94
            $connections[] = new MappedUser(
95
                $mappedUser['app_user_id'],
96
                $mappedUser['vendor_name'],
97
                $mappedUser['vendor_email'],
98
                $mappedUser['vendor_access_token'],
99
                $mappedUser['vendor_data']
100
            );
101
        }
102
103
        return $connections;
104
    }
105
106
    /**
107
     * @param AppUser $appUser
108
     * @param ThirdPartyUser $thirdPartyUser
109
     * @param CommonAccessToken $accessToken
110
     * @throws DataCannotBeStoredException
111
     */
112
    public function save(
113
        AppUser $appUser,
114
        ThirdPartyUser $thirdPartyUser,
115
        CommonAccessToken $accessToken
116
    ) {
117
        $sql = <<<SQL
118
            INSERT INTO `{$this->table}`
119
            (
120
                `app_user_id`,
121
                `vendor_name`,
122
                `vendor_email`,
123
                `vendor_access_token`,
124
                `vendor_data`,
125
                `created_at`
126
            )
127
            VALUES
128
            (
129
                :appUserId,
130
                :vendorName,
131
                :vendorEmail,
132
                :vendorToken,
133
                :vendorData,
134
                NOW()
135
            )
136
            ON DUPLICATE KEY UPDATE
137
                `vendor_access_token` = VALUES(`vendor_access_token`),
138
                `vendor_data` = VALUES(`vendor_data`),
139
                `updated_at` = NOW()
140
SQL;
141
        try {
142
            $vendorData = json_encode($thirdPartyUser->toArray());
143
            $appUserId = $appUser->id();
144
            $vendorName = $accessToken->vendor();
145
            $vendorEmail = $thirdPartyUser->email();
146
            $vendorToken = $accessToken->token();
147
148
            $stmt = $this->dbConnection->prepare($sql);
149
            $stmt->bindParam(':appUserId', $appUserId, PDO::PARAM_STR);
150
            $stmt->bindParam(':vendorName', $vendorName, PDO::PARAM_STR);
151
            $stmt->bindParam(':vendorEmail', $vendorEmail, PDO::PARAM_STR);
152
            $stmt->bindParam(':vendorToken', $vendorToken, PDO::PARAM_STR);
153
            $stmt->bindParam(':vendorData', $vendorData, PDO::PARAM_STR);
154
            $stmt->execute();
155
        } catch (PDOException $ex) {
156
            throw new DataCannotBeStoredException(
157
                sprintf("Couldn't save the third party user data. Error : %s", $ex->getMessage()),
158
                $ex->getCode(),
159
                $ex
160
            );
161
        }
162
    }
163
164
    /**
165
     * Use this to clean the storage after revoking access to a third party for example.
166
     *
167
     * @param string $emailAddress email address used within the given vendor system
168
     * @param string $vendorName name of the third party where the given email belongs to
169
     * @return bool
170
     */
171
    public function remove($emailAddress, $vendorName)
172
    {
173
        $sql = "DELETE FROM `{$this->table}` WHERE `vendor_email` = :email AND `vendor_name` = :vendor LIMIT 1";
174
        $stmt = $this->dbConnection->prepare($sql);
175
        $stmt->bindParam(':email', $emailAddress, PDO::PARAM_STR);
176
        $stmt->bindParam(':vendor', $vendorName, PDO::PARAM_STR);
177
        return $stmt->execute();
178
    }
179
}
180