DbUser::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
3
namespace Shinbuntu\DbUser;
4
5
use Doctrine\DBAL\Connection as DoctrineConnection;
6
7
/**
8
 * Create sql users.
9
 *
10
 * @author  Stéphane Monnot <[email protected]>
11
 * @license MIT http://mit-license.org/
12
 */
13
class DbUser
14
{
15
    /**
16
     * Constant for privilege CREATE.
17
     */
18
    const PRIVILEGE_CREATE = 'CREATE';
19
20
    /**
21
     * Constant for privilege DROP.
22
     */
23
    const PRIVILEGE_DROP = 'DROP';
24
25
    /**
26
     * Constant for privilege GRANT OPTION.
27
     */
28
    const PRIVILEGE_GRANT_OPTION = 'GRANT OPTION';
29
30
    /**
31
     * Constant for privilege LOCK TABLES.
32
     */
33
    const PRIVILEGE_LOCK_TABLES = 'LOCK TABLES';
34
35
    /**
36
     * Constant for privilege REFERENCES.
37
     */
38
    const PRIVILEGE_REFERENCES = 'REFERENCES';
39
40
    /**
41
     * Constant for privilege EVENT.
42
     */
43
    const PRIVILEGE_EVENT = 'EVENT';
44
45
    /**
46
     * Constant for privilege ALTER.
47
     */
48
    const PRIVILEGE_ALTER = 'ALTER';
49
50
    /**
51
     * Constant for privilege DELETE.
52
     */
53
    const PRIVILEGE_DELETE = 'DELETE';
54
55
    /**
56
     * Constant for privilege INDEX.
57
     */
58
    const PRIVILEGE_INDEX = 'INDEX';
59
60
    /**
61
     * Constant for privilege INSERT.
62
     */
63
    const PRIVILEGE_INSERT = 'INSERT';
64
65
    /**
66
     * Constant for privilege SELECT.
67
     */
68
    const PRIVILEGE_SELECT = 'SELECT';
69
70
    /**
71
     * Constant for privilege UPDATE.
72
     */
73
    const PRIVILEGE_UPDATE = 'UPDATE';
74
75
    /**
76
     * Constant for privilege CREATE TEMPORARY TABLES.
77
     */
78
    const PRIVILEGE_CREATE_TEMPORARY_TABLES = 'CREATE TEMPORARY TABLES';
79
80
    /**
81
     * Constant for privilege TRIGGER.
82
     */
83
    const PRIVILEGE_TRIGGER = 'TRIGGER';
84
85
    /**
86
     * Constant for privilege CREATE VIEW.
87
     */
88
    const PRIVILEGE_CREATE_VIEW = 'CREATE VIEW';
89
90
    /**
91
     * Constant for privilege SHOW VIEW.
92
     */
93
    const PRIVILEGE_SHOW_VIEW = 'SHOW VIEW';
94
95
    /**
96
     * Constant for privilege ALTER ROUTINE.
97
     */
98
    const PRIVILEGE_ALTER_ROUTINE = 'ALTER ROUTINE';
99
100
    /**
101
     * Constant for privilege CREATE ROUTINE.
102
     */
103
    const PRIVILEGE_CREATE_ROUTINE = 'CREATE ROUTINE';
104
105
    /**
106
     * Constant for privilege EXECUTE.
107
     */
108
    const PRIVILEGE_EXECUTE = 'EXECUTE';
109
110
    /**
111
     * Constant for privilege FILE.
112
     */
113
    const PRIVILEGE_FILE = 'FILE';
114
115
    /**
116
     * Constant for privilege CREATE USER.
117
     */
118
    const PRIVILEGE_CREATE_USER = 'CREATE USER';
119
120
    /**
121
     * Constant for privilege PROCESS.
122
     */
123
    const PRIVILEGE_PROCESS = 'PROCESS';
124
125
    /**
126
     * Constant for privilege RELOAD.
127
     */
128
    const PRIVILEGE_RELOAD = 'RELOAD';
129
130
    /**
131
     * Constant for privilege REPLICATION CLIENT.
132
     */
133
    const PRIVILEGE_REPLICATION_CLIENT = 'REPLICATION CLIENT';
134
135
    /**
136
     * Constant for privilege REPLICATION SLAVE.
137
     */
138
    const PRIVILEGE_REPLICATION_SLAVE = 'REPLICATION SLAVE';
139
140
    /**
141
     * Constant for privilege SHOW DATABASES.
142
     */
143
    const PRIVILEGE_SHOW_DATABASES = 'SHOW DATABASES';
144
145
    /**
146
     * Constant for privilege SHUTDOWN.
147
     */
148
    const PRIVILEGE_SHUTDOWN = 'SHUTDOWN';
149
150
    /**
151
     * Constant for privilege SUPER.
152
     */
153
    const PRIVILEGE_SUPER = 'SUPER';
154
155
    /**
156
     * Constant for privilege ALL.
157
     */
158
    const PRIVILEGE_ALL = 'ALL';
159
160
    /**
161
     * Constant for privilege USAGE.
162
     */
163
    const PRIVILEGE_USAGE = 'USAGE';
164
165
    /**
166
     * Constant for privilege statement GRANT.
167
     */
168
    const PRIVILEGE_STATEMENT_GRANT = 'GRANT';
169
170
    /**
171
     * Constant for privilege statement REVOKE.
172
     */
173
    const PRIVILEGE_STATEMENT_REVOKE = 'REVOKE';
174
175
    /**
176
     * The connection.
177
     *
178
     * @var DoctrineConnection|\PDO
179
     */
180
    protected $connection;
181
182
    /**
183
     * Constructor.
184
     *
185
     * @param DoctrineConnection|\PDO $connection The connection
186
     */
187
    public function __construct($connection)
188
    {
189
        $this->connection = $connection;
190
    }
191
192
    /**
193
     * Create MYSQL user.
194
     *
195
     * @param string $username Mysql username
196
     * @param string $password Mysql password
197
     *
198
     * @throws \Doctrine\DBAL\DBALException
199
     *
200
     * @return bool TRUE on success or FALSE on failure.
201
     */
202
    public function createUser($username, $password)
203
    {
204
        return $this->connection->exec($this->createUserQuery($username, $password)) !== false;
205
    }
206
207
    /**
208
     * Build query to create MYSQL user.
209
     *
210
     * @param string $username Mysql username
211
     * @param string $password Mysql password
212
     *
213
     * @return string SQL Query string
214
     */
215
    public function createUserQuery($username, $password)
216
    {
217
        return 'CREATE USER '.$username.'@localhost IDENTIFIED BY '.$this->connection->quote($password).';';
218
    }
219
220
    /**
221
     * Delete MYSQL user.
222
     *
223
     * @param string $username Mysql username
224
     *
225
     * @return bool TRUE if exist or FALSE if not.
226
     */
227
    public function dropUser($username)
228
    {
229
        return $this->connection->exec($this->dropUserQuery($username)) !== false;
230
    }
231
232
    /**
233
     * Build query to drop MYSQL user.
234
     *
235
     * @param string $username Mysql username
236
     *
237
     * @return string SQL Query string
238
     */
239
    public function dropUserQuery($username)
240
    {
241
        return 'DROP USER '.$username.'@localhost;';
242
    }
243
244
    /**
245
     * Test if MYSQL user exist.
246
     *
247
     * @param string $username Mysql username
248
     *
249
     * @return bool TRUE if exist or FALSE if not.
250
     */
251
    public function userExist($username)
252
    {
253
        return $this->connection->fetchColumn($this->userExistQuery($username));
0 ignored issues
show
Bug introduced by
The method fetchColumn does only exist in Doctrine\DBAL\Connection, but not in PDO.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
254
    }
255
256
    /**
257
     * Build query to test if MYSQL user exist.
258
     *
259
     * @param string $username Mysql username
260
     *
261
     * @return string SQL Query string
262
     */
263
    public function userExistQuery($username)
264
    {
265
        return 'SELECT EXISTS(SELECT 1 FROM mysql.user WHERE user = '.$this->connection->quote($username).');';
266
    }
267
268
    /**
269
     * Grant privileges to mysql user.
270
     *
271
     * @param string       $username   Mysql username
272
     * @param array|string $privileges Mysql privileges
273
     * @param string       $database   Mysql database name
274
     * @param string       $table      Mysql $table name
275
     *
276
     * @throws \Doctrine\DBAL\DBALException
277
     *
278
     * @return bool TRUE on success or FALSE on failure.
279
     */
280 View Code Duplication
    public function grantPrivileges($username, $privileges = self::PRIVILEGE_USAGE, $database = '*', $table = '*')
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
281
    {
282
        $sqlQuery = $this->changePrivilegesQuery(
283
            self::PRIVILEGE_STATEMENT_GRANT,
284
            $username,
285
            $privileges,
286
            $database,
287
            $table
288
        );
289
290
        return $this->connection->exec($sqlQuery) !== false;
291
    }
292
293
    /**
294
     * Revoke privileges to mysql user.
295
     *
296
     * @param string       $username   Mysql username
297
     * @param array|string $privileges Mysql privileges
298
     * @param string       $database   Mysql database name
299
     * @param string       $table      Mysql $table name
300
     *
301
     * @throws \Doctrine\DBAL\DBALException
302
     *
303
     * @return bool TRUE on success or FALSE on failure.
304
     */
305 View Code Duplication
    public function revokePrivileges($username, $privileges = self::PRIVILEGE_USAGE, $database = '*', $table = '*')
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
306
    {
307
        $sqlQuery = $this->changePrivilegesQuery(
308
            self::PRIVILEGE_STATEMENT_REVOKE,
309
            $username,
310
            $privileges,
311
            $database,
312
            $table
313
        );
314
315
        return $this->connection->exec($sqlQuery) !== false;
316
    }
317
318
    /**
319
     * Flush privileges.
320
     *
321
     * @return bool TRUE on success or FALSE on failure.
322
     */
323
    public function flushPrivileges()
324
    {
325
        return $this->connection->exec($this->flushPrivilegesQuery()) !== false;
326
    }
327
328
    /**
329
     * Build query to flush privileges.
330
     *
331
     * @return string SQL Query string
332
     */
333
    public function flushPrivilegesQuery()
334
    {
335
        return 'FLUSH PRIVILEGES;';
336
    }
337
338
    /**
339
     * Build query to Grant or Revoke privileges to mysql user.
340
     *
341
     * @param string       $privilegeStatement REVOKE or GRANT
342
     * @param string       $username           Mysql username
343
     * @param array|string $privileges         Mysql privileges
344
     * @param string       $database           Mysql database name
345
     * @param string       $table              Mysql $table name
346
     *
347
     * @return string SQL Query string
348
     */
349
    public function changePrivilegesQuery(
350
        $privilegeStatement,
351
        $username,
352
        $privileges = self::PRIVILEGE_USAGE,
353
        $database = '*',
354
        $table = '*'
355
    ) {
356
        if (is_string($privileges)) {
357
            $privileges = [$privileges];
358
        }
359
360
        $usernameQuoted = $this->connection->quote($username);
361
362
        $sqlQuery = $privilegeStatement.' '.implode(', ', $privileges)
363
            .' ON '.$database.'.'.$table.' TO '.$usernameQuoted.'@localhost;';
364
365
        return $sqlQuery;
366
    }
367
}
368