diff --git a/php/data/user.php b/php/data/user.php index 78f8be1..92e9362 100644 --- a/php/data/user.php +++ b/php/data/user.php @@ -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) | ''; diff --git a/php/dio/user.php b/php/dio/user.php index e75d2c9..d31db63 100644 --- a/php/dio/user.php +++ b/php/dio/user.php @@ -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); } diff --git a/plugins/dummyconnector.php b/plugins/dummyconnector.php index 9155d7a..eee527c 100644 --- a/plugins/dummyconnector.php +++ b/plugins/dummyconnector.php @@ -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; diff --git a/plugins/rediscache.php b/plugins/rediscache.php index 8bbef5f..cf9b47a 100644 --- a/plugins/rediscache.php +++ b/plugins/rediscache.php @@ -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,); } } diff --git a/progress.md b/progress.md index 1f0494d..88ea82b 100644 --- a/progress.md +++ b/progress.md @@ -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 diff --git a/rediscache.ini b/rediscache.ini index 52244cd..2b9f0d5 100644 --- a/rediscache.ini +++ b/rediscache.ini @@ -3,3 +3,4 @@ host = localhost port = 6379 username = federator password = redis*change*password +userttl = 10 diff --git a/sql/2024-08-19.sql b/sql/2024-08-19.sql index 247f588..3380708 100644 --- a/sql/2024-08-19.sql +++ b/sql/2024-08-19.sql @@ -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");