232 lines
7.6 KiB
PHP
232 lines
7.6 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\DIO;
|
|
|
|
/**
|
|
* IO functions related to users
|
|
*/
|
|
class User
|
|
{
|
|
/**
|
|
* 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 addLocalUser($dbh, $user, $_user)
|
|
{
|
|
// check if it is timed out user
|
|
$sql = 'select unix_timestamp(`validuntil`) from users where id=?';
|
|
$stmt = $dbh->prepare($sql);
|
|
if ($stmt === false) {
|
|
throw new \Federator\Exceptions\ServerError();
|
|
}
|
|
$stmt->bind_param("s", $_user);
|
|
$validuntil = 0;
|
|
$ret = $stmt->bind_result($validuntil);
|
|
$stmt->execute();
|
|
if ($ret) {
|
|
$stmt->fetch();
|
|
}
|
|
$stmt->close();
|
|
if ($validuntil == 0) {
|
|
$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, validuntil, type, name, summary, registered, iconmediatype, iconurl, imagemediatype, imageurl)';
|
|
$sql .= ' values (?, ?, ?, ?, now() + interval 1 day, ?, ?, ?, ?, ?, ?, ?, ?)';
|
|
$stmt = $dbh->prepare($sql);
|
|
if ($stmt === false) {
|
|
throw new \Federator\Exceptions\ServerError();
|
|
}
|
|
$registered = gmdate('Y-m-d H:i:s', $user->registered);
|
|
$stmt->bind_param(
|
|
"ssssssssssss",
|
|
$_user,
|
|
$user->externalid,
|
|
$public,
|
|
$private,
|
|
$user->type,
|
|
$user->name,
|
|
$user->summary,
|
|
$registered,
|
|
$user->iconMediaType,
|
|
$user->iconURL,
|
|
$user->imageMediaType,
|
|
$user->imageURL
|
|
);
|
|
} else {
|
|
// update to existing user
|
|
$sql = 'update users set validuntil=now() + interval 1 day, type=?, name=?, summary=?, registered=?, iconmediatype=?, iconurl=?, imagemediatype=?, imageurl=? where id=?';
|
|
$stmt = $dbh->prepare($sql);
|
|
if ($stmt === false) {
|
|
throw new \Federator\Exceptions\ServerError();
|
|
}
|
|
$registered = gmdate('Y-m-d H:i:s', $user->registered);
|
|
$stmt->bind_param(
|
|
"sssssssss",
|
|
$user->type,
|
|
$user->name,
|
|
$user->summary,
|
|
$registered,
|
|
$user->iconMediaType,
|
|
$user->iconURL,
|
|
$user->imageMediaType,
|
|
$user->imageURL,
|
|
$_user
|
|
);
|
|
}
|
|
try {
|
|
$stmt->execute();
|
|
$stmt->close();
|
|
$user->id = $_user;
|
|
} catch (\mysqli_sql_exception $e) {
|
|
error_log($sql);
|
|
error_log(print_r($user, true));
|
|
error_log($e->getMessage());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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,unix_timestamp(`validuntil`) from users where id=?';
|
|
$stmt = $dbh->prepare($sql);
|
|
if ($stmt === false) {
|
|
throw new \Federator\Exceptions\ServerError();
|
|
}
|
|
$stmt->bind_param("s", $_user);
|
|
$validuntil = 0;
|
|
$ret = $stmt->bind_result($user->id, $validuntil);
|
|
$stmt->execute();
|
|
if ($ret) {
|
|
$stmt->fetch();
|
|
}
|
|
$stmt->close();
|
|
// if a new user, create own database entry with additionally needed info
|
|
if ($user->id === null || $validuntil < time()) {
|
|
self::addLocalUser($dbh, $user, $_user);
|
|
}
|
|
|
|
// no further processing for now
|
|
}
|
|
|
|
/**
|
|
* get user by name
|
|
*
|
|
* @param \mysqli $dbh
|
|
* database handle
|
|
* @param string $_name
|
|
* user name
|
|
* @param \Federator\Connector\Connector $connector
|
|
* connector to fetch use with
|
|
* @param \Federator\Cache\Cache|null $cache
|
|
* optional caching service
|
|
* @return \Federator\Data\User
|
|
*/
|
|
public static function getUserByName($dbh, $_name, $connector, $cache)
|
|
{
|
|
$user = false;
|
|
// ask cache
|
|
if ($cache !== null) {
|
|
$user = $cache->getRemoteUserByName($_name);
|
|
}
|
|
if ($user !== false) {
|
|
return $user;
|
|
}
|
|
// check our db
|
|
$sql = 'select id,externalid,type,name,summary,unix_timestamp(registered),rsapublic,iconmediatype,iconurl,imagemediatype,imageurl from users where id=? and validuntil>=now()';
|
|
$stmt = $dbh->prepare($sql);
|
|
if ($stmt === false) {
|
|
throw new \Federator\Exceptions\ServerError();
|
|
}
|
|
$stmt->bind_param("s", $_name);
|
|
$user = new \Federator\Data\User();
|
|
$ret = $stmt->bind_result(
|
|
$user->id,
|
|
$user->externalid,
|
|
$user->type,
|
|
$user->name,
|
|
$user->summary,
|
|
$user->registered,
|
|
$user->publicKey,
|
|
$user->iconMediaType,
|
|
$user->iconURL,
|
|
$user->imageMediaType,
|
|
$user->imageURL,
|
|
);
|
|
$stmt->execute();
|
|
if ($ret) {
|
|
$stmt->fetch();
|
|
}
|
|
$stmt->close();
|
|
if ($user->id === null) {
|
|
// ask connector for user-id
|
|
$ruser = $connector->getRemoteUserByName($_name);
|
|
if ($ruser !== false) {
|
|
$user = $ruser;
|
|
}
|
|
}
|
|
if ($cache !== null) {
|
|
if ($user->id === null && $user->externalid !== null) {
|
|
self::addLocalUser($dbh, $user, $_name);
|
|
}
|
|
$cache->saveRemoteUserByName($_name, $user);
|
|
}
|
|
return $user;
|
|
}
|
|
|
|
/**
|
|
* get User by session id
|
|
*
|
|
* @param \mysqli $dbh
|
|
* database handle
|
|
* @param string $_session
|
|
* session
|
|
* @param string $_user
|
|
* user/profile name
|
|
* @param \Federator\Connector\Connector $connector
|
|
* connector to fetch use with
|
|
* @param \Federator\Cache\Cache|null $cache
|
|
* optional caching service
|
|
* @return \Federator\Data\User|false
|
|
*/
|
|
public static function getUserBySession($dbh, $_session, $_user, $connector, $cache)
|
|
{
|
|
$saveToCache = false;
|
|
$user = false;
|
|
if ($cache !== null) {
|
|
$user = $cache->getRemoteUserBySession($_session, $_user);
|
|
}
|
|
|
|
if ($user === false) {
|
|
// ask connector for user-id
|
|
$user = $connector->getRemoteUserBySession($_session, $_user);
|
|
$saveToCache = true;
|
|
}
|
|
if ($user === false) {
|
|
return false;
|
|
}
|
|
self::extendUser($dbh, $user, $_user);
|
|
if ($cache !== null && $saveToCache) {
|
|
$cache->saveRemoteUserBySession($_session, $_user, $user);
|
|
}
|
|
return $user;
|
|
}
|
|
}
|