]> jfr.im git - irc/unrealircd/unrealircd-webpanel.git/blame - settings/rpc-servers.php
Adding/Editing RPC servers is superadmin only
[irc/unrealircd/unrealircd-webpanel.git] / settings / rpc-servers.php
CommitLineData
41aad10c
BM
1<?php
2require_once "../inc/common.php";
3require_once "../inc/header.php";
4
6737f4c9
VP
5$can_edit = current_user_can(PERMISSION_MANAGE_USERS);
6
7if ($can_edit)
41e618f4 8{
6737f4c9 9 if (isset($_POST['do_del_server']))
41e618f4 10 {
6737f4c9
VP
11 $server = $_POST['del_server_name'] ?? null;
12 if (isset($config["unrealircd"][$server]))
13 {
14 unset($config["unrealircd"][$server]);
15 set_at_least_one_default_rpc_server();
16 write_config("unrealircd");
17 } else {
18 Message::Fail("Delete failed: could not find server");
19 }
20 } else
21 if (isset($_POST['do_add_server']))
41aad10c 22 {
6737f4c9 23 $opts = (object)$_POST;
41aad10c 24
6737f4c9 25 /* TODO: Server-side validation */
41aad10c 26
6737f4c9 27 // TODO: syntax of each item
41aad10c 28
6737f4c9 29 // TODO: check server already exists with that (new) displayname
41e618f4 30
6737f4c9
VP
31 if (isset($config["unrealircd"][$opts->rpc_displayname]) &&
32 !($opts->rpc_displayname == $opts->edit_existing))
33 {
34 die("Server with that name already exists"); // TODO: pretier :D
35 }
36
37 $new_properties = [
38 "rpc_user" => $opts->rpc_user,
39 "rpc_password" => $opts->rpc_password,
40 "host"=>$opts->rpc_host,
41 "port"=>$opts->rpc_port,
42 "tls_verify_cert"=>isset($opts->rpc_tls_verify_cert)?true:false,
43 "default"=>isset($opts->rpc_default)?true:false,
44 ];
45
46 if (!empty($opts->edit_existing))
47 {
48 // Change existing server
49 if (!isset($config["unrealircd"][$opts->edit_existing]))
50 die("Editing a server that does not exist!?"); // not very graceful, isn't it?
51 if ($new_properties["rpc_password"] == "****************")
52 $new_properties["rpc_password"] = $config["unrealircd"][$opts->edit_existing]["rpc_password"];
53 // name change? unset the old one
54 if ($opts->edit_existing != $opts->rpc_displayname)
55 unset($config["unrealircd"][$opts->edit_existing]);
56 // set new properties
57 $config["unrealircd"][$opts->rpc_displayname] = $new_properties;
58 } else {
59 // Add new server
60 $config["unrealircd"][$opts->rpc_displayname] = $new_properties;
61 // TODO: encrypt pwd ;)
62 }
63
64 if ($new_properties["default"])
65 set_default_rpc_server($opts->rpc_displayname);
66 else
67 set_at_least_one_default_rpc_server();
68
69 /* And write the new config */
70 write_config();
71
72 Message::Success("RPC Server successfully ". (empty($opts->edit_existing) ? "added" : "modified").".");
73 }
41aad10c
BM
74}
75
76?>
77
78<h2>RPC Servers</h2>
79You can configure which JSON-RPC server(s) the panel can connect to.<br><br>
80You normally only need one server, but it can be useful to have multiple servers, so
81you can switch to a secondary server in case the primary server goes down.<br>
82<br>
83
336126ea
BM
84<?php
85if (empty($config["unrealircd"]))
86{
87 Message::Info("Let's get your panel linked to UnrealIRCd. ".
88 "Read <u><a href=\"https://www.unrealircd.org/docs/UnrealIRCd_webpanel#Configuring_UnrealIRCd\" target=\"_blank\">the UnrealIRCd instructions</a></u> ".
89 "and then click <i>Add Server</i> below.");
90}
91?>
92
41aad10c
BM
93<!-- Server action buttons (only Add server) -->
94<div id="ServerActions">
95 <div class="row">
96 <?php if (1) /* current_user_can(PERMISSION_MANAGE_RPC_SERVERS)) */ { ?>
97 <div class="col-sm-3">
98 <form method="post">
6737f4c9 99 <div class="btn btn-primary" <?php echo ($can_edit) ? 'onclick="add_rpc_server()"' : 'hidden'?>>Add Server</div>
41aad10c
BM
100 </form>
101 </div>
102 <?php } ?>
103 </div>
104<br>
105
106<!-- Add server modal -->
107<div class="modal" id="server_add" tabindex="-1" role="dialog" aria-labelledby="confirmModalCenterTitle" aria-hidden="true">
108 <div class="modal-dialog modal-dialog-centered" role="document">
109 <form method="post">
110 <input name="edit_existing" type="hidden" id="edit_existing" value="">
111 <div class="modal-content">
112 <div class="modal-header">
113 <h5 class="modal-title" id="server_add_title">Add RPC Server</h5>
114 <button type="button" class="close" data-dismiss="modal" aria-label="Close">
115 <span aria-hidden="true">&times;</span></button>
116 </div>
117 <div class="modal-body">
118 <div class="form-group">
119 <label for="rpc_displayname">Display name</label>
120 <input name="rpc_displayname" type="text" class="form-control" id="rpc_displayname" aria-describedby="rpc_displayname_help" value="" required>
121 <small id="rpc_displayname_help" class="form-text text-muted">A short display name for in the RPC server list.</small>
122 </div>
123 <div class="form-group form-check">
124 <input name="rpc_default" type="checkbox" class="revalidation-needed-rpc form-check-input" id="rpc_default">
125 <label class="form-check-label" for="rpc_default">Default server</label>
126 <small id="rpc_default_help" class="form-text text-muted">Make this the default (primary) server that will be used for connections.</code></small>
127 </div>
128 <div class="form-group">
a0ffe9f9
BM
129 <label for="rpc_host">Hostname or IP</label>
130 <input name="rpc_host" type="text" class="revalidation-needed-rpc form-control" id="rpc_host" aria-describedby="hostname_help" value="127.0.0.1">
41aad10c
BM
131 <small id="hostname_help" class="form-text text-muted">The hostname or IP address of your UnrealIRCd server. You should use <code>127.0.0.1</code> for the same machine.</small>
132 </div>
133 <div class="form-group">
134 <label for="rpc_port">Server Port</label>
135 <input name="rpc_port" type="text" class="revalidation-needed-rpc form-control" id="rpc_port" aria-describedby="port_help" value="8600">
136 <small id="port_help" class="form-text text-muted">The port which you designated for RPC connections in your <code>unrealircd.conf</code></small>
137 </div>
138 <div class="form-group form-check">
139 <input name="rpc_tls_verify_cert" type="checkbox" class="revalidation-needed-rpc form-check-input" id="rpc_tls_verify_cert">
140 <label class="form-check-label" for="rpc_tls_verify_cert">Verify SSL/TLS certificate</label>
141 <small id="rpc_tls_verify_cert_help" class="form-text text-muted">Can only be used with hostnames, don't enable this for 127.0.0.1.</code></small>
142 </div>
143 <div class="form-group">
144 <label for="rpc_username">Username</label>
145 <input name="rpc_user" type="text" class="revalidation-needed-rpc form-control" id="rpc_user" aria-describedby="username_help" autocomplete="new-password">
146 <small id="username_help" class="form-text text-muted">The name of your <code>rpc-user</code> block as defined in your <code>unrealircd.conf</code></small>
147 </div>
148 <div class="form-group">
149 <label for="rpc_password">Password</label>
150 <input name="rpc_password" type="password" class="revalidation-needed-rpc form-control" id="rpc_password" autocomplete="new-password">
151 </div>
152 </div>
153
154 <div class="modal-footer">
155 <button id="CloseButton" type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
156 <button type="submit" name="do_add_server" id="do_add_server" class="btn btn-primary">Add Server</button>
157 </div>
158 </div>
159 </form>
160 </div>
161</div>
162
163<!-- Server error modal -->
164<div class="modal" id="server_error" tabindex="-1" role="dialog" aria-labelledby="confirmModalCenterTitle" aria-hidden="true">
165 <div class="modal-dialog modal-dialog-centered" role="document">
166 <div class="modal-content">
167 <div class="modal-header">
168 <h5 class="modal-title">RPC Server error</h5>
169 <button type="button" class="close" data-dismiss="modal" aria-label="Close">
170 <span aria-hidden="true">&times;</span>
171 </button>
172 </div>
173 <div class="modal-body">
174 The RPC Server failed to connect. Check your settings and try again.
175 </div>
176
177 <div class="modal-footer">
178 <button id="CloseButton" type="button" class="btn btn-primary" data-dismiss="modal" onclick="cancel_error()">OK</button>
179 </div>
180 </div>
181 </div>
182</div>
183
a5328c73
BM
184<!-- Server delete confirmation modal -->
185<div class="modal" id="server_confirm_del" tabindex="-1" role="dialog" aria-labelledby="confirmModalCenterTitle" aria-hidden="true">
186 <div class="modal-dialog modal-dialog-centered" role="document">
187 <div class="modal-content">
188 <form method="post">
189 <input name="del_server_name" type="hidden" id="del_server_name" value="">
190 <div class="modal-header">
191 <h5 class="modal-title">Confirm deletion</h5>
192 <button type="button" class="close" data-dismiss="modal" aria-label="Close">
193 <span aria-hidden="true">&times;</span>
194 </button>
195 </div>
196 <div class="modal-body">
197 Are you sure you want to delete this server?
198 </div>
199 <div class="modal-footer">
200 <button id="CloseButton" type="button" class="btn btn-primary" data-dismiss="modal">Cancel</button>
201 <button type="submit" name="do_del_server" id="do_del_server" class="btn btn-danger">Delete Server</button>
202 </div>
203 </form>
204 </div>
205 </div>
206</div>
207
208<!-- Todo figure out why it didnt work in css -->
209<style>
210.btn-group-xs > .btn, .btn-xs {
211padding: 1px 5px;
212font-size: 12px;
213line-height: 1.5;
214border-radius: 3px;
215}
216</style>
217
41aad10c
BM
218<!-- Server list -->
219<form method="post">
220<table class="container-xxl table table-sm table-responsive caption-top table-striped">
221 <thead class="table-primary">
6737f4c9 222 <?php if ($can_edit){ ?><th scope="col"></th><?php }?>
41aad10c
BM
223 <th scope="col">Display name</th>
224 <th scope="col">Hostname</th>
225 <th scope="col">Port</th>
226 <th scope="col">RPC User</th>
227 </thead>
228 <tbody>
229 <?php
c9e0e590
BM
230 $servers = get_config('unrealircd');
231 if (!$servers)
232 $servers = [];
233 foreach($servers as $name=>$e)
41aad10c
BM
234 {
235 $primary = "";
236 if (isset($e["default"]) && $e["default"])
237 $primary = " <span class=\"badge rounded-pill badge-success\">Default</span>";
238 $name = htmlspecialchars($name);
239 $default_server = $e["default"] ? "true" : "false";
240 $host = htmlspecialchars($e["host"]);
241 $port = htmlspecialchars($e["port"]);
242 $rpc_user = htmlspecialchars($e["rpc_user"]);
243 $tls_verify_cert = $e["tls_verify_cert"] ? "true" : "false";
a5328c73 244 $html_name = "<a href=\"javascript:edit_rpc_server('$name',$default_server,'$host','$port','$rpc_user',$tls_verify_cert)\">$name</a>";
41aad10c 245 echo "<tr>";
6737f4c9
VP
246 if ($can_edit)
247 echo "<td scope=\"col\"><button type=\"button\" class=\"btn btn-xs btn-danger\" onclick=\"confirm_delete('".$name."')\"><i class=\"fa fa-trash fa-1\" aria-hidden=\"true\"></i></button></td>";
a5328c73 248 echo "<td scope=\"col\">".$html_name.$primary."</td>";
41aad10c
BM
249 echo "<td scope=\"col\"><code>".$host."</code></td>";
250 echo "<td scope=\"col\"><code>".$port."</code></td>";
251 echo "<td scope=\"col\"><code>".$rpc_user."</code></td>";
252 echo "</tr>";
253 }
254 ?>
255 </tbody>
256</table>
257
258<script>
259 let do_add_server = document.getElementById('do_add_server');
260
a0ffe9f9 261 let rpc_host = document.getElementById('rpc_host');
41aad10c
BM
262 let rpc_port = document.getElementById('rpc_port');
263 let rpc_user = document.getElementById('rpc_user');
264 let rpc_pass = document.getElementById('rpc_password');
265 let rpc_tls_verify_cert = document.getElementById('rpc_tls_verify_cert');
266 let rpc_server_ok = false;
267
268 do_add_server.addEventListener('click', e => {
269 if (rpc_server_ok)
270 return true;
271 e.preventDefault();
272 test_rpc_server();
273 return false;
274 });
275
276 /* The RPC connection tester! */
277 function test_rpc_server()
278 {
b0d05b54 279 fetch('<?php echo get_config("base_url"); ?>' + 'api/test_rpc_server.php', {
41aad10c
BM
280 method:'POST',
281 headers: {'Content-Type':'application/x-www-form-urlencoded'},
282 body: 'method=rpc&'+
283 'host='+encodeURIComponent(rpc_host.value)+
284 '&port='+encodeURIComponent(rpc_port.value)+
285 '&user='+encodeURIComponent(rpc_user.value)+
286 '&password='+encodeURIComponent(rpc_pass.value)+
287 '&tls_verify='+rpc_tls_verify_cert.checked+
288 '&edit_existing='+encodeURIComponent(edit_existing.value)
289 })
290 .then(response => response.json())
291 .then(data => {
292 if (data.success)
293 {
294 rpc_server_ok = true;
295 do_add_server.click();
296 }
297 else
298 {
299 $('#server_add').modal('hide');
300 $('#server_error').modal();
301 }
302 })
303 .catch(error => {
304 test_conn.innerHTML = "Failed!";
305 $('#server_add').modal('hide');
306 $('#server_error').modal();
307 });
308 }
309
310 function cancel_error()
311 {
312 $('#server_add').modal('show');
313 return true;
314 }
315
316 function edit_rpc_server(name, default_server, host, port, rpc_user, tls_verify_cert)
317 {
318 $('#edit_existing').val(name);
319 $('#rpc_displayname').val(name);
320 $('#rpc_default').prop('checked', default_server);
321 $('#rpc_host').val(host);
322 $('#rpc_port').val(port);
323 $('#rpc_user').val(rpc_user);
324 $('#rpc_password').val("****************"); // magic value to indicate saved password
325 $('#server_add_title').html("Edit Server");
326 $('#do_add_server').html("Submit");
327 $('#rpc_tls_verify_cert').prop('checked', tls_verify_cert);
41e618f4 328 $('#do_del_server').show();
41aad10c
BM
329 $('#server_add').modal('show');
330 }
331
332 // This is in a function because a canceled edit_rpc_server otherwise causes a prefilled effect
333 function add_rpc_server()
334 {
41e618f4 335 $('#edit_existing').val("");
41aad10c
BM
336 $('#rpc_displayname').val("");
337 $('#rpc_host').val("127.0.0.1");
338 $('#rpc_port').val("8600");
339 $('#rpc_user').val("");
340 $('#rpc_password').val("");
341 $('#server_add_title').html("Add Server");
342 $('#do_add_server').html("Add Server");
343 $('#rpc_tls_verify_cert').prop('checked', false);
41e618f4 344 $('#do_del_server').hide();
41aad10c
BM
345 $('#server_add').modal('show');
346 }
a5328c73
BM
347
348 function confirm_delete(name)
349 {
350 $('#del_server_name').val(name);
351 $('#server_confirm_del').modal('show');
352 }
353
354
41aad10c
BM
355</script>
356
357<?php
358require_once "../inc/footer.php";