Compare commits

...

5 Commits

Author SHA1 Message Date
b1d153aa9f Change Attribute/UserCertificate into Syntax/Certificate for any Certificate attributes. Add Syntax/CertificateList.
All checks were successful
Create Docker Image / Test Application (x86_64) (push) Successful in 29s
Create Docker Image / Build Docker Image (x86_64) (push) Successful in 1m30s
Create Docker Image / Build Docker Image (arm64) (push) Successful in 4m34s
Create Docker Image / Final Docker Image Manifest (push) Successful in 8s
2025-04-11 08:55:32 +10:00
8b0af505a1 When viewing the schema, highlight Structural and non-Structural classes
Some checks failed
Create Docker Image / Test Application (x86_64) (push) Has been cancelled
Create Docker Image / Build Docker Image (arm64) (push) Has been cancelled
Create Docker Image / Build Docker Image (x86_64) (push) Has been cancelled
Create Docker Image / Final Docker Image Manifest (push) Has been cancelled
2025-04-11 08:55:32 +10:00
f0eaff7d42 Removing debugging that made it into LDIF import 2025-04-11 08:55:32 +10:00
352bbe2b75 Capture PLA version when submitting a bug report 2025-04-11 08:50:31 +10:00
0fe4894192 Create config.yml to disable blank issues reporting 2025-04-11 08:43:37 +10:00
12 changed files with 93 additions and 40 deletions

View File

@ -10,6 +10,9 @@ assignees: ''
**Describe the bug**
A clear and concise description of what the bug is. (One issue per report please.)
**Version of PLA**
What version of PLA are you using. Are you using the docker container, an distribution package or running from GIT source?
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'

1
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@ -0,0 +1 @@
blank_issues_enabled: false

View File

@ -37,6 +37,9 @@ class Attribute implements \Countable, \ArrayAccess
// The objectclasses of the entry that has this attribute
protected(set) Collection $oc;
private const SYNTAX_CERTIFICATE = '1.3.6.1.4.1.1466.115.121.1.8';
private const SYNTAX_CERTIFICATE_LIST = '1.3.6.1.4.1.1466.115.121.1.9';
/*
# Has the attribute been modified
protected $modified = false;
@ -123,6 +126,11 @@ class Attribute implements \Countable, \ArrayAccess
*/
}
public function __call(string $name,array $arguments)
{
abort(555,'Method not handled: '.$name);
}
public function __get(string $key): mixed
{
return match ($key) {
@ -303,9 +311,14 @@ class Attribute implements \Countable, \ArrayAccess
*/
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE): View
{
$view = view()->exists($x='components.attribute.'.$this->name_lc)
? view($x)
: view('components.attribute');
$view = match ($this->schema->syntax_oid) {
self::SYNTAX_CERTIFICATE => view('components.syntax.certificate'),
self::SYNTAX_CERTIFICATE_LIST => view('components.syntax.certificatelist'),
default => view()->exists($x = 'components.attribute.' . $this->name_lc)
? view($x)
: view('components.attribute'),
};
return $view
->with('o',$this)
@ -316,7 +329,12 @@ class Attribute implements \Countable, \ArrayAccess
public function render_item_old(string $dotkey): ?string
{
return Arr::get($this->values_old->dot(),$dotkey);
return match ($this->schema->syntax_oid) {
self::SYNTAX_CERTIFICATE => join("\n",str_split(base64_encode(Arr::get($this->values_old->dot(),$dotkey)),80)),
self::SYNTAX_CERTIFICATE_LIST => join("\n",str_split(base64_encode(Arr::get($this->values_old->dot(),$dotkey)),80)),
default => Arr::get($this->values_old->dot(),$dotkey),
};
}
public function render_item_new(string $dotkey): ?string

View File

@ -11,7 +11,7 @@ use App\Traits\MD5Updates;
/**
* Represents an attribute whose values is a binary user certificate
*/
final class UserCertificate extends Attribute
final class Certificate extends Attribute
{
use MD5Updates;
@ -38,11 +38,6 @@ final class UserCertificate extends Attribute
return Carbon::createFromTimestampUTC($this->cert_info('validTo_time_t',$key));
}
public function render_item_old(string $dotkey): ?string
{
return join("\n",str_split(base64_encode(parent::render_item_old($dotkey)),80));
}
public function subject($key=0): string
{
$subject = collect($this->cert_info('subject',$key))->reverse();

View File

@ -0,0 +1,17 @@
<?php
namespace App\Classes\LDAP\Attribute;
use Carbon\Carbon;
use Illuminate\Support\Arr;
use App\Classes\LDAP\Attribute;
use App\Traits\MD5Updates;
/**
* Represents an attribute whose values is a binary user certificate
*/
final class CertificateList extends Attribute
{
use MD5Updates;
}

View File

@ -20,6 +20,9 @@ class Factory
* Map of attributes to appropriate class
*/
public const map = [
'authorityrevocationlist' => CertificateList::class,
'cacertificate' => Certificate::class,
'certificaterevocationlist' => CertificateList::class,
'createtimestamp' => Internal\Timestamp::class,
'creatorsname' => Internal\DN::class,
'configcontext' => Schema\Generic::class,
@ -52,7 +55,7 @@ class Factory
'supportedfeatures' => Schema\OID::class,
'supportedldapversion' => Schema\Generic::class,
'supportedsaslmechanisms' => Schema\Mechanisms::class,
'usercertificate' => UserCertificate::class,
'usercertificate' => Certificate::class,
'userpassword' => Password::class,
];

View File

@ -66,7 +66,6 @@ class LDIF extends Import
$m = [];
preg_match('/^([a-zA-Z0-9;-]+)(:+)\s+(.*)$/',$line,$m);
dump(['m'=>$m,'line'=>$line]);
switch (Arr::get($m,1)) {
case 'changetype':

2
public/js/custom.js vendored
View File

@ -44,8 +44,10 @@ function getNode(item) {
location.reload();
break;
case 500:
case 555: // Missing Method
$('.main-content').empty().append(e.responseText);
break;
default:
alert('Well that didnt work? Code ['+e.status+']');
}

View File

@ -1,12 +1,29 @@
@use(App\Classes\LDAP\Attribute\Certificate)
@use(App\Classes\LDAP\Attribute\CertificateList)
@use(App\Classes\LDAP\Attribute\Binary\JpegPhoto)
@use(App\Classes\LDAP\Attribute\ObjectClass)
@use(App\Classes\LDAP\Attribute\UserCertificate)
@php($clone=FALSE)
<span class="p-0 m-0">
@if($o->is_rdn)
<button class="btn btn-sm btn-outline-focus mt-3" disabled><i class="fas fa-fw fa-exchange"></i> @lang('Rename')</button>
@elseif($edit && $o->can_addvalues)
@switch(get_class($o))
@case(Certificate::class)
@case(CertificateList::class)
<span @class(['btn','btn-sm','btn-outline-primary','mt-3','addable','d-none'=>(! $new)]) id="{{ $o->name }}-replace" disabled><i class="fas fa-fw fa-certificate"></i> @lang('Replace')</span>
@section('page-scripts')
<script type="text/javascript">
$(document).ready(function() {
$('#{{ $o->name }}-replace.addable').click(function(e) {
alert('Sorry, not implemented yet');
e.preventDefault();
return false;
});
});
</script>
@append
@break
@case(ObjectClass::class)
<span type="button" @class(['btn','btn-sm','btn-outline-primary','mt-3','addable','d-none'=>(! $new)]) data-bs-toggle="modal" data-bs-target="#new_objectclass-modal"><i class="fas fa-fw fa-plus"></i> @lang('Add Objectclass')</span>
@ -230,21 +247,6 @@
@append
@break
@case(UserCertificate::class)
<span @class(['btn','btn-sm','btn-outline-primary','mt-3','addable','d-none'=>(! $new)]) id="{{ $o->name }}-replace" disabled><i class="fas fa-fw fa-certificate"></i> @lang('Replace Certificate')</span>
@section('page-scripts')
<script type="text/javascript">
$(document).ready(function() {
$('#{{ $o->name }}-replace.addable').click(function(e) {
alert('Sorry, not implemented yet');
e.preventDefault();
return false;
});
});
</script>
@append
@break
<!-- All other attributes -->
@default
@if($o->isDynamic()) @break @endif

View File

@ -1,7 +1,10 @@
<!-- $o=UserCertificate::class -->
@use(App\Classes\LDAP\Attribute\Certificate)
<!-- $o=Certificate::class -->
<x-attribute.layout :edit="$edit" :new="$new" :o="$o" langtag="binary">
@foreach($o->tagValuesOld('binary') as $key => $value)
@if($edit)
<!-- If this attribute is not handle, it'll be an Attribute::class, we'll just render it normally -->
@if(($o instanceof Certificate) && $edit)
<input type="hidden" name="name={{ $o->name_lc }}[binary][]" value="{{ md5($value) }}">
<div class="input-group has-validation mb-3">

View File

@ -0,0 +1,7 @@
<!-- $o=CertificateList::class -->
<x-attribute.layout :edit="$edit" :new="$new" :o="$o" langtag="binary">
@foreach($o->tagValuesOld('binary') as $key => $value)
<!-- If this attribute is not handle, it'll be an Attribute::class, we'll just render it normally -->
<span class="form-control mb-1"><pre class="m-0">{{ $o->render_item_old('binary.'.$key) }}</pre></span>
@endforeach
</x-attribute.layout>

View File

@ -2,14 +2,17 @@
<div class="col-12 col-xl-3">
<select id="objectclass" class="form-control">
<option value="-all-">-all-</option>
@foreach ($objectclasses as $o)
<option value="{{ $o->name_lc }}">{{ $o->name }}</option>
@foreach($objectclasses->groupBy(fn($item)=>$item->isStructural()) as $oo)
<optgroup label="{{ __($oo->first()->isStructural() ? 'Structural' : 'Auxillary') }} Object Class"></optgroup>
@foreach($oo as $o)
<option value="{{ $o->name_lc }}">{{ $o->name }}</option>
@endforeach
@endforeach
</select>
</div>
<div class="col-12 col-xl-9">
@foreach ($objectclasses as $o)
@foreach($objectclasses as $o)
<span id="oc-{{ $o->name_lc }}">
<table class="schema table table-sm table-bordered table-striped">
<thead>
@ -32,10 +35,10 @@
<td>@lang('Inherits from')</td>
<td colspan="3">
<strong>
@if ($o->sup->count() === 0)
@if($o->sup->count() === 0)
@lang('(none)')
@else
@foreach ($o->sup as $sup)
@foreach($o->sup as $sup)
@if($loop->index)</strong> <strong>@endif
<a class="objectclass" id="{{ strtolower($sup) }}" href="#{{ strtolower($sup) }}">{{ $sup }}</a>
@endforeach
@ -48,12 +51,12 @@
<td>@lang('Parent to')</td>
<td colspan="3">
<strong>
@if (strtolower($o->name) === 'top')
@if(strtolower($o->name) === 'top')
<a class="objectclass" id="-all-">(all)</a>
@elseif (! $o->getChildObjectClasses()->count())
@elseif(! $o->getChildObjectClasses()->count())
@lang('(none)')
@else
@foreach ($o->getChildObjectClasses() as $childoc)
@foreach($o->getChildObjectClasses() as $childoc)
@if($loop->index)</strong> <strong>@endif
<a class="objectclass" id="{{ strtolower($childoc) }}" href="#{{ strtolower($childoc) }}">{{ $childoc }}</a>
@endforeach
@ -75,7 +78,7 @@
<tr>
<td>
<ul class="ps-3" style="list-style-type: square;">
@foreach ($o->getMustAttrs(TRUE) as $oo)
@foreach($o->getMustAttrs(TRUE) as $oo)
<li>{{ $oo->name }} @if($oo->source !== $o->name)[<strong><a class="objectclass" id="{{ strtolower($oo->source) }}" href="#{{ strtolower($oo->source) }}">{{ $oo->source }}</a></strong>]@endif</li>
@endforeach
</ul>
@ -97,7 +100,7 @@
<tr>
<td>
<ul class="ps-3" style="list-style-type: square;">
@foreach ($o->getMayAttrs(TRUE) as $oo)
@foreach($o->getMayAttrs(TRUE) as $oo)
<li>{{ $oo->name }} @if($oo->source !== $o->name)[<strong><a class="objectclass" id="{{ strtolower($oo->source) }}" href="#{{ strtolower($oo->source) }}">{{ $oo->source }}</a></strong>]@endif</li>
@endforeach
</ul>