mirror of
https://github.com/flarum/core.git
synced 2025-10-11 23:14:29 +02:00
User edit permission tightening (#2620)
- Split user edit permision into edit attributes, edit credentials, and edit groups - Only Admins can edit Admin Credentials - Only Admins can Promote/Demote to/from Admin
This commit is contained in:
@@ -19,14 +19,14 @@ class UserSerializer extends BasicUserSerializer
|
||||
{
|
||||
$attributes = parent::getDefaultAttributes($user);
|
||||
|
||||
$canEdit = $this->actor->can('edit', $user);
|
||||
|
||||
$attributes += [
|
||||
'joinTime' => $this->formatDate($user->joined_at),
|
||||
'discussionCount' => (int) $user->discussion_count,
|
||||
'commentCount' => (int) $user->comment_count,
|
||||
'canEdit' => $canEdit,
|
||||
'canDelete' => $this->actor->can('delete', $user),
|
||||
'joinTime' => $this->formatDate($user->joined_at),
|
||||
'discussionCount' => (int) $user->discussion_count,
|
||||
'commentCount' => (int) $user->comment_count,
|
||||
'canEdit' => $this->actor->can('edit', $user),
|
||||
'canEditCredentials' => $this->actor->can('editCredentials', $user),
|
||||
'canEditGroups' => $this->actor->can('editGroups', $user),
|
||||
'canDelete' => $this->actor->can('delete', $user),
|
||||
];
|
||||
|
||||
if ($user->getPreference('discloseOnline') || $this->actor->can('viewLastSeenAt', $user)) {
|
||||
@@ -35,7 +35,7 @@ class UserSerializer extends BasicUserSerializer
|
||||
];
|
||||
}
|
||||
|
||||
if ($canEdit || $this->actor->id === $user->id) {
|
||||
if ($attributes['canEditCredentials'] || $this->actor->id === $user->id) {
|
||||
$attributes += [
|
||||
'isEmailConfirmed' => (bool) $user->is_email_confirmed,
|
||||
'email' => $user->email
|
||||
|
@@ -24,4 +24,19 @@ class UserPolicy extends AbstractPolicy
|
||||
return $this->allow();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $actor
|
||||
* @param User $user
|
||||
*/
|
||||
public function editCredentials(User $actor, User $user)
|
||||
{
|
||||
if ($user->isAdmin() && ! $actor->isAdmin()) {
|
||||
return $this->deny();
|
||||
}
|
||||
|
||||
if ($actor->hasPermission('user.editCredentials')) {
|
||||
return $this->allow();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -58,7 +58,6 @@ class EditUserHandler
|
||||
|
||||
$user = $this->users->findOrFail($command->userId, $actor);
|
||||
|
||||
$canEdit = $actor->can('edit', $user);
|
||||
$isSelf = $actor->id === $user->id;
|
||||
|
||||
$attributes = Arr::get($data, 'attributes', []);
|
||||
@@ -66,7 +65,7 @@ class EditUserHandler
|
||||
$validate = [];
|
||||
|
||||
if (isset($attributes['username'])) {
|
||||
$actor->assertPermission($canEdit);
|
||||
$actor->assertCan('editCredentials', $user);
|
||||
$user->rename($attributes['username']);
|
||||
}
|
||||
|
||||
@@ -78,17 +77,18 @@ class EditUserHandler
|
||||
$validate['email'] = $attributes['email'];
|
||||
}
|
||||
} else {
|
||||
$actor->assertPermission($canEdit);
|
||||
$actor->assertCan('editCredentials', $user);
|
||||
$user->changeEmail($attributes['email']);
|
||||
}
|
||||
}
|
||||
|
||||
if ($actor->isAdmin() && ! empty($attributes['isEmailConfirmed'])) {
|
||||
if (! empty($attributes['isEmailConfirmed'])) {
|
||||
$actor->assertAdmin();
|
||||
$user->activate();
|
||||
}
|
||||
|
||||
if (isset($attributes['password'])) {
|
||||
$actor->assertPermission($canEdit);
|
||||
$actor->assertCan('editCredentials', $user);
|
||||
$user->changePassword($attributes['password']);
|
||||
|
||||
$validate['password'] = $attributes['password'];
|
||||
@@ -108,7 +108,10 @@ class EditUserHandler
|
||||
}
|
||||
|
||||
if (isset($relationships['groups']['data']) && is_array($relationships['groups']['data'])) {
|
||||
$actor->assertPermission($canEdit);
|
||||
$actor->assertCan('editGroups', $user);
|
||||
|
||||
$oldGroups = $user->groups()->get()->all();
|
||||
$oldGroupIds = Arr::pluck($oldGroups, 'id');
|
||||
|
||||
$newGroupIds = [];
|
||||
foreach ($relationships['groups']['data'] as $group) {
|
||||
@@ -117,8 +120,12 @@ class EditUserHandler
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure non-admins aren't adding/removing admins
|
||||
$adminChanged = in_array('1', array_diff($oldGroupIds, $newGroupIds)) || in_array('1', array_diff($newGroupIds, $oldGroupIds));
|
||||
$actor->assertPermission(! $adminChanged || $actor->isAdmin());
|
||||
|
||||
$user->raise(
|
||||
new GroupsChanged($user, $user->groups()->get()->all())
|
||||
new GroupsChanged($user, $oldGroups)
|
||||
);
|
||||
|
||||
$user->afterSave(function (User $user) use ($newGroupIds) {
|
||||
|
Reference in New Issue
Block a user