permissions
This commit is contained in:
@@ -2,13 +2,18 @@
|
||||
|
||||
namespace Lucent\Account;
|
||||
|
||||
use Lucent\Channel\ChannelService;
|
||||
use Lucent\Primitive\Collection;
|
||||
use Lucent\Schema\SchemaService;
|
||||
|
||||
readonly class AccountService
|
||||
{
|
||||
|
||||
public function __construct(
|
||||
private UserRepo $userRepo,
|
||||
private AuthService $authService,
|
||||
private ChannelService $channelService,
|
||||
private SchemaService $schemaService,
|
||||
private UserRepo $userRepo,
|
||||
)
|
||||
{
|
||||
|
||||
@@ -37,5 +42,20 @@ readonly class AccountService
|
||||
return $this->all()->map(fn($user) => $user->safe());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string>
|
||||
*/
|
||||
public function currentReadableSchemas(): array
|
||||
{
|
||||
$roles = $this->authService->currentUserRoles();
|
||||
return $this->channelService->schemasReadableByRoles($roles);
|
||||
}
|
||||
|
||||
public function currentWritableSchemas(): array
|
||||
{
|
||||
$roles = $this->authService->currentUserRoles();
|
||||
return $this->channelService->schemasWritableByRoles($roles);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
+27
-14
@@ -25,14 +25,19 @@ readonly class AuthService
|
||||
|
||||
public function currentUserId(): ?string
|
||||
{
|
||||
if(app()->runningInConsole()){
|
||||
if (app()->runningInConsole()) {
|
||||
return config("lucent.systemUserId");
|
||||
}else{
|
||||
} else {
|
||||
return $this->session->get("user.id");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function currentUserRoles(): array
|
||||
{
|
||||
return $this->session->get("user.roles") ?? [];
|
||||
}
|
||||
|
||||
public function isLoggedIn(): bool
|
||||
{
|
||||
return !empty($this->currentUserId());
|
||||
@@ -50,7 +55,7 @@ readonly class AuthService
|
||||
throw new LucentException("You account was not found");
|
||||
}
|
||||
|
||||
if ($user->get()->role === Role::REMOVED) {
|
||||
if ($user->get()->isRemoved()) {
|
||||
throw new LucentException("Your account is not active");
|
||||
}
|
||||
|
||||
@@ -66,18 +71,17 @@ readonly class AuthService
|
||||
$newUser->updatedAt = Carbon::now()->toJson();
|
||||
$newUser->mailToken = null;
|
||||
$this->userRepo->update($newUser);
|
||||
|
||||
$this->session->put(["user" => $user->get()->safe()]);
|
||||
}
|
||||
|
||||
|
||||
public function create(string $name, string $email, string $role): User
|
||||
public function create(string $name, string $email, array $roles): User
|
||||
{
|
||||
$user = new User(
|
||||
id: (string)Str::uuid(),
|
||||
name: new Name($name),
|
||||
email: new Email($email),
|
||||
role: Role::from($role),
|
||||
roles: $this->validateRoles($roles),
|
||||
createdAt: Carbon::now()->toJson(),
|
||||
updatedAt: Carbon::now()->toJson(),
|
||||
loggedInAt: Carbon::now()->toJson(),
|
||||
@@ -101,7 +105,7 @@ readonly class AuthService
|
||||
throw new LucentException("User not found");
|
||||
}
|
||||
|
||||
if ($user->get()->role === Role::REMOVED) {
|
||||
if ($user->get()->isRemoved()) {
|
||||
throw new LucentException("Cannot reset email if the user is not active");
|
||||
}
|
||||
|
||||
@@ -121,7 +125,7 @@ readonly class AuthService
|
||||
/**
|
||||
* @throws LucentException
|
||||
*/
|
||||
public function changeRole(string $userId, string $newRole): void
|
||||
public function changeRoles(string $userId, array $roles): void
|
||||
{
|
||||
$user = $this->userRepo->findById($userId);
|
||||
|
||||
@@ -130,7 +134,7 @@ readonly class AuthService
|
||||
}
|
||||
|
||||
$newUser = $user->get();
|
||||
$newUser->role = Role::from($newRole);
|
||||
$newUser->roles = $this->validateRoles($roles);
|
||||
$newUser->updatedAt = Carbon::now()->toJson();
|
||||
$this->userRepo->update($newUser);
|
||||
}
|
||||
@@ -138,7 +142,7 @@ readonly class AuthService
|
||||
/**
|
||||
* @throws LucentException
|
||||
*/
|
||||
public function updateName( string $name): void
|
||||
public function updateName(string $name): void
|
||||
{
|
||||
$name = (new Name($name));
|
||||
$this->userRepo->updateName($this->currentUserId(), $name);
|
||||
@@ -153,7 +157,7 @@ readonly class AuthService
|
||||
{
|
||||
$email = (new Email($email));
|
||||
$user = $this->userRepo->findByEmail($email);
|
||||
if($user->isDefined()){
|
||||
if ($user->isDefined()) {
|
||||
throw new LucentException("Email already assigned to user");
|
||||
}
|
||||
|
||||
@@ -169,10 +173,10 @@ readonly class AuthService
|
||||
public function invite(
|
||||
string $name,
|
||||
string $email,
|
||||
string $role
|
||||
array $roles
|
||||
): User
|
||||
{
|
||||
$user = $this->create($name, $email, $role);
|
||||
$user = $this->create($name, $email, $roles);
|
||||
$this->sendLoginEmail($user->email);
|
||||
return $user;
|
||||
}
|
||||
@@ -185,10 +189,19 @@ readonly class AuthService
|
||||
string $email
|
||||
): User
|
||||
{
|
||||
$user = $this->invite($name, $email, "admin");
|
||||
$user = $this->invite($name, $email, ["admin"]);
|
||||
$this->sendLoginEmail($user->email);
|
||||
return $user;
|
||||
}
|
||||
|
||||
public function validateRoles(array $roles): array
|
||||
{
|
||||
return collect($roles)
|
||||
->filter(fn(string $role) => in_array($role, $this->channelService->channel->roles))
|
||||
->unique()
|
||||
->values()
|
||||
->toArray();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Lucent\Account;
|
||||
|
||||
enum Role: string
|
||||
{
|
||||
case ADMIN = 'admin';
|
||||
case EDITOR = 'editor';
|
||||
case READER = 'reader';
|
||||
case REMOVED = 'removed';
|
||||
|
||||
function hasAccess(string $roleName): bool
|
||||
{
|
||||
$trialRole = Role::from($roleName);
|
||||
|
||||
$access = match ($trialRole) {
|
||||
Role::ADMIN => [Role::ADMIN, Role::DEVELOPER, Role::EDITOR, Role::READER],
|
||||
Role::EDITOR => [Role::EDITOR, Role::READER],
|
||||
Role::READER => [Role::READER],
|
||||
Role::REMOVED => [],
|
||||
};
|
||||
|
||||
return in_array($trialRole, $access);
|
||||
}
|
||||
}
|
||||
+9
-15
@@ -6,11 +6,14 @@ namespace Lucent\Account;
|
||||
class User
|
||||
{
|
||||
|
||||
/**
|
||||
* @param array<string> $roles
|
||||
*/
|
||||
function __construct(
|
||||
public string $id,
|
||||
public Name $name,
|
||||
public Email $email,
|
||||
public Role $role,
|
||||
public array $roles,
|
||||
public string $createdAt,
|
||||
public string $updatedAt,
|
||||
public ?string $loggedInAt = null,
|
||||
@@ -20,24 +23,15 @@ class User
|
||||
{
|
||||
}
|
||||
|
||||
public static function fromArray(array $data): User
|
||||
{
|
||||
return new User(
|
||||
id: $data["id"],
|
||||
name: new Name($data["name"] ?? ""),
|
||||
email: new Email($data["email"]),
|
||||
role: Role::tryFrom($data["role"]),
|
||||
createdAt: $data["createdAt"],
|
||||
updatedAt: $data["updatedAt"],
|
||||
loggedInAt: $data["loggedInAt"] ?? null,
|
||||
mailToken: $data["mailToken"] ?? null,
|
||||
);
|
||||
}
|
||||
|
||||
public function isRemoved()
|
||||
{
|
||||
return in_array("removed", $this->roles);
|
||||
}
|
||||
|
||||
public function safe(): array
|
||||
{
|
||||
$userData = collect(toArray($this));
|
||||
return $userData->only(["id", "name", "email", "role", "status"])->toArray();
|
||||
return $userData->only(["id", "name", "email", "roles", "status"])->toArray();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,31 +9,10 @@ readonly class UserProfile
|
||||
public string $id,
|
||||
public string $name,
|
||||
public string $email,
|
||||
public Role $role,
|
||||
public array $roles,
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
public static function fromUser(User $user): UserProfile
|
||||
{
|
||||
return new UserProfile(
|
||||
$user->id,
|
||||
$user->name,
|
||||
$user->email,
|
||||
$user->role,
|
||||
);
|
||||
}
|
||||
|
||||
public static function fromArray(array $data): ?UserProfile
|
||||
{
|
||||
if (empty($data)) {
|
||||
return null;
|
||||
}
|
||||
return new UserProfile(
|
||||
id: data_get($data, "id"),
|
||||
name: data_get($data, "name"),
|
||||
email: data_get($data, "email"),
|
||||
role: data_get($data, "role"),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ class UserRepo
|
||||
{
|
||||
$usersData = DB::table("users")->get();
|
||||
|
||||
$users = array_map(fn($userData) => User::fromArray((array)$userData), $usersData->toArray());
|
||||
$users = array_map(fn($userData) => $this->fromArray((array)$userData), $usersData->toArray());
|
||||
return new Collection($users);
|
||||
}
|
||||
|
||||
@@ -30,12 +30,14 @@ class UserRepo
|
||||
public static function insert(User $user): void
|
||||
{
|
||||
$userData = toArray($user);
|
||||
$userData["roles"] = json_encode($userData["roles"]);
|
||||
DB::table("users")->insert($userData);
|
||||
}
|
||||
|
||||
public function update(User $user): void
|
||||
{
|
||||
$userData = toArray($user);
|
||||
$userData["roles"] = json_encode($userData["roles"]);
|
||||
DB::table("users")->where("id", $user->id)->update($userData);
|
||||
}
|
||||
|
||||
@@ -66,7 +68,7 @@ class UserRepo
|
||||
return none();
|
||||
}
|
||||
|
||||
return some(User::fromArray((array)$user));
|
||||
return some($this->fromArray((array)$user));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -80,7 +82,7 @@ class UserRepo
|
||||
return none();
|
||||
}
|
||||
|
||||
return some(User::fromArray((array)$user));
|
||||
return some($this->fromArray((array)$user));
|
||||
}
|
||||
|
||||
|
||||
@@ -93,4 +95,18 @@ class UserRepo
|
||||
{
|
||||
DB::table("users")->where("id", $userId)->update(["email" => $email->value()]);
|
||||
}
|
||||
|
||||
public function fromArray(array $data): User
|
||||
{
|
||||
return new User(
|
||||
id: $data["id"],
|
||||
name: new Name($data["name"] ?? ""),
|
||||
email: new Email($data["email"]),
|
||||
roles: json_decode($data["roles"] ?? [],true),
|
||||
createdAt: $data["createdAt"],
|
||||
updatedAt: $data["updatedAt"],
|
||||
loggedInAt: $data["loggedInAt"] ?? null,
|
||||
mailToken: $data["mailToken"] ?? null,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user