Move getBaseDN to Entry class, some cleanup

This commit is contained in:
Deon George 2020-09-21 22:20:59 +10:00
parent 4ef074fac4
commit 2a099e2dc4
5 changed files with 126 additions and 103 deletions

View File

@ -2,33 +2,32 @@
namespace App\Classes\LDAP; namespace App\Classes\LDAP;
use App\Ldap\Entry; use Exception;
use Illuminate\Support\Arr; use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
use LdapRecord\Models\Model;
use LdapRecord\Query\Collection;
use LdapRecord\Query\Model\Builder;
use App\Ldap\Entry;
class Server class Server
{ {
/** /**
* Query the server for a DN * Query the server for a DN and return it's children and if those children have children.
* *
* @param string $dn * @param string $dn
* @return array|\LdapRecord\Query\Collection|null * @return array|Collection|null
*/ */
public function children(string $dn) public function children(string $dn): ?Collection
{ {
try { return ($x=(new Entry)
return ($x=(new Entry) ->query()
->query() ->select(['*','hassubordinates'])
->select(['dn','hassubordinates']) ->setDn($dn)
->setDn($dn) ->listing()
->listing() ->get()) ? $x : NULL;
->get()) ? $x : NULL;
// @todo Tidy up this exception
} catch (\Exception $e) {
dd(['e'=>$e]);
}
} }
/** /**
@ -36,66 +35,14 @@ class Server
* *
* @param string $dn * @param string $dn
* @param array $attrs * @param array $attrs
* @return array|\LdapRecord\Models\Model|\LdapRecord\Query\Collection|\LdapRecord\Query\Model\Builder|null * @return array|Model|Collection|Builder|null
*/ */
public function fetch(string $dn,array $attrs=['*','+']) public function fetch(string $dn,array $attrs=['*','+']): ?Entry
{ {
try { return ($x=(new Entry)
return ($x=(new Entry) ->query()
->query() ->select($attrs)
->select($attrs) ->find($dn)) ? $x : NULL;
->find($dn)) ? $x : NULL;
// @todo Tidy up this exception
} catch (\Exception $e) {
dd(['e'=>$e]);
}
}
/**
* Gets the root DN of the specified LDAPServer, or NULL if it
* can't find it (ie, the server won't give it to us, or it isnt
* specified in the configuration file).
*
* @return Collection|null array|NULL The root DN(s) of the server on success (string) or NULL if it cannot be determine.
* @todo Sort the entries, so that they are in the correct DN order.
* @testedby GetBaseDNTest::testBaseDNExists()
*/
public function getBaseDN(): ?Collection
{
//findBaseDn()?
// If the base is set in the configuration file, then just return that after validating it exists.
// @todo
if (false) {
// We need to work out the baseDN
} else {
$result = $this->getDNAttrValues('',['namingcontexts']);
return $result ? collect($result->namingcontexts) : NULL;
}
}
/**
* Search for a DN and return its attributes
*
* @param $dn
* @param array $attrs
* @param int $deref // @todo
* @return Entry|bool
*/
protected function getDNAttrValues(string $dn,array $attrs=['*','+'],int $deref=LDAP_DEREF_NEVER): ?Entry
{
try {
return ($x=(new Entry)
->query()
->select($attrs)
->find($dn)) ? $x : NULL;
// @todo Tidy up this exception
} catch (\Exception $e) {
dd(['e'=>$e]);
}
} }
/** /**
@ -119,11 +66,10 @@ class Server
public static function getOID(string $oid,string $key): ?string public static function getOID(string $oid,string $key): ?string
{ {
$oids = Cache::remember('oids',86400,function() { $oids = Cache::remember('oids',86400,function() {
try { try {
$f = fopen(config_path('ldap_supported_oids.txt'),'r'); $f = fopen(config_path('ldap_supported_oids.txt'),'r');
} catch (\Exception $e) { } catch (Exception $e) {
return NULL; return NULL;
} }
@ -154,4 +100,37 @@ class Server
($key == 'desc' ? 'No description available, can you help with one?' : ($key == 'title' ? $oid : NULL)) ($key == 'desc' ? 'No description available, can you help with one?' : ($key == 'title' ? $oid : NULL))
); );
} }
public static function icon(Entry $dn): string
{
$objectclasses = array_map('strtolower',$dn->objectclass);
// Return icon based upon objectClass value
if (in_array('person',$objectclasses) ||
in_array('organizationalperson',$objectclasses) ||
in_array('inetorgperson',$objectclasses) ||
in_array('account',$objectclasses) ||
in_array('posixaccount',$objectclasses))
return 'fas fa-user';
elseif (in_array('organization',$objectclasses))
return 'fas fa-university';
elseif (in_array('organizationalunit',$objectclasses))
return 'fas fa-object-group';
elseif (in_array('dcobject',$objectclasses) ||
in_array('domainrelatedobject',$objectclasses) ||
in_array('domain',$objectclasses) ||
in_array('builtindomain',$objectclasses))
return 'fas fa-network-wired';
elseif (in_array('country',$objectclasses))
return sprintf('flag %s',strtolower(Arr::get($dn->c,0)));
// Default
return 'fa-fw fas fa-cog';
}
} }

View File

@ -11,16 +11,20 @@ use Illuminate\Support\Facades\File;
use App\Ldap\Entry; use App\Ldap\Entry;
use App\Classes\LDAP\Server; use App\Classes\LDAP\Server;
use LdapRecord\Models\ModelNotFoundException;
class HomeController extends Controller class HomeController extends Controller
{ {
public function home() public function home()
{ {
$o = new Server; $base = (new Entry)->baseDN();
if (! $base)
$base = collect();
return view('home') return view('home')
->with('server',config('ldap.connections.default.name')) ->with('server',config('ldap.connections.default.name'))
->with('bases',$o->getBaseDN()->transform(function($item) { ->with('bases',$base->transform(function($item) {
return [ return [
'title'=>$item, 'title'=>$item,
'item'=>Crypt::encryptString($item), 'item'=>Crypt::encryptString($item),
@ -33,22 +37,28 @@ class HomeController extends Controller
public function info() public function info()
{ {
$attrs = collect((new Entry)->rootDSE()->getAttributes()) try {
->transform(function($item,$key) { $attrs = collect((new Entry)->rootDSE()->getAttributes())
foreach ($item as $k=>$v) { ->transform(function($item,$key) {
if (preg_match('/[0-9]+\.[0-9]+\.[0-9]+/',$v)) { foreach ($item as $k=>$v) {
$format = sprintf( if (preg_match('/[0-9]+\.[0-9]+\.[0-9]+/',$v)) {
'<abbr class="pb-1" title="%s"><i class="fas fa-list-ol pr-2"></i>%s</abbr>%s<p class="mb-0">%s</p>', $format = sprintf(
$v, '<abbr class="pb-1" title="%s"><i class="fas fa-list-ol pr-2"></i>%s</abbr>%s<p class="mb-0">%s</p>',
Server::getOID($v,'title'), $v,
($x=Server::getOID($v,'ref')) ? sprintf('<abbr class="pl-2" title="%s"><i class="fas fa-comment-dots"></i></abbr>',$x) : '', Server::getOID($v,'title'),
Server::getOID($v,'desc'), ($x=Server::getOID($v,'ref')) ? sprintf('<abbr class="pl-2" title="%s"><i class="fas fa-comment-dots"></i></abbr>',$x) : '',
Server::getOID($v,'desc'),
); );
$item[$k] = $format; $item[$k] = $format;
}
} }
} return $item;
return $item; });
});
// @todo If we cant get server info, we should probably show a nice error dialog
} catch (ModelNotFoundException $e) {
$attrs = collect();
}
return view('widgets.dn') return view('widgets.dn')
->with('dn',__('Server Info')) ->with('dn',__('Server Info'))
@ -62,7 +72,7 @@ class HomeController extends Controller
return view('widgets.dn') return view('widgets.dn')
->with('dn',$dn) ->with('dn',$dn)
->with('leaf',$x=(new Server())->fetch($dn)) ->with('leaf',$x=(new Server())->fetch($dn))
->with('attributes',$this->sortAttrs(collect($x->getAttributes()))); ->with('attributes',$x ? $this->sortAttrs(collect($x->getAttributes())) : []);
} }
/** /**

View File

@ -2,7 +2,10 @@
namespace App\Ldap; namespace App\Ldap;
use Illuminate\Support\Collection;
use LdapRecord\Models\Model; use LdapRecord\Models\Model;
use LdapRecord\Models\ModelNotFoundException;
use LdapRecord\Query\Model\Builder;
class Entry extends Model class Entry extends Model
{ {
@ -13,10 +16,39 @@ class Entry extends Model
*/ */
public static $objectClasses = []; public static $objectClasses = [];
public function rootDSE($connection = null) /**
* Gets the root DN of the specified LDAPServer, or throws an exception if it
* can't find it.
*
* @param null $connection
* @return Collection
* @throws ModelNotFoundException
* @testedin GetBaseDNTest::testBaseDNExists();
*/
public function baseDN($connection = NULL): ?Collection
{
$base = static::on($connection ?? (new static)->getConnectionName())
->in(NULL)
->read()
->select(['namingcontexts'])
->whereHas('objectclass')
->firstOrFail();
return $base->namingcontexts ? collect($base->namingcontexts) : NULL;
}
/**
* Obtain the rootDSE for the server, that gives us server information
*
* @param null $connection
* @return Entry|null
* @throws ModelNotFoundException
* @testedin TranslateOidTest::testRootDSE();
*/
public function rootDSE($connection = NULL): ?Entry
{ {
return static::on($connection ?? (new static)->getConnectionName()) return static::on($connection ?? (new static)->getConnectionName())
->in(null) ->in(NULL)
->read() ->read()
->select(['+']) ->select(['+'])
->whereHas('objectclass') ->whereHas('objectclass')

View File

@ -7,7 +7,7 @@ use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase; use Tests\TestCase;
use App\Classes\LDAP\Server; use App\Ldap\Entry;
class GetBaseDNTest extends TestCase class GetBaseDNTest extends TestCase
{ {
@ -15,14 +15,15 @@ class GetBaseDNTest extends TestCase
* Test that we can get the Base DN of an LDAP server * Test that we can get the Base DN of an LDAP server
* *
* @return void * @return void
* @throws \LdapRecord\Models\ModelNotFoundException
* @covers \App\Ldap\Entry::baseDN()
*/ */
public function testBaseDNExists() public function testBaseDNExists()
{ {
$o = new Server(); $o = (new Entry)->baseDN();
$x = $o->getBaseDN();
$this->assertIsObject($x); $this->assertIsObject($o);
$this->assertCount(1,$x->toArray()); $this->assertCount(1,$o->toArray());
$this->assertContains('dc=Test',$x->toArray()); $this->assertContains('dc=Test',$o->toArray());
} }
} }

View File

@ -15,7 +15,8 @@ class TranslateOidTest extends TestCase
* A basic feature test example. * A basic feature test example.
* *
* @return void * @return void
* @covers Server::getOID() * @throws \LdapRecord\Models\ModelNotFoundException
* @covers \App\Classes\LDAP\Server::getOID()
*/ */
public function testRootDSE() public function testRootDSE()
{ {