aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Eilertsen <haraldei@anduin.net>2024-07-06 11:12:53 +0200
committerHarald Eilertsen <haraldei@anduin.net>2024-07-06 11:42:08 +0200
commitf6132cac7e534d26ae3189b09f55be3a06aa7beb (patch)
tree0307aa8a9f5d64af77a8fffec7994bcde6b6efc3
parentb98c9ee7fa567785ba442841c233526f53ff546e (diff)
downloadvolse-webtrap-f6132cac7e534d26ae3189b09f55be3a06aa7beb.tar.gz
volse-webtrap-f6132cac7e534d26ae3189b09f55be3a06aa7beb.tar.bz2
volse-webtrap-f6132cac7e534d26ae3189b09f55be3a06aa7beb.zip
Add class for representing XML-RPC payloads.
-rw-r--r--src/XmlRpcMethod.php75
-rw-r--r--tests/unit/XmlRpcTest.php26
2 files changed, 101 insertions, 0 deletions
diff --git a/src/XmlRpcMethod.php b/src/XmlRpcMethod.php
new file mode 100644
index 0000000..2167e53
--- /dev/null
+++ b/src/XmlRpcMethod.php
@@ -0,0 +1,75 @@
+<?php
+
+// SPDX-FileCopyrightText: 2024 Eilertsens Kodeknekkeri
+// SPDX-FileCopyrightText: 2024 Harald Eilertsen
+//
+// SPDX-License-Identifier: AGPL-3.0-or-later
+
+namespace VolseNet\Webtrap;
+
+/**
+ * A representation of an XML-RPC method call.
+ *
+ * This is just a representation to hold information about the attempted
+ * call. It does not try to perform any action on it.
+ */
+class XmlRpcMethod
+{
+ /**
+ * Parse raw XML to an XmlRpcMethod object.
+ *
+ * We're not very strict when parsing, but trying to extract the
+ * most useful information. At the moment that is the method `name`,
+ * and an array of the `params` passed to the method.
+ *
+ * @param string $payload The raw XML representation of the method call.
+ *
+ * @return XmlRpcMethod
+ */
+ public static function parse(string $payload): self
+ {
+ $parser = xml_parser_create();
+ xml_parse_into_struct($parser, $payload, $elements, $index);
+ xml_parser_free($parser);
+
+ $in_param = false;
+ $method_name = null;
+
+ foreach ($elements as $e) {
+ switch ($e['tag']) {
+ case 'METHODNAME':
+ $method_name = $e['value'];
+ break;
+
+ case 'PARAM':
+ if ($e['type'] === 'open') {
+ $in_param = true;
+ } else {
+ $in_param = false;
+ }
+ break;
+
+ case 'VALUE':
+ if ($in_param) {
+ $params[] = $e['value'];
+ }
+ break;
+
+ default:
+ // nothing
+ }
+ }
+
+ return new XmlRpcMethod($method_name, $params);
+ }
+
+ /**
+ * Constructs a new XmlRpcMethod object from the method name and params.
+ *
+ * @param string $name The method name
+ * @param array $params An array or params for the method call.
+ */
+ public function __construct(public string $name, public array $params)
+ {
+ }
+}
diff --git a/tests/unit/XmlRpcTest.php b/tests/unit/XmlRpcTest.php
new file mode 100644
index 0000000..c245917
--- /dev/null
+++ b/tests/unit/XmlRpcTest.php
@@ -0,0 +1,26 @@
+<?php
+
+// SPDX-FileCopyrightText: 2024 Eilertsens Kodeknekkeri
+// SPDX-FileCopyrightText: 2024 Harald Eilertsen
+//
+// SPDX-License-Identifier: AGPL-3.0-or-later
+
+namespace VolseNet\Webtrap\Tests\Unit;
+
+use PHPUnit\Framework\TestCase;
+use VolseNet\Webtrap\XmlRpcMethod;
+
+class XmlRpcTest extends TestCase
+{
+ public function testGetUserBlog(): void
+ {
+ $payload = '<methodCall><methodName>wp.getUsersBlogs</methodName>'
+ . '<params><param><value>someuser</value></param>'
+ . '<param><value>verysecretpassword</value></param></params></methodCall>';
+
+ $method = XmlRpcMethod::parse($payload);
+
+ $this->assertEquals('wp.getUsersBlogs', $method->name);
+ $this->assertEquals(['someuser', 'verysecretpassword'], $method->params);
+ }
+}