1<?php
2/**
3 * @author Stephen "TheCodeAssassin" Hoogendijk
4 */
5
6namespace InfluxDB\Client;
7
8
9use InfluxDB\Client;
10use InfluxDB\Database;
11
12/**
13 * Class Admin
14 *
15 * @package InfluxDB\Client
16 */
17class Admin
18{
19    /**
20     * @var Client
21     */
22    private $client;
23
24    const PRIVILEGE_READ = 'READ';
25    const PRIVILEGE_WRITE = 'WRITE';
26    const PRIVILEGE_ALL= 'ALL';
27
28    public function __construct(Client $client)
29    {
30        $this->client = $client;
31    }
32
33    /**
34     * Create a user
35     *
36     * @param string $username
37     * @param string $password
38     *
39     * @param string $privilege
40     *
41     * @throws \InfluxDB\Exception
42     * @return \InfluxDB\ResultSet
43     */
44    public function createUser($username, $password, $privilege = null)
45    {
46        $query = sprintf('CREATE USER %s WITH PASSWORD \'%s\'', $username, $password);
47
48        if ($privilege) {
49            $query .= " WITH $privilege PRIVILEGES";
50        }
51
52        return $this->client->query(null, $query);
53    }
54
55    /**
56     * @param string $username
57     *
58     * @return \InfluxDB\ResultSet
59     * @throws \InfluxDB\Exception
60     */
61    public function dropUser($username)
62    {
63        return $this->client->query(null, 'DROP USER ' . $username);
64    }
65
66    /**
67     * Change a users password
68     *
69     * @param string $username
70     * @param string $newPassword
71     *
72     * @return \InfluxDB\ResultSet
73     * @throws \InfluxDB\Exception
74     */
75    public function changeUserPassword($username, $newPassword)
76    {
77        return $this->client->query(null, "SET PASSWORD FOR $username = '$newPassword'");
78    }
79
80    /**
81     * Shows a list of all the users
82     *
83     * @return \InfluxDB\ResultSet
84     * @throws \InfluxDB\Exception
85     */
86    public function showUsers()
87    {
88        return $this->client->query(null, 'SHOW USERS');
89    }
90
91    /**
92     * Grants permissions
93     *
94     * @param string $privilege
95     * @param string $username
96     * @param Database|string $database
97     *
98     * @return \InfluxDB\ResultSet
99     * @throws \InfluxDB\Exception
100     */
101    public function grant($privilege, $username, $database = null)
102    {
103        return $this->executePrivilege('GRANT', $privilege, $username, $database);
104    }
105
106    /**
107     * Revokes permissions
108     *
109     * @param string          $privilege
110     * @param string          $username
111     * @param Database|string $database
112     *
113     * @throws \InfluxDB\Exception
114     * @return \InfluxDB\ResultSet
115     */
116    public function revoke($privilege, $username, $database = null)
117    {
118        return $this->executePrivilege('REVOKE', $privilege, $username, $database);
119    }
120
121    /**
122     * @param string          $type
123     * @param string          $privilege
124     * @param string          $username
125     * @param Database|string $database
126     *
127     * @throws \InfluxDB\Exception
128     * @return \InfluxDB\ResultSet
129     */
130    private function executePrivilege($type, $privilege, $username, $database = null)
131    {
132
133        if (!in_array($privilege, [self::PRIVILEGE_READ, self::PRIVILEGE_WRITE, self::PRIVILEGE_ALL], true)) {
134            throw new Exception($privilege . ' is not a valid privileges, allowed privileges: READ, WRITE, ALL');
135        }
136
137        if ($privilege !== self::PRIVILEGE_ALL && !$database) {
138            throw new Exception('Only grant ALL cluster-wide privileges are allowed');
139        }
140
141        $database = ($database instanceof Database ? $database->getName() : (string) $database);
142
143        $query = "$type $privilege";
144
145        if ($database) {
146            $query .= sprintf(' ON %s ', $database);
147        } else {
148            $query .= ' PRIVILEGES ';
149        }
150
151        if ($username && $type === 'GRANT') {
152            $query .= "TO $username";
153        } elseif ($username && $type === 'REVOKE') {
154            $query .= "FROM $username";
155        }
156
157        return $this->client->query(null, $query);
158    }
159}