Compare commits
3 Commits
21b2d18f5f
...
89d414ccd9
Author | SHA1 | Date | |
---|---|---|---|
89d414ccd9 | |||
ffb98631a6 | |||
be69e22867 |
@ -3,7 +3,7 @@ run-name: ${{ gitea.actor }} Building Docker Image 🐳
|
|||||||
on: [push]
|
on: [push]
|
||||||
env:
|
env:
|
||||||
DOCKER_HOST: tcp://127.0.0.1:2375
|
DOCKER_HOST: tcp://127.0.0.1:2375
|
||||||
ASSETS: c2780a3
|
ASSETS: 10eca55
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
|
59
app/Http/Controllers/SearchController.php
Normal file
59
app/Http/Controllers/SearchController.php
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
use Illuminate\Support\Facades\Crypt;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
use App\Ldap\Entry;
|
||||||
|
|
||||||
|
class SearchController extends Controller
|
||||||
|
{
|
||||||
|
public function search(Request $request): Collection
|
||||||
|
{
|
||||||
|
$so = config('server');
|
||||||
|
|
||||||
|
// We are searching for a value
|
||||||
|
if (strpos($request->term,'=')) {
|
||||||
|
list($attr,$value) = explode('=',$request->term,2);
|
||||||
|
$value = trim($value);
|
||||||
|
|
||||||
|
$result = collect();
|
||||||
|
|
||||||
|
foreach ($so->baseDNs() as $base) {
|
||||||
|
$search = (new Entry)
|
||||||
|
->in($base);
|
||||||
|
|
||||||
|
$search = ($x=Str::startsWith($value,'*'))
|
||||||
|
? $search->whereEndsWith($attr,substr($value,1))
|
||||||
|
: $search->whereStartsWith($attr,$value);
|
||||||
|
|
||||||
|
$result = $result->merge($search->get());
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result
|
||||||
|
->map(fn($item)=>[
|
||||||
|
'name'=>$item->getDN(),
|
||||||
|
'value'=>Crypt::encryptString($item->getDN()),
|
||||||
|
'category'=>sprintf('%s: [%s=%s%s]',__('Result'),$attr,$value,($x ? '' : '*'))
|
||||||
|
]);
|
||||||
|
|
||||||
|
// We are searching for an attribute
|
||||||
|
} else {
|
||||||
|
$attrs = $so
|
||||||
|
->schema('attributetypes')
|
||||||
|
->sortBy('name')
|
||||||
|
->filter(fn($item)=>Str::contains($item->name_lc,$request->term));
|
||||||
|
|
||||||
|
return $attrs
|
||||||
|
->map(fn($item)=>[
|
||||||
|
'name'=>$item->name,
|
||||||
|
'value'=>'',
|
||||||
|
'category'=>__('Select attribute...')
|
||||||
|
])
|
||||||
|
->values();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1 +1 @@
|
|||||||
v2.1.2-rel
|
v2.1.3-dev
|
||||||
|
@ -33,8 +33,12 @@
|
|||||||
<div class="app-header-left">
|
<div class="app-header-left">
|
||||||
<div class="search-wrapper">
|
<div class="search-wrapper">
|
||||||
<div class="input-holder">
|
<div class="input-holder">
|
||||||
<input type="text" class="search-input" placeholder="Type to search">
|
<input type="text" class="search-input" id="search" placeholder="Type to search">
|
||||||
<button class="search-icon"><span></span></button>
|
<button class="search-icon">
|
||||||
|
<span></span>
|
||||||
|
<div id="searching" class="d-none"><i class="fas fa-fw fa-spinner fa-pulse text-light"></i></div>
|
||||||
|
</button>
|
||||||
|
<div id="search_results" style="height: 300px; overflow: scroll"></div>
|
||||||
</div>
|
</div>
|
||||||
<button class="btn-close"></button>
|
<button class="btn-close"></button>
|
||||||
</div>
|
</div>
|
||||||
@ -160,6 +164,13 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
@section('page-scripts')
|
@section('page-scripts')
|
||||||
|
<style>
|
||||||
|
#search_results ul.typeahead.dropdown-menu {
|
||||||
|
overflow: scroll;
|
||||||
|
max-height: 300px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
$('button[id^="link-"]').on('click',function(item) {
|
$('button[id^="link-"]').on('click',function(item) {
|
||||||
@ -190,6 +201,70 @@
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('.search-wrapper input[id="search"]').typeahead({
|
||||||
|
autoSelect: false,
|
||||||
|
scrollHeight: 10,
|
||||||
|
theme: 'bootstrap5',
|
||||||
|
delay: 500,
|
||||||
|
minLength: 2,
|
||||||
|
items: {{ $search_limit ?? 100 }},
|
||||||
|
selectOnBlur: false,
|
||||||
|
appendTo: "#search_results",
|
||||||
|
source: function(query,process) {
|
||||||
|
search('{{ url('search') }}',query,process);
|
||||||
|
},
|
||||||
|
// Disable sorting and just return the items (items should be sorted by the ajax method)
|
||||||
|
sorter: function(items) {
|
||||||
|
return items;
|
||||||
|
},
|
||||||
|
matcher: function() { return true; },
|
||||||
|
// Disable sorting and just return the items (items should by the ajax method)
|
||||||
|
updater: function(item) {
|
||||||
|
// If item has a data value, then we'll use that
|
||||||
|
if (item.data && item.data.length)
|
||||||
|
return item.data;
|
||||||
|
|
||||||
|
if (! item.value)
|
||||||
|
return item.name+'=';
|
||||||
|
|
||||||
|
location.replace('/#'+item.value);
|
||||||
|
location.reload();
|
||||||
|
return '';
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.on('keyup keypress',function(event) {
|
||||||
|
var key = event.keyCode || event.which;
|
||||||
|
if (key === 13) {
|
||||||
|
event.preventDefault();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var search = _.debounce(function(url,query,process){
|
||||||
|
$.ajax({
|
||||||
|
url : url,
|
||||||
|
type : 'POST',
|
||||||
|
data : 'term=' + query,
|
||||||
|
dataType : 'JSON',
|
||||||
|
async : true,
|
||||||
|
cache : false,
|
||||||
|
beforeSend : function() {
|
||||||
|
$('.search-wrapper div#searching').removeClass('d-none');
|
||||||
|
$('.search-wrapper .search-icon span').addClass('d-none');
|
||||||
|
},
|
||||||
|
success : function(data) {
|
||||||
|
// if json is null, means no match, won't do again.
|
||||||
|
if(data==null || (data.length===0)) return;
|
||||||
|
|
||||||
|
process(data);
|
||||||
|
},
|
||||||
|
complete : function() {
|
||||||
|
$('.search-wrapper div#searching').addClass('d-none');
|
||||||
|
$('.search-wrapper .search-icon span').removeClass('d-none');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}, 500);
|
||||||
</script>
|
</script>
|
||||||
@append
|
@append
|
@ -23,18 +23,51 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-12 col-sm-8">
|
<div class="col-12 col-sm-8">
|
||||||
<h3 class="mb-1">Welcome to phpLDAPadmin</h3>
|
<h1 class="mb-2">Welcome to phpLDAPadmin</h1>
|
||||||
<h4 class="mb-3"><small>{{ config('app.version') }}</small></h4>
|
<p>phpLDAPadmin (or PLA for short) is an LDAP (Lightweight Directory Access Protocol) data management tool for administrators.</p>
|
||||||
<p>phpLDAPadmin (or PLA for short) is an LDAP data management tool for administrators.</p>
|
<p>PLA provides an easy-to-use interface for browsing, searching, and modifying data in an LDAP directory. Essentially, it's a user-friendly alternative to using command-line tools for LDAP management.</p>
|
||||||
<p>PLA aims to adhere to the LDAP standards so that it can interact with any LDAP server that implements those standards.</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<hr>
|
<hr>
|
||||||
<p>Version 2 is a complete re-write of PLA, leveraging the advancements and modernisation of web tools and methods, libraries since version 1 was released.</p>
|
</div>
|
||||||
<p>You can support this application by letting us know which LDAP server you use (including version and platform).</p>
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12 col-sm-4">
|
||||||
|
<span class="text-dark">
|
||||||
|
<a class="link-opacity-50 link-opacity-100-hover link-dark" href="https://phpldapadmin.org"><i class="fas fa-fw fa-2x fa-globe me-1"></i></a>
|
||||||
|
<a class="link-opacity-50 link-opacity-100-hover link-dark" href="https://github.com/leenooks/phpldapadmin"><i class="fab fa-fw fa-2x fa-github me-1"></i></a>
|
||||||
|
<a class="link-opacity-50 link-opacity-100-hover link-dark" href="https://github.com/leenooks/phpLDAPadmin/discussions"><i class="fas fa-fw fa-2x fa-hand me-1"></i></a>
|
||||||
|
<a class="link-opacity-50 link-opacity-100-hover link-dark" href="https://github.com/leenooks/phpLDAPadmin/issues"><i class="fas fa-fw fa-2x fa-bug me-1"></i></a>
|
||||||
|
<a class="link-opacity-50 link-opacity-100-hover link-dark" href="https://hub.docker.com/r/phpldapadmin/phpldapadmin"><i class="fab fa-fw fa-2x fa-docker me-1"></i></a>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-12 col-sm-8 col-xl-4">
|
||||||
|
<h5>Key Features and Functionality</h5>
|
||||||
|
<ul class="list-unstyled">
|
||||||
|
<li class="ps-0 p-1">
|
||||||
|
<i class="fas fa-fw fa-globe me-2"></i> Easy To Use Web Interface
|
||||||
|
</li>
|
||||||
|
<li class="ps-0 p-1">
|
||||||
|
<i class="fas fa-fw fa-sitemap me-2"></i> Hierarchical Tree View
|
||||||
|
</li>
|
||||||
|
<li class="ps-0 p-1">
|
||||||
|
<i class="fas fa-fw fa-language me-2"></i> Multi-language Support
|
||||||
|
</li>
|
||||||
|
<li class="ps-0 p-1">
|
||||||
|
<i class="fas fa-fw fa-file-export me-2"></i> LDIF Import/Export
|
||||||
|
</li>
|
||||||
|
<li class="ps-0 p-1">
|
||||||
|
<i class="fas fa-fw fa-clipboard-list me-2"></i> Build on RFC Standards
|
||||||
|
</li>
|
||||||
|
<li class="ps-0 p-1">
|
||||||
|
<i class="fas fa-fw fa-pen-to-square me-2"></i> Open Source
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
|
|
||||||
use App\Http\Controllers\{AjaxController,HomeController};
|
use App\Http\Controllers\{AjaxController,HomeController,SearchController};
|
||||||
use App\Http\Controllers\Auth\LoginController;
|
use App\Http\Controllers\Auth\LoginController;
|
||||||
use App\Http\Middleware\AllowAnonymous;
|
use App\Http\Middleware\AllowAnonymous;
|
||||||
|
|
||||||
@ -27,6 +27,7 @@ Auth::routes([
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
Route::get('logout',[LoginController::class,'logout']);
|
Route::get('logout',[LoginController::class,'logout']);
|
||||||
|
Route::post('search',[SearchController::class,'search']);
|
||||||
|
|
||||||
Route::controller(HomeController::class)->group(function() {
|
Route::controller(HomeController::class)->group(function() {
|
||||||
Route::middleware(AllowAnonymous::class)->group(function() {
|
Route::middleware(AllowAnonymous::class)->group(function() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user