diff options
author | Harald Eilertsen <haraldei@anduin.net> | 2024-07-06 11:12:53 +0200 |
---|---|---|
committer | Harald Eilertsen <haraldei@anduin.net> | 2024-07-06 11:42:08 +0200 |
commit | f6132cac7e534d26ae3189b09f55be3a06aa7beb (patch) | |
tree | 0307aa8a9f5d64af77a8fffec7994bcde6b6efc3 | |
parent | b98c9ee7fa567785ba442841c233526f53ff546e (diff) | |
download | volse-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.php | 75 | ||||
-rw-r--r-- | tests/unit/XmlRpcTest.php | 26 |
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); + } +} |