forked from stephane-monnot/db-user
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDbUser.php
408 lines (352 loc) · 9.8 KB
/
DbUser.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
<?php
namespace Shinbuntu\DbUser;
use Doctrine\DBAL\Connection as DoctrineConnection;
/**
* Create sql users.
*
* @author Stéphane Monnot <smonnot@solire.fr>
* @license MIT http://mit-license.org/
*/
class DbUser
{
/**
* Constant for privilege CREATE.
*/
const PRIVILEGE_CREATE = 'CREATE';
/**
* Constant for privilege DROP.
*/
const PRIVILEGE_DROP = 'DROP';
/**
* Constant for privilege GRANT OPTION.
*/
const PRIVILEGE_GRANT_OPTION = 'GRANT OPTION';
/**
* Constant for privilege LOCK TABLES.
*/
const PRIVILEGE_LOCK_TABLES = 'LOCK TABLES';
/**
* Constant for privilege REFERENCES.
*/
const PRIVILEGE_REFERENCES = 'REFERENCES';
/**
* Constant for privilege EVENT.
*/
const PRIVILEGE_EVENT = 'EVENT';
/**
* Constant for privilege ALTER.
*/
const PRIVILEGE_ALTER = 'ALTER';
/**
* Constant for privilege DELETE.
*/
const PRIVILEGE_DELETE = 'DELETE';
/**
* Constant for privilege INDEX.
*/
const PRIVILEGE_INDEX = 'INDEX';
/**
* Constant for privilege INSERT.
*/
const PRIVILEGE_INSERT = 'INSERT';
/**
* Constant for privilege SELECT.
*/
const PRIVILEGE_SELECT = 'SELECT';
/**
* Constant for privilege UPDATE.
*/
const PRIVILEGE_UPDATE = 'UPDATE';
/**
* Constant for privilege CREATE TEMPORARY TABLES.
*/
const PRIVILEGE_CREATE_TEMPORARY_TABLES = 'CREATE TEMPORARY TABLES';
/**
* Constant for privilege TRIGGER.
*/
const PRIVILEGE_TRIGGER = 'TRIGGER';
/**
* Constant for privilege CREATE VIEW.
*/
const PRIVILEGE_CREATE_VIEW = 'CREATE VIEW';
/**
* Constant for privilege SHOW VIEW.
*/
const PRIVILEGE_SHOW_VIEW = 'SHOW VIEW';
/**
* Constant for privilege ALTER ROUTINE.
*/
const PRIVILEGE_ALTER_ROUTINE = 'ALTER ROUTINE';
/**
* Constant for privilege CREATE ROUTINE.
*/
const PRIVILEGE_CREATE_ROUTINE = 'CREATE ROUTINE';
/**
* Constant for privilege EXECUTE.
*/
const PRIVILEGE_EXECUTE = 'EXECUTE';
/**
* Constant for privilege FILE.
*/
const PRIVILEGE_FILE = 'FILE';
/**
* Constant for privilege CREATE USER.
*/
const PRIVILEGE_CREATE_USER = 'CREATE USER';
/**
* Constant for privilege PROCESS.
*/
const PRIVILEGE_PROCESS = 'PROCESS';
/**
* Constant for privilege RELOAD.
*/
const PRIVILEGE_RELOAD = 'RELOAD';
/**
* Constant for privilege REPLICATION CLIENT.
*/
const PRIVILEGE_REPLICATION_CLIENT = 'REPLICATION CLIENT';
/**
* Constant for privilege REPLICATION SLAVE.
*/
const PRIVILEGE_REPLICATION_SLAVE = 'REPLICATION SLAVE';
/**
* Constant for privilege SHOW DATABASES.
*/
const PRIVILEGE_SHOW_DATABASES = 'SHOW DATABASES';
/**
* Constant for privilege SHUTDOWN.
*/
const PRIVILEGE_SHUTDOWN = 'SHUTDOWN';
/**
* Constant for privilege SUPER.
*/
const PRIVILEGE_SUPER = 'SUPER';
/**
* Constant for privilege ALL.
*/
const PRIVILEGE_ALL = 'ALL';
/**
* Constant for privilege USAGE.
*/
const PRIVILEGE_USAGE = 'USAGE';
/**
* Constant for privilege statement GRANT.
*/
const PRIVILEGE_STATEMENT_GRANT = 'GRANT';
/**
* Constant for privilege statement REVOKE.
*/
const PRIVILEGE_STATEMENT_REVOKE = 'REVOKE';
/**
* The connection.
*
* @var DoctrineConnection|\PDO
*/
protected $connection;
/**
* Constructor.
*
* @param DoctrineConnection|\PDO $connection The connection
*/
public function __construct($connection)
{
$this->connection = $connection;
}
/**
* Create MYSQL user.
*
* @param string $username Mysql username
* @param string $password Mysql password
* @param string $host Mysql host
*
* @return bool TRUE on success or FALSE on failure.
* @throws \Doctrine\DBAL\DBALException
*
*/
public function createUser($username, $password, $host = 'localhost')
{
return $this->connection->exec($this->createUserQuery($username, $password, $host)) !== false;
}
/**
* Build query to create MYSQL user.
*
* @param string $username Mysql username
* @param string $password Mysql password
* @param string $host Mysql host
*
* @return string SQL Query string
*/
public function createUserQuery($username, $password, $host = 'localhost')
{
return 'CREATE USER ' . $this->connection->quote($username) . '@' . $this->quoteIfNotWildcard($host) . ' IDENTIFIED BY ' . $this->connection->quote($password) . ';';
}
/**
* Delete MYSQL user.
*
* @param string $username Mysql username
* @param string $host Mysql host
*
* @return bool TRUE if exist or FALSE if not.
*/
public function dropUser($username, $host = 'localhost')
{
return $this->connection->exec($this->dropUserQuery($username, $host)) !== false;
}
/**
* Build query to drop MYSQL user.
*
* @param string $username Mysql username
* @param string $host Mysql host
*
* @return string SQL Query string
*/
public function dropUserQuery($username, $host = 'localhost')
{
return 'DROP USER ' . $this->connection->quote($username) . '@' . $this->quoteIfNotWildcard($host) . ';';
}
/**
* Test if MYSQL user exist.
*
* @param string $username Mysql username
*
* @return bool TRUE if exist or FALSE if not.
*/
public function userExist($username)
{
return $this->connection->query($this->userExistQuery($username))->fetchColumn();
}
/**
* Build query to test if MYSQL user exist.
*
* @param string $username Mysql username
*
* @return string SQL Query string
*/
public function userExistQuery($username)
{
return 'SELECT EXISTS(SELECT 1 FROM mysql.user WHERE user = ' . $this->connection->quote($username) . ');';
}
/**
* Grant privileges to mysql user.
*
* @param string $username Mysql username
* @param array|string $privileges Mysql privileges
* @param string $database Mysql database name
* @param string $table Mysql $table name
* @param string $host Mysql host
*
* @return bool TRUE on success or FALSE on failure.
* @throws \Doctrine\DBAL\DBALException
*
*/
public function grantPrivileges(
$username,
$privileges = self::PRIVILEGE_USAGE,
$database = '*',
$table = '*',
$host = 'localhost'
) {
$sqlQuery = $this->changePrivilegesQuery(
self::PRIVILEGE_STATEMENT_GRANT,
$username,
$privileges,
$database,
$table,
$host
);
return $this->connection->exec($sqlQuery) !== false;
}
/**
* Revoke privileges to mysql user.
*
* @param string $username Mysql username
* @param array|string $privileges Mysql privileges
* @param string $database Mysql database name
* @param string $table Mysql $table name
* @param string $host Mysql host
*
* @return bool TRUE on success or FALSE on failure.
* @throws \Doctrine\DBAL\DBALException
*
*/
public function revokePrivileges(
$username,
$privileges = self::PRIVILEGE_USAGE,
$database = '*',
$table = '*',
$host = 'localhost'
) {
$sqlQuery = $this->changePrivilegesQuery(
self::PRIVILEGE_STATEMENT_REVOKE,
$username,
$privileges,
$database,
$table,
$host
);
return $this->connection->exec($sqlQuery) !== false;
}
/**
* Flush privileges.
*
* @return bool TRUE on success or FALSE on failure.
*/
public function flushPrivileges()
{
return $this->connection->exec($this->flushPrivilegesQuery()) !== false;
}
/**
* Build query to flush privileges.
*
* @return string SQL Query string
*/
public function flushPrivilegesQuery()
{
return 'FLUSH PRIVILEGES;';
}
/**
* Build query to Grant or Revoke privileges to mysql user.
*
* @param string $privilegeStatement REVOKE or GRANT
* @param string $username Mysql username
* @param array|string $privileges Mysql privileges
* @param string $database Mysql database name
* @param string $table Mysql $table name
* @param string $host Mysql host
*
* @return string SQL Query string
*/
public function changePrivilegesQuery(
$privilegeStatement,
$username,
$privileges = self::PRIVILEGE_USAGE,
$database = '*',
$table = '*',
$host = 'localhost'
) {
if (is_string($privileges)) {
$privileges = [$privileges];
}
$usernameQuoted = $this->connection->quote($username);
$hostQuoted = $this->quoteIfNotWildcard($host);
$databaseQuoted = $this->quoteIdentifierIfNotWildcard($database);
$tableQuoted = $this->quoteIfNotWildcard($table);
$sqlQuery = $privilegeStatement . ' ' . implode(', ', $privileges)
. ' ON ' . $databaseQuoted . '.' . $tableQuoted . ' TO ' . $usernameQuoted . '@' . $hostQuoted . ';';
return $sqlQuery;
}
protected function quoteIfNotWildcard(string $value): string
{
if ('*' === $value) {
return $value;
}
return $this->connection->quote($value);
}
protected function quoteIdentifierIfNotWildcard(string $value): string
{
if ('*' === $value) {
return $value;
}
return $this->connection->quoteIdentifier($value);
}
}