summaryrefslogtreecommitdiff
path: root/app/Auth
diff options
context:
space:
mode:
Diffstat (limited to 'app/Auth')
-rw-r--r--app/Auth/Base.php60
-rw-r--r--app/Auth/Database.php52
-rw-r--r--app/Auth/GitHub.php178
-rw-r--r--app/Auth/Google.php153
-rw-r--r--app/Auth/Ldap.php150
-rw-r--r--app/Auth/RememberMe.php349
-rw-r--r--app/Auth/ReverseProxy.php73
7 files changed, 1015 insertions, 0 deletions
diff --git a/app/Auth/Base.php b/app/Auth/Base.php
new file mode 100644
index 00000000..f9c1c329
--- /dev/null
+++ b/app/Auth/Base.php
@@ -0,0 +1,60 @@
+<?php
+
+namespace Auth;
+
+use Core\Tool;
+use Core\Registry;
+use PicoDb\Database;
+
+/**
+ * Base auth class
+ *
+ * @package auth
+ * @author Frederic Guillot
+ *
+ * @property \Model\Acl $acl
+ * @property \Model\LastLogin $lastLogin
+ * @property \Model\User $user
+ */
+abstract class Base
+{
+ /**
+ * Database instance
+ *
+ * @access protected
+ * @var \PicoDb\Database
+ */
+ protected $db;
+
+ /**
+ * Registry instance
+ *
+ * @access protected
+ * @var \Core\Registry
+ */
+ protected $registry;
+
+ /**
+ * Constructor
+ *
+ * @access public
+ * @param \Core\Registry $registry Registry instance
+ */
+ public function __construct(Registry $registry)
+ {
+ $this->registry = $registry;
+ $this->db = $this->registry->shared('db');
+ }
+
+ /**
+ * Load automatically models
+ *
+ * @access public
+ * @param string $name Model name
+ * @return mixed
+ */
+ public function __get($name)
+ {
+ return Tool::loadModel($this->registry, $name);
+ }
+}
diff --git a/app/Auth/Database.php b/app/Auth/Database.php
new file mode 100644
index 00000000..67881593
--- /dev/null
+++ b/app/Auth/Database.php
@@ -0,0 +1,52 @@
+<?php
+
+namespace Auth;
+
+use Model\User;
+
+/**
+ * Database authentication
+ *
+ * @package auth
+ * @author Frederic Guillot
+ */
+class Database extends Base
+{
+ /**
+ * Backend name
+ *
+ * @var string
+ */
+ const AUTH_NAME = 'Database';
+
+ /**
+ * Authenticate a user
+ *
+ * @access public
+ * @param string $username Username
+ * @param string $password Password
+ * @return boolean
+ */
+ public function authenticate($username, $password)
+ {
+ $user = $this->db->table(User::TABLE)->eq('username', $username)->eq('is_ldap_user', 0)->findOne();
+
+ if ($user && password_verify($password, $user['password'])) {
+
+ // Update user session
+ $this->user->updateSession($user);
+
+ // Update login history
+ $this->lastLogin->create(
+ self::AUTH_NAME,
+ $user['id'],
+ $this->user->getIpAddress(),
+ $this->user->getUserAgent()
+ );
+
+ return true;
+ }
+
+ return false;
+ }
+}
diff --git a/app/Auth/GitHub.php b/app/Auth/GitHub.php
new file mode 100644
index 00000000..1e99df41
--- /dev/null
+++ b/app/Auth/GitHub.php
@@ -0,0 +1,178 @@
+<?php
+
+namespace Auth;
+
+require __DIR__.'/../../vendor/OAuth/bootstrap.php';
+
+use OAuth\Common\Storage\Session;
+use OAuth\Common\Consumer\Credentials;
+use OAuth\Common\Http\Uri\UriFactory;
+use OAuth\ServiceFactory;
+use OAuth\Common\Http\Exception\TokenResponseException;
+
+/**
+ * GitHub backend
+ *
+ * @package auth
+ */
+class GitHub extends Base
+{
+ /**
+ * Backend name
+ *
+ * @var string
+ */
+ const AUTH_NAME = 'Github';
+
+ /**
+ * Authenticate a GitHub user
+ *
+ * @access public
+ * @param string $github_id GitHub user id
+ * @return boolean
+ */
+ public function authenticate($github_id)
+ {
+ $user = $this->user->getByGitHubId($github_id);
+
+ if ($user) {
+
+ // Create the user session
+ $this->user->updateSession($user);
+
+ // Update login history
+ $this->lastLogin->create(
+ self::AUTH_NAME,
+ $user['id'],
+ $this->user->getIpAddress(),
+ $this->user->getUserAgent()
+ );
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Unlink a GitHub account for a given user
+ *
+ * @access public
+ * @param integer $user_id User id
+ * @return boolean
+ */
+ public function unlink($user_id)
+ {
+ return $this->user->update(array(
+ 'id' => $user_id,
+ 'github_id' => '',
+ ));
+ }
+
+ /**
+ * Update the user table based on the GitHub profile information
+ *
+ * @access public
+ * @param integer $user_id User id
+ * @param array $profile GitHub profile
+ * @return boolean
+ * @todo Don't overwrite existing email/name with empty GitHub data
+ */
+ public function updateUser($user_id, array $profile)
+ {
+ return $this->user->update(array(
+ 'id' => $user_id,
+ 'github_id' => $profile['id'],
+ 'email' => $profile['email'],
+ 'name' => $profile['name'],
+ ));
+ }
+
+ /**
+ * Get the GitHub service instance
+ *
+ * @access public
+ * @return \OAuth\OAuth2\Service\GitHub
+ */
+ public function getService()
+ {
+ $uriFactory = new UriFactory();
+ $currentUri = $uriFactory->createFromSuperGlobalArray($_SERVER);
+ $currentUri->setQuery('controller=user&action=gitHub');
+
+ $storage = new Session(false);
+
+ $credentials = new Credentials(
+ GITHUB_CLIENT_ID,
+ GITHUB_CLIENT_SECRET,
+ $currentUri->getAbsoluteUri()
+ );
+
+ $serviceFactory = new ServiceFactory();
+
+ return $serviceFactory->createService(
+ 'gitHub',
+ $credentials,
+ $storage,
+ array('')
+ );
+ }
+
+ /**
+ * Get the authorization URL
+ *
+ * @access public
+ * @return \OAuth\Common\Http\Uri\Uri
+ */
+ public function getAuthorizationUrl()
+ {
+ return $this->getService()->getAuthorizationUri();
+ }
+
+ /**
+ * Get GitHub profile information from the API
+ *
+ * @access public
+ * @param string $code GitHub authorization code
+ * @return bool|array
+ */
+ public function getGitHubProfile($code)
+ {
+ try {
+ $gitHubService = $this->getService();
+ $gitHubService->requestAccessToken($code);
+
+ return json_decode($gitHubService->request('user'), true);
+ }
+ catch (TokenResponseException $e) {
+ return false;
+ }
+
+ return false;
+ }
+
+ /**
+ * Revokes this user's GitHub tokens for Kanboard
+ *
+ * @access public
+ * @return bool|array
+ * @todo Currently this simply removes all our tokens for this user, ideally it should
+ * restrict itself to the one in question
+ */
+ public function revokeGitHubAccess()
+ {
+ try {
+ $gitHubService = $this->getService();
+
+ $basicAuthHeader = array('Authorization' => 'Basic ' .
+ base64_encode(GITHUB_CLIENT_ID.':'.GITHUB_CLIENT_SECRET));
+
+ return json_decode($gitHubService->request('/applications/'.GITHUB_CLIENT_ID.'/tokens', 'DELETE', null, $basicAuthHeader), true);
+ }
+ catch (TokenResponseException $e) {
+ return false;
+ }
+
+ return false;
+ }
+}
diff --git a/app/Auth/Google.php b/app/Auth/Google.php
new file mode 100644
index 00000000..3dca96be
--- /dev/null
+++ b/app/Auth/Google.php
@@ -0,0 +1,153 @@
+<?php
+
+namespace Auth;
+
+require __DIR__.'/../../vendor/OAuth/bootstrap.php';
+
+use OAuth\Common\Storage\Session;
+use OAuth\Common\Consumer\Credentials;
+use OAuth\Common\Http\Uri\UriFactory;
+use OAuth\ServiceFactory;
+use OAuth\Common\Http\Exception\TokenResponseException;
+
+/**
+ * Google backend
+ *
+ * @package auth
+ * @author Frederic Guillot
+ */
+class Google extends Base
+{
+ /**
+ * Backend name
+ *
+ * @var string
+ */
+ const AUTH_NAME = 'Google';
+
+ /**
+ * Authenticate a Google user
+ *
+ * @access public
+ * @param string $google_id Google unique id
+ * @return boolean
+ */
+ public function authenticate($google_id)
+ {
+ $user = $this->user->getByGoogleId($google_id);
+
+ if ($user) {
+
+ // Create the user session
+ $this->user->updateSession($user);
+
+ // Update login history
+ $this->lastLogin->create(
+ self::AUTH_NAME,
+ $user['id'],
+ $this->user->getIpAddress(),
+ $this->user->getUserAgent()
+ );
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Unlink a Google account for a given user
+ *
+ * @access public
+ * @param integer $user_id User id
+ * @return boolean
+ */
+ public function unlink($user_id)
+ {
+ return $this->user->update(array(
+ 'id' => $user_id,
+ 'google_id' => '',
+ ));
+ }
+
+ /**
+ * Update the user table based on the Google profile information
+ *
+ * @access public
+ * @param integer $user_id User id
+ * @param array $profile Google profile
+ * @return boolean
+ */
+ public function updateUser($user_id, array $profile)
+ {
+ return $this->user->update(array(
+ 'id' => $user_id,
+ 'google_id' => $profile['id'],
+ 'email' => $profile['email'],
+ 'name' => $profile['name'],
+ ));
+ }
+
+ /**
+ * Get the Google service instance
+ *
+ * @access public
+ * @return \OAuth\OAuth2\Service\Google
+ */
+ public function getService()
+ {
+ $uriFactory = new UriFactory();
+ $currentUri = $uriFactory->createFromSuperGlobalArray($_SERVER);
+ $currentUri->setQuery('controller=user&action=google');
+
+ $storage = new Session(false);
+
+ $credentials = new Credentials(
+ GOOGLE_CLIENT_ID,
+ GOOGLE_CLIENT_SECRET,
+ $currentUri->getAbsoluteUri()
+ );
+
+ $serviceFactory = new ServiceFactory();
+
+ return $serviceFactory->createService(
+ 'google',
+ $credentials,
+ $storage,
+ array('userinfo_email', 'userinfo_profile')
+ );
+ }
+
+ /**
+ * Get the authorization URL
+ *
+ * @access public
+ * @return \OAuth\Common\Http\Uri\Uri
+ */
+ public function getAuthorizationUrl()
+ {
+ return $this->getService()->getAuthorizationUri();
+ }
+
+ /**
+ * Get Google profile information from the API
+ *
+ * @access public
+ * @param string $code Google authorization code
+ * @return bool|array
+ */
+ public function getGoogleProfile($code)
+ {
+ try {
+
+ $googleService = $this->getService();
+ $googleService->requestAccessToken($code);
+ return json_decode($googleService->request('https://www.googleapis.com/oauth2/v1/userinfo'), true);
+ }
+ catch (TokenResponseException $e) {
+ return false;
+ }
+
+ return false;
+ }
+}
diff --git a/app/Auth/Ldap.php b/app/Auth/Ldap.php
new file mode 100644
index 00000000..bb17653d
--- /dev/null
+++ b/app/Auth/Ldap.php
@@ -0,0 +1,150 @@
+<?php
+
+namespace Auth;
+
+/**
+ * LDAP model
+ *
+ * @package auth
+ * @author Frederic Guillot
+ */
+class Ldap extends Base
+{
+ /**
+ * Backend name
+ *
+ * @var string
+ */
+ const AUTH_NAME = 'LDAP';
+
+ /**
+ * Authenticate the user
+ *
+ * @access public
+ * @param string $username Username
+ * @param string $password Password
+ * @return boolean
+ */
+ public function authenticate($username, $password)
+ {
+ $result = $this->findUser($username, $password);
+
+ if (is_array($result)) {
+
+ $user = $this->user->getByUsername($username);
+
+ if ($user) {
+
+ // There is already a local user with that name
+ if ($user['is_ldap_user'] == 0) {
+ return false;
+ }
+ }
+ else {
+
+ // We create automatically a new user
+ if ($this->createUser($username, $result['name'], $result['email'])) {
+ $user = $this->user->getByUsername($username);
+ }
+ else {
+ return false;
+ }
+ }
+
+ // We open the session
+ $this->user->updateSession($user);
+
+ // Update login history
+ $this->lastLogin->create(
+ self::AUTH_NAME,
+ $user['id'],
+ $this->user->getIpAddress(),
+ $this->user->getUserAgent()
+ );
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Find the user from the LDAP server
+ *
+ * @access public
+ * @param string $username Username
+ * @param string $password Password
+ * @return boolean|array
+ */
+ public function findUser($username, $password)
+ {
+ if (! function_exists('ldap_connect')) {
+ die('The PHP LDAP extension is required');
+ }
+
+ // Skip SSL certificate verification
+ if (! LDAP_SSL_VERIFY) {
+ putenv('LDAPTLS_REQCERT=never');
+ }
+
+ $ldap = ldap_connect(LDAP_SERVER, LDAP_PORT);
+
+ if (! is_resource($ldap)) {
+ die('Unable to connect to the LDAP server: "'.LDAP_SERVER.'"');
+ }
+
+ ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
+ ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
+
+ if (! @ldap_bind($ldap, LDAP_USERNAME, LDAP_PASSWORD)) {
+ die('Unable to bind to the LDAP server: "'.LDAP_SERVER.'"');
+ }
+
+ $sr = @ldap_search($ldap, LDAP_ACCOUNT_BASE, sprintf(LDAP_USER_PATTERN, $username), array(LDAP_ACCOUNT_FULLNAME, LDAP_ACCOUNT_EMAIL));
+
+ if ($sr === false) {
+ return false;
+ }
+
+ $info = ldap_get_entries($ldap, $sr);
+
+ // User not found
+ if (count($info) == 0 || $info['count'] == 0) {
+ return false;
+ }
+
+ // We got our user
+ if (@ldap_bind($ldap, $info[0]['dn'], $password)) {
+
+ return array(
+ 'username' => $username,
+ 'name' => isset($info[0][LDAP_ACCOUNT_FULLNAME][0]) ? $info[0][LDAP_ACCOUNT_FULLNAME][0] : '',
+ 'email' => isset($info[0][LDAP_ACCOUNT_EMAIL][0]) ? $info[0][LDAP_ACCOUNT_EMAIL][0] : '',
+ );
+ }
+
+ return false;
+ }
+
+ /**
+ * Create a new local user after the LDAP authentication
+ *
+ * @access public
+ * @param string $username Username
+ * @param string $name Name of the user
+ * @param string $email Email address
+ * @return bool
+ */
+ public function createUser($username, $name, $email)
+ {
+ $values = array(
+ 'username' => $username,
+ 'name' => $name,
+ 'email' => $email,
+ 'is_admin' => 0,
+ 'is_ldap_user' => 1,
+ );
+
+ return $this->user->create($values);
+ }
+}
diff --git a/app/Auth/RememberMe.php b/app/Auth/RememberMe.php
new file mode 100644
index 00000000..3cf6fc86
--- /dev/null
+++ b/app/Auth/RememberMe.php
@@ -0,0 +1,349 @@
+<?php
+
+namespace Auth;
+
+use Core\Security;
+
+/**
+ * RememberMe model
+ *
+ * @package auth
+ * @author Frederic Guillot
+ */
+class RememberMe extends Base
+{
+ /**
+ * Backend name
+ *
+ * @var string
+ */
+ const AUTH_NAME = 'RememberMe';
+
+ /**
+ * SQL table name
+ *
+ * @var string
+ */
+ const TABLE = 'remember_me';
+
+ /**
+ * Cookie name
+ *
+ * @var string
+ */
+ const COOKIE_NAME = '__R';
+
+ /**
+ * Expiration (60 days)
+ *
+ * @var integer
+ */
+ const EXPIRATION = 5184000;
+
+ /**
+ * Get a remember me record
+ *
+ * @access public
+ * @param $token
+ * @param $sequence
+ * @return mixed
+ */
+ public function find($token, $sequence)
+ {
+ return $this->db
+ ->table(self::TABLE)
+ ->eq('token', $token)
+ ->eq('sequence', $sequence)
+ ->gt('expiration', time())
+ ->findOne();
+ }
+
+ /**
+ * Get all sessions for a given user
+ *
+ * @access public
+ * @param integer $user_id User id
+ * @return array
+ */
+ public function getAll($user_id)
+ {
+ return $this->db
+ ->table(self::TABLE)
+ ->eq('user_id', $user_id)
+ ->desc('date_creation')
+ ->columns('id', 'ip', 'user_agent', 'date_creation', 'expiration')
+ ->findAll();
+ }
+
+ /**
+ * Authenticate the user with the cookie
+ *
+ * @access public
+ * @return bool
+ */
+ public function authenticate()
+ {
+ $credentials = $this->readCookie();
+
+ if ($credentials !== false) {
+
+ $record = $this->find($credentials['token'], $credentials['sequence']);
+
+ if ($record) {
+
+ // Update the sequence
+ $this->writeCookie(
+ $record['token'],
+ $this->update($record['token'], $record['sequence']),
+ $record['expiration']
+ );
+
+ // Create the session
+ $this->user->updateSession($this->user->getById($record['user_id']));
+ $this->acl->isRememberMe(true);
+
+ // Update last login infos
+ $this->lastLogin->create(
+ self::AUTH_NAME,
+ $this->acl->getUserId(),
+ $this->user->getIpAddress(),
+ $this->user->getUserAgent()
+ );
+
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Update the database and the cookie with a new sequence
+ *
+ * @access public
+ */
+ public function refresh()
+ {
+ $credentials = $this->readCookie();
+
+ if ($credentials !== false) {
+
+ $record = $this->find($credentials['token'], $credentials['sequence']);
+
+ if ($record) {
+
+ // Update the sequence
+ $this->writeCookie(
+ $record['token'],
+ $this->update($record['token'], $record['sequence']),
+ $record['expiration']
+ );
+ }
+ }
+ }
+
+ /**
+ * Remove a session record
+ *
+ * @access public
+ * @param integer $session_id Session id
+ * @return mixed
+ */
+ public function remove($session_id)
+ {
+ return $this->db
+ ->table(self::TABLE)
+ ->eq('id', $session_id)
+ ->remove();
+ }
+
+ /**
+ * Remove the current RememberMe session and the cookie
+ *
+ * @access public
+ * @param integer $user_id User id
+ */
+ public function destroy($user_id)
+ {
+ $credentials = $this->readCookie();
+
+ if ($credentials !== false) {
+
+ $this->deleteCookie();
+
+ $this->db
+ ->table(self::TABLE)
+ ->eq('user_id', $user_id)
+ ->eq('token', $credentials['token'])
+ ->remove();
+ }
+ }
+
+ /**
+ * Create a new RememberMe session
+ *
+ * @access public
+ * @param integer $user_id User id
+ * @param string $ip IP Address
+ * @param string $user_agent User Agent
+ * @return array
+ */
+ public function create($user_id, $ip, $user_agent)
+ {
+ $token = hash('sha256', $user_id.$user_agent.$ip.Security::generateToken());
+ $sequence = Security::generateToken();
+ $expiration = time() + self::EXPIRATION;
+
+ $this->cleanup($user_id);
+
+ $this->db
+ ->table(self::TABLE)
+ ->insert(array(
+ 'user_id' => $user_id,
+ 'ip' => $ip,
+ 'user_agent' => $user_agent,
+ 'token' => $token,
+ 'sequence' => $sequence,
+ 'expiration' => $expiration,
+ 'date_creation' => time(),
+ ));
+
+ return array(
+ 'token' => $token,
+ 'sequence' => $sequence,
+ 'expiration' => $expiration,
+ );
+ }
+
+ /**
+ * Remove old sessions for a given user
+ *
+ * @access public
+ * @param integer $user_id User id
+ * @return bool
+ */
+ public function cleanup($user_id)
+ {
+ return $this->db
+ ->table(self::TABLE)
+ ->eq('user_id', $user_id)
+ ->lt('expiration', time())
+ ->remove();
+ }
+
+ /**
+ * Return a new sequence token and update the database
+ *
+ * @access public
+ * @param string $token Session token
+ * @param string $sequence Sequence token
+ * @return string
+ */
+ public function update($token, $sequence)
+ {
+ $new_sequence = Security::generateToken();
+
+ $this->db
+ ->table(self::TABLE)
+ ->eq('token', $token)
+ ->eq('sequence', $sequence)
+ ->update(array('sequence' => $new_sequence));
+
+ return $new_sequence;
+ }
+
+ /**
+ * Encode the cookie
+ *
+ * @access public
+ * @param string $token Session token
+ * @param string $sequence Sequence token
+ * @return string
+ */
+ public function encodeCookie($token, $sequence)
+ {
+ return implode('|', array($token, $sequence));
+ }
+
+ /**
+ * Decode the value of a cookie
+ *
+ * @access public
+ * @param string $value Raw cookie data
+ * @return array
+ */
+ public function decodeCookie($value)
+ {
+ list($token, $sequence) = explode('|', $value);
+
+ return array(
+ 'token' => $token,
+ 'sequence' => $sequence,
+ );
+ }
+
+ /**
+ * Return true if the current user has a RememberMe cookie
+ *
+ * @access public
+ * @return bool
+ */
+ public function hasCookie()
+ {
+ return ! empty($_COOKIE[self::COOKIE_NAME]);
+ }
+
+ /**
+ * Write and encode the cookie
+ *
+ * @access public
+ * @param string $token Session token
+ * @param string $sequence Sequence token
+ * @param string $expiration Cookie expiration
+ */
+ public function writeCookie($token, $sequence, $expiration)
+ {
+ setcookie(
+ self::COOKIE_NAME,
+ $this->encodeCookie($token, $sequence),
+ $expiration,
+ BASE_URL_DIRECTORY,
+ null,
+ ! empty($_SERVER['HTTPS']),
+ true
+ );
+ }
+
+ /**
+ * Read and decode the cookie
+ *
+ * @access public
+ * @return mixed
+ */
+ public function readCookie()
+ {
+ if (empty($_COOKIE[self::COOKIE_NAME])) {
+ return false;
+ }
+
+ return $this->decodeCookie($_COOKIE[self::COOKIE_NAME]);
+ }
+
+ /**
+ * Remove the cookie
+ *
+ * @access public
+ */
+ public function deleteCookie()
+ {
+ setcookie(
+ self::COOKIE_NAME,
+ '',
+ time() - 3600,
+ BASE_URL_DIRECTORY,
+ null,
+ ! empty($_SERVER['HTTPS']),
+ true
+ );
+ }
+}
diff --git a/app/Auth/ReverseProxy.php b/app/Auth/ReverseProxy.php
new file mode 100644
index 00000000..e23ee24f
--- /dev/null
+++ b/app/Auth/ReverseProxy.php
@@ -0,0 +1,73 @@
+<?php
+
+namespace Auth;
+
+use Core\Security;
+
+/**
+ * ReverseProxy backend
+ *
+ * @package auth
+ * @author Sylvain VeyriƩ
+ */
+class ReverseProxy extends Base
+{
+ /**
+ * Backend name
+ *
+ * @var string
+ */
+ const AUTH_NAME = 'ReverseProxy';
+
+ /**
+ * Authenticate the user with the HTTP header
+ *
+ * @access public
+ * @return bool
+ */
+ public function authenticate()
+ {
+ if (isset($_SERVER[REVERSE_PROXY_USER_HEADER])) {
+
+ $login = $_SERVER[REVERSE_PROXY_USER_HEADER];
+ $user = $this->user->getByUsername($login);
+
+ if (! $user) {
+ $this->createUser($login);
+ $user = $this->user->getByUsername($login);
+ }
+
+ // Create the user session
+ $this->user->updateSession($user);
+
+ // Update login history
+ $this->lastLogin->create(
+ self::AUTH_NAME,
+ $user['id'],
+ $this->user->getIpAddress(),
+ $this->user->getUserAgent()
+ );
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Create automatically a new local user after the authentication
+ *
+ * @access private
+ * @param string $login Username
+ * @return bool
+ */
+ private function createUser($login)
+ {
+ return $this->user->create(array(
+ 'email' => strpos($login, '@') !== false ? $login : '',
+ 'username' => $login,
+ 'is_admin' => REVERSE_PROXY_DEFAULT_ADMIN === $login,
+ 'is_ldap_user' => 1,
+ ));
+ }
+}