forked from grumpydevelop/federator
		
	basic redis cache support
This commit is contained in:
		
							parent
							
								
									d96b05a658
								
							
						
					
					
						commit
						a32220442c
					
				
					 6 changed files with 127 additions and 12 deletions
				
			
		| 
						 | 
				
			
			@ -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>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										5
									
								
								rediscache.ini
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								rediscache.ini
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,5 @@
 | 
			
		|||
[redis]
 | 
			
		||||
host = localhost
 | 
			
		||||
port = 6379
 | 
			
		||||
username = federator
 | 
			
		||||
password = redis*change*password
 | 
			
		||||
		Loading…
	
	Add table
		
		Reference in a new issue