Compare commits
No commits in common. "ebf3d05620f738aab940b85eb69f1a95be49c903" and "073fba5312a2b95fa9760921ad0bbb16ddc94359" have entirely different histories.
ebf3d05620
...
073fba5312
|
@ -29,7 +29,7 @@ This will be changed, but works for the current develop verison.
|
||||||
|
|
||||||
If the include redis cache is enabled, create a users.acl for redis with the content:
|
If the include redis cache is enabled, create a users.acl for redis with the content:
|
||||||
|
|
||||||
user federator on ~u_* +get +set ~s_* +get +setex ~m_* +get +setex >redis*change*password
|
user federator on ~u_* +get +set >redis*change*password
|
||||||
|
|
||||||
change password in the rediscache.ini to match your given password.
|
change password in the rediscache.ini to match your given password.
|
||||||
|
|
||||||
|
|
|
@ -94,10 +94,6 @@ class Api extends Main
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch ($this->paths[0]) {
|
switch ($this->paths[0]) {
|
||||||
case '.well-known':
|
|
||||||
case 'nodeinfo':
|
|
||||||
$handler = new Api\WellKnown($this);
|
|
||||||
break;
|
|
||||||
case 'v1':
|
case 'v1':
|
||||||
switch ($this->paths[1]) {
|
switch ($this->paths[1]) {
|
||||||
case 'dummy':
|
case 'dummy':
|
||||||
|
@ -105,6 +101,9 @@ class Api extends Main
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case '.well-known':
|
||||||
|
$handler = new Api\WellKnown($this);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
$printresponse = true;
|
$printresponse = true;
|
||||||
if ($handler !== null) {
|
if ($handler !== null) {
|
||||||
|
@ -127,13 +126,14 @@ class Api extends Main
|
||||||
header($name . ': ' . $value);
|
header($name . ': ' . $value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($this->responseCode != 200) {
|
|
||||||
http_response_code($this->responseCode);
|
|
||||||
}
|
|
||||||
if ($printresponse) {
|
if ($printresponse) {
|
||||||
if ($this->redirect !== null) {
|
if ($this->redirect !== null) {
|
||||||
header("Location: $this->redirect");
|
header("Location: $this->redirect");
|
||||||
}
|
}
|
||||||
|
// @phan-suppress-next-line PhanSuspiciousValueComparison
|
||||||
|
if ($this->responseCode != 200) {
|
||||||
|
http_response_code($this->responseCode);
|
||||||
|
}
|
||||||
if ($this->responseCode != 404) {
|
if ($this->responseCode != 404) {
|
||||||
header("Content-type: " . $this->contentType);
|
header("Content-type: " . $this->contentType);
|
||||||
header("Access-Control-Allow-Origin: *");
|
header("Access-Control-Allow-Origin: *");
|
||||||
|
|
|
@ -37,19 +37,6 @@ class WellKnown implements APIInterface
|
||||||
$this->main = $main;
|
$this->main = $main;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* return host-meta information
|
|
||||||
*
|
|
||||||
* @return true
|
|
||||||
*/
|
|
||||||
private function hostMeta()
|
|
||||||
{
|
|
||||||
$data = [
|
|
||||||
'fqdn' => $_SERVER['SERVER_NAME']
|
|
||||||
];
|
|
||||||
$this->response = $this->main->renderTemplate('host-meta.xml', $data);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* run given url path
|
* run given url path
|
||||||
*
|
*
|
||||||
|
@ -64,17 +51,7 @@ class WellKnown implements APIInterface
|
||||||
case 'GET':
|
case 'GET':
|
||||||
switch (sizeof($paths)) {
|
switch (sizeof($paths)) {
|
||||||
case 2:
|
case 2:
|
||||||
if ($paths[0] === 'nodeinfo') {
|
if ($paths[1] === 'webfinger') {
|
||||||
$ni = new WellKnown\NodeInfo($this, $this->main);
|
|
||||||
return $ni->exec($paths);
|
|
||||||
}
|
|
||||||
switch ($paths[1]) {
|
|
||||||
case 'host-meta':
|
|
||||||
return $this->hostMeta();
|
|
||||||
case 'nodeinfo':
|
|
||||||
$ni = new WellKnown\NodeInfo($this, $this->main);
|
|
||||||
return $ni->exec($paths);
|
|
||||||
case 'webfinger':
|
|
||||||
$wf = new WellKnown\WebFinger($this, $this->main);
|
$wf = new WellKnown\WebFinger($this, $this->main);
|
||||||
return $wf->exec();
|
return $wf->exec();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,77 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* SPDX-FileCopyrightText: 2024 Sascha Nitsch (grumpydeveloper) https://contentnation.net/@grumpydevelop
|
|
||||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
*
|
|
||||||
* @author Sascha Nitsch (grumpydeveloper)
|
|
||||||
**/
|
|
||||||
|
|
||||||
namespace Federator\Api\WellKnown;
|
|
||||||
|
|
||||||
class NodeInfo
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* parent instance
|
|
||||||
*
|
|
||||||
* @var \Federator\Api\WellKnown $wellKnown
|
|
||||||
*/
|
|
||||||
private $wellKnown;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* main instance
|
|
||||||
*
|
|
||||||
* @var \Federator\Main $main
|
|
||||||
*/
|
|
||||||
private $main;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* constructor
|
|
||||||
*
|
|
||||||
* @param \Federator\Api\WellKnown $wellKnown parent instance
|
|
||||||
* @param \Federator\Main $main main instance
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function __construct($wellKnown, $main)
|
|
||||||
{
|
|
||||||
$this->wellKnown = $wellKnown;
|
|
||||||
$this->main = $main;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* handle nodeinfo request
|
|
||||||
*
|
|
||||||
* @param string[] $paths path of us
|
|
||||||
* @return bool true on success
|
|
||||||
*/
|
|
||||||
public function exec($paths)
|
|
||||||
{
|
|
||||||
$data = [
|
|
||||||
'fqdn' => $_SERVER['SERVER_NAME']
|
|
||||||
];
|
|
||||||
$template = null;
|
|
||||||
if (sizeof($paths) == 2 && $paths[0] === '.well-known' && $paths[1] === 'nodeinfo') {
|
|
||||||
$template = 'nodeinfo.json';
|
|
||||||
} else {
|
|
||||||
if ($paths[0] !== 'nodeinfo') {
|
|
||||||
throw new \Federator\Exceptions\FileNotFound();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($template === null) {
|
|
||||||
switch ($paths[1]) {
|
|
||||||
case '2.1':
|
|
||||||
$template = 'nodeinfo2.1.json';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$template = 'nodeinfo2.0.json';
|
|
||||||
}
|
|
||||||
$stats = \Federator\DIO\Stats::getStats($this->main);
|
|
||||||
echo "fetch usercount via connector\n";
|
|
||||||
$data['usercount'] = $stats->userCount;
|
|
||||||
$data['postcount'] = $stats->postCount;
|
|
||||||
$data['commentcount'] = $stats->commentCount;
|
|
||||||
}
|
|
||||||
$tpl = $this->main->renderTemplate($template, $data);
|
|
||||||
$this->wellKnown->setResponse($tpl);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -13,14 +13,6 @@ namespace Federator\Cache;
|
||||||
*/
|
*/
|
||||||
interface Cache extends \Federator\Connector\Connector
|
interface Cache extends \Federator\Connector\Connector
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* save remote stats
|
|
||||||
*
|
|
||||||
* @param \Federator\Data\Stats $stats stats to save
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function saveRemoteStats($stats);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* save remote user by given name
|
* save remote user by given name
|
||||||
*
|
*
|
||||||
|
|
|
@ -29,11 +29,4 @@ interface Connector
|
||||||
* @return \Federator\Data\User | false
|
* @return \Federator\Data\User | false
|
||||||
*/
|
*/
|
||||||
public function getRemoteUserBySession(string $_session, string $_user);
|
public function getRemoteUserBySession(string $_session, string $_user);
|
||||||
|
|
||||||
/**
|
|
||||||
* get statistics from remote system
|
|
||||||
*
|
|
||||||
* @return \Federator\Data\Stats|false
|
|
||||||
*/
|
|
||||||
public function getRemoteStats();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,70 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* SPDX-FileCopyrightText: 2024 Sascha Nitsch (grumpydeveloper) https://contentnation.net/@grumpydevelop
|
|
||||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
*
|
|
||||||
* @author Sascha Nitsch (grumpydeveloper)
|
|
||||||
**/
|
|
||||||
|
|
||||||
namespace Federator\Data;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* storage class for statistics
|
|
||||||
*/
|
|
||||||
class Stats
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* user count on the external system
|
|
||||||
*
|
|
||||||
* @var int $userCount
|
|
||||||
*/
|
|
||||||
public $userCount;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* post count on the external system
|
|
||||||
*
|
|
||||||
* @var int $postCount
|
|
||||||
*/
|
|
||||||
public $postCount;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* comment count on the external system
|
|
||||||
*
|
|
||||||
* @var int $commentCount
|
|
||||||
*/
|
|
||||||
public $commentCount;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* create new user object from json string
|
|
||||||
*
|
|
||||||
* @param string $input input string
|
|
||||||
* @return Stats
|
|
||||||
*/
|
|
||||||
public static function createFromJson($input)
|
|
||||||
{
|
|
||||||
$stats = new Stats();
|
|
||||||
$data = json_decode($input, true);
|
|
||||||
if ($data === null) {
|
|
||||||
return $stats;
|
|
||||||
}
|
|
||||||
$stats->userCount = $data['userCount'];
|
|
||||||
$stats->postCount = $data['postCount'];
|
|
||||||
$stats->commentCount = $data['commentCount'];
|
|
||||||
return $stats;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* convert internal data to json string
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function toJson()
|
|
||||||
{
|
|
||||||
$data = [
|
|
||||||
'userCount' => $this->userCount,
|
|
||||||
'postCount' => $this->postCount,
|
|
||||||
'commentCount' => $this->commentCount
|
|
||||||
];
|
|
||||||
return json_encode($data) | '';
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,45 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* SPDX-FileCopyrightText: 2024 Sascha Nitsch (grumpydeveloper) https://contentnation.net/@grumpydevelop
|
|
||||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
*
|
|
||||||
* @author Sascha Nitsch (grumpydeveloper)
|
|
||||||
**/
|
|
||||||
|
|
||||||
namespace Federator\DIO;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* IO functions related to stats
|
|
||||||
*/
|
|
||||||
class Stats
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get remote stats
|
|
||||||
*
|
|
||||||
* @param \Federator\Main $main
|
|
||||||
* main instance
|
|
||||||
* @return \Federator\Data\Stats
|
|
||||||
*/
|
|
||||||
public static function getStats($main)
|
|
||||||
{
|
|
||||||
$cache = $main->getCache();
|
|
||||||
// ask cache
|
|
||||||
if ($cache !== null) {
|
|
||||||
$stats = $cache->getRemoteStats();
|
|
||||||
if ($stats !== false) {
|
|
||||||
return $stats;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$connector = $main->getConnector();
|
|
||||||
// ask connector for stats
|
|
||||||
$stats = $connector->getRemoteStats();
|
|
||||||
if ($cache !== null && $stats !== false) {
|
|
||||||
$cache->saveRemoteStats($stats);
|
|
||||||
}
|
|
||||||
if ($stats === false) {
|
|
||||||
$stats = new \Federator\Data\Stats();
|
|
||||||
}
|
|
||||||
return $stats;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -37,30 +37,6 @@ class ContentNation implements Connector
|
||||||
$this->service = $config['service-uri'];
|
$this->service = $config['service-uri'];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* get statistics from remote system
|
|
||||||
*
|
|
||||||
* @return \Federator\Data\Stats|false
|
|
||||||
*/
|
|
||||||
public function getRemoteStats()
|
|
||||||
{
|
|
||||||
$remoteURL = $this->service . '/api/stats';
|
|
||||||
[$response, $info] = \Federator\Main::getFromRemote($remoteURL, []);
|
|
||||||
if ($info['http_code'] != 200) {
|
|
||||||
print_r($info);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$r = json_decode($response, true);
|
|
||||||
if ($r === false || $r === null || !is_array($r)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$stats = new \Federator\Data\Stats();
|
|
||||||
$stats->userCount = array_key_exists('userCount', $r) ? $r['userCount'] : 0;
|
|
||||||
$stats->postCount = array_key_exists('pageCount', $r) ? $r['pageCount'] : 0;
|
|
||||||
$stats->commentCount = array_key_exists('commentCount', $r) ? $r['commentCount'] : 0;
|
|
||||||
return $stats;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get remote user by given name
|
* get remote user by given name
|
||||||
*
|
*
|
||||||
|
|
|
@ -19,20 +19,6 @@ class DummyConnector implements Connector
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* get statistics from remote system
|
|
||||||
*
|
|
||||||
* @return \Federator\Data\Stats|false
|
|
||||||
*/
|
|
||||||
public function getRemoteStats()
|
|
||||||
{
|
|
||||||
$stats = new \Federator\Data\Stats();
|
|
||||||
$stats->userCount = 9;
|
|
||||||
$stats->postCount = 11;
|
|
||||||
$stats->commentCount = 13;
|
|
||||||
return $stats;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get remote user by name
|
* get remote user by name
|
||||||
* @param string $_name user or profile name
|
* @param string $_name user or profile name
|
||||||
|
|
|
@ -77,25 +77,6 @@ class RedisCache implements Cache
|
||||||
return $prefix . '_' . md5($input);
|
return $prefix . '_' . md5($input);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* get statistics from remote system
|
|
||||||
*
|
|
||||||
* @return \Federator\Data\Stats|false
|
|
||||||
*/
|
|
||||||
public function getRemoteStats()
|
|
||||||
{
|
|
||||||
if (!$this->connected) {
|
|
||||||
$this->connect();
|
|
||||||
}
|
|
||||||
$key = 'm_stats';
|
|
||||||
$data = $this->redis->get($key);
|
|
||||||
if ($data === false) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$stats = \Federator\Data\Stats::createFromJson($data);
|
|
||||||
return $stats;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get remote user by given name
|
* get remote user by given name
|
||||||
*
|
*
|
||||||
|
@ -138,22 +119,7 @@ class RedisCache implements Cache
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* save remote stats
|
* save remote user by namr
|
||||||
*
|
|
||||||
* @param \Federator\Data\Stats $stats stats to save
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function saveRemoteStats($stats)
|
|
||||||
{
|
|
||||||
if (!$this->connected) {
|
|
||||||
$this->connect();
|
|
||||||
}
|
|
||||||
$key = 'm_stats';
|
|
||||||
$serialized = $stats->toJson();
|
|
||||||
$this->redis->setEx($key, $this->config['statsttl'], $serialized);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* save remote user by name
|
|
||||||
*
|
*
|
||||||
* @param string $_name user/profile name
|
* @param string $_name user/profile name
|
||||||
* @param \Federator\Data\User $user user data
|
* @param \Federator\Data\User $user user data
|
||||||
|
@ -163,7 +129,7 @@ class RedisCache implements Cache
|
||||||
{
|
{
|
||||||
$key = self::createKey('u', $_name);
|
$key = self::createKey('u', $_name);
|
||||||
$serialized = $user->toJson();
|
$serialized = $user->toJson();
|
||||||
$this->redis->setEx($key, $this->userTTL, $serialized);
|
$this->redis->setEx($key, $this->userTTL, $serialized,);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -4,4 +4,3 @@ port = 6379
|
||||||
username = federator
|
username = federator
|
||||||
password = redis*change*password
|
password = redis*change*password
|
||||||
userttl = 10
|
userttl = 10
|
||||||
statsttl = 60
|
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
version="1.0" encoding="UTF-8"?>
|
|
||||||
<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
|
|
||||||
<Link rel="lrdd" template="https://{$fqdn}/.well-known/webfinger?resource={ldelim}uri{rdelim}"/>
|
|
||||||
</XRD>
|
|
|
@ -1,8 +0,0 @@
|
||||||
{ldelim}
|
|
||||||
"links": [
|
|
||||||
{
|
|
||||||
"rel": "http://nodeinfo.diaspora.software/ns/schema/2.1",
|
|
||||||
"href": "https://{$fqdn}/nodeinfo/2.1"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
{rdelim}}
|
|
|
@ -1,29 +0,0 @@
|
||||||
{ldelim}
|
|
||||||
"version": "2.0",
|
|
||||||
"software": {ldelim}
|
|
||||||
"name": "federator",
|
|
||||||
"version": "1.0.0",
|
|
||||||
{rdelim},
|
|
||||||
"protocols": [
|
|
||||||
"activitypub"
|
|
||||||
],
|
|
||||||
"relay": "none",
|
|
||||||
"services": {ldelim}
|
|
||||||
"inbound": [],
|
|
||||||
"outbound": [
|
|
||||||
"atom1.0",
|
|
||||||
"rss2.0"
|
|
||||||
]
|
|
||||||
{rdelim},
|
|
||||||
"openRegistrations": true,
|
|
||||||
"usage": {ldelim}
|
|
||||||
"users": {ldelim}
|
|
||||||
"total": {$usercount}
|
|
||||||
{* "activeMonth": activemonth,
|
|
||||||
"activeHalfyear": activehalfyear *}
|
|
||||||
{rdelim},
|
|
||||||
"localPosts": {$postcount},
|
|
||||||
"localComments": {$commentcount}
|
|
||||||
{rdelim},
|
|
||||||
"metadata": {ldelim}{rdelim}
|
|
||||||
{rdelim}
|
|
|
@ -1,30 +0,0 @@
|
||||||
{ldelim}
|
|
||||||
"version": "2.1",
|
|
||||||
"software": {ldelim}
|
|
||||||
"name": "federator",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"repository": "https://git.contentnation.net/grumpydevelop/federator"
|
|
||||||
{rdelim},
|
|
||||||
"protocols": [
|
|
||||||
"activitypub"
|
|
||||||
],
|
|
||||||
"relay": "none",
|
|
||||||
"services": {ldelim}
|
|
||||||
"inbound": [],
|
|
||||||
"outbound": [
|
|
||||||
"atom1.0",
|
|
||||||
"rss2.0"
|
|
||||||
]
|
|
||||||
{rdelim},
|
|
||||||
"openRegistrations": true,
|
|
||||||
"usage": {ldelim}
|
|
||||||
"users": {ldelim}
|
|
||||||
"total": {$usercount}
|
|
||||||
{* "activeMonth": activemonth,
|
|
||||||
"activeHalfyear": activehalfyear *}
|
|
||||||
{rdelim},
|
|
||||||
"localPosts": {$postcount},
|
|
||||||
"localComments": {$commentcount}
|
|
||||||
{rdelim},
|
|
||||||
"metadata": {ldelim}{rdelim}
|
|
||||||
{rdelim}
|
|
Loading…
Reference in New Issue