+<?php
+
+namespace BookStack\Auth\Access\Guards;
+
+use Illuminate\Auth\GuardHelpers;
+use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
+use Illuminate\Contracts\Auth\StatefulGuard;
+use Illuminate\Contracts\Auth\UserProvider;
+use Illuminate\Contracts\Session\Session;
+
+/**
+ * Class BaseSessionGuard
+ * A base implementation of a session guard. Is a copy of the default Laravel
+ * guard with 'remember' functionality removed. Basic auth and event emission
+ * has also been removed to keep this simple. Designed to be extended by external
+ * Auth Guards.
+ *
+ * @package Illuminate\Auth
+ */
+class ExternalBaseSessionGuard implements StatefulGuard
+{
+ use GuardHelpers;
+
+ /**
+ * The name of the Guard. Typically "session".
+ *
+ * Corresponds to guard name in authentication configuration.
+ *
+ * @var string
+ */
+ protected $name;
+
+ /**
+ * The user we last attempted to retrieve.
+ *
+ * @var \Illuminate\Contracts\Auth\Authenticatable
+ */
+ protected $lastAttempted;
+
+ /**
+ * The session used by the guard.
+ *
+ * @var \Illuminate\Contracts\Session\Session
+ */
+ protected $session;
+
+ /**
+ * Indicates if the logout method has been called.
+ *
+ * @var bool
+ */
+ protected $loggedOut = false;
+
+ /**
+ * Create a new authentication guard.
+ *
+ * @param string $name
+ * @param \Illuminate\Contracts\Auth\UserProvider $provider
+ * @param \Illuminate\Contracts\Session\Session $session
+ * @return void
+ */
+ public function __construct($name,
+ UserProvider $provider,
+ Session $session)
+ {
+ $this->name = $name;
+ $this->session = $session;
+ $this->provider = $provider;
+ }
+
+ /**
+ * Get the currently authenticated user.
+ *
+ * @return \Illuminate\Contracts\Auth\Authenticatable|null
+ */
+ public function user()
+ {
+ if ($this->loggedOut) {
+ return;
+ }
+
+ // If we've already retrieved the user for the current request we can just
+ // return it back immediately. We do not want to fetch the user data on
+ // every call to this method because that would be tremendously slow.
+ if (! is_null($this->user)) {
+ return $this->user;
+ }
+
+ $id = $this->session->get($this->getName());
+
+ // First we will try to load the user using the
+ // identifier in the session if one exists.
+ if (! is_null($id)) {
+ $this->user = $this->provider->retrieveById($id);
+ }
+
+ return $this->user;
+ }
+
+ /**
+ * Get the ID for the currently authenticated user.
+ *
+ * @return int|null
+ */
+ public function id()
+ {
+ if ($this->loggedOut) {
+ return;
+ }
+
+ return $this->user()
+ ? $this->user()->getAuthIdentifier()
+ : $this->session->get($this->getName());
+ }
+
+ /**
+ * Log a user into the application without sessions or cookies.
+ *
+ * @param array $credentials
+ * @return bool
+ */
+ public function once(array $credentials = [])
+ {
+ if ($this->validate($credentials)) {
+ $this->setUser($this->lastAttempted);
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Log the given user ID into the application without sessions or cookies.
+ *
+ * @param mixed $id
+ * @return \Illuminate\Contracts\Auth\Authenticatable|false
+ */
+ public function onceUsingId($id)
+ {
+ if (! is_null($user = $this->provider->retrieveById($id))) {
+ $this->setUser($user);
+
+ return $user;
+ }
+
+ return false;
+ }
+
+ /**
+ * Validate a user's credentials.
+ *
+ * @param array $credentials
+ * @return bool
+ */
+ public function validate(array $credentials = [])
+ {
+ return false;
+ }
+
+
+ /**
+ * Attempt to authenticate a user using the given credentials.
+ *
+ * @param array $credentials
+ * @param bool $remember
+ * @return bool
+ */
+ public function attempt(array $credentials = [], $remember = false)
+ {
+ return false;
+ }
+
+ /**
+ * Log the given user ID into the application.
+ *
+ * @param mixed $id
+ * @param bool $remember
+ * @return \Illuminate\Contracts\Auth\Authenticatable|false
+ */
+ public function loginUsingId($id, $remember = false)
+ {
+ if (! is_null($user = $this->provider->retrieveById($id))) {
+ $this->login($user, $remember);
+
+ return $user;
+ }
+
+ return false;
+ }
+
+ /**
+ * Log a user into the application.
+ *
+ * @param \Illuminate\Contracts\Auth\Authenticatable $user
+ * @param bool $remember
+ * @return void
+ */
+ public function login(AuthenticatableContract $user, $remember = false)
+ {
+ $this->updateSession($user->getAuthIdentifier());
+
+ $this->setUser($user);
+ }
+
+ /**
+ * Update the session with the given ID.
+ *
+ * @param string $id
+ * @return void
+ */
+ protected function updateSession($id)
+ {
+ $this->session->put($this->getName(), $id);
+
+ $this->session->migrate(true);
+ }
+
+ /**
+ * Log the user out of the application.
+ *
+ * @return void
+ */
+ public function logout()
+ {
+ $this->clearUserDataFromStorage();
+
+ // Now we will clear the users out of memory so they are no longer available
+ // as the user is no longer considered as being signed into this
+ // application and should not be available here.
+ $this->user = null;
+
+ $this->loggedOut = true;
+ }
+
+ /**
+ * Remove the user data from the session and cookies.
+ *
+ * @return void
+ */
+ protected function clearUserDataFromStorage()
+ {
+ $this->session->remove($this->getName());
+ }
+
+ /**
+ * Get the last user we attempted to authenticate.
+ *
+ * @return \Illuminate\Contracts\Auth\Authenticatable
+ */
+ public function getLastAttempted()
+ {
+ return $this->lastAttempted;
+ }
+
+ /**
+ * Get a unique identifier for the auth session value.
+ *
+ * @return string
+ */
+ public function getName()
+ {
+ return 'login_'.$this->name.'_'.sha1(static::class);
+ }
+
+ /**
+ * Determine if the user was authenticated via "remember me" cookie.
+ *
+ * @return bool
+ */
+ public function viaRemember()
+ {
+ return false;
+ }
+
+ /**
+ * Return the currently cached user.
+ *
+ * @return \Illuminate\Contracts\Auth\Authenticatable|null
+ */
+ public function getUser()
+ {
+ return $this->user;
+ }
+
+ /**
+ * Set the current user.
+ *
+ * @param \Illuminate\Contracts\Auth\Authenticatable $user
+ * @return $this
+ */
+ public function setUser(AuthenticatableContract $user)
+ {
+ $this->user = $user;
+
+ $this->loggedOut = false;
+
+ return $this;
+ }
+
+}