]> jfr.im git - irc/unrealircd/unrealircd-webpanel.git/commitdiff
Initial commit
authorValerie Pond <redacted>
Fri, 30 Dec 2022 20:58:39 +0000 (20:58 +0000)
committerValerie Pond <redacted>
Fri, 30 Dec 2022 20:58:39 +0000 (20:58 +0000)
Classes/class-rpc.php [new file with mode: 0644]
Classes/index.php [new file with mode: 0644]
css/index.php [new file with mode: 0644]
css/unrealircd-admin.css [new file with mode: 0644]
index.php [new file with mode: 0644]
js/index.php [new file with mode: 0644]
js/unrealircd-admin.js [new file with mode: 0644]

diff --git a/Classes/class-rpc.php b/Classes/class-rpc.php
new file mode 100644 (file)
index 0000000..76bdb65
--- /dev/null
@@ -0,0 +1,218 @@
+<?php
+
+if (!defined('UPATH'))
+    die("Access denied");
+
+
+/** The RPC User name as defined in your unrealircd.conf */
+define( 'UNREALIRCD_RPC_USER', 'apiuser' );
+
+/** The RPC User password as defined in your unrealircd.conf */
+define( 'UNREALIRCD_RPC_PASSWORD', 'securepassword' );
+
+/** The host of the RPC server */
+define( 'UNREALIRCD_HOST', '127.0.0.1' );
+
+/** The port of your RPC server as defined in your unrealircd.conf */
+define( 'UNREALIRCD_PORT', '8000' );
+
+/* You should only really uncomment this if you are running on 
+ * localhost and for some reason don't have a fully valid cert
+*/
+define( 'UNREALIRCD_SSL_VERIFY', false );
+
+/* You should only really need this if you're developing something. */
+define( 'UNREALIRCD_DEBUG', true );
+
+class RPC
+{
+       public $errs = [];
+       public $errcount = 0; // more of a bool check
+       public $content = [];
+       public $body = [];
+    public $result = NULL;
+       function __construct()
+       {
+               if (!defined('UNREALIRCD_RPC_USER') ||
+                       !defined('UNREALIRCD_RPC_PASSWORD') ||
+                       !defined('UNREALIRCD_HOST') ||
+                       !defined('UNREALIRCD_PORT')
+               ) die("Unable to find RPC credentials in your wp-config");
+
+               $sslverify = (defined('UNREALIRCD_SSL_VERIFY')) ? UNREALIRCD_SSL_VERIFY : true;
+
+               $this->content['sslverify'] = $sslverify;
+               $this->body['id'] = $this->generate_id();
+               $this->body['jsonrpc'] = "2.0";
+               $this->body['method'] = NULL; // MUST be set later
+               $this->body['params'] = []; // CAN be set later
+       }
+       function add_body(array $b) : void
+       {
+               array_merge($this->body, $b);
+       }
+
+       private function generate_id()
+       {
+               $time = microtime(true);
+               $str = (string)$time;
+               $last = $str[strlen($str) - 1];
+               $last = (int)$last;
+               $id = $time * $time * $last;
+               $id = md5(base64_encode($id));
+               return $id;
+       }
+
+       /**
+        * This function sets the method of the RPC call you're making.
+        * For a list of available methods, see:
+        * https://www.unrealircd.org/docs/JSON-RPC#JSON-RPC_Methods
+        */
+       function set_method(String $method) : void
+       {
+               $this->body['method'] = $method;
+       }
+
+       function set_params(array $params) : void
+       {
+               array_merge($this->body['params'], $params);
+       }
+
+       function execute()
+       {
+               $this->content['body'] = json_encode($this->body);
+        if (!$this->content['body'])
+                       return;
+               $url = "https://".UNREALIRCD_HOST.":".UNREALIRCD_PORT."/api";
+               $curl = curl_init($url);
+               curl_setopt($curl, CURLOPT_URL, $url);
+               curl_setopt($curl, CURLOPT_POST, true);
+               curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
+
+               $headers = array(
+                       "Accept: application/json",
+                       "Content-Type: application/json",
+            "Authorization: Basic ". base64_encode(UNREALIRCD_RPC_USER.":".UNREALIRCD_RPC_PASSWORD),
+               );
+               curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
+
+               curl_setopt($curl, CURLOPT_POSTFIELDS, $this->content['body']);
+
+               //for debug only!
+               curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
+               curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
+
+               $apiResponse = curl_exec($curl);
+               curl_close($curl);
+               
+               $this->result = $apiResponse;
+       }
+
+       function fetch_assoc()
+       {
+               return json_decode($this->result, true);
+       }
+
+       static function die(array $err)
+       {
+               die("There was a problem processing the request: ".$err['message']." (".$err['code'].")<br>Please contact the plugin author.<br>".
+                                       "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>");
+       }
+}
+
+class RPC_List
+{
+    static $user = [];
+    static $channel = [];
+    static $tkl = [];
+    static $spamfilter = [];
+
+       static $opercount = 0;
+       static $services_count = 0;
+       static $most_populated_channel = NULL;
+       static $channel_pop_count = 0;
+}
+
+function rpc_pop_lists()
+{
+       $rpc = new RPC();
+
+       /* Get the user list */
+       $rpc->set_method("user.list");
+       $rpc->execute();
+
+       foreach($rpc->fetch_assoc() as $key => $value)
+       {
+               if ($key == "error")
+               {
+                       RPC::die($value);
+                       return;
+               }
+               if ($key == "result")
+                       foreach($value['list'] as $r)
+                       {
+                               RPC_List::$user[] = $r;
+                               if (strpos($r['user']['modes'],"o") !== false && strpos($r['user']['modes'],"S") == false)
+                                       RPC_List::$opercount++;
+                               elseif (strpos($r['user']['modes'],"S") !== false)
+                                       RPC_List::$services_count++;
+                       }
+       }
+
+       /* Get the channels list */
+       $rpc->set_method("channel.list");
+       $rpc->execute();
+
+       foreach($rpc->fetch_assoc() as $key => $value)
+       {
+               if ($key == "error")
+               {
+                       RPC::die($value);
+                       return;
+               }
+               if ($key == "result")
+                       foreach($value['list'] as $r)
+                       {
+                               RPC_List::$channel[] = $r;
+                               if ($r['num_users'] > RPC_List::$channel_pop_count)
+                               {
+                                       RPC_List::$channel_pop_count = $r['num_users'];
+                                       RPC_List::$most_populated_channel = $r['name'];
+                               }
+                       }
+       }
+       
+       /* Get the tkl list */
+       $rpc->set_method("server_ban.list");
+       $rpc->execute();
+
+       foreach($rpc->fetch_assoc() as $key => $value)
+       {
+               if ($key == "error")
+               {
+                       RPC::die($value);
+                       return;
+               }
+               if ($key == "result")
+                       foreach($value['list'] as $r)
+                               RPC_List::$tkl[] = $r;
+       }
+
+       
+       /* Get the tkl list */
+       $rpc->set_method("spamfilter.list");
+       $rpc->execute();
+
+       foreach($rpc->fetch_assoc() as $key => $value)
+       {
+               if ($key == "error")
+               {
+                       RPC::die($value);
+                       return;
+               }
+               if ($key == "result")
+                       foreach($value['list'] as $r)
+                               RPC_List::$spamfilter[] = $r;
+       }
+
+}
\ No newline at end of file
diff --git a/Classes/index.php b/Classes/index.php
new file mode 100644 (file)
index 0000000..5d01148
--- /dev/null
@@ -0,0 +1,3 @@
+<?php
+
+// Silence is golden or something idk I'm not a goldsmith
\ No newline at end of file
diff --git a/css/index.php b/css/index.php
new file mode 100644 (file)
index 0000000..5d01148
--- /dev/null
@@ -0,0 +1,3 @@
+<?php
+
+// Silence is golden or something idk I'm not a goldsmith
\ No newline at end of file
diff --git a/css/unrealircd-admin.css b/css/unrealircd-admin.css
new file mode 100644 (file)
index 0000000..5aa44b6
--- /dev/null
@@ -0,0 +1,74 @@
+.unrealircd_overview {
+    font-family: arial, sans-serif;
+    border-collapse: collapse;
+    border-radius: 15px;
+    width: 25%;
+}
+
+td,
+th {
+    border: 1px solid #000;
+    text-align: left;
+    padding: 8px;
+}
+
+tr:nth-child(even) {
+    background-color: #bec8d3;
+}
+
+* {
+    box-sizing: border-box;
+}
+
+.row {
+    display: flex;
+}
+
+.column {
+    flex: 50%;
+    padding: 5px;
+}
+
+.topnav {
+    background-color: #333;
+    overflow: hidden;
+}
+
+/* Style the links inside the navigation bar */
+.topnav a {
+    float: left;
+    color: #f2f2f2;
+    text-align: center;
+    padding: 14px 16px;
+    text-decoration: none;
+    font-size: 17px;
+}
+
+/* Change the color of links on hover */
+.topnav a:hover {
+    background-color: #ddd;
+    color: black;
+}
+
+/* Add a color to the active/current link */
+.topnav a.active {
+    background-color: #4e50c2;
+    color: white;
+}
+
+
+[data-tab-content] {
+    display: none;
+}
+
+.active[data-tab-content] {
+    display: block;
+}
+
+.tab.active {
+    background-color: #AAA;
+}
+
+.tab:hover {
+    background-color: #AAA;
+}
\ No newline at end of file
diff --git a/index.php b/index.php
new file mode 100644 (file)
index 0000000..9108bcf
--- /dev/null
+++ b/index.php
@@ -0,0 +1,41 @@
+<script src="js/unrealircd-admin.js" defer></script>
+<div class="topnav">
+  <a data-tab-target="#overview" class="active" href="#overview">Overview</a>
+  <a data-tab-target="#Users" href="#Users">Users</a>
+  <a data-tab-target="#Channels" href="#Channels">Channels</a>
+  <a data-tab-target="#TKL" href="#TKL">Server Bans</a>
+  <a data-tab-target="#Spamfilter" href="#Spamfilter">Spamfilter</a>
+</div> 
+<?php
+/**
+ * Provide a admin area view for the plugin
+ *
+ * This file is used to markup the admin-facing aspects of the plugin.
+ *
+ * @link       https://https://github.com/ValwareIRC
+ * @since      1.0.0
+ *
+ * @package    Unrealircd
+ * @subpackage Unrealircd/admin/partials
+ */
+
+define('UPATH', true);
+include "Classes/class-rpc.php";
+
+rpc_pop_lists();
+echo "
+<link href=\"/css/unrealircd-admin.css\" rel=\"stylesheet\">
+<h1>UnrealIRCd</h1>
+<div class=\"tab-content\">
+<div id=\"overview\" data-tab-content class=\"active\">
+    <h2>IRC Overview Panel</h2>
+    <table class='unrealircd_overview'>
+        <tr><td>Users</td><td>".count(RPC_List::$user)."</td></tr>
+        <tr><td>Opers</td><td>".RPC_List::$opercount."</td></tr>
+        <tr><td>Services</td><td>".RPC_List::$services_count."</td></tr>
+        <tr><td>Most popular channel</td><td>".RPC_List::$most_populated_channel." (".RPC_List::$channel_pop_count." users)</td></tr>
+        <tr><td>Channels</td><td>".count(RPC_List::$channel)."</td></tr>
+        <tr><td>Server bans</td><td>".count(RPC_List::$tkl)."</td></tr>
+        <tr><td>Spamfilter entries</td><td>".count(RPC_List::$spamfilter)."</td></tr>
+    </table></div></div>";
+?>
diff --git a/js/index.php b/js/index.php
new file mode 100644 (file)
index 0000000..5d01148
--- /dev/null
@@ -0,0 +1,3 @@
+<?php
+
+// Silence is golden or something idk I'm not a goldsmith
\ No newline at end of file
diff --git a/js/unrealircd-admin.js b/js/unrealircd-admin.js
new file mode 100644 (file)
index 0000000..81805b4
--- /dev/null
@@ -0,0 +1,16 @@
+const tabs = document.querySelectorAll('[data-tab-target]');
+const tabContents = document.querySelectorAll('[data-tab-content]')
+
+tabs.forEach(tab => {
+    tab.addEventListener('click', () => {
+        const target = document.querySelector(tab.dataset.tabTarget)
+        tabContents.forEach(tabContent => {
+            tabContent.classList.remove('active')
+        })
+        tabs.forEach(tab => {
+            tab.classList.remove('active')
+        })
+        tab.classList.add('active');
+        target.classList.add('active');
+    })
+})
\ No newline at end of file