Passed
Push — main ( 317226...e95517 )
by Thierry
07:32
created

Server   A

Complexity

Total Complexity 26

Size/Duplication

Total Lines 185
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 45
dl 0
loc 185
rs 10
c 0
b 0
f 0
wmc 26

15 Methods

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