koel/app/Services/UserService.php

140 lines
4 KiB
PHP
Raw Normal View History

2022-06-10 10:47:46 +00:00
<?php
namespace App\Services;
2023-08-20 22:35:58 +00:00
use App\Exceptions\UserProspectUpdateDeniedException;
2024-03-30 16:49:25 +00:00
use App\Facades\License;
2022-06-10 10:47:46 +00:00
use App\Models\User;
2024-03-30 16:49:25 +00:00
use App\Repositories\UserRepository;
use App\Values\SSOUser;
2022-06-10 10:47:46 +00:00
use Illuminate\Contracts\Hashing\Hasher;
2024-03-19 22:48:12 +00:00
use Illuminate\Support\Facades\File;
use Illuminate\Support\Str;
2022-06-10 10:47:46 +00:00
class UserService
{
2024-03-30 16:49:25 +00:00
public function __construct(
2024-04-18 14:36:28 +00:00
private readonly UserRepository $repository,
private readonly Hasher $hash,
private readonly ImageWriter $imageWriter
2024-03-30 16:49:25 +00:00
) {
2022-06-10 10:47:46 +00:00
}
2024-03-30 16:49:25 +00:00
/** @noinspection PhpIncompatibleReturnTypeInspection */
public function createUser(
string $name,
string $email,
string $plainTextPassword,
bool $isAdmin,
?string $avatar = null,
?string $ssoId = null,
?string $ssoProvider = null,
): User {
if ($ssoProvider) {
License::requirePlus();
SSOUser::assertValidProvider($ssoProvider);
2024-03-30 16:49:25 +00:00
}
return User::query()->create([
2022-06-10 10:47:46 +00:00
'name' => $name,
'email' => $email,
2024-03-30 16:49:25 +00:00
'password' => $plainTextPassword ? $this->hash->make($plainTextPassword) : '',
2022-06-10 10:47:46 +00:00
'is_admin' => $isAdmin,
2024-03-30 16:49:25 +00:00
'sso_id' => $ssoId,
'sso_provider' => $ssoProvider,
2024-04-24 20:44:47 +00:00
'avatar' => $avatar ? $this->createNewAvatar($avatar) : null,
2022-06-10 10:47:46 +00:00
]);
}
public function createOrUpdateUserFromSSO(SSOUser $ssoUser): User
2024-03-30 16:49:25 +00:00
{
License::requirePlus();
$existingUser = $this->repository->findOneBySSO($ssoUser);
2024-03-30 16:49:25 +00:00
if ($existingUser) {
$existingUser->update([
'avatar' => $existingUser->has_custom_avatar ? $existingUser->avatar : $ssoUser->avatar,
'sso_id' => $ssoUser->id,
'sso_provider' => $ssoUser->provider,
2024-03-30 16:49:25 +00:00
]);
return $existingUser;
}
return $this->createUser(
name: $ssoUser->name,
email: $ssoUser->email,
2024-03-30 16:49:25 +00:00
plainTextPassword: '',
isAdmin: false,
avatar: $ssoUser->avatar,
ssoId: $ssoUser->id,
ssoProvider: $ssoUser->provider,
2024-03-30 16:49:25 +00:00
);
}
2024-03-19 22:48:12 +00:00
public function updateUser(
User $user,
string $name,
string $email,
2024-03-30 16:49:25 +00:00
?string $password = null,
2024-03-19 22:48:12 +00:00
?bool $isAdmin = null,
?string $avatar = null
): User {
2023-08-20 22:35:58 +00:00
throw_if($user->is_prospect, new UserProspectUpdateDeniedException());
2024-03-30 16:49:25 +00:00
if ($user->sso_provider) {
// An SSO profile is largely managed by the SSO provider
$user->update([
'is_admin' => $isAdmin ?? $user->is_admin,
'name' => $name,
'avatar' => $avatar ? $this->createNewAvatar($avatar, $user) : null,
]);
} else {
$user->update([
'name' => $name,
'email' => $email,
'password' => $password ? $this->hash->make($password) : $user->password,
'is_admin' => $isAdmin ?? $user->is_admin,
'avatar' => $avatar ? $this->createNewAvatar($avatar, $user) : null,
]);
2022-07-29 06:47:10 +00:00
}
2024-03-30 16:49:25 +00:00
return $user;
}
2024-03-19 22:48:12 +00:00
2024-03-30 16:49:25 +00:00
/**
* @param string $avatar Either the URL of the avatar or image data
*/
private function createNewAvatar(string $avatar, ?User $user = null): string
{
if (Str::startsWith($avatar, ['http://', 'https://'])) {
return $avatar;
2024-03-19 22:48:12 +00:00
}
2024-03-30 16:49:25 +00:00
$path = self::generateUserAvatarPath();
$this->imageWriter->write($path, $avatar, ['max_width' => 480]);
2022-06-10 10:47:46 +00:00
2024-03-30 16:49:25 +00:00
optional($user?->getRawOriginal('avatar'), static fn (string $oldAvatar) => File::delete($oldAvatar));
return basename($path);
2022-06-10 10:47:46 +00:00
}
public function deleteUser(User $user): void
{
$user->delete();
}
public function savePreference(User $user, string $key, mixed $value): void
{
$user->preferences = $user->preferences->set($key, $value);
$user->save();
}
2024-03-19 22:48:12 +00:00
private static function generateUserAvatarPath(): string
{
return user_avatar_path(sprintf('%s.webp', sha1(Str::uuid())));
}
2022-06-10 10:47:46 +00:00
}