forked from grumpydevelop/federator
		
	support for user discovery endpoint
This commit is contained in:
		
							parent
							
								
									4c8e765a9e
								
							
						
					
					
						commit
						61203001a3
					
				
					 10 changed files with 424 additions and 31 deletions
				
			
		
							
								
								
									
										15
									
								
								README.md
									
										
									
									
									
								
							
							
						
						
									
										15
									
								
								README.md
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -25,7 +25,10 @@ Needed SQL commands:
 | 
			
		|||
    create user if not exists 'federatoradmin'@'localhost' identified by '*change*me*as*well';
 | 
			
		||||
    grant all privileges on federator.* to 'federatoradmin'@'localhost';
 | 
			
		||||
 | 
			
		||||
This will be changed, but works for the current develop verison.
 | 
			
		||||
After this, change the settings in the ini file to match above changed passwords.
 | 
			
		||||
change to php/federator and run
 | 
			
		||||
    php maintenance dbupgrade
 | 
			
		||||
to install all the needed table. Also run this after an update.
 | 
			
		||||
 | 
			
		||||
If the include redis cache is enabled, create a users.acl for redis with the content:
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -38,8 +41,15 @@ To configure an apache server, add the following rewrite rules:
 | 
			
		|||
    <Directory /where/ever/you/put/it>
 | 
			
		||||
      RewriteEngine on
 | 
			
		||||
      RewriteBase /
 | 
			
		||||
      RewriteRule ^api/federator/(.+)$ federator.php?_call=$1 [L]
 | 
			
		||||
      RewriteCond expr "%{HTTP:accept} -strcmatch '*application/ld+json*'" [OR]
 | 
			
		||||
      RewriteCond expr "%{HTTP:accept} -strcmatch '*application/jrd+json*'" [OR]
 | 
			
		||||
      RewriteCond expr "%{HTTP:accept} -strcmatch '*application/activity+json*'" [OR]
 | 
			
		||||
      RewriteCond expr "%{HTTP:content-type} -strcmatch '*application/activity+json*'"
 | 
			
		||||
      RewriteRule ^@(.*)$ /federator.php?_call=fedusers/$1 [L,END]
 | 
			
		||||
      RewriteRule ^users/(.*)$ /federator.php?_call=fedusers/$1 [L,END]
 | 
			
		||||
      RewriteRule ^api/federator/(.+)$ federator.php?_call=$1 [L,END]
 | 
			
		||||
      RewriteRule ^(\.well-known/.*)$ /federator.php?_call=$1 [L,END]
 | 
			
		||||
      RewriteRule ^(nodeinfo/2\.[01])$ /federator.php?_call=$1 [L,END]
 | 
			
		||||
    </Directory>
 | 
			
		||||
 | 
			
		||||
With the dummy plugin and everything installed correctly a
 | 
			
		||||
| 
						 | 
				
			
			@ -47,4 +57,3 @@ With the dummy plugin and everything installed correctly a
 | 
			
		|||
> curl -v http://localhost/api/federator/v1/dummy/moo -H "X-Session: somethingvalid" -H "X-Profile: ihaveone"
 | 
			
		||||
 | 
			
		||||
should return a piece of ascii art.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -98,6 +98,9 @@ class Api extends Main
 | 
			
		|||
            case 'nodeinfo':
 | 
			
		||||
                $handler = new Api\WellKnown($this);
 | 
			
		||||
                break;
 | 
			
		||||
            case 'fedusers':
 | 
			
		||||
                $handler = new Api\FedUsers($this);
 | 
			
		||||
                break;
 | 
			
		||||
            case 'v1':
 | 
			
		||||
                switch ($this->paths[1]) {
 | 
			
		||||
                    case 'dummy':
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										117
									
								
								php/federator/api/fedusers.php
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								php/federator/api/fedusers.php
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,117 @@
 | 
			
		|||
<?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"];
 | 
			
		||||
        switch ($method) {
 | 
			
		||||
            case 'GET':
 | 
			
		||||
                switch (sizeof($paths)) {
 | 
			
		||||
                    case 2:
 | 
			
		||||
                        // /users/username or /@username
 | 
			
		||||
                        return $this->returnUserProfile($paths[1]);
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
        $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' => str_replace("\n", "\\n", $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;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -20,6 +20,20 @@ class User
 | 
			
		|||
     */
 | 
			
		||||
    public $externalid;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * icon media type
 | 
			
		||||
     *
 | 
			
		||||
     * @var string $iconMediaType
 | 
			
		||||
     */
 | 
			
		||||
    public $iconMediaType;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * icon url
 | 
			
		||||
     *
 | 
			
		||||
     * @var string $iconURL
 | 
			
		||||
     */
 | 
			
		||||
    public $iconURL;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * user id
 | 
			
		||||
     *
 | 
			
		||||
| 
						 | 
				
			
			@ -27,9 +41,29 @@ class User
 | 
			
		|||
     */
 | 
			
		||||
    public $id;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * image media type
 | 
			
		||||
     *
 | 
			
		||||
     * @var string $imageMediaType
 | 
			
		||||
     */
 | 
			
		||||
    public $imageMediaType;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * image url
 | 
			
		||||
     *
 | 
			
		||||
     * @var string $imageURL
 | 
			
		||||
     */
 | 
			
		||||
    public $imageURL;
 | 
			
		||||
 | 
			
		||||
    /* @var string user language */
 | 
			
		||||
    //public $lang;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * user name
 | 
			
		||||
     *
 | 
			
		||||
     * @var string $name
 | 
			
		||||
     */
 | 
			
		||||
    public $name = '';
 | 
			
		||||
    /**
 | 
			
		||||
     * user permissions
 | 
			
		||||
     *
 | 
			
		||||
| 
						 | 
				
			
			@ -38,12 +72,40 @@ class User
 | 
			
		|||
     */
 | 
			
		||||
    public $permissions = [];
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * user public key
 | 
			
		||||
     *
 | 
			
		||||
     * @var string $publicKey
 | 
			
		||||
     */
 | 
			
		||||
    public $publicKey;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * registered unix timestamp
 | 
			
		||||
     *
 | 
			
		||||
     * @var int $registered
 | 
			
		||||
     */
 | 
			
		||||
    public $registered = 0;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * session id
 | 
			
		||||
     *
 | 
			
		||||
     * @var string $session
 | 
			
		||||
     * */
 | 
			
		||||
    public $session;
 | 
			
		||||
    public $session = '';
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * summary for user/profile
 | 
			
		||||
     *
 | 
			
		||||
     * @var string $summary
 | 
			
		||||
     */
 | 
			
		||||
    public $summary = '';
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * type of user (user/group)
 | 
			
		||||
     *
 | 
			
		||||
     * @var string $type
 | 
			
		||||
     */
 | 
			
		||||
    public $type = 'group';
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * create new user object from json string
 | 
			
		||||
| 
						 | 
				
			
			@ -58,10 +120,18 @@ class User
 | 
			
		|||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        $user = new User();
 | 
			
		||||
        $user->iconMediaType = $data['iconMediaType'];
 | 
			
		||||
        $user->iconURL = $data['iconURL'];
 | 
			
		||||
        $user->id = $data['id'];
 | 
			
		||||
        $user->imageMediaType = $data['imageMediaType'];
 | 
			
		||||
        $user->imageURL = $data['imageURL'];
 | 
			
		||||
        $user->externalid = $data['externalid'];
 | 
			
		||||
        $user->name = $data['name'];
 | 
			
		||||
        /// TODO: replace with enums
 | 
			
		||||
        $user->permissions = $data['permissions'];
 | 
			
		||||
        $user->publicKey = $data['publicKey'];
 | 
			
		||||
        $user->summary = $data['summary'];
 | 
			
		||||
        $user->type = $data['type'];
 | 
			
		||||
        return $user;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -86,9 +156,17 @@ class User
 | 
			
		|||
    public function toJson()
 | 
			
		||||
    {
 | 
			
		||||
        $data = [
 | 
			
		||||
          'id' => $this->id,
 | 
			
		||||
          'externalid' => $this->externalid,
 | 
			
		||||
          'permissions' => $this->permissions
 | 
			
		||||
            'iconMediaType' => $this->iconMediaType,
 | 
			
		||||
            'iconURL' => $this->iconURL,
 | 
			
		||||
            'id' => $this->id,
 | 
			
		||||
            'imageMediaType' => $this->iconMediaType,
 | 
			
		||||
            'imageURL' => $this->iconURL,
 | 
			
		||||
            'externalid' => $this->externalid,
 | 
			
		||||
            'name' => $this->name,
 | 
			
		||||
            'permissions' => $this->permissions,
 | 
			
		||||
            'publicKey' => $this->publicKey,
 | 
			
		||||
            'summary' => $this->summary,
 | 
			
		||||
            'type' => $this->type
 | 
			
		||||
        ];
 | 
			
		||||
        return json_encode($data) | '';
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,27 +22,78 @@ class User
 | 
			
		|||
     */
 | 
			
		||||
    protected static function addLocalUser($dbh, $user, $_user)
 | 
			
		||||
    {
 | 
			
		||||
        // needed fields: RSA key pair, user name (handle)
 | 
			
		||||
        $private_key = openssl_pkey_new();
 | 
			
		||||
        if ($private_key === false) {
 | 
			
		||||
        // 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();
 | 
			
		||||
        }
 | 
			
		||||
        $public = openssl_pkey_get_details($private_key)['key'];
 | 
			
		||||
        $private = '';
 | 
			
		||||
        openssl_pkey_export($private_key, $private);
 | 
			
		||||
        try {
 | 
			
		||||
            $sql = 'insert into users (id, externalid, rsapublic, rsaprivate, validuntil)';
 | 
			
		||||
            $sql .= ' values (?, ?, ?, ?, now() + interval 1 day)';
 | 
			
		||||
            $sql .= ' on duplicate key update validuntil=now() + interval 1 day';
 | 
			
		||||
        $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();
 | 
			
		||||
            }
 | 
			
		||||
            $stmt->bind_param("ssss", $_user, $user->externalid, $public, $private);
 | 
			
		||||
            $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());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -55,20 +106,21 @@ class User
 | 
			
		|||
     */
 | 
			
		||||
    protected static function extendUser(\mysqli $dbh, $user, $_user) : void
 | 
			
		||||
    {
 | 
			
		||||
        $sql = 'select id from users where id=?';
 | 
			
		||||
        $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);
 | 
			
		||||
        $ret = $stmt->bind_result($user->id);
 | 
			
		||||
        $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) {
 | 
			
		||||
        if ($user->id === null || $validuntil < time()) {
 | 
			
		||||
            self::addLocalUser($dbh, $user, $_user);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -99,14 +151,26 @@ class User
 | 
			
		|||
            return $user;
 | 
			
		||||
        }
 | 
			
		||||
        // check our db
 | 
			
		||||
        $sql = 'select id,externalid from users where id=? and validuntil>=now()';
 | 
			
		||||
        $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);
 | 
			
		||||
        $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();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -83,11 +83,16 @@ class ContentNation implements Connector
 | 
			
		|||
        if ($r === false || $r === null || !is_array($r)) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        if (!array_key_exists('name', $r) || $r['name'] !== $_name) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        $user = new \Federator\Data\User();
 | 
			
		||||
        $user->externalid = $_name;
 | 
			
		||||
        $user->iconMediaType = $r['iconMediaType'];
 | 
			
		||||
        $user->iconURL = $r['iconURL'];
 | 
			
		||||
        $user->imageMediaType = $r['imageMediaType'];
 | 
			
		||||
        $user->imageURL = $r['imageURL'];
 | 
			
		||||
        $user->name = $r['name'];
 | 
			
		||||
        $user->summary = $r['summary'];
 | 
			
		||||
        $user->type = $r['type'];
 | 
			
		||||
        $user->registered = intval($r['registered'], 10);
 | 
			
		||||
        return $user;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -118,8 +123,11 @@ class ContentNation implements Connector
 | 
			
		|||
        if ($r === false || !is_array($r) ||  !array_key_exists($_user, $r)) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        $user = new \Federator\Data\User();
 | 
			
		||||
        $user->externalid = $_user;
 | 
			
		||||
        $user = $this->getRemoteUserByName($_user);
 | 
			
		||||
        if ($user === false) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        // extend with permissions
 | 
			
		||||
        $user->permissions = [];
 | 
			
		||||
        $user->session = $_session;
 | 
			
		||||
        foreach ($r[$_user] as $p) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -43,8 +43,6 @@ class DummyConnector implements Connector
 | 
			
		|||
        // validate $_session and $user
 | 
			
		||||
        $user = new \Federator\Data\User();
 | 
			
		||||
        $user->externalid = $_name;
 | 
			
		||||
        $user->permissions = [];
 | 
			
		||||
        $user->session = '';
 | 
			
		||||
        return $user;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										9
									
								
								sql/2024-07-23.sql
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								sql/2024-07-23.sql
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,9 @@
 | 
			
		|||
alter table users add `type` enum('person', 'group') default 'person';
 | 
			
		||||
alter table users add `name` varchar(255) default '';
 | 
			
		||||
alter table users add `summary` text default '';
 | 
			
		||||
alter table users add `registered` timestamp default 0;
 | 
			
		||||
alter table users add `iconmediatype` varchar(255) default '';
 | 
			
		||||
alter table users add `iconurl` varchar(255) default '';
 | 
			
		||||
alter table users add `imagemediatype` varchar(255) default '';
 | 
			
		||||
alter table users add `imageurl` varchar(255) default '';
 | 
			
		||||
update settings set `value`="2024-07-23" where `key`="database_version";
 | 
			
		||||
							
								
								
									
										104
									
								
								templates/federator/user.json
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								templates/federator/user.json
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,104 @@
 | 
			
		|||
{ldelim}
 | 
			
		||||
    "@context":[
 | 
			
		||||
        "https://www.w3.org/ns/activitystreams",
 | 
			
		||||
        "https://w3id.org/security/v1",
 | 
			
		||||
        {ldelim}
 | 
			
		||||
            "manuallyApprovesFollowers":"as:manuallyApprovesFollowers",
 | 
			
		||||
            "toot":"http://joinmastodon.org/ns#",
 | 
			
		||||
            "featured":{ldelim}
 | 
			
		||||
                "@id":"toot:featured",
 | 
			
		||||
                "@type":"@id"
 | 
			
		||||
            {rdelim},
 | 
			
		||||
            "featuredTags":{ldelim}
 | 
			
		||||
                "@id":"toot:featuredTags",
 | 
			
		||||
                "@type":"@id"
 | 
			
		||||
            {rdelim},
 | 
			
		||||
            "alsoKnownAs":{ldelim}
 | 
			
		||||
                "@id":"as:alsoKnownAs",
 | 
			
		||||
                "@type":"@id"
 | 
			
		||||
            {rdelim},
 | 
			
		||||
            "movedTo":{ldelim}
 | 
			
		||||
                "@id":"as:movedTo",
 | 
			
		||||
                "@type":"@id"
 | 
			
		||||
            {rdelim},
 | 
			
		||||
            "schema":"http://schema.org#",
 | 
			
		||||
            "PropertyValue":"schema:PropertyValue",
 | 
			
		||||
            "value":"schema:value",
 | 
			
		||||
            "discoverable":"toot:discoverable",
 | 
			
		||||
            "Device":"toot:Device",
 | 
			
		||||
            "Ed25519Signature":"toot:Ed25519Signature",
 | 
			
		||||
            "Ed25519Key":"toot:Ed25519Key",
 | 
			
		||||
            "Curve25519Key":"toot:Curve25519Key",
 | 
			
		||||
            "EncryptedMessage":"toot:EncryptedMessage",
 | 
			
		||||
            "publicKeyBase64":"toot:publicKeyBase64",
 | 
			
		||||
            "deviceId":"toot:deviceId",
 | 
			
		||||
            "claim":{ldelim}
 | 
			
		||||
                "@type":"@id",
 | 
			
		||||
                "@id":"toot:claim"
 | 
			
		||||
            {rdelim},
 | 
			
		||||
            "fingerprintKey":{ldelim}
 | 
			
		||||
                "@type":"@id",
 | 
			
		||||
                "@id":"toot:fingerprintKey"
 | 
			
		||||
            {rdelim},
 | 
			
		||||
            "identityKey":{ldelim}
 | 
			
		||||
                "@type":"@id",
 | 
			
		||||
                "@id":"toot:identityKey"
 | 
			
		||||
            {rdelim},
 | 
			
		||||
            "devices":{ldelim}
 | 
			
		||||
                "@type":"@id",
 | 
			
		||||
                "@id":"toot:devices"
 | 
			
		||||
            {rdelim},
 | 
			
		||||
            "messageFranking":"toot:messageFranking",
 | 
			
		||||
            "messageType":"toot:messageType",
 | 
			
		||||
            "cipherText":"toot:cipherText",
 | 
			
		||||
            "suspended":"toot:suspended",
 | 
			
		||||
            "focalPoint":{ldelim}
 | 
			
		||||
                "@container":"@list",
 | 
			
		||||
                "@id":"toot:focalPoint"
 | 
			
		||||
            {rdelim}
 | 
			
		||||
        {rdelim}
 | 
			
		||||
    ],
 | 
			
		||||
    "id":"https://{$fqdn}/users/{$username}",
 | 
			
		||||
    "type":"{$type}",
 | 
			
		||||
    "following":"https://{$fqdn}/users/{$username}/following",
 | 
			
		||||
    "followers":"https://{$fqdn}/users/{$username}/followers",
 | 
			
		||||
    "inbox":"https://{$fqdn}/users/{$username}/inbox",
 | 
			
		||||
    "outbox":"https://{$fqdn}/users/{$username}/outbox",
 | 
			
		||||
    "featured":"https://{$fqdn}/users/{$username}/collections/featured",
 | 
			
		||||
    "featuredTags":"https://{$fqdn}/users/{$username}/collections/tags",
 | 
			
		||||
    "preferredUsername":"{$username}",
 | 
			
		||||
    "name":"{$name}",
 | 
			
		||||
    "summary":"{$summary}",
 | 
			
		||||
    "url":"https://{$fqdn}/@{$username}",
 | 
			
		||||
    "manuallyApprovesFollowers":false,
 | 
			
		||||
    "discoverable":true,
 | 
			
		||||
    "published":"{$registered}",
 | 
			
		||||
    "publicKey":{ldelim}
 | 
			
		||||
    "id":"https://{$fqdn}/users/{$username}#main-key",
 | 
			
		||||
    "owner":"https://{$fqdn}/users/{$username}",
 | 
			
		||||
    "publicKeyPem":"{$publickey}"
 | 
			
		||||
    {rdelim},
 | 
			
		||||
    "tag":[],
 | 
			
		||||
    "attachment":[
 | 
			
		||||
        {if $type==='group'}{ldelim}
 | 
			
		||||
        "type":"PropertyValue",
 | 
			
		||||
        "name":"website",
 | 
			
		||||
        "value":"\u003ca href=\"https://{$fqdn}/@{$username}\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"\u003e\u003cspan class=\"invisible\"\u003ehttps://\u003c/span\u003e\u003cspan class=\"\"\u003e{$fqdn}/@{$username}\u003c/span\u003e\u003cspan class=\"invisible\"\u003e\u003c/span\u003e\u003c/a\u003e"
 | 
			
		||||
        {rdelim}{/if}
 | 
			
		||||
    ],
 | 
			
		||||
    "endpoints":{ldelim}
 | 
			
		||||
        "sharedInbox":"https://{$fqdn}/inbox"
 | 
			
		||||
    {rdelim},
 | 
			
		||||
{if $iconURL !== ''}    "icon":{ldelim}
 | 
			
		||||
        "type":"Image",
 | 
			
		||||
        "mediaType":"{$iconMediaType}",
 | 
			
		||||
        "url":"{$iconURL}"
 | 
			
		||||
    {rdelim},
 | 
			
		||||
{/if}
 | 
			
		||||
{if $imageURL !== ''}    "image":{ldelim}
 | 
			
		||||
        "type":"Image",
 | 
			
		||||
        "mediaType":"{$imageMediaType}",
 | 
			
		||||
        "url":"{$imageURL}"
 | 
			
		||||
    {rdelim}
 | 
			
		||||
{/if}
 | 
			
		||||
{rdelim}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +1,9 @@
 | 
			
		|||
{ldelim}
 | 
			
		||||
  "subject": "acct:{$username}@{$domain}",
 | 
			
		||||
  "aliases": ["https://{$domain}/@{$username}"],
 | 
			
		||||
  "aliases": [
 | 
			
		||||
    "https://{$domain}/@{$username}"
 | 
			
		||||
    "https://{$domain}/users/{$username}"
 | 
			
		||||
  ],
 | 
			
		||||
  "links": [
 | 
			
		||||
    {ldelim}"rel": "self", "type": "application/activity+json", "href": "https://{$domain}/{$username}"{rdelim},
 | 
			
		||||
{if $type=='Group'}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue