support for local users with extra-data needed for activity-pub

This commit is contained in:
Sascha Nitsch 2024-07-19 20:37:09 +02:00
parent 199922299d
commit 0d3a7c871b
7 changed files with 76 additions and 11 deletions

View file

@ -13,6 +13,13 @@ namespace Federator\Data;
*/
class User
{
/**
* user id on the external system
*
* @var string $externalid
*/
public $externalid;
/**
* user id
*
@ -52,6 +59,7 @@ class User
}
$user = new User();
$user->id = $data['id'];
$user->externalid = $data['externalid'];
/// TODO: replace with enums
$user->permissions = $data['permissions'];
return $user;
@ -79,6 +87,7 @@ class User
{
$data = [
'id' => $this->id,
'externalid' => $this->externalid,
'permissions' => $this->permissions
];
return json_encode($data) | '';

View file

@ -14,14 +14,60 @@ namespace Federator\DIO;
class User
{
/**
* extend the given user with internal data
* @param \mysqli $dbh database handle @unused-param
* @param \Federator\Data\User $user user to extend @unused-param
* add local user based on given user object received from remote service
* @param \mysqli $dbh database handle
* @param \Federator\Data\User $user user object to use
* @param string $_user user/profile name
* @return void
*/
protected static function extendUser(\mysqli $dbh, \Federator\Data\User $user) : void
protected static function addLocalUser($dbh, $user, $_user)
{
// do nothing for now
// TODO: if a new user, create own database entry with additionally needed info
echo "a new user\n";
// needed fields: RSA key pair, user name (handle)
$private_key = openssl_pkey_new();
if ($private_key === false) {
throw new \Federator\Exceptions\ServerError();
}
$public = openssl_pkey_get_details($private_key)['key'];
$private = '';
openssl_pkey_export($private_key, $private);
$sql = 'insert into users (id, externalid, rsapublic, rsaprivate) values (?, ?, ?, ?)';
$stmt = $dbh->prepare($sql);
if ($stmt === false) {
throw new \Federator\Exceptions\ServerError();
}
$stmt->bind_param("ssss", $_user, $user->externalid, $public, $private);
$stmt->execute();
$stmt->close();
}
/**
* extend the given user with internal data
* @param \mysqli $dbh database handle
* @param \Federator\Data\User $user user to extend
* @param string $_user user/profile name
*/
protected static function extendUser(\mysqli $dbh, $user, $_user) : void
{
$sql = 'select id from users where id=?';
$stmt = $dbh->prepare($sql);
if ($stmt === false) {
throw new \Federator\Exceptions\ServerError();
}
$stmt->bind_param("s", $_user);
$ret = $stmt->bind_result($user->id);
$stmt->execute();
if ($ret) {
$stmt->fetch();
}
$stmt->close();
// if a new user, create own database entry with additionally needed info
if ($user->id === null) {
self::addLocalUser($dbh, $user, $_user);
}
// no further processing for now
}
/**
@ -55,7 +101,7 @@ class User
if ($user === false) {
return false;
}
self::extendUser($dbh, $user);
self::extendUser($dbh, $user, $_user);
if ($cache !== null && $saveToCache) {
$cache->saveRemoteUserBySession($_session, $_user, $user);
}

View file

@ -29,7 +29,7 @@ class DummyConnector implements Connector
{
// validate $_session and $user
$user = new \Federator\Data\User();
$user->id = $_user;
$user->externalid = $_user;
$user->permissions = ['PUBLISH'];
$user->session = $_session;
return $user;

View file

@ -34,6 +34,13 @@ class RedisCache implements Cache
*/
private $redis;
/**
* user cache time to life
*
* @var int time to life in secons
*/
private $userTTL;
/**
* constructor
*/
@ -42,6 +49,7 @@ class RedisCache implements Cache
$config = parse_ini_file('../rediscache.ini');
if ($config !== false) {
$this->config = $config;
$this->userTTL = array_key_exists('userttl', $config) ? intval($config['userttl'], 10) : 60;
}
}
@ -104,7 +112,7 @@ class RedisCache implements Cache
{
$key = self::createKey('u', $_session, $_user);
$serialized = $user->toJson();
$this->redis->set($key, $serialized);
$this->redis->setEx($key, $this->userTTL, $serialized,);
}
}

View file

@ -15,8 +15,8 @@ primary goal is to connect ContentNation via ActivityPub again.
- [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, ...
- [ ] full cache for users
- [X] overlay to extend with needed info like private keys, urls, ...
- [X] full cache for users
- [ ] webfinger
- [ ] discovery endpoints
- [ ] ap outbox

View file

@ -3,3 +3,4 @@ host = localhost
port = 6379
username = federator
password = redis*change*password
userttl = 10

View file

@ -1,2 +1,3 @@
create table settings(`key` varchar(255) unique primary key, `value` text);
create table users(`id` varchar(255) unique primary key, `externalid` varchar(255), index(`externalid`), `rsapublic` text, `rsaprivate` text);
insert into settings (`key`, `value`) value ("database_version", "2024-08-19");