mirror of
https://github.com/filegator/filegator.git
synced 2025-10-28 14:25:09 +01:00
* Adds an attribute parameter to the ldap adapter Using this parameter is much more efficient than the default action (which is to return all attributes and their associated values). The use of this parameter should therefore be considered good practice. (from https://www.php.net/manual/en/function.ldap-search.php) * Updates the docs about ldap_attributes parameter * Enhances portuguese translation * Update backend/Services/Auth/Adapters/LDAP.php Commit suggestion
229 lines
7.0 KiB
PHP
229 lines
7.0 KiB
PHP
<?php
|
|
|
|
/*
|
|
* This file is part of the FileGator package.
|
|
*
|
|
* (c) Adriano Hänggli <https://github.com/ahaenggli>
|
|
*
|
|
*/
|
|
|
|
namespace Filegator\Services\Auth\Adapters;
|
|
|
|
use Filegator\Services\Auth\AuthInterface;
|
|
use Filegator\Services\Auth\User;
|
|
use Filegator\Services\Auth\UsersCollection;
|
|
use Filegator\Services\Service;
|
|
use Filegator\Services\Session\SessionStorageInterface as Session;
|
|
|
|
/**
|
|
* @codeCoverageIgnore
|
|
*/
|
|
class LDAP implements Service, AuthInterface
|
|
{
|
|
const SESSION_KEY = 'LDAP_auth';
|
|
const GUEST_USERNAME = 'guest';
|
|
|
|
protected $session;
|
|
protected $private_repos = false;
|
|
protected $ldap_server;
|
|
protected $ldap_bindDN;
|
|
protected $ldap_bindPass;
|
|
protected $ldap_baseDN;
|
|
protected $ldap_filter;
|
|
protected $ldap_attributes;
|
|
protected $ldap_userFieldMapping;
|
|
|
|
public function __construct(Session $session)
|
|
{
|
|
$this->session = $session;
|
|
}
|
|
|
|
public function init(array $config = [])
|
|
{
|
|
if(!isset($config['ldap_server']) || empty($config['ldap_server']))
|
|
throw new \Exception('config ldap_server missing');
|
|
|
|
if (!extension_loaded('ldap')) throw new \Exception('ldap extension missing');
|
|
|
|
if($connect=ldap_connect($config['ldap_server'])){
|
|
ldap_set_option($connect, LDAP_OPT_PROTOCOL_VERSION, 3);
|
|
$this->private_repos = $config['private_repos'];
|
|
$this->ldap_server = $config['ldap_server'];
|
|
$this->ldap_bindDN = $config['ldap_bindDN'];
|
|
$this->ldap_bindPass = $config['ldap_bindPass'];
|
|
$this->ldap_baseDN = $config['ldap_baseDN'];
|
|
$this->ldap_filter = $config['ldap_filter'];
|
|
$this->ldap_attributes = isset($config['ldap_attributes']) ? $config['ldap_attributes'] : ['*'];
|
|
$this->ldap_userFieldMapping = $config['ldap_userFieldMapping'];
|
|
}else {
|
|
@ldap_close($connect);
|
|
throw new \Exception('could not connect to domain');
|
|
}
|
|
|
|
@ldap_close($connect);
|
|
}
|
|
|
|
public function user(): ?User
|
|
{
|
|
return $this->session ? $this->session->get(self::SESSION_KEY, null) : null;
|
|
}
|
|
|
|
public function authenticate($username, $password): bool
|
|
{
|
|
$all_users = $this->getUsers();
|
|
|
|
foreach ($all_users as &$u) {
|
|
if ($u['username'] == $username && $this->verifyPassword($u['userDN'], $password)) {
|
|
$user = $this->mapToUserObject($u);
|
|
$this->store($user);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public function forget()
|
|
{
|
|
return $this->session->invalidate();
|
|
}
|
|
|
|
public function store(User $user)
|
|
{
|
|
return $this->session->set(self::SESSION_KEY, $user);
|
|
}
|
|
|
|
public function update($username, User $user, $password = ''): User
|
|
{
|
|
return new User(); // not used
|
|
}
|
|
|
|
public function add(User $user, $password): User
|
|
{
|
|
return new User(); // not used
|
|
}
|
|
|
|
public function delete(User $user)
|
|
{
|
|
return true; // not used
|
|
}
|
|
|
|
public function find($username): ?User
|
|
{
|
|
foreach ($this->getUsers() as $user) {
|
|
if ($user['username'] == $username) {
|
|
return $this->mapToUserObject($user);
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public function getGuest(): User
|
|
{
|
|
$guest = $this->find(self::GUEST_USERNAME);
|
|
|
|
if (!$guest || !$guest->isGuest()) {
|
|
$guest = new User();
|
|
$guest->setUsername('guest');
|
|
$guest->setName('Guest');
|
|
$guest->setRole('guest');
|
|
$guest->setHomedir('/');
|
|
$guest->setPermissions([]);
|
|
return $guest;
|
|
}
|
|
|
|
return $guest;
|
|
}
|
|
|
|
public function allUsers(): UsersCollection
|
|
{
|
|
$users = new UsersCollection();
|
|
|
|
foreach ($this->getUsers() as $user) {
|
|
$users->addUser($this->mapToUserObject($user));
|
|
}
|
|
|
|
return $users;
|
|
}
|
|
|
|
protected function mapToUserObject(array $user): User
|
|
{
|
|
$new = new User();
|
|
$new->setUsername($user['username']);
|
|
$new->setName($user['name']);
|
|
$new->setRole($user['role']);
|
|
$new->setHomedir($user['homedir']);
|
|
$new->setPermissions($user['permissions'], true);
|
|
return $new;
|
|
}
|
|
|
|
protected function getUsers(): array
|
|
{
|
|
$ldapConn = @ldap_connect($this->ldap_server);
|
|
if (!$ldapConn) throw new \Exception('Cannot Connect to LDAP server');
|
|
@ldap_set_option($ldapConn, LDAP_OPT_PROTOCOL_VERSION, 3);
|
|
|
|
$ldapBind = @ldap_bind($ldapConn, $this->ldap_bindDN,$this->ldap_bindPass);
|
|
if (!$ldapBind) throw new \Exception('Cannot Bind to LDAP server: Wrong credentials?');
|
|
|
|
// search the LDAP server for users
|
|
$ldapSearch = @ldap_search($ldapConn, $this->ldap_baseDN, $this->ldap_filter, $this->ldap_attributes);
|
|
$ldapResults = @ldap_get_entries($ldapConn, $ldapSearch);
|
|
@ldap_close($ldapConn);
|
|
|
|
$users = [];
|
|
|
|
for ($item = 0; $item < $ldapResults['count']; $item++)
|
|
{
|
|
$user = [];
|
|
$user['username'] = $ldapResults[$item][$this->ldap_userFieldMapping['username']][0];
|
|
$user['name'] = $ldapResults[$item][$this->ldap_userFieldMapping['name']][0];
|
|
$user['role'] = 'user';
|
|
$user['homedir'] = '/';
|
|
$user['permissions']=$this->ldap_userFieldMapping['default_permissions'];
|
|
$user['userDN'] = $ldapResults[$item][$this->ldap_userFieldMapping['userDN']];
|
|
|
|
if(is_array($this->ldap_userFieldMapping['admin_usernames']))
|
|
{
|
|
if(in_array($user['username'], $this->ldap_userFieldMapping['admin_usernames'])) $user['role'] = 'admin';
|
|
}
|
|
|
|
// private repositories for each user?
|
|
if ($this->private_repos) {
|
|
$user->setHomedir('/'.$user['username']);
|
|
}
|
|
|
|
// ...but not for admins
|
|
if ($user['role'] == 'admin'){
|
|
$user['homedir'] = '/';
|
|
$user['permissions'] = 'read|write|upload|download|batchdownload|zip';
|
|
}
|
|
|
|
if(is_array($user) && !empty($user)) $users[] = $user;
|
|
}
|
|
return is_array($users) ? $users : [];
|
|
}
|
|
|
|
private function verifyPassword($auth_user, $password)
|
|
{
|
|
if(!isset($this->ldap_server) || empty($this->ldap_server)) return false;
|
|
if(!extension_loaded('ldap')) return false;
|
|
|
|
if($connect=ldap_connect($this->ldap_server))
|
|
{
|
|
ldap_set_option($connect, LDAP_OPT_PROTOCOL_VERSION, 3);
|
|
if($bind=ldap_bind($connect, $auth_user, $password)){
|
|
@ldap_close($connect);
|
|
return true;
|
|
} else {
|
|
@ldap_close($connect);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
@ldap_close($connect);
|
|
return false;
|
|
}
|
|
}
|