diff --git a/lib/REST/Fever/API.php b/lib/REST/Fever/API.php
index b9fd5ad..6effe27 100644
--- a/lib/REST/Fever/API.php
+++ b/lib/REST/Fever/API.php
@@ -20,7 +20,7 @@ use JKingWeb\Arsse\REST\Exception404;
use JKingWeb\Arsse\REST\Exception405;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;
-use Zend\Diactoros\Response\JsonResponse as Response;
+use Zend\Diactoros\Response\JsonResponse;
use Zend\Diactoros\Response\EmptyResponse;
class API extends \JKingWeb\Arsse\REST\AbstractHandler {
@@ -31,7 +31,8 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler {
public function dispatch(ServerRequestInterface $req): ResponseInterface {
$inR = $req->getQueryParams();
- if (!array_key_exists("api")) {
+ $inW = $req->getParsedBody();
+ if (!array_key_exists("api", $inR)) {
// the original would have shown the Fever UI in the absence of the "api" parameter, but we'll return 404
return new EmptyResponse(404);
}
@@ -44,7 +45,6 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler {
if (strlen($req->getHeaderLine("Content-Type")) && $req->getHeaderLine("Content-Type") !== "application/x-www-form-urlencoded") {
return new EmptyResponse(415, ['Accept' => "application/x-www-form-urlencoded"]);
}
- $inW = $req->getParsedBody();
$out = [
'api_version' => self::LEVEL,
'auth' => 0,
@@ -80,7 +80,7 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler {
}
try {
// verify the supplied hash is valid
- $s = Arsse::$db->TokenLookup($id, "fever.login");
+ $s = Arsse::$db->TokenLookup("fever.login", $hash);
} catch (\JKingWeb\Arsse\Db\ExceptionInput $e) {
return false;
}
diff --git a/tests/cases/REST/Fever/PDO/TestAPI.php b/tests/cases/REST/Fever/PDO/TestAPI.php
new file mode 100644
index 0000000..02caa3d
--- /dev/null
+++ b/tests/cases/REST/Fever/PDO/TestAPI.php
@@ -0,0 +1,13 @@
+
+ * @group optional */
+class TestAPI extends \JKingWeb\Arsse\TestCase\REST\Fever\TestAPI {
+ use \JKingWeb\Arsse\Test\PDOTest;
+}
diff --git a/tests/cases/REST/Fever/TestAPI.php b/tests/cases/REST/Fever/TestAPI.php
new file mode 100644
index 0000000..54b3e07
--- /dev/null
+++ b/tests/cases/REST/Fever/TestAPI.php
@@ -0,0 +1,100 @@
+ */
+class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
+
+ protected function v($value) {
+ return $value;
+ }
+
+ protected function req($dataGet, $dataPost, string $method = "POST", string $type = null, string $url = "", string $user = null): ResponseInterface {
+ $url = "/fever/".$url;
+ $server = [
+ 'REQUEST_METHOD' => $method,
+ 'REQUEST_URI' => $url,
+ 'HTTP_CONTENT_TYPE' => $type ?? "application/x-www-form-urlencoded",
+ ];
+ $req = new ServerRequest($server, [], $url, $method, "php://memory");
+ if (is_array($dataGet)) {
+ $req = $req->withRequestTarget($url)->withQueryParams($dataGet);
+ } else {
+ $req = $req->withRequestTarget($url."?".http_build_query((string) $dataGet, "", "&", \PHP_QUERY_RFC3986));
+ }
+ if (is_array($dataPost)) {
+ $req = $req->withParsedBody($dataPost);
+ } else {
+ $body = $req->getBody();
+ $body->write($strData);
+ $req = $req->withBody($body);
+ }
+ if (isset($user)) {
+ if (strlen($user)) {
+ $req = $req->withAttribute("authenticated", true)->withAttribute("authenticatedUser", $user);
+ } else {
+ $req = $req->withAttribute("authenticationFailed", true);
+ }
+ }
+ return $this->h->dispatch($req);
+ }
+
+ public function setUp() {
+ self::clearData();
+ self::setConf();
+ // create a mock user manager
+ Arsse::$user = Phake::mock(User::class);
+ Phake::when(Arsse::$user)->auth->thenReturn(true);
+ Arsse::$user->id = "john.doe@example.com";
+ // create a mock database interface
+ Arsse::$db = Phake::mock(Database::class);
+ Phake::when(Arsse::$db)->begin->thenReturn(Phake::mock(Transaction::class));
+ // instantiate the handler
+ $this->h = new API();
+ }
+
+ public function tearDown() {
+ self::clearData();
+ }
+
+ /** @dataProvider provideAuthenticationRequests */
+ public function testAuthenticateAUser(bool $httpRequired, bool $tokenEnforced, string $httpUser = null, array $dataPost, array $dataGet, bool $success) {
+ self::setConf([
+ 'userHTTPAuthRequired' => $httpRequired,
+ 'userSessionEnforced' => $tokenEnforced,
+ ], true);
+ \Phake::when(Arsse::$db)->tokenLookup->thenThrow(new ExceptionInput("subjectMissing"));
+ \Phake::when(Arsse::$db)->tokenLookup("fever.login", "validtoken")->thenReturn(['user' => "jane.doe@example.com"]);
+ $exp = new JsonResponse($success ? ['api_version' => API::LEVEL, 'auth' => 1] : ['api_version' => API::LEVEL, 'auth' => 0]);
+ $act = $this->req($dataGet, $dataPost, "POST", null, "", $httpUser);
+ $this->assertMessage($exp, $act);
+ }
+
+ public function provideAuthenticationRequests() {
+ return [
+ [false, true, null, ['api_key' => "validToken"], ['api' => null], true],
+ ];
+ }
+}
diff --git a/tests/phpunit.xml b/tests/phpunit.xml
index aac033b..9200dd8 100644
--- a/tests/phpunit.xml
+++ b/tests/phpunit.xml
@@ -104,6 +104,10 @@
cases/REST/TinyTinyRSS/TestIcon.php
cases/REST/TinyTinyRSS/PDO/TestAPI.php
+
+ cases/REST/Fever/TestAPI.php
+ cases/REST/Fever/PDO/TestAPI.php
+
cases/Service/TestService.php
cases/CLI/TestCLI.php