* @link https://getkirby.com * @copyright Bastian Allgeier * @license https://getkirby.com/license */ trait AppUsers { /** * Cache for the auth auth layer * * @var Auth */ protected $auth; /** * Returns the Authentication layer class * * @internal * @return \Kirby\Cms\Auth */ public function auth() { return $this->auth = $this->auth ?? new Auth($this); } /** * Become any existing user or disable the current user * * @param string|null $who User ID or email address, * `null` to use the actual user again, * `'kirby'` for a virtual admin user or * `'nobody'` to disable the actual user * @param Closure|null $callback Optional action function that will be run with * the permissions of the impersonated user; the * impersonation will be reset afterwards * @return mixed If called without callback: User that was impersonated; * if called with callback: Return value from the callback * @throws \Throwable */ public function impersonate(?string $who = null, ?Closure $callback = null) { $auth = $this->auth(); $userBefore = $auth->currentUserFromImpersonation(); $userAfter = $auth->impersonate($who); if ($callback === null) { return $userAfter; } try { // bind the App object to the callback return $callback->call($this, $userAfter); } catch (Throwable $e) { throw $e; } finally { // ensure that the impersonation is *always* reset // to the original value, even if an error occurred $auth->impersonate($userBefore !== null ? $userBefore->id() : null); } } /** * Set the currently active user id * * @param \Kirby\Cms\User|string $user * @return \Kirby\Cms\App */ protected function setUser($user = null) { $this->user = $user; return $this; } /** * Create your own set of app users * * @param array|null $users * @return \Kirby\Cms\App */ protected function setUsers(array $users = null) { if ($users !== null) { $this->users = Users::factory($users, [ 'kirby' => $this ]); } return $this; } /** * Returns a specific user by id * or the current user if no id is given * * @param string|null $id * @param bool $allowImpersonation If set to false, only the actually * logged in user will be returned * (when `$id` is passed as `null`) * @return \Kirby\Cms\User|null */ public function user(?string $id = null, bool $allowImpersonation = true) { if ($id !== null) { return $this->users()->find($id); } if ($allowImpersonation === true && is_string($this->user) === true) { return $this->auth()->impersonate($this->user); } else { try { return $this->auth()->user(null, $allowImpersonation); } catch (Throwable $e) { return null; } } } /** * Returns all users * * @return \Kirby\Cms\Users */ public function users() { if (is_a($this->users, 'Kirby\Cms\Users') === true) { return $this->users; } return $this->users = Users::load($this->root('accounts'), ['kirby' => $this]); } }