actor_id = $actor_id; return $this; } public function getActorId(): int { return $this->actor_id; } public function setToken(string $token): self { $this->token = mb_substr($token, 0, 64); return $this; } public function getToken(): string { return $this->token; } public function setEnabled(bool $enabled): self { $this->enabled = $enabled; return $this; } public function getEnabled(): bool { return $this->enabled; } public function setCreated(DateTimeInterface $created): self { $this->created = $created; return $this; } public function getCreated(): DateTimeInterface { return $this->created; } // @codeCoverageIgnoreEnd // }}} Autocode public static function cacheKeys(string $nickname): array { return [ 'user-token' => "pinboard-token-{$nickname}", ]; } public function getUser(): LocalUser { return LocalUser::getById($this->getActorId()); } /** * Get a token for a $nickname and $token pair, unless given a $user, in which case the token field is not validated * * XXX: may need to verify it's timing safe */ public static function get(?string $nickname, ?string $token, ?LocalUser $user = null): ?self { if (!\is_null($user)) { return Cache::get( self::cacheKeys($user->getNickname())['user-token'], fn () => DB::dql( 'select t from \Plugin\Pinboard\Entity\Token t where t.actor_id = :id', ['id' => $user->getId()], options: ['limit' => 1], ), ); } elseif (!\is_null($nickname) && !\is_null($token)) { return Cache::get( self::cacheKeys($nickname)['user-token'], fn () => DB::dql( <<<'EOF' select lu from \App\Entity\LocalUser lu join \Plugin\Pinboard\Entity\Token t on t.actor_id = lu.actor_id where lu.nickname = :nickname and t.token = :token and t.enabled = true EOF, ['nickname' => $nickame, 'token' => $token], options: ['limit' => 1], ), ); } } public function getUserTokenString() { return LocalUser::getById($this->getActorId())->getNickname() . ':' . $this->getToken(); } public static function generateTokenString(): string { return bin2hex(random_bytes(Common::config('plugin_pinboard', 'token_length') / 2)); } public static function schemaDef(): array { return [ 'name' => 'pinboard_token', 'fields' => [ 'actor_id' => ['type' => 'int', 'not null' => true, 'description' => 'Actor who created this note'], 'token' => ['type' => 'varchar', 'length' => 64, 'not null' => true, 'description' => 'The token this user has enabled'], 'enabled' => ['type' => 'bool', 'not null' => true, 'default' => false, 'description whether this user enabled the pinboard API'], 'created' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was created'], ], 'primary key' => ['actor_id'], ]; } }