Skip to content

Commit

Permalink
Backport 1.1 security fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
LukeTowers committed Aug 26, 2021
1 parent 873c041 commit 8e66336
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 3 deletions.
66 changes: 64 additions & 2 deletions modules/backend/models/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ class User extends UserBase
public $rules = [
'email' => 'required|between:6,255|email|unique:backend_users',
'login' => 'required|between:2,255|unique:backend_users',
'password' => 'required:create|between:4,255|confirmed',
'password_confirmation' => 'required_with:password|between:4,255'
'password' => 'required:create|min:4|confirmed',
'password_confirmation' => 'required_with:password|min:4'
];

/**
Expand Down Expand Up @@ -209,4 +209,66 @@ public function unsuspend()
{
BackendAuth::findThrottleByUserId($this->id)->unsuspend();
}

//
// Impersonation
//

/**
* Returns an array of merged permissions based on the user's individual permissions
* and their group permissions filtering out any permissions the impersonator doesn't
* have access to (if the current user is being impersonated)
*
* @return array
*/
public function getMergedPermissions()
{
if (!$this->mergedPermissions) {
$permissions = parent::getMergedPermissions();

// If the user is being impersonated filter out any permissions the impersonator doesn't have access to already
if (BackendAuth::isImpersonator()) {
$impersonator = BackendAuth::getImpersonator();
if ($impersonator && $impersonator !== $this) {
foreach ($permissions as $i => $permission) {
if (!$impersonator->hasAccess($permission)) {
unset($permissions[$i]);
}
}
$this->mergedPermissions = $permissions;
}
}
}

return $this->mergedPermissions;
}

/**
* Check if this user can be impersonated by the provided impersonator
* Super users cannot be impersonated and all users cannot be impersonated unless there is an impersonator
* present and the impersonator has access to `backend.impersonate_users`, and the impersonator is not the
* user being impersonated
*
* @param \Winter\Storm\Auth\Models\User|false $impersonator The user attempting to impersonate this user, false when not available
* @return boolean
*/
public function canBeImpersonated($impersonator = false)
{
if (
$this->isSuperUser() ||
!$impersonator ||
!($impersonator instanceof static) ||
!$impersonator->hasAccess('backend.impersonate_users') ||
$impersonator === $this
) {
return false;
}

// Clear the merged permissions before the impersonation starts
// so that they are correct even if they had been loaded prior
// to the impersonation starting
$this->mergedPermissions = null;

return true;
}
}
2 changes: 1 addition & 1 deletion modules/cms/models/ThemeLog.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public static function add(HalcyonModel $template, $type = null)
$record->content = $isDelete ? '' : $newContent;
$record->old_content = $oldContent;

if ($user = BackendAuth::getUser()) {
if ($user = BackendAuth::getRealUser()) {
$record->user_id = $user->id;
}

Expand Down

0 comments on commit 8e66336

Please sign in to comment.