mirror of
https://code.mensbeam.com/MensBeam/Arsse.git
synced 2024-12-22 13:12:41 +00:00
Basic Fever skeleton
Authentication should work, but not tests have been written yet
This commit is contained in:
parent
38bdde1167
commit
3aa2b62d02
3 changed files with 106 additions and 6 deletions
12
lib/REST.php
12
lib/REST.php
|
@ -16,14 +16,12 @@ use Zend\Diactoros\Response\EmptyResponse;
|
|||
|
||||
class REST {
|
||||
const API_LIST = [
|
||||
// NextCloud News version enumerator
|
||||
'ncn' => [
|
||||
'ncn' => [ // NextCloud News version enumerator
|
||||
'match' => '/index.php/apps/news/api',
|
||||
'strip' => '/index.php/apps/news/api',
|
||||
'class' => REST\NextCloudNews\Versions::class,
|
||||
],
|
||||
// NextCloud News v1-2 https://github.com/nextcloud/news/blob/master/docs/externalapi/Legacy.md
|
||||
'ncn_v1-2' => [
|
||||
'ncn_v1-2' => [ // NextCloud News v1-2 https://github.com/nextcloud/news/blob/master/docs/externalapi/Legacy.md
|
||||
'match' => '/index.php/apps/news/api/v1-2/',
|
||||
'strip' => '/index.php/apps/news/api/v1-2',
|
||||
'class' => REST\NextCloudNews\V1_2::class,
|
||||
|
@ -38,9 +36,13 @@ class REST {
|
|||
'strip' => '/tt-rss/feed-icons/',
|
||||
'class' => REST\TinyTinyRSS\Icon::class,
|
||||
],
|
||||
'fever' => [ // Fever https://web.archive.org/web/20161217042229/https://feedafever.com/api
|
||||
'match' => '/fever/',
|
||||
'strip' => '/fever/',
|
||||
'class' => REST\Fever\API::class,
|
||||
],
|
||||
// Other candidates:
|
||||
// Google Reader http://feedhq.readthedocs.io/en/latest/api/index.html
|
||||
// Fever https://web.archive.org/web/20161217042229/https://feedafever.com/api
|
||||
// Feedbin v2 https://github.com/feedbin/feedbin-api
|
||||
// CommaFeed https://www.commafeed.com/api/
|
||||
// Selfoss https://github.com/SSilence/selfoss/wiki/Restful-API-for-Apps-or-any-other-external-access
|
||||
|
|
98
lib/REST/Fever/API.php
Normal file
98
lib/REST/Fever/API.php
Normal file
|
@ -0,0 +1,98 @@
|
|||
<?php
|
||||
/** @license MIT
|
||||
* Copyright 2017 J. King, Dustin Wilson et al.
|
||||
* See LICENSE and AUTHORS files for details */
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace JKingWeb\Arsse\REST\Fever;
|
||||
|
||||
use JKingWeb\Arsse\Arsse;
|
||||
use JKingWeb\Arsse\Database;
|
||||
use JKingWeb\Arsse\User;
|
||||
use JKingWeb\Arsse\Service;
|
||||
use JKingWeb\Arsse\Context\Context;
|
||||
use JKingWeb\Arsse\Misc\ValueInfo;
|
||||
use JKingWeb\Arsse\AbstractException;
|
||||
use JKingWeb\Arsse\Db\ExceptionInput;
|
||||
use JKingWeb\Arsse\Feed\Exception as FeedException;
|
||||
use JKingWeb\Arsse\REST\Target;
|
||||
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\EmptyResponse;
|
||||
|
||||
class API extends \JKingWeb\Arsse\REST\AbstractHandler {
|
||||
const LEVEL = 3;
|
||||
|
||||
public function __construct() {
|
||||
}
|
||||
|
||||
public function dispatch(ServerRequestInterface $req): ResponseInterface {
|
||||
$inR = $req->getQueryParams();
|
||||
if (!array_key_exists("api")) {
|
||||
// the original would have shown the Fever UI in the absence of the "api" parameter, but we'll return 404
|
||||
return new EmptyResponse(404);
|
||||
}
|
||||
$xml = $inR['api'] === "xml";
|
||||
switch ($req->getMethod()) {
|
||||
case "OPTIONS":
|
||||
// do stuff
|
||||
break;
|
||||
case "POST":
|
||||
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,
|
||||
];
|
||||
// check that the user specified credentials
|
||||
if ($this->logIn(strtolower($inW['api_key'] ?? ""))) {
|
||||
$out['auth'] = 1;
|
||||
} else {
|
||||
return $this->formatResponse($out, $xml);
|
||||
}
|
||||
// handle each possible parameter
|
||||
# do stuff
|
||||
// return the result
|
||||
return $this->formatResponse($out, $xml);
|
||||
break;
|
||||
default:
|
||||
return new EmptyResponse(405, ['Allow' => "OPTIONS,POST"]);
|
||||
}
|
||||
}
|
||||
|
||||
protected function formatResponse(array $data, bool $xml): ResponseInterface {
|
||||
if ($xml) {
|
||||
throw \Exception("Not implemented yet");
|
||||
} else {
|
||||
return new JsonResponse($data, 200, [], \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
}
|
||||
|
||||
protected function logIn(string $hash): bool {
|
||||
// if HTTP authentication was successful and sessions are not enforced, proceed unconditionally
|
||||
if (isset(Arsse::$user->id) && !Arsse::$conf->userSessionEnforced) {
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
// verify the supplied hash is valid
|
||||
$s = Arsse::$db->TokenLookup($id, "fever.login");
|
||||
} catch (\JKingWeb\Arsse\Db\ExceptionInput $e) {
|
||||
return false;
|
||||
}
|
||||
// set the user name
|
||||
Arsse::$user->id = $s['user'];
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function registerUser(string $user, string $password = null): string {
|
||||
$password = $password ?? Arsse::$user->generatePassword();
|
||||
$hash = md5("$user:$password");
|
||||
Arsse::$db->tokenCreate($user, "fever.login", $hash);
|
||||
return $password;
|
||||
}
|
||||
}
|
|
@ -114,7 +114,7 @@ class User {
|
|||
return $out;
|
||||
}
|
||||
|
||||
protected function generatePassword(): string {
|
||||
public function generatePassword(): string {
|
||||
return (new PassGen)->length(Arsse::$conf->userTempPasswordLength)->get();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue