Passed
Push — main ( 5ed508...867457 )
by Thierry
35:39 queued 27:58
created

Server::isSystemSchema()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 3
rs 10
1
<?php
2
3
namespace Lagdo\DbAdmin\Driver\Db;
4
5
use Lagdo\DbAdmin\Driver\DriverInterface;
6
use Lagdo\DbAdmin\Driver\Entity\UserEntity;
7
use Lagdo\DbAdmin\Driver\Utils\Utils;
8
9
use function preg_match;
10
use function preg_match_all;
11
12
abstract class Server implements ServerInterface
13
{
14
    /**
15
     * @var DriverInterface
16
     */
17
    protected $driver;
18
19
    /**
20
     * @var Utils
21
     */
22
    protected $utils;
23
24
    /**
25
     * The constructor
26
     *
27
     * @param DriverInterface $driver
28
     * @param Utils $utils
29
     */
30
    public function __construct(DriverInterface $driver, Utils $utils)
31
    {
32
        $this->driver = $driver;
33
        $this->utils = $utils;
34
    }
35
36
    /**
37
     * @inheritDoc
38
     */
39
    public function getUsers(string $database): array
40
    {
41
        // From privileges.inc.php
42
        $clause = ($database == '' ? 'user' : 'db WHERE ' . $this->driver->quote($database) . ' LIKE Db');
43
        $query = "SELECT User, Host FROM mysql.$clause ORDER BY Host, User";
44
        $statement = $this->driver->query($query);
45
        // $grant = $statement;
46
        if (!$statement) {
47
            // list logged user, information_schema.USER_PRIVILEGES lists just the current user too
48
            $statement = $this->driver->query("SELECT SUBSTRING_INDEX(CURRENT_USER, '@', 1) " .
49
                "AS User, SUBSTRING_INDEX(CURRENT_USER, '@', -1) AS Host");
50
        }
51
        $users = [];
52
        while ($user = $statement->fetchAssoc()) {
53
            $users[] = $user;
54
        }
55
        return $users;
56
    }
57
58
    /**
59
     * @param UserEntity $user
60
     * @param array $grant
61
     *
62
     * @return void
63
     */
64
    private function addUserGrant(UserEntity $user, array $grant)
65
    {
66
        if (preg_match('~GRANT (.*) ON (.*) TO ~', $grant[0], $match) &&
67
            preg_match_all('~ *([^(,]*[^ ,(])( *\([^)]+\))?~', $match[1], $matches, PREG_SET_ORDER)) {
68
            //! escape the part between ON and TO
69
            foreach ($matches as $val) {
70
                $match2 = $match[2] ?? '';
71
                $val2 = $val[2] ?? '';
72
                if ($val[1] != 'USAGE') {
73
                    $user->grants["$match2$val2"][$val[1]] = true;
74
                }
75
                if (preg_match('~ WITH GRANT OPTION~', $grant[0])) { //! don't check inside strings and identifiers
76
                    $user->grants["$match2$val2"]['GRANT OPTION'] = true;
77
                }
78
            }
79
        }
80
        if (preg_match("~ IDENTIFIED BY PASSWORD '([^']+)~", $grant[0], $match)) {
81
            $user->password = $match[1];
82
        }
83
    }
84
85
    /**
86
     * @inheritDoc
87
     */
88
    public function getUserGrants(string $user, string $host): UserEntity
89
    {
90
        $entity = new UserEntity($user, $host);
91
92
        // From user.inc.php
93
        //! use information_schema for MySQL 5 - column names in column privileges are not escaped
94
        $query = 'SHOW GRANTS FOR ' . $this->driver->quote($user) . '@' . $this->driver->quote($host);
95
        if (!($statement = $this->driver->query($query))) {
96
            return $entity;
97
        }
98
99
        while ($grant = $statement->fetchRow()) {
100
            $this->addUserGrant($entity, $grant);
101
        }
102
        return $entity;
103
    }
104
105
    /**
106
     * @inheritDoc
107
     */
108
    public function getUserPrivileges(UserEntity $user)
109
    {
110
        $user->privileges = $this->driver->rows('SHOW PRIVILEGES');
111
    }
112
113
    /**
114
     * @inheritDoc
115
     */
116
    public function engines()
117
    {
118
        return [];
119
    }
120
121
    /**
122
     * @inheritDoc
123
     */
124
    public function collations()
125
    {
126
        return [];
127
    }
128
129
    /**
130
     * @inheritDoc
131
     */
132
    public function databaseCollation(string $database, array $collations)
133
    {
134
        return '';
135
    }
136
137
    /**
138
     * @inheritDoc
139
     */
140
    public function isInformationSchema(string $database)
141
    {
142
        return false;
143
    }
144
145
    /**
146
     * @inheritDoc
147
     */
148
    public function isSystemSchema(string $database)
149
    {
150
        return false;
151
    }
152
153
    /**
154
     * @inheritDoc
155
     */
156
    public function variables()
157
    {
158
        return [];
159
    }
160
161
    /**
162
     * @inheritDoc
163
     */
164
    public function statusVariables()
165
    {
166
        return [];
167
    }
168
169
    /**
170
     * @inheritDoc
171
     */
172
    public function routineLanguages()
173
    {
174
        return [];
175
    }
176
177
    /**
178
     * @inheritDoc
179
     */
180
    public function renameDatabase(string $name, string $collation)
181
    {
182
        return false;
183
    }
184
185
    /**
186
     * @inheritDoc
187
     */
188
    public function processes()
189
    {
190
        return [];
191
    }
192
193
    /**
194
     * @inheritDoc
195
     */
196
    public function processAttr(array $process, string $key, string $val): string
197
    {
198
        return $this->utils->str->html($val);
199
    }
200
}
201