Compare commits
2 Commits
6ea9c2728f
...
a32220442c
Author | SHA1 | Date |
---|---|---|
Sascha Nitsch | a32220442c | |
Sascha Nitsch | d96b05a658 |
|
@ -359,6 +359,9 @@ return [
|
|||
'directory_list' => [
|
||||
'vendor/phan/phan/src/Phan',
|
||||
'vendor/smarty/smarty/src',
|
||||
'php/',
|
||||
'plugins',
|
||||
'htdocs',
|
||||
],
|
||||
|
||||
// A list of individual files to include in analysis
|
||||
|
|
|
@ -25,6 +25,12 @@ Needed SQL commands:
|
|||
|
||||
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:
|
||||
|
||||
user federator on ~u_* +get +set >redis*change*password
|
||||
|
||||
change password in the rediscache.ini to match your given password.
|
||||
|
||||
To configure an apache server, add the following rewrite rules:
|
||||
|
||||
<Directory /where/ever/you/put/it>
|
||||
|
|
|
@ -11,7 +11,7 @@ if (! array_key_exists('_call', $_REQUEST)) {
|
|||
exit();
|
||||
}
|
||||
date_default_timezone_set("Europe/Berlin");
|
||||
spl_autoload_register(function ($className) {
|
||||
spl_autoload_register(static function (string $className) {
|
||||
// strip Federator from class path
|
||||
$className = str_replace('Federator\\', '', $className);
|
||||
include '../php/' . str_replace("\\", "/", strtolower($className)) . '.php';
|
||||
|
|
16
php/api.php
16
php/api.php
|
@ -30,7 +30,7 @@ class Api extends Main
|
|||
/**
|
||||
* current user
|
||||
*
|
||||
* @var Data\User $user
|
||||
* @var Data\User|false $user
|
||||
* */
|
||||
private $user;
|
||||
|
||||
|
@ -56,8 +56,9 @@ class Api extends Main
|
|||
*
|
||||
* @param string $call
|
||||
* path of called function
|
||||
* @return void
|
||||
*/
|
||||
public function setPath(string $call) : void
|
||||
public function setPath($call)
|
||||
{
|
||||
$this->path = $call;
|
||||
while ($this->path[0] === '/') {
|
||||
|
@ -71,7 +72,7 @@ class Api extends Main
|
|||
*/
|
||||
public function run() : void
|
||||
{
|
||||
$this->setPath($_REQUEST["_call"]);
|
||||
$this->setPath((string)$_REQUEST['_call']);
|
||||
$this->openDatabase();
|
||||
$this->loadPlugins();
|
||||
$retval = "";
|
||||
|
@ -131,6 +132,7 @@ class Api extends Main
|
|||
if ($this->redirect !== null) {
|
||||
header("Location: $this->redirect");
|
||||
}
|
||||
// @phan-suppress-next-line PhanSuspiciousValueComparison
|
||||
if ($this->responseCode != 200) {
|
||||
http_response_code($this->responseCode);
|
||||
}
|
||||
|
@ -168,6 +170,9 @@ class Api extends Main
|
|||
public function checkPermission($permission, $exception = "\Exceptions\PermissionDenied", $message = null) : void
|
||||
{
|
||||
// generic check first
|
||||
if ($this->user === false) {
|
||||
throw new Exceptions\PermissionDenied();
|
||||
}
|
||||
if ($this->user->id == 0) {
|
||||
throw new Exceptions\PermissionDenied();
|
||||
}
|
||||
|
@ -228,10 +233,7 @@ class Api extends Main
|
|||
if ($int === true) {
|
||||
return intval($_POST[$key]);
|
||||
}
|
||||
$ret = $this->dbh->escape_string($this->stripHTML($_POST[$key]));
|
||||
if ($ret === false) {
|
||||
return $int ? 0 : "";
|
||||
}
|
||||
$ret = $this->dbh->escape_string($this->stripHTML((string)$_POST[$key]));
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ class Dummy implements \Federator\Api\V1
|
|||
/**
|
||||
* constructor
|
||||
*
|
||||
* @param \Main $main main instance
|
||||
* @param \Federator\Main $main main instance
|
||||
*/
|
||||
public function __construct(\Federator\Main $main)
|
||||
{
|
||||
|
|
|
@ -15,9 +15,10 @@ interface Cache extends \Federator\Connector\Connector
|
|||
{
|
||||
/**
|
||||
* save remote user by given session
|
||||
*
|
||||
* @param string $_session session id
|
||||
* @param string $_user user/profile name
|
||||
* @aramm \Federator\Data\User $user user data
|
||||
* @param \Federator\Data\User $user user data
|
||||
* @return void
|
||||
*/
|
||||
public function saveRemoteUserBySession($_session, $_user, $user);
|
||||
|
|
|
@ -15,6 +15,7 @@ interface Connector
|
|||
{
|
||||
/**
|
||||
* get remote user by given session
|
||||
*
|
||||
* @param string $_session session id
|
||||
* @param string $_user user/profile name
|
||||
* @return \Federator\Data\User | false
|
||||
|
|
|
@ -38,6 +38,25 @@ class User
|
|||
* */
|
||||
public $session;
|
||||
|
||||
/**
|
||||
* create new user object from json string
|
||||
*
|
||||
* @param string $input input string
|
||||
* @return User|false
|
||||
*/
|
||||
public static function createFromJson($input)
|
||||
{
|
||||
$data = json_decode($input, true);
|
||||
if ($data === null) {
|
||||
return false;
|
||||
}
|
||||
$user = new User();
|
||||
$user->id = $data['id'];
|
||||
/// TODO: replace with enums
|
||||
$user->permissions = $data['permissions'];
|
||||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* check if use has asked permission
|
||||
* @param string $p @unused-param
|
||||
|
@ -48,6 +67,20 @@ class User
|
|||
*/
|
||||
public function hasPermission(string $p)
|
||||
{
|
||||
return in_array($p, $this->permissions);
|
||||
return in_array($p, $this->permissions, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* convert internal data to json string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function toJson()
|
||||
{
|
||||
$data = [
|
||||
'id' => $this->id,
|
||||
'permissions' => $this->permissions
|
||||
];
|
||||
return json_encode($data) | '';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,28 +33,32 @@ class User
|
|||
* session
|
||||
* @param string $_user
|
||||
* user/profile name
|
||||
* @param \Connector\Connector? $connector @unused-param
|
||||
* @param \Federator\Connector\Connector $connector
|
||||
* connector to fetch use with
|
||||
* @param \Cache\Cache? $cache
|
||||
* @param \Federator\Cache\Cache|null $cache
|
||||
* optional caching service
|
||||
* @return \Data\User|bool
|
||||
* @return \Federator\Data\User|false
|
||||
*/
|
||||
public static function getUserBySession($dbh, $_session, $_user, $connector, $cache)
|
||||
{
|
||||
$saveToCache = false;
|
||||
$user = false;
|
||||
if ($cache) {
|
||||
if ($cache !== null) {
|
||||
$user = $cache->getRemoteUserBySession($_session, $_user);
|
||||
}
|
||||
|
||||
// ask connector for user-id
|
||||
$user = $connector->getRemoteUserBySession($_session, $_user);
|
||||
if ($user === false) {
|
||||
// ask connector for user-id
|
||||
$user = $connector->getRemoteUserBySession($_session, $_user);
|
||||
$saveToCache = true;
|
||||
}
|
||||
if ($user === false) {
|
||||
return false;
|
||||
}
|
||||
if ($cache) {
|
||||
self::extendUser($dbh, $user);
|
||||
if ($cache !== null && $saveToCache) {
|
||||
$cache->saveRemoteUserBySession($_session, $_user, $user);
|
||||
}
|
||||
self::extendUser($dbh, $user);
|
||||
return $user;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ class Language
|
|||
}
|
||||
}
|
||||
if ($uselang === null && array_key_exists('_lang', $_REQUEST)) {
|
||||
$language = $_REQUEST['_lang'];
|
||||
$language = (string)$_REQUEST['_lang'];
|
||||
if (array_key_exists($language, $this->validLanguages)) {
|
||||
$uselang = $language;
|
||||
}
|
||||
|
@ -126,7 +126,7 @@ class Language
|
|||
*
|
||||
* @param string $group
|
||||
* group name to fetch keys
|
||||
* @return array<string> list of keys
|
||||
* @return list<string> list of keys
|
||||
*/
|
||||
public function getKeys(string $group)
|
||||
{
|
||||
|
@ -135,6 +135,7 @@ class Language
|
|||
require_once($_SERVER['DOCUMENT_ROOT'] . '/../lang/' . $this->uselang . "/$group.inc");
|
||||
$this->lang[$group] = $l;
|
||||
}
|
||||
// @phan-suppress-next-line PhanPartialTypeMismatchReturn
|
||||
return array_keys($this->lang[$group]);
|
||||
}
|
||||
|
||||
|
@ -263,11 +264,11 @@ function smarty_function_printlang($params, $template) : string
|
|||
{
|
||||
$lang = $template->getTemplateVars("language");
|
||||
<<<'PHAN'
|
||||
@phan-var \Language $lang
|
||||
@phan-var \Federator\Language $lang
|
||||
PHAN;
|
||||
$forcelang = array_key_exists('lang', $params) ? $params['lang'] : null;
|
||||
if ($forcelang !== null) {
|
||||
$lang = new Language($forcelang);
|
||||
$lang = new \Federator\Language($forcelang);
|
||||
}
|
||||
if (isset($params['var'])) {
|
||||
return $lang->printlang($params['group'], $params['key'], $params['var']);
|
||||
|
|
11
php/main.php
11
php/main.php
|
@ -53,7 +53,7 @@ class Main
|
|||
/**
|
||||
* languange instance
|
||||
*
|
||||
* @var \Language $lang
|
||||
* @var Language $lang
|
||||
*/
|
||||
protected $lang = null;
|
||||
/**
|
||||
|
@ -80,7 +80,11 @@ class Main
|
|||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->config = parse_ini_file('../config.ini', true);
|
||||
$this->responseCode = 200;
|
||||
$config = parse_ini_file('../config.ini', true);
|
||||
if ($config !== false) {
|
||||
$this->config = $config;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -92,6 +96,9 @@ class Main
|
|||
public static function getFromRemote(string $remoteURL, $headers)
|
||||
{
|
||||
$ch = curl_init();
|
||||
if ($ch === false) {
|
||||
return ['', null];
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_URL, $remoteURL);
|
||||
curl_setopt($ch, CURLOPT_HEADER, 0);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
|
|
|
@ -23,7 +23,7 @@ class DummyConnector implements Connector
|
|||
* get remote user by given session
|
||||
* @param string $_session session id
|
||||
* @param string $_user user or profile name
|
||||
* @return Data\User | false
|
||||
* @return \Federator\Data\User | false
|
||||
*/
|
||||
public function getRemoteUserBySession(string $_session, string $_user)
|
||||
{
|
||||
|
|
|
@ -13,6 +13,20 @@ namespace Federator\Cache;
|
|||
*/
|
||||
class RedisCache implements Cache
|
||||
{
|
||||
/**
|
||||
* config data
|
||||
*
|
||||
* @var array<string, mixed> $config
|
||||
*/
|
||||
private $config;
|
||||
|
||||
/**
|
||||
* connection to redis open flag
|
||||
*
|
||||
* @var bool $connected
|
||||
*/
|
||||
private $connected = false;
|
||||
|
||||
/**
|
||||
* connection handle
|
||||
*
|
||||
|
@ -25,20 +39,72 @@ class RedisCache implements Cache
|
|||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$config = parse_ini_file('../rediscache.ini');
|
||||
if ($config !== false) {
|
||||
$this->config = $config;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* connect to redis
|
||||
* @return void
|
||||
*/
|
||||
private function connect()
|
||||
{
|
||||
$this->redis = new \Redis();
|
||||
$this->redis->pconnect($this->config['host'], intval($this->config['port'], 10));
|
||||
// @phan-suppress-next-line PhanTypeMismatchArgumentInternalProbablyReal
|
||||
$this->redis->auth([$this->config['username'], $this->config['password']]);
|
||||
}
|
||||
|
||||
/**
|
||||
* create key from session and user
|
||||
*
|
||||
* @param string $prefix prefix to create name spaces
|
||||
* @param string $_session session id
|
||||
* @param string $_user user/profile name
|
||||
* @return string key
|
||||
*/
|
||||
private static function createKey($prefix, $_session, $_user)
|
||||
{
|
||||
$key = $prefix . '_';
|
||||
$key .= md5($_session . $_user);
|
||||
return $key;
|
||||
}
|
||||
/**
|
||||
* get remote user by given session
|
||||
*
|
||||
* @param string $_session session id
|
||||
* @param string $_user user/profile name
|
||||
* @return \Federator\Data\User | false
|
||||
*/
|
||||
public function getRemoteUserBySession($_session, $_user)
|
||||
{
|
||||
if (!$this->connected) {
|
||||
$this->connect();
|
||||
}
|
||||
$key = self::createKey('u', $_session, $_user);
|
||||
$data = $this->redis->get($key);
|
||||
if ($data === false) {
|
||||
return false;
|
||||
}
|
||||
$user = \Federator\Data\User::createFromJson($data);
|
||||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* save remote user by given session
|
||||
*
|
||||
* @param string $_session session id
|
||||
* @param string $_user user/profile name
|
||||
* @param \Federator\Data\User $user user data
|
||||
* @return void
|
||||
*/
|
||||
public function saveRemoteUserBySession($_session, $_user, $user)
|
||||
{
|
||||
$key = self::createKey('u', $_session, $_user);
|
||||
$serialized = $user->toJson();
|
||||
$this->redis->set($key, $serialized);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,8 +14,9 @@ primary goal is to connect ContentNation via ActivityPub again.
|
|||
## roadmap to v1.0
|
||||
- [X] API framework
|
||||
- [X] interfact to connect to existing service
|
||||
- [X] cache layer for users minmal version
|
||||
- [ ] overlay to extend with needed info like private keys, urls, ...
|
||||
- [ ] cache layer for users
|
||||
- [ ] full cache for users
|
||||
- [ ] webfinger
|
||||
- [ ] discovery endpoints
|
||||
- [ ] ap outbox
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
[redis]
|
||||
host = localhost
|
||||
port = 6379
|
||||
username = federator
|
||||
password = redis*change*password
|
Loading…
Reference in New Issue