]> jfr.im git - irc/unrealircd/unrealircd-webpanel.git/blob - Classes/class-rpc.php
Merge branch 'main' of https://github.com/ValwareIRC/unrealircd-webpanel
[irc/unrealircd/unrealircd-webpanel.git] / Classes / class-rpc.php
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 }
272
273 /** Convert the duration_string */
274 function rpc_convert_duration_string($str)
275 {
276 $tok = explode("w", $str);
277 $weeks = $tok[0];
278 $tok = explode("d", $tok[1]);
279 $days = $tok[0];
280 $tok = explode("h", $tok[1]);
281 $hours = $tok[0];
282 return "$weeks weeks, $days days and $hours hours";
283
284 }