forked from grumpydevelop/federator

- includes hacky following-mechanic in order to simulate a follow on mastodon (not properly working, need to also inject the user this creates into the followers db for the target mastodon-user) - created endpoint for inbox. SharedInbox is used when no user is provided (/api/federator/fedusers/inbox'), the regular inbox link now works (/users/username/inbox). - Retrieve all followers of sender and, if they're part of our system, send the activity into their personal inbox - Support Announce and Undo Activity-Types - Inbox currently converts to proper ActPub-objects and saves data to log-files
185 lines
5.7 KiB
PHP
185 lines
5.7 KiB
PHP
<?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;
|
|
|
|
/**
|
|
* /@username or /users/ handlers
|
|
*/
|
|
class FedUsers implements APIInterface
|
|
{
|
|
/**
|
|
* main instance
|
|
*
|
|
* @var \Federator\Main $main
|
|
*/
|
|
private $main;
|
|
|
|
/**
|
|
* response from sub-calls
|
|
*
|
|
* @var string $response
|
|
*/
|
|
private $response;
|
|
|
|
/**
|
|
* constructor
|
|
*
|
|
* @param \Federator\Main $main main instance
|
|
* @return void
|
|
*/
|
|
public function __construct($main)
|
|
{
|
|
$this->main = $main;
|
|
}
|
|
|
|
/**
|
|
* run given url path
|
|
*
|
|
* @param array<string> $paths path array split by /
|
|
* @param \Federator\Data\User|false $user user who is calling us @unused-param
|
|
* @return bool true on success
|
|
*/
|
|
public function exec($paths, $user)
|
|
{
|
|
$method = $_SERVER["REQUEST_METHOD"];
|
|
$handler = null;
|
|
switch (sizeof($paths)) {
|
|
case 2:
|
|
if ($method === 'GET') {
|
|
// /fedusers/username or /@username
|
|
return $this->returnUserProfile($paths[1]);
|
|
} else {
|
|
switch ($paths[1]) {
|
|
case 'inbox':
|
|
$handler = new FedUsers\Inbox($this->main);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
case 3:
|
|
// /fedusers/username/(inbox|outbox|following|followers)
|
|
switch ($paths[2]) {
|
|
case 'following':
|
|
// $handler = new FedUsers\Following();
|
|
break;
|
|
case 'followers':
|
|
// $handler = new FedUsers\Followers();
|
|
break;
|
|
case 'inbox':
|
|
$handler = new FedUsers\Inbox($this->main);
|
|
$user = $paths[1];
|
|
if (!preg_match("#^([^@]+)@([^/]+)#", $user, $matches) === 1) {
|
|
$hostUrl = $this->main->getHost();
|
|
if ($hostUrl !== false) {
|
|
$host = parse_url($hostUrl, PHP_URL_HOST);
|
|
$port = parse_url($hostUrl, PHP_URL_PORT);
|
|
if ($port !== null) {
|
|
$host .= `:$port`;
|
|
}
|
|
$user = `$user@$host`;
|
|
}
|
|
}
|
|
break;
|
|
case 'outbox':
|
|
$handler = new FedUsers\Outbox($this->main);
|
|
$user = $paths[1];
|
|
if (!preg_match("#^([^@]+)@([^/]+)#", $user, $matches) === 1) {
|
|
$hostUrl = $this->main->getHost();
|
|
if ($hostUrl !== false) {
|
|
$host = parse_url($hostUrl, PHP_URL_HOST);
|
|
$port = parse_url($hostUrl, PHP_URL_PORT);
|
|
if ($port !== null) {
|
|
$host .= `:$port`;
|
|
}
|
|
$user = `$user@$host`;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
case 4:
|
|
// /fedusers/username/collections/(features|tags)
|
|
// not yet implemented
|
|
break;
|
|
}
|
|
if ($handler !== null) {
|
|
$ret = false;
|
|
switch ($method) {
|
|
case 'GET':
|
|
$ret = $handler->get($user);
|
|
break;
|
|
case 'POST':
|
|
$ret = $handler->post($user);
|
|
break;
|
|
}
|
|
if ($ret !== false) {
|
|
$this->response = $ret;
|
|
return true;
|
|
}
|
|
}
|
|
$this->main->setResponseCode(404);
|
|
return false;
|
|
}
|
|
|
|
|
|
/**
|
|
* return user profile
|
|
*
|
|
* @param string $_name
|
|
* @return boolean true on success
|
|
*/
|
|
private function returnUserProfile($_name)
|
|
{
|
|
$user = \Federator\DIO\User::getUserByName(
|
|
$this->main->getDatabase(),
|
|
$_name,
|
|
$this->main->getConnector(),
|
|
$this->main->getCache()
|
|
);
|
|
if ($user === false || $user->id === null) {
|
|
throw new \Federator\Exceptions\FileNotFound();
|
|
}
|
|
$data = [
|
|
'iconMediaType' => $user->iconMediaType,
|
|
'iconURL' => $user->iconURL,
|
|
'imageMediaType' => $user->imageMediaType,
|
|
'imageURL' => $user->imageURL,
|
|
'fqdn' => $_SERVER['SERVER_NAME'],
|
|
'name' => $user->name,
|
|
'username' => $user->id,
|
|
'publickey' => $user->publicKey,
|
|
'registered' => gmdate('Y-m-d\TH:i:s\Z', $user->registered), // 2021-03-25T00:00:00Z
|
|
'summary' => $user->summary,
|
|
'type' => $user->type
|
|
];
|
|
$this->response = $this->main->renderTemplate('user.json', $data);
|
|
return true;
|
|
}
|
|
/**
|
|
* set response
|
|
*
|
|
* @param string $response response to set
|
|
* @return void
|
|
*/
|
|
public function setResponse($response)
|
|
{
|
|
$this->response = $response;
|
|
}
|
|
|
|
/**
|
|
* get internal represenation as json string
|
|
* @return string json string or html
|
|
*/
|
|
public function toJson()
|
|
{
|
|
return $this->response;
|
|
}
|
|
}
|