This commit is contained in:
2023-10-02 23:10:49 +03:00
commit c6cb488379
255 changed files with 18731 additions and 0 deletions
+56
View File
@@ -0,0 +1,56 @@
<?php
namespace Lucent\AccessKey;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Validator;
use Lucent\LucentException;
use Lucent\Member\Role;
class AccessKey
{
public function __construct(
public readonly string $_id,
public readonly string $name,
public readonly Role $role,
public readonly string $token,
private readonly ?string $showOnceToken = null,
) {
$validator = Validator::make($this->toArray(), [
'name' => 'min:3,max:120',
]);
if ($validator->fails()) {
throw new LucentException($validator->errors()->first());
}
}
public static function fromArray(array $data): AccessKey
{
return new AccessKey(
_id: data_get($data, "_id"),
name: data_get($data, "name"),
role: Role::from(data_get($data, "role")),
token: data_get($data, "token"),
);
}
public function getShowOnceToken(): ?string
{
return $this->showOnceToken;
}
public function isValid(string $token): bool
{
return Hash::check($token, $this->token);
}
public function toArray(): array
{
return \json_decode(\json_encode($this), true);
}
}
+43
View File
@@ -0,0 +1,43 @@
<?php
namespace Lucent\AccessKey;
use Carbon\Carbon;
use Lucent\Channel\ChannelContext;
use Lucent\DB\Monger;
class AccessKeyRepo
{
public static function findByToken(string $token): ?AccessKey
{
$channel = ChannelContext::get()->channel;
return $channel->accessKeys->firstWhere("token",$token);
}
public static function add(AccessKey $accessKey): void
{
$channel = ChannelContext::get()->channel;
Monger::central()->updateOne("channels", ["_id" => $channel->_id], [
'$push' => [
"accessKeys" => $accessKey->toArray()
],
'$set' => [
"updatedAt" => Carbon::now()->toJson(),
]
]);
}
public static function remove(string $id): void
{
$channel = ChannelContext::get()->channel;
Monger::central()->updateOne("channels", ["_id" => $channel->_id], [
'$pull' => [
"accessKeys" => ["_id" => $id]
],
'$set' => [
"updatedAt" => Carbon::now()->toJson(),
]
]);
}
}
+40
View File
@@ -0,0 +1,40 @@
<?php
namespace Lucent\AccessKey;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
use Lucent\Id\Id;
use Lucent\LucentException;
use Lucent\Member\Role;
class AccessKeyService
{
public static function create(string $name, string $role): AccessKey
{
$showOnceToken = Str::random(48);
$accessKey = new AccessKey(
_id: Id::new(),
name: $name,
token: hash("sha256", $showOnceToken),
role: Role::from($role),
showOnceToken: $showOnceToken,
);
AccessKeyRepo::add($accessKey);
return $accessKey;
}
public static function findByToken(string $token): ?AccessKey
{
$hashedToken = hash("sha256", $token);
return AccessKeyRepo::findByToken($hashedToken);
}
public static function remove(string $id): void
{
AccessKeyRepo::remove($id);
}
}
+41
View File
@@ -0,0 +1,41 @@
<?php
namespace Lucent\AccessKey;
use Illuminate\Support\Collection;
/**
* @extends \Illuminate\Support\Collection<int|string, AccessKey>
*/
final class AccessKeysCollection extends Collection
{
public function __construct(
AccessKey ...$array
) {
parent::__construct($array);
}
/**
* @return AccessKey[]
**/
public function toArray(): array
{
return collect($this)->values()->toArray();
}
public function toDB(): array
{
return \json_decode(\json_encode($this), true);
}
public static function fromArray(array $data): AccessKeysCollection
{
$item = array_map([AccessKey::class, 'fromArray'], $data);
return new AccessKeysCollection(...$item);
}
}
+40
View File
@@ -0,0 +1,40 @@
<?php
namespace Lucent\AccessKey;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Lucent\Account\Role;
class ApiMiddleware
{
public function handle(Request $request, Closure $next, string $accessLevel): Response
{
$bearerToken = $request->header('Authorization');
$token = str_replace('Bearer ', '', $bearerToken);
$role = match ($token) {
config("lucent.read_key") => Role::READER,
config("lucent.write_key") => Role::EDITOR,
config("lucent.developer_key") => Role::DEVELOPER,
default => ""
};
if (empty($role)) {
abort(401);
}
if (!$role->hasAccess($accessLevel)) {
abort(401);
}
$request->mergeIfMissing(['userId' => "system"]);
$request->mergeIfMissing(['userRole' => $role->value]);
return $next($request);
}
}