2021-09-21 22:43:39 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace App\Services;
|
|
|
|
|
2021-12-02 13:15:53 +01:00
|
|
|
use App\Models\Group;
|
|
|
|
use App\Models\TwoFAccount;
|
2023-02-27 00:32:49 +01:00
|
|
|
use App\Models\User;
|
|
|
|
use Illuminate\Auth\Access\AuthorizationException;
|
2021-09-21 22:43:39 +02:00
|
|
|
use Illuminate\Database\Eloquent\Collection;
|
2021-10-15 23:46:21 +02:00
|
|
|
use Illuminate\Support\Facades\Log;
|
2021-09-21 22:43:39 +02:00
|
|
|
|
|
|
|
class GroupService
|
|
|
|
{
|
|
|
|
/**
|
2023-02-27 00:32:49 +01:00
|
|
|
* Returns all existing groups for the given user
|
2022-11-22 15:15:52 +01:00
|
|
|
*
|
2023-02-27 00:32:49 +01:00
|
|
|
* @param \App\Models\User $user
|
2022-11-21 11:16:43 +01:00
|
|
|
* @return Collection<int, Group>
|
2021-09-21 22:43:39 +02:00
|
|
|
*/
|
2023-02-27 00:32:49 +01:00
|
|
|
public static function getAll(User $user) : Collection
|
2021-09-21 22:43:39 +02:00
|
|
|
{
|
2023-02-27 00:32:49 +01:00
|
|
|
return self::prependTheAllGroup($user->groups()->withCount('twofaccounts')->get(), $user->id);
|
2021-09-21 22:43:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2023-02-27 00:32:49 +01:00
|
|
|
* Creates a group for the given user
|
2022-11-22 15:15:52 +01:00
|
|
|
*
|
|
|
|
* @param array $data
|
2023-02-27 00:32:49 +01:00
|
|
|
* @param \App\Models\User $user
|
2021-12-02 13:15:53 +01:00
|
|
|
* @return \App\Models\Group The created group
|
2023-02-27 00:32:49 +01:00
|
|
|
*
|
|
|
|
* @throws \Illuminate\Auth\Access\AuthorizationException
|
2021-09-21 22:43:39 +02:00
|
|
|
*/
|
2023-02-27 00:32:49 +01:00
|
|
|
public static function create(array $data, User $user) : Group
|
2021-09-21 22:43:39 +02:00
|
|
|
{
|
2023-02-27 00:32:49 +01:00
|
|
|
if ($user->cannot('create', Group::class)) {
|
|
|
|
Log::notice(sprintf('User ID #%s cannot create groups', $user->id));
|
|
|
|
throw new AuthorizationException();
|
|
|
|
}
|
|
|
|
|
|
|
|
$group = $user->groups()->create([
|
2021-09-21 22:43:39 +02:00
|
|
|
'name' => $data['name'],
|
|
|
|
]);
|
|
|
|
|
2023-02-27 00:32:49 +01:00
|
|
|
Log::info(sprintf('Group "%s" created for user ID #%s', var_export($group->name, true), $user->id));
|
2021-10-15 23:46:21 +02:00
|
|
|
|
2021-09-21 22:43:39 +02:00
|
|
|
return $group;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Updates a group using a list of parameters
|
2022-11-22 15:15:52 +01:00
|
|
|
*
|
|
|
|
* @param \App\Models\Group $group The group
|
|
|
|
* @param array $data The parameters
|
2023-02-27 00:32:49 +01:00
|
|
|
* @param \App\Models\User $user
|
2021-12-02 13:15:53 +01:00
|
|
|
* @return \App\Models\Group The updated group
|
2023-02-27 00:32:49 +01:00
|
|
|
*
|
|
|
|
* @throws \Illuminate\Auth\Access\AuthorizationException
|
2021-09-21 22:43:39 +02:00
|
|
|
*/
|
2023-02-27 00:32:49 +01:00
|
|
|
public static function update(Group $group, array $data, User $user) : Group
|
2021-09-21 22:43:39 +02:00
|
|
|
{
|
2023-02-27 00:32:49 +01:00
|
|
|
if ($user->cannot('update', $group)) {
|
|
|
|
Log::notice(sprintf('User ID #%s cannot update group "%s"', $user->id, var_export($group->name, true)));
|
|
|
|
throw new AuthorizationException();
|
|
|
|
}
|
|
|
|
|
2021-09-21 22:43:39 +02:00
|
|
|
$group->update([
|
|
|
|
'name' => $data['name'],
|
|
|
|
]);
|
|
|
|
|
2023-02-27 00:32:49 +01:00
|
|
|
Log::info(sprintf('Group "%s" updated by user ID #%s', var_export($group->name, true), $user->id));
|
2021-10-15 23:46:21 +02:00
|
|
|
|
2021-09-21 22:43:39 +02:00
|
|
|
return $group;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Deletes one or more groups
|
2022-11-22 15:15:52 +01:00
|
|
|
*
|
|
|
|
* @param int|array $ids group ids to delete
|
2023-02-27 00:32:49 +01:00
|
|
|
* @param \App\Models\User $user
|
2021-09-21 22:43:39 +02:00
|
|
|
* @return int The number of deleted
|
|
|
|
*/
|
2023-02-27 00:32:49 +01:00
|
|
|
public static function delete($ids, User $user) : int
|
2021-09-21 22:43:39 +02:00
|
|
|
{
|
2023-02-27 00:32:49 +01:00
|
|
|
$ids = is_array($ids) ? $ids : [$ids];
|
2021-10-09 19:17:05 +02:00
|
|
|
|
2023-02-27 00:32:49 +01:00
|
|
|
$groups = Group::findMany($ids);
|
2021-10-09 19:17:05 +02:00
|
|
|
|
2023-02-27 00:32:49 +01:00
|
|
|
if ($groups->count() > 0) {
|
|
|
|
if ($user->cannot('deleteEach', [$groups[0], $groups])) {
|
|
|
|
Log::notice(sprintf('User ID #%s cannot delete all groups in IDs #%s', $user->id, implode(',', $ids)));
|
|
|
|
throw new AuthorizationException();
|
|
|
|
}
|
2021-10-09 19:17:05 +02:00
|
|
|
|
2023-02-27 00:32:49 +01:00
|
|
|
// One of the groups is possibly set as the default group of the given user.
|
|
|
|
// In this case we reset the preference to "No group" (groupId = 0)
|
|
|
|
if (in_array($user->preferences['defaultGroup'], $ids)) {
|
|
|
|
$user['preferences->defaultGroup'] = 0;
|
|
|
|
$user->save();
|
|
|
|
}
|
2021-10-09 19:17:05 +02:00
|
|
|
|
2023-02-27 00:32:49 +01:00
|
|
|
// One of the groups is also possibly set as the active group if the user
|
|
|
|
// configured 2FAuth to memorize the active group.
|
|
|
|
// In this case we reset the preference to the pseudo "All" group (groupId = 0)
|
|
|
|
if (in_array($user->preferences['activeGroup'], $ids)) {
|
|
|
|
$user['preferences->activeGroup'] = 0;
|
|
|
|
$user->save();
|
|
|
|
}
|
2021-10-09 19:17:05 +02:00
|
|
|
|
2023-02-27 00:32:49 +01:00
|
|
|
$deleted = Group::destroy($ids);
|
|
|
|
Log::info(sprintf('Groups IDs #%s deleted', implode(',#', $ids)));
|
2021-09-21 22:43:39 +02:00
|
|
|
|
2023-02-27 00:32:49 +01:00
|
|
|
return $deleted;
|
|
|
|
}
|
2021-10-15 23:46:21 +02:00
|
|
|
|
2023-02-27 00:32:49 +01:00
|
|
|
return 0;
|
2021-09-21 22:43:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2023-02-27 00:32:49 +01:00
|
|
|
* Assign one or more accounts to a user group
|
2022-11-22 15:15:52 +01:00
|
|
|
*
|
|
|
|
* @param array|int $ids accounts ids to assign
|
2023-02-27 00:32:49 +01:00
|
|
|
* @param \App\Models\User $user
|
2022-11-22 15:15:52 +01:00
|
|
|
* @param \App\Models\Group $group The target group
|
2021-10-08 23:18:39 +02:00
|
|
|
* @return void
|
2023-02-27 00:32:49 +01:00
|
|
|
*
|
|
|
|
* @throws \Illuminate\Auth\Access\AuthorizationException
|
|
|
|
* @throws \Illuminate\Database\Eloquent\ModelNotFoundException<\App\Models\TwoFAccount>
|
2021-09-21 22:43:39 +02:00
|
|
|
*/
|
2023-02-27 00:32:49 +01:00
|
|
|
public static function assign($ids, User $user, Group $group = null) : void
|
2021-09-21 22:43:39 +02:00
|
|
|
{
|
2022-11-22 15:15:52 +01:00
|
|
|
if (! $group) {
|
2023-02-27 00:32:49 +01:00
|
|
|
$group = self::defaultGroup($user);
|
|
|
|
} else {
|
|
|
|
if ($user->cannot('update', $group)) {
|
|
|
|
Log::notice(sprintf('User ID #%s cannot update group "%s"', $user->id, var_export($group->name, true)));
|
|
|
|
throw new AuthorizationException();
|
|
|
|
}
|
2021-10-08 00:52:15 +02:00
|
|
|
}
|
2021-09-21 22:43:39 +02:00
|
|
|
|
2021-10-08 23:18:39 +02:00
|
|
|
if ($group) {
|
2023-02-27 00:32:49 +01:00
|
|
|
$ids = is_array($ids) ? $ids : [$ids];
|
|
|
|
|
|
|
|
$twofaccounts = TwoFAccount::findOrFail($ids);
|
|
|
|
|
|
|
|
if ($user->cannot('updateEach', [$twofaccounts[0], $twofaccounts])) {
|
|
|
|
Log::notice(sprintf('User ID #%s cannot assign twofaccounts %s to group "%s"', $user->id, implode(',', $ids), var_export($group->name, true)));
|
|
|
|
throw new AuthorizationException();
|
2021-10-08 23:18:39 +02:00
|
|
|
}
|
2021-09-21 22:43:39 +02:00
|
|
|
|
2021-10-08 23:18:39 +02:00
|
|
|
$group->twofaccounts()->saveMany($twofaccounts);
|
2021-11-13 12:13:22 +01:00
|
|
|
$group->loadCount('twofaccounts');
|
2021-10-15 23:46:21 +02:00
|
|
|
|
2023-02-27 00:32:49 +01:00
|
|
|
Log::info(sprintf('Twofaccounts IDS #%s assigned to groups "%s"', implode(',', $ids), var_export($group->name, true)));
|
2022-11-22 15:15:52 +01:00
|
|
|
} else {
|
|
|
|
Log::info('Cannot find a group to assign the TwoFAccounts to');
|
2021-10-08 23:18:39 +02:00
|
|
|
}
|
2021-09-21 22:43:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2023-02-27 00:32:49 +01:00
|
|
|
* Prepends the pseudo group named 'All' to a group collection
|
|
|
|
*
|
|
|
|
* @param Collection<int, Group> $groups
|
|
|
|
* @return Collection<int, Group>
|
|
|
|
*/
|
|
|
|
private static function prependTheAllGroup(Collection $groups, int $userId) : Collection
|
|
|
|
{
|
|
|
|
$theAllGroup = new Group([
|
|
|
|
'name' => __('commons.all'),
|
|
|
|
]);
|
|
|
|
|
|
|
|
$theAllGroup->id = 0;
|
|
|
|
$theAllGroup->twofaccounts_count = TwoFAccount::where('user_id', $userId)->count();
|
|
|
|
|
|
|
|
return $groups->prepend($theAllGroup);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Determines the default group of the given user
|
2022-11-22 15:15:52 +01:00
|
|
|
*
|
2023-02-27 00:32:49 +01:00
|
|
|
* @param \App\Models\User $user
|
2021-12-02 13:15:53 +01:00
|
|
|
* @return \App\Models\Group|null The group or null if it does not exist
|
2021-09-21 22:43:39 +02:00
|
|
|
*/
|
2023-02-27 00:32:49 +01:00
|
|
|
private static function defaultGroup(User $user)
|
2021-09-21 22:43:39 +02:00
|
|
|
{
|
2023-02-27 00:32:49 +01:00
|
|
|
$id = $user->preferences['defaultGroup'] === -1 ? (int) $user->preferences['activeGroup'] : (int) $user->preferences['defaultGroup'];
|
2021-09-21 22:43:39 +02:00
|
|
|
|
|
|
|
return Group::find($id);
|
|
|
|
}
|
2022-11-22 15:15:52 +01:00
|
|
|
}
|