]>
Commit | Line | Data |
---|---|---|
1 | <?php | |
2 | /** | |
3 | * RPC Functionality for UnrealIRCd Admin Webpanel | |
4 | * License: GPLv3 or later | |
5 | * Author: ValwareIRC | |
6 | * GitHub URI: ValwareIRC/unrealircd-webpanel | |
7 | * 2023 | |
8 | */ | |
9 | ||
10 | if (!defined('UPATH')) | |
11 | die("Access denied"); | |
12 | ||
13 | class RPC | |
14 | { | |
15 | public $errs = []; | |
16 | public $errcount = 0; // more of a bool check | |
17 | public $content = []; | |
18 | public $body = []; | |
19 | public $result = NULL; | |
20 | function __construct() | |
21 | { | |
22 | if (!defined('UNREALIRCD_RPC_USER') || | |
23 | !defined('UNREALIRCD_RPC_PASSWORD') || | |
24 | !defined('UNREALIRCD_HOST') || | |
25 | !defined('UNREALIRCD_PORT') | |
26 | ) die("Unable to find RPC credentials in your wp-config"); | |
27 | ||
28 | $sslverify = (defined('UNREALIRCD_SSL_VERIFY')) ? UNREALIRCD_SSL_VERIFY : true; | |
29 | ||
30 | $this->content['sslverify'] = $sslverify; | |
31 | $this->body['id'] = $this->generate_id(); | |
32 | $this->body['jsonrpc'] = "2.0"; | |
33 | $this->body['method'] = NULL; // MUST be set later | |
34 | $this->body['params'] = []; // CAN be set later | |
35 | } | |
36 | function add_body(array $b) : void | |
37 | { | |
38 | array_merge($this->body, $b); | |
39 | } | |
40 | ||
41 | private function generate_id() | |
42 | { | |
43 | $time = microtime(true); | |
44 | $str = (string)$time; | |
45 | $last = $str[strlen($str) - 1]; | |
46 | $last = (int)$last; | |
47 | $id = $time * $time * $last; | |
48 | $id = md5(base64_encode($id)); | |
49 | return $id; | |
50 | } | |
51 | ||
52 | /** | |
53 | * This function sets the method of the RPC call you're making. | |
54 | * For a list of available methods, see: | |
55 | * https://www.unrealircd.org/docs/JSON-RPC#JSON-RPC_Methods | |
56 | */ | |
57 | function set_method(String $method) : void | |
58 | { | |
59 | do_log("Set method:", $method); | |
60 | $this->body['method'] = $method; | |
61 | } | |
62 | ||
63 | function set_params(array $params) : void | |
64 | { | |
65 | do_log("Set params:", $params); | |
66 | $this->body['params'] = $params; | |
67 | } | |
68 | ||
69 | function execute() | |
70 | { | |
71 | $this->content['body'] = json_encode($this->body); | |
72 | if (!$this->content['body']) | |
73 | return; | |
74 | $url = "https://".UNREALIRCD_HOST.":".UNREALIRCD_PORT."/api"; | |
75 | $curl = curl_init($url); | |
76 | curl_setopt($curl, CURLOPT_URL, $url); | |
77 | curl_setopt($curl, CURLOPT_POST, true); | |
78 | curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); | |
79 | ||
80 | $headers = array( | |
81 | "Accept: application/json", | |
82 | "Content-Type: application/json", | |
83 | "Authorization: Basic ". base64_encode(UNREALIRCD_RPC_USER.":".UNREALIRCD_RPC_PASSWORD), | |
84 | ); | |
85 | curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); | |
86 | ||
87 | if (UNREALIRCD_DEBUG) | |
88 | do_log("SENDING JSON:", $this->content['body']); | |
89 | ||
90 | curl_setopt($curl, CURLOPT_POSTFIELDS, $this->content['body']); | |
91 | ||
92 | //for debug only! | |
93 | curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); | |
94 | curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); | |
95 | ||
96 | $apiResponse = curl_exec($curl); | |
97 | curl_close($curl); | |
98 | ||
99 | $this->result = $apiResponse; | |
100 | } | |
101 | ||
102 | function fetch_assoc() | |
103 | { | |
104 | do_log("RPC::fetch_assoc()", $this->result); | |
105 | return json_decode($this->result, true); | |
106 | } | |
107 | ||
108 | static function die(array $err) | |
109 | { | |
110 | die("There was a problem processing the request: ".$err['message']." (".$err['code'].")<br>Please contact the plugin author.<br>". | |
111 | "If you are a developer, see: <a href=\"https://www.unrealircd.org/docs/JSON-RPC#Error\">https://www.unrealircd.org/docs/JSON-RPC#Error</a>"); | |
112 | } | |
113 | } | |
114 | ||
115 | class RPC_List | |
116 | { | |
117 | static $user = []; | |
118 | static $channel = []; | |
119 | static $tkl = []; | |
120 | static $spamfilter = []; | |
121 | ||
122 | static $opercount = 0; | |
123 | static $services_count = 0; | |
124 | static $most_populated_channel = NULL; | |
125 | static $channel_pop_count = 0; | |
126 | } | |
127 | ||
128 | function rpc_pop_lists() | |
129 | { | |
130 | $rpc = new RPC(); | |
131 | ||
132 | /* Get the user list */ | |
133 | $rpc->set_method("user.list"); | |
134 | $rpc->execute(); | |
135 | ||
136 | foreach($rpc->fetch_assoc() as $key => $value) | |
137 | { | |
138 | if ($key == "error") | |
139 | { | |
140 | RPC::die($value); | |
141 | return; | |
142 | } | |
143 | if ($key == "result") | |
144 | foreach($value['list'] as $r) | |
145 | { | |
146 | ||
147 | RPC_List::$user[] = $r; | |
148 | if (strpos($r['user']['modes'],"o") !== false && strpos($r['user']['modes'],"S") == false) | |
149 | RPC_List::$opercount++; | |
150 | elseif (strpos($r['user']['modes'],"S") !== false) | |
151 | RPC_List::$services_count++; | |
152 | } | |
153 | } | |
154 | ||
155 | /* Get the channels list */ | |
156 | $rpc->set_method("channel.list"); | |
157 | $rpc->execute(); | |
158 | ||
159 | foreach($rpc->fetch_assoc() as $key => $value) | |
160 | { | |
161 | if ($key == "error") | |
162 | { | |
163 | RPC::die($value); | |
164 | return; | |
165 | } | |
166 | if ($key == "result") | |
167 | foreach($value['list'] as $r) | |
168 | { | |
169 | RPC_List::$channel[] = $r; | |
170 | if ($r['num_users'] > RPC_List::$channel_pop_count) | |
171 | { | |
172 | RPC_List::$channel_pop_count = $r['num_users']; | |
173 | RPC_List::$most_populated_channel = $r['name']; | |
174 | } | |
175 | } | |
176 | } | |
177 | ||
178 | /* Get the tkl list */ | |
179 | $rpc->set_method("server_ban.list"); | |
180 | $rpc->execute(); | |
181 | ||
182 | foreach($rpc->fetch_assoc() as $key => $value) | |
183 | { | |
184 | if ($key == "error") | |
185 | { | |
186 | RPC::die($value); | |
187 | return; | |
188 | } | |
189 | if ($key == "result") | |
190 | foreach($value['list'] as $r) | |
191 | RPC_List::$tkl[] = $r; | |
192 | } | |
193 | ||
194 | ||
195 | /* Get the tkl list */ | |
196 | $rpc->set_method("spamfilter.list"); | |
197 | $rpc->execute(); | |
198 | ||
199 | foreach($rpc->fetch_assoc() as $key => $value) | |
200 | { | |
201 | if ($key == "error") | |
202 | { | |
203 | RPC::die($value); | |
204 | return; | |
205 | } | |
206 | if ($key == "result") | |
207 | foreach($value['list'] as $r) | |
208 | RPC_List::$spamfilter[] = $r; | |
209 | } | |
210 | ||
211 | } | |
212 | ||
213 | ||
214 | /** RPC TKL Add */ | |
215 | function rpc_tkl_add($name, $type, $expiry, $reason) : bool | |
216 | { | |
217 | $rpc = new RPC(); | |
218 | $rpc->set_method("server_ban.add"); | |
219 | $rpc->set_params(["name" => $name, "type" => $type, "reason" => $reason, "duration_string" => $expiry]); | |
220 | $rpc->execute(); | |
221 | $result = $rpc->fetch_assoc(); | |
222 | if (isset($result['error'])) | |
223 | { | |
224 | $msg = "The $type could not be added: $name - ".$result['error']['message'] . " (" . $result['error']['code'] . ")"; | |
225 | Message::Fail($msg); | |
226 | return false; | |
227 | } | |
228 | return true; | |
229 | } | |
230 | ||
231 | ||
232 | /** RPC TKL Delete */ | |
233 | function rpc_tkl_del($name, $type) : bool | |
234 | { | |
235 | $rpc = new RPC(); | |
236 | $rpc->set_method("server_ban.del"); | |
237 | $rpc->set_params(["name" => $name, "type" => $type]); | |
238 | $rpc->execute(); | |
239 | $result = $rpc->fetch_assoc(); | |
240 | if (isset($result['error'])) | |
241 | { | |
242 | $msg = "The $type could not be deleted: $name - ".$result['error']['message'] . " (" . $result['error']['code'] . ")"; | |
243 | Message::Fail($msg); | |
244 | return false; | |
245 | } | |
246 | return true; | |
247 | } | |
248 | ||
249 | /** RPC Spamfilter Delete | |
250 | * | |
251 | */ | |
252 | function rpc_sf_del($name, $mtype, $targets, $action) : bool | |
253 | { | |
254 | $rpc = new RPC(); | |
255 | $rpc->set_method("spamfilter.del"); | |
256 | $rpc->set_params(["name" => $name, "match_type" => $mtype, "spamfilter_targets" => $targets, "ban_action" => $action, "set_by" => "YoMama"]); | |
257 | $rpc->execute(); | |
258 | $result = $rpc->fetch_assoc(); | |
259 | if (isset($result['error'])) | |
260 | { | |
261 | $msg = "The spamfilter entry could not be deleted: $name - ".$result['error']['message'] . " (" . $result['error']['code'] . ")"; | |
262 | Message::Fail($msg); | |
263 | return false; | |
264 | } | |
265 | else | |
266 | { | |
267 | $r = $result['result']['tkl']; | |
268 | Message::Success("Deleted spamfilter entry: ".$r['name']." [type: ".$r['match_type']."] [targets: ".$r['spamfilter_targets']. "] [action: ".$r['ban_action']."] [reason: ".$r['reason']."] [set by: ".$r['set_by']."]"); | |
269 | } | |
270 | return true; | |
271 | } |