diff --git a/VERSION b/VERSION
index 8b13789..34725a9 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-
+GIT
diff --git a/app/Classes/LDAP/Server.php b/app/Classes/LDAP/Server.php
index 7a04ea8..3ca77b3 100644
--- a/app/Classes/LDAP/Server.php
+++ b/app/Classes/LDAP/Server.php
@@ -5,11 +5,14 @@ namespace App\Classes\LDAP;
use Carbon\Carbon;
use Exception;
use Illuminate\Support\Arr;
-use Illuminate\Support\Collection as ArrayCollection;
+use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Log;
-use LdapRecord\Query\Collection;
+use LdapRecord\LdapRecordException;
+use LdapRecord\Models\Model;
+use LdapRecord\Query\Collection as LDAPCollection;
+use LdapRecord\Query\ObjectNotFoundException;
use App\Classes\LDAP\Schema\{AttributeType,Base,LDAPSyntax,MatchingRule,MatchingRuleUse,ObjectClass};
use App\Exceptions\InvalidUsage;
@@ -18,11 +21,11 @@ use App\Ldap\Entry;
class Server
{
// This servers schema objectclasses
- private ArrayCollection $attributetypes;
- private ArrayCollection $ldapsyntaxes;
- private ArrayCollection $matchingrules;
- private ArrayCollection $matchingruleuse;
- private ArrayCollection $objectclasses;
+ private Collection $attributetypes;
+ private Collection $ldapsyntaxes;
+ private Collection $matchingrules;
+ private Collection $matchingruleuse;
+ private Collection $objectclasses;
// Valid items that can be fetched
public const schema_types = [
@@ -45,13 +48,187 @@ class Server
}
}
+ /* STATIC METHODS */
+
+ /**
+ * Gets the root DN of the specified LDAPServer, or throws an exception if it
+ * can't find it.
+ *
+ * @param null $connection Return a collection of baseDNs
+ * @param bool $objects Return a collection of Entry Models
+ * @return Collection
+ * @throws ObjectNotFoundException
+ * @testedin GetBaseDNTest::testBaseDNExists();
+ */
+ public static function baseDNs($connection=NULL,bool $objects=TRUE): Collection
+ {
+ $cachetime = Carbon::now()->addSeconds(Config::get('ldap.cache.time'));
+
+ try {
+ $base = self::rootDSE($connection,$cachetime);
+
+ /**
+ * LDAP Error Codes:
+ * https://ldap.com/ldap-result-code-reference/
+ * + success 0
+ * + operationsError 1
+ * + protocolError 2
+ * + timeLimitExceeded 3
+ * + sizeLimitExceeded 4
+ * + compareFalse 5
+ * + compareTrue 6
+ * + authMethodNotSupported 7
+ * + strongerAuthRequired 8
+ * + referral 10
+ * + adminLimitExceeded 11
+ * + unavailableCriticalExtension 12
+ * + confidentialityRequired 13
+ * + saslBindInProgress 14
+ * + noSuchAttribute 16
+ * + undefinedAttributeType 17
+ * + inappropriateMatching 18
+ * + constraintViolation 19
+ * + attributeOrValueExists 20
+ * + invalidAttributeSyntax 21
+ * + noSuchObject 32
+ * + aliasProblem 33
+ * + invalidDNSyntax 34
+ * + isLeaf 35
+ * + aliasDereferencingProblem 36
+ * + inappropriateAuthentication 48
+ * + invalidCredentials 49
+ * + insufficientAccessRights 50
+ * + busy 51
+ * + unavailable 52
+ * + unwillingToPerform 53
+ * + loopDetect 54
+ * + sortControlMissing 60
+ * + offsetRangeError 61
+ * + namingViolation 64
+ * + objectClassViolation 65
+ * + notAllowedOnNonLeaf 66
+ * + notAllowedOnRDN 67
+ * + entryAlreadyExists 68
+ * + objectClassModsProhibited 69
+ * + resultsTooLarge 70
+ * + affectsMultipleDSAs 71
+ * + virtualListViewError or controlError 76
+ * + other 80
+ * + serverDown 81
+ * + localError 82
+ * + encodingError 83
+ * + decodingError 84
+ * + timeout 85
+ * + authUnknown 86
+ * + filterError 87
+ * + userCanceled 88
+ * + paramError 89
+ * + noMemory 90
+ * + connectError 91
+ * + notSupported 92
+ * + controlNotFound 93
+ * + noResultsReturned 94
+ * + moreResultsToReturn 95
+ * + clientLoop 96
+ * + referralLimitExceeded 97
+ * + invalidResponse 100
+ * + ambiguousResponse 101
+ * + tlsNotSupported 112
+ * + intermediateResponse 113
+ * + unknownType 114
+ * + canceled 118
+ * + noSuchOperation 119
+ * + tooLate 120
+ * + cannotCancel 121
+ * + assertionFailed 122
+ * + authorizationDenied 123
+ * + e-syncRefreshRequired 4096
+ * + noOperation 16654
+ *
+ * LDAP Tag Codes:
+ * + A client bind operation 97
+ * + The entry for which you were searching 100
+ * + The result from a search operation 101
+ * + The result from a modify operation 103
+ * + The result from an add operation 105
+ * + The result from a delete operation 107
+ * + The result from a modify DN operation 109
+ * + The result from a compare operation 111
+ * + A search reference when the entry you perform your search on holds a referral to the entry you require.
+ * + Search references are expressed in terms of a referral.
+ * 115
+ * + A result from an extended operation 120
+ */
+ // If we cannot get to our LDAP server we'll head straight to the error page
+ } catch (LdapRecordException $e) {
+ switch ($e->getDetailedError()->getErrorCode()) {
+ case 49:
+ abort(401,$e->getDetailedError()->getErrorMessage());
+
+ default:
+ abort(597,$e->getDetailedError()->getErrorMessage());
+ }
+ }
+
+ if (! $objects)
+ return collect($base->namingcontexts);
+
+ /**
+ * @note While we are caching our baseDNs, it seems if we have more than 1,
+ * our caching doesnt generate a hit on a subsequent call to this function (before the cache expires).
+ * IE: If we have 5 baseDNs, it takes 5 calls to this function to case them all.
+ * @todo Possibly a bug wtih ldaprecord, so need to investigate
+ */
+ $result = collect();
+ foreach ($base->namingcontexts as $dn) {
+ $result->push((new Entry)->cache($cachetime)->findOrFail($dn));
+ }
+
+ return $result;
+ }
+
+ /**
+ * Obtain the rootDSE for the server, that gives us server information
+ *
+ * @param null $connection
+ * @return Entry|null
+ * @throws ObjectNotFoundException
+ * @testedin TranslateOidTest::testRootDSE();
+ */
+ public static function rootDSE($connection=NULL,Carbon $cachetime=NULL): ?Model
+ {
+ $e = new Entry;
+
+ return Entry::on($connection ?? $e->getConnectionName())
+ ->cache($cachetime)
+ ->in(NULL)
+ ->read()
+ ->select(['+'])
+ ->whereHas('objectclass')
+ ->firstOrFail();
+ }
+
+ /**
+ * Get the Schema DN
+ *
+ * @param $connection
+ * @return string
+ * @throws ObjectNotFoundException
+ */
+ public static function schemaDN($connection=NULL): string
+ {
+ $cachetime = Carbon::now()->addSeconds(Config::get('ldap.cache.time'));
+
+ return collect(self::rootDSE($connection,$cachetime)->subschemasubentry)->first();
+ }
+
/**
* Query the server for a DN and return its children and if those children have children.
*
* @param string $dn
- * @return Collection|null
+ * @return LDAPCollection|NULL
*/
- public function children(string $dn): ?Collection
+ public function children(string $dn): ?LDAPCollection
{
return ($x=(new Entry)
->query()
@@ -150,10 +327,10 @@ class Server
*
* @param string $item Schema Item to Fetch
* @param string|null $key
- * @return ArrayCollection|Base
+ * @return Collection|Base|NULL
* @throws InvalidUsage
*/
- public function schema(string $item,string $key=NULL): ArrayCollection|Base|NULL
+ public function schema(string $item,string $key=NULL): Collection|Base|NULL
{
// Ensure our item to fetch is lower case
$item = strtolower($item);
@@ -215,8 +392,8 @@ class Server
}
// Try to get the schema DN from the specified entry.
- $schema_dn = Entry::schemaDN();
- $schema = (new Server)->fetch($schema_dn);
+ $schema_dn = $this->schemaDN();
+ $schema = $this->fetch($schema_dn);
switch ($item) {
case 'attributetypes':
diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php
index 4217c92..d1086e5 100644
--- a/app/Http/Controllers/HomeController.php
+++ b/app/Http/Controllers/HomeController.php
@@ -10,8 +10,8 @@ use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\File;
use LdapRecord\Query\ObjectNotFoundException;
-use App\Ldap\Entry;
use App\Classes\LDAP\Server;
+use App\Exceptions\InvalidUsage;
class HomeController extends Controller
{
@@ -30,7 +30,7 @@ class HomeController extends Controller
*/
public function home()
{
- $base = (new Entry)->baseDNs() ?: collect();
+ $base = Server::baseDNs() ?: collect();
return view('home')
->with('server',config('ldap.connections.default.name'))
@@ -53,34 +53,13 @@ class HomeController extends Controller
*/
public function info()
{
- $root = (new Entry)->rootDSE();
+ // Load our attributes
+ $s = new Server;
+ $s->schema('objectclasses');
+ $s->schema('attributetypes');
- try {
- $attrs = collect($root->getAttributes())
- ->transform(function($item) {
- foreach ($item as $k=>$v) {
- if (preg_match('/[0-9]+\.[0-9]+\.[0-9]+/',$v)) {
- $format = sprintf(
- '%s%s
%s
',
- $v,
- Server::getOID($v,'title'),
- ($x=Server::getOID($v,'ref')) ? sprintf('',$x) : '',
- Server::getOID($v,'desc'),
- );
- $item[$k] = $format;
- }
- }
- return $item;
- });
-
- // @todo If we cant get server info, we should probably show a nice error dialog
- } catch (ObjectNotFoundException $e) {
- $attrs = collect();
- }
-
- return view('frames.dn')
- ->with('o',$root)
- ->with('dn',__('Server Info'));
+ return view('frames.info')
+ ->with('s',$s);
}
/**
@@ -98,9 +77,25 @@ class HomeController extends Controller
->with('dn',$dn);
}
- public function schema_frame()
+ /**
+ * Show the Schema Viewer
+ *
+ * @note Our route will validate that types are valid.
+ * @param Request $request
+ * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View
+ * @throws InvalidUsage
+ */
+ public function schema_frame(Request $request)
{
- return view('frames.schema');
+ $s = new Server;
+
+ // If an invalid key, we'll 404
+ if ($request->type && $request->key && ($s->schema($request->type)->has($request->key) === FALSE))
+ abort(404);
+
+ return view('frames.schema')
+ ->with('type',$request->type)
+ ->with('key',$request->key);
}
/**
diff --git a/app/Ldap/Entry.php b/app/Ldap/Entry.php
index 76ba501..b05dfda 100644
--- a/app/Ldap/Entry.php
+++ b/app/Ldap/Entry.php
@@ -2,13 +2,8 @@
namespace App\Ldap;
-use Carbon\Carbon;
use Illuminate\Support\Arr;
-use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Config;
-use LdapRecord\LdapRecordException;
use LdapRecord\Models\Model;
-use LdapRecord\Query\ObjectNotFoundException;
use App\Classes\LDAP\Attribute\Factory;
@@ -26,171 +21,6 @@ class Entry extends Model
return $result->toArray();
}
- /* STATIC METHODS */
-
- /**
- * Gets the root DN of the specified LDAPServer, or throws an exception if it
- * can't find it.
- *
- * @param null $connection Return a collection of baseDNs
- * @param bool $objects Return a collection of Entry Models
- * @return Collection
- * @throws ObjectNotFoundException
- * @testedin GetBaseDNTest::testBaseDNExists();
- */
- public static function baseDNs($connection=NULL,bool $objects=TRUE): Collection
- {
- $cachetime = Carbon::now()->addSeconds(Config::get('ldap.cache.time'));
-
- try {
- $base = self::rootDSE($connection,$cachetime);
-
- /**
- * LDAP Error Codes:
- * https://ldap.com/ldap-result-code-reference/
- * + success 0
- * + operationsError 1
- * + protocolError 2
- * + timeLimitExceeded 3
- * + sizeLimitExceeded 4
- * + compareFalse 5
- * + compareTrue 6
- * + authMethodNotSupported 7
- * + strongerAuthRequired 8
- * + referral 10
- * + adminLimitExceeded 11
- * + unavailableCriticalExtension 12
- * + confidentialityRequired 13
- * + saslBindInProgress 14
- * + noSuchAttribute 16
- * + undefinedAttributeType 17
- * + inappropriateMatching 18
- * + constraintViolation 19
- * + attributeOrValueExists 20
- * + invalidAttributeSyntax 21
- * + noSuchObject 32
- * + aliasProblem 33
- * + invalidDNSyntax 34
- * + isLeaf 35
- * + aliasDereferencingProblem 36
- * + inappropriateAuthentication 48
- * + invalidCredentials 49
- * + insufficientAccessRights 50
- * + busy 51
- * + unavailable 52
- * + unwillingToPerform 53
- * + loopDetect 54
- * + sortControlMissing 60
- * + offsetRangeError 61
- * + namingViolation 64
- * + objectClassViolation 65
- * + notAllowedOnNonLeaf 66
- * + notAllowedOnRDN 67
- * + entryAlreadyExists 68
- * + objectClassModsProhibited 69
- * + resultsTooLarge 70
- * + affectsMultipleDSAs 71
- * + virtualListViewError or controlError 76
- * + other 80
- * + serverDown 81
- * + localError 82
- * + encodingError 83
- * + decodingError 84
- * + timeout 85
- * + authUnknown 86
- * + filterError 87
- * + userCanceled 88
- * + paramError 89
- * + noMemory 90
- * + connectError 91
- * + notSupported 92
- * + controlNotFound 93
- * + noResultsReturned 94
- * + moreResultsToReturn 95
- * + clientLoop 96
- * + referralLimitExceeded 97
- * + invalidResponse 100
- * + ambiguousResponse 101
- * + tlsNotSupported 112
- * + intermediateResponse 113
- * + unknownType 114
- * + canceled 118
- * + noSuchOperation 119
- * + tooLate 120
- * + cannotCancel 121
- * + assertionFailed 122
- * + authorizationDenied 123
- * + e-syncRefreshRequired 4096
- * + noOperation 16654
- *
- * LDAP Tag Codes:
- * + A client bind operation 97
- * + The entry for which you were searching 100
- * + The result from a search operation 101
- * + The result from a modify operation 103
- * + The result from an add operation 105
- * + The result from a delete operation 107
- * + The result from a modify DN operation 109
- * + The result from a compare operation 111
- * + A search reference when the entry you perform your search on holds a referral to the entry you require.
- * + Search references are expressed in terms of a referral.
- * 115
- * + A result from an extended operation 120
- */
- // If we cannot get to our LDAP server we'll head straight to the error page
- } catch (LdapRecordException $e) {
- switch ($e->getDetailedError()->getErrorCode()) {
- case 49:
- abort(401,$e->getDetailedError()->getErrorMessage());
-
- default:
- abort(597,$e->getDetailedError()->getErrorMessage());
- }
- }
-
- if (! $objects)
- return collect($base->namingcontexts);
-
- /**
- * @note While we are caching our baseDNs, it seems if we have more than 1,
- * our caching doesnt generate a hit on a subsequent call to this function (before the cache expires).
- * IE: If we have 5 baseDNs, it takes 5 calls to this function to case them all.
- * @todo Possibly a bug wtih ldaprecord, so need to investigate
- */
- $result = collect();
- foreach ($base->namingcontexts as $dn) {
- $result->push((new self)->cache($cachetime)->findOrFail($dn));
- }
-
- return $result;
- }
-
- /**
- * Obtain the rootDSE for the server, that gives us server information
- *
- * @param null $connection
- * @return Entry|null
- * @throws ObjectNotFoundException
- * @testedin TranslateOidTest::testRootDSE();
- */
- public static function rootDSE($connection=NULL,Carbon $cachetime=NULL): ?Model
- {
- return static::on($connection ?? (new static)->getConnectionName())
- ->cache($cachetime)
- ->in(NULL)
- ->read()
- ->select(['+'])
- ->whereHas('objectclass')
- ->firstOrFail();
- }
-
- public static function schemaDN($connection = NULL): string
- {
- $cachetime = Carbon::now()->addSeconds(Config::get('ldap.cache.time'));
-
- return collect(self::rootDSE($connection,$cachetime)->subschemasubentry)->first();
- }
-
/* ATTRIBUTES */
/**
diff --git a/app/Ldap/LdapUserRepository.php b/app/Ldap/LdapUserRepository.php
index 990a00a..ced1017 100644
--- a/app/Ldap/LdapUserRepository.php
+++ b/app/Ldap/LdapUserRepository.php
@@ -8,6 +8,8 @@ use LdapRecord\Laravel\Events\Auth\DiscoveredWithCredentials;
use LdapRecord\Laravel\LdapUserRepository as LdapUserRepositoryBase;
use LdapRecord\Models\Model;
+use App\Classes\LDAP\Server;
+
class LdapUserRepository extends LdapUserRepositoryBase
{
/**
@@ -25,7 +27,7 @@ class LdapUserRepository extends LdapUserRepositoryBase
}
// Look for a user using all our baseDNs
- foreach ((new Entry)->baseDNs() as $base) {
+ foreach (Server::baseDNs() as $base) {
$query = $this->query()->setBaseDn($base);
foreach ($credentials as $key => $value) {
@@ -61,7 +63,7 @@ class LdapUserRepository extends LdapUserRepositoryBase
public function findByGuid($guid): ?Model
{
// Look for a user using all our baseDNs
- foreach ((new Entry)->baseDNs() as $base) {
+ foreach (Server::baseDNs() as $base) {
$user = $this->query()->setBaseDn($base)->findByGuid($guid);
if ($user)
diff --git a/resources/views/debug.blade.php b/resources/views/debug.blade.php
index 04e1116..7032089 100644
--- a/resources/views/debug.blade.php
+++ b/resources/views/debug.blade.php
@@ -24,7 +24,7 @@
BaseDN(s) |
- @foreach(\App\Ldap\Entry::baseDNs()->sort(function($item) { return $item->sortKey; }) as $item)
+ @foreach(\App\Classes\LDAP\Server::baseDNs()->sort(function($item) { return $item->sortKey; }) as $item)
{{ $item->getDn() }} |
@@ -36,7 +36,7 @@
Schema DN |
- {{ \App\Ldap\Entry::schemaDN() }} |
+ {{ \App\Classes\LDAP\Server::schemaDN() }} |
diff --git a/resources/views/frames/dn.blade.php b/resources/views/frames/dn.blade.php
index 8cfb191..9a474a9 100644
--- a/resources/views/frames/dn.blade.php
+++ b/resources/views/frames/dn.blade.php
@@ -14,7 +14,7 @@
@foreach ($o->getAttributes() as $attribute => $value)
- {{ $attribute }} |
+ {{ $attribute }} |
{!! $value !!} |
@endforeach
diff --git a/resources/views/frames/info.blade.php b/resources/views/frames/info.blade.php
new file mode 100644
index 0000000..b8d7e4b
--- /dev/null
+++ b/resources/views/frames/info.blade.php
@@ -0,0 +1,27 @@
+@extends('layouts.dn')
+
+@section('page_title')
+
+
+
|
+ {{ __('Server Info') }} {{ $s->rootDSE()->entryuuid[0] ?? '' }} |
+
+
+@endsection
+
+@section('main-content')
+
+
+ @foreach ($s->rootDSE()->getAttributes() as $attribute => $value)
+
+
+ {!! ($x=$s->schema('attributetypes',$attribute))
+ ? sprintf('%s',$x->name_lc,url('schema/attributetypes',$x->name_lc),$x->name)
+ : $attribute !!}
+ |
+ {!! $value !!} |
+
+ @endforeach
+
+
+@endsection
\ No newline at end of file
diff --git a/resources/views/frames/schema.blade.php b/resources/views/frames/schema.blade.php
index 012023b..5279ad7 100644
--- a/resources/views/frames/schema.blade.php
+++ b/resources/views/frames/schema.blade.php
@@ -4,7 +4,7 @@
|
- {{ \App\Ldap\Entry::schemaDN() }} {{ $o->entryuuid[0] ?? '' }} |
+ {{ \App\Classes\LDAP\Server::schemaDN() }} |
@endsection
diff --git a/tests/Unit/GetBaseDNTest.php b/tests/Unit/GetBaseDNTest.php
index d7ceffd..defd6fa 100644
--- a/tests/Unit/GetBaseDNTest.php
+++ b/tests/Unit/GetBaseDNTest.php
@@ -4,7 +4,7 @@ namespace Tests\Unit;
use Tests\TestCase;
-use App\Ldap\Entry;
+use App\Classes\LDAP\Server;
class GetBaseDNTest extends TestCase
{
@@ -13,11 +13,11 @@ class GetBaseDNTest extends TestCase
*
* @return void
* @throws \LdapRecord\Query\ObjectNotFoundException
- * @covers \App\Ldap\Entry::baseDNs()
+ * @covers \App\Classes\LDAP\Server::baseDNs()
*/
public function testBaseDnExists()
{
- $o = (new Entry)->baseDNs();
+ $o = Server::baseDNs();
$this->assertIsObject($o);
$this->assertCount(6,$o->toArray());
diff --git a/tests/Unit/TranslateOidTest.php b/tests/Unit/TranslateOidTest.php
index 4dca3b5..ef43c68 100644
--- a/tests/Unit/TranslateOidTest.php
+++ b/tests/Unit/TranslateOidTest.php
@@ -2,10 +2,10 @@
namespace Tests\Unit;
+use LdapRecord\Query\ObjectNotFoundException;
use Tests\TestCase;
use App\Classes\LDAP\Server;
-use App\Ldap\Entry;
class TranslateOidTest extends TestCase
{
@@ -13,12 +13,12 @@ class TranslateOidTest extends TestCase
* A basic feature test example.
*
* @return void
- * @throws \LdapRecord\Query\ObjectNotFoundException
* @covers \App\Classes\LDAP\Server::getOID()
+ * @throws ObjectNotFoundException
*/
public function testRootDse()
{
- $dse = (new Entry)->rootDSE();
+ $dse = Server::rootDSE();
// Test our rootDSE returns an objectclass attribute
$this->assertIsArray($dse->objectclass);
|