1
0
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:
Matt Kilgore
2021-03-01 15:52:29 -05:00
committed by GitHub
parent d0adb244da
commit 9627eb73f1
9 changed files with 779 additions and 103 deletions

View File

@@ -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

View File

@@ -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();
}
}
}

View File

@@ -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) {