-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
firstly a user has to enable api in settings, then they use basic authentication to obtain a bearer token (valid for 1 hour) with which they can query private/sensitive data tokens can be invalidated prematurely by api itself or from settings (new page api tokens) the only private data that can be accessed with tokens at the moment is tokens themselves (reading and deleting)
- Loading branch information
1 parent
c310e34
commit f546f52
Showing
25 changed files
with
651 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace Nexendrie\Api; | ||
|
||
class ApiNotEnabledException extends \Nexendrie\Model\AccessDeniedException { | ||
|
||
} | ||
?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace Nexendrie\Api; | ||
|
||
class TokenExpiredException extends \RuntimeException { | ||
|
||
} | ||
?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace Nexendrie\Api; | ||
|
||
class TokenNotFoundException extends \Nexendrie\Model\RecordNotFoundException { | ||
|
||
} | ||
?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace Nexendrie\Api; | ||
|
||
use Nette\Security\User; | ||
use Nette\Utils\Random; | ||
use Nexendrie\Model\AuthenticationNeededException; | ||
use Nexendrie\Orm\ApiToken; | ||
use Nexendrie\Orm\Model as ORM; | ||
|
||
/** | ||
* @property-read int $length | ||
*/ | ||
final class Tokens { | ||
use \Nette\SmartObject; | ||
|
||
private int $ttl; | ||
private int $length; | ||
private ORM $orm; | ||
private User $user; | ||
|
||
public function __construct(int $ttl, int $length, ORM $orm, User $user) { | ||
$this->ttl = $ttl; | ||
$this->length = $length; | ||
$this->orm = $orm; | ||
$this->user = $user; | ||
} | ||
|
||
public function create(): ApiToken { | ||
if(!$this->user->isLoggedIn()) { | ||
throw new AuthenticationNeededException(); | ||
} | ||
|
||
/** @var \Nexendrie\Orm\User $user */ | ||
$user = $this->orm->users->getById($this->user->id); | ||
if(!$user->api) { | ||
throw new ApiNotEnabledException(); | ||
} | ||
|
||
$token = new ApiToken(); | ||
$token->user = $user; | ||
$token->token = Random::generate(max(1, $this->length)); | ||
$token->expire = time() + $this->ttl; | ||
$this->orm->apiTokens->persistAndFlush($token); | ||
|
||
return $token; | ||
} | ||
|
||
public function invalidate(string $token): void { | ||
if(!$this->user->isLoggedIn()) { | ||
throw new AuthenticationNeededException(); | ||
} | ||
|
||
$tokenEntity = $this->orm->apiTokens->getByToken($token); | ||
if($tokenEntity === null || $tokenEntity->user->id !== $this->user->id) { | ||
throw new TokenNotFoundException(); | ||
} | ||
|
||
$dt = new \DateTime(); | ||
if($tokenEntity->expire <= $dt->getTimestamp()) { | ||
throw new TokenExpiredException(); | ||
} | ||
|
||
$tokenEntity->expire = $dt->getTimestamp(); | ||
$this->orm->apiTokens->persistAndFlush($tokenEntity); | ||
} | ||
|
||
public function getLength(): int { | ||
return $this->length; | ||
} | ||
} | ||
?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace Nexendrie\Api\Transformers; | ||
|
||
class ApiTokenTransformer extends BaseTransformer { | ||
protected array $fields = ["id", "token", "expireAt", "createdAt", "user",]; | ||
protected array $fieldsRename = ["createdAt" => "created", "expireAt" => "expire",]; | ||
|
||
public function getEntityClassName(): string { | ||
return \Nexendrie\Orm\ApiToken::class; | ||
} | ||
|
||
public function getCollectionName(): string { | ||
return "tokens"; | ||
} | ||
} | ||
?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace Nexendrie\Orm; | ||
|
||
/** | ||
* Api token | ||
* | ||
* @author Jakub Konečný | ||
* @property int $id {primary} | ||
* @property string $token | ||
* @property User $user {m:1 User::$apiTokens} | ||
* @property int $expire | ||
* @property-read string $expireAt {virtual} | ||
* @property int $created | ||
* @property-read string $createdAt {virtual} | ||
*/ | ||
final class ApiToken extends BaseEntity { | ||
protected \Nexendrie\Model\Locale $localeModel; | ||
|
||
public function injectLocaleModel(\Nexendrie\Model\Locale $localeModel): void { | ||
$this->localeModel = $localeModel; | ||
} | ||
|
||
protected function getterExpireAt(): string { | ||
return $this->localeModel->formatDateTime($this->expire); | ||
} | ||
|
||
protected function getterCreatedAt(): string { | ||
return $this->localeModel->formatDateTime($this->created); | ||
} | ||
} | ||
?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace Nexendrie\Orm; | ||
|
||
/** | ||
* @author Jakub Konečný | ||
*/ | ||
final class ApiTokensMapper extends \Nextras\Orm\Mapper\Mapper { | ||
|
||
} | ||
?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace Nexendrie\Orm; | ||
|
||
use Nextras\Orm\Collection\ICollection; | ||
|
||
/** | ||
* @author Jakub Konečný | ||
* @method ApiToken|null getById(int $id) | ||
* @method ApiToken|null getBy(array $conds) | ||
* @method ICollection|ApiToken[] findBy(array $conds) | ||
* @method ICollection|ApiToken[] findAll() | ||
*/ | ||
final class ApiTokensRepository extends \Nextras\Orm\Repository\Repository { | ||
public static function getEntityClassNames(): array { | ||
return [ApiToken::class]; | ||
} | ||
|
||
/** | ||
* @param User|int $user | ||
* @return ICollection|ApiToken[] | ||
*/ | ||
public function findByUser($user): ICollection { | ||
return $this->findBy(["user" => $user]); | ||
} | ||
|
||
public function getByToken(string $token): ?ApiToken { | ||
return $this->getBy(["token" => $token]); | ||
} | ||
|
||
/** | ||
* @param User|int $user | ||
* @return ICollection|ApiToken[] | ||
*/ | ||
public function findActiveForUser($user): ICollection { | ||
return $this->findBy(["user" => $user, "expire>=" => time(),]); | ||
} | ||
} | ||
?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.