Commit af9fc674 authored by Côme Chilliet's avatar Côme Chilliet
Browse files

feat(ldap) Add OID, GeneralizedTime and autoload

Move OID lists to from ldap-config-manager to the library.

Move LdapGeneralizedTime to Ldap\GeneralizedTime.

Add an autoload.php file allowing to easily use the library without
 composer.

issue #1
parent 95ec8fc6
Pipeline #8906 failed with stages
in 45 seconds
<?php
/*
This code is part of FusionDirectory (http://www.fusiondirectory.org/)
Copyright (C) 2020 FusionDirectory
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/*! \class LdapGeneralizedTime
\brief LdapGeneralizedTime allows you to convert from and to LDAP GeneralizedTime format PHP DateTime objects
This class provides function to convert from LDAP GeneralizedTime to DateTime and the other way.
Please note that leap seconds will be lost as PHP has no support for it (see https://bugs.php.net/bug.php?id=70335). 01:60 will become 02:00.
Also, this class does not support fraction of hours or fraction of minutes (fraction of seconds are supported).
*/
declare(strict_types=1);
namespace FusionDirectory\Ldap;
use DateTime, DateTimeZone;
class GeneralizedTime
{
/**
* @brief Convert from LDAP GeneralizedTime formatted string to DateTime object
* @param string $string GeneralizedTime formatted string to convert
*/
public static function fromString (string $string): DateTime
{
// century = 2(%x30-39) ; "00" to "99"
// year = 2(%x30-39) ; "00" to "99"
$year = '(?P<year>\d{4})';
// month = ( %x30 %x31-39 ) ; "01" (January) to "09"
// / ( %x31 %x30-32 ) ; "10" to "12"
$month = '(?P<month>0[1-9]|1[0-2])';
// day = ( %x30 %x31-39 ) ; "01" to "09"
// / ( %x31-32 %x30-39 ) ; "10" to "29"
// / ( %x33 %x30-31 ) ; "30" to "31"
$day = '(?P<day>0[1-9]|[0-2]\d|3[01])';
// hour = ( %x30-31 %x30-39 ) / ( %x32 %x30-33 ) ; "00" to "23"
$hour = '(?P<hour>[0-1]\d|2[0-3])';
// minute = %x30-35 %x30-39 ; "00" to "59"
$minute = '(?P<minute>[0-5]\d)';
// second = ( %x30-35 %x30-39 ) ; "00" to "59"
// leap-second = ( %x36 %x30 ) ; "60"
$second = '(?P<second>[0-5]\d|60)';
// fraction = ( DOT / COMMA ) 1*(%x30-39)
$fraction = '([.,](?P<fraction>\d+))';
// g-time-zone = %x5A ; "Z"
// / g-differential
// g-differential = ( MINUS / PLUS ) hour [ minute ]
$timezone = '(?P<timezone>Z|[-+]([0-1]\d|2[0-3])([0-5]\d)?)';
// GeneralizedTime = century year month day hour
// [ minute [ second / leap-second ] ]
// [ fraction ]
// g-time-zone
$pattern = '/^'.
"$year$month$day$hour".
"($minute$second?)?".
"$fraction?".
$timezone.
'$/';
if (preg_match($pattern, $string, $m)) {
if (empty($m['minute'])) {
$m['minute'] = '00';
}
if (empty($m['second'])) {
$m['second'] = '00';
}
if (empty($m['fraction'])) {
$m['fraction'] = '0';
}
$date = new DateTime($m['year'].'-'.$m['month'].'-'.$m['day'].'T'.$m['hour'].':'.$m['minute'].':'.$m['second'].'.'.$m['fraction'].$m['timezone']);
$date->setTimezone(new DateTimeZone('UTC'));
return $date;
} else {
throw new Exception("$string does not match LDAP GeneralizedTime format");
}
}
/**
* @brief Convert from DateTime object to LDAP GeneralizedTime formatted string
* @param DateTime $date DateTime object to convert
* @param boolean $setToUTC Whether or not to set the date timezone to UTC. Defaults to TRUE.
*/
public static function toString (DateTime $date, bool $setToUTC = TRUE): string
{
if ($setToUTC) {
$date->setTimezone(new DateTimeZone('UTC'));
}
$fraction = preg_replace('/0+$/', '', $date->format('u'));
$string = $date->format('YmdHis');
if (empty($fraction)) {
return preg_replace('/(00){1,2}$/', '', $string).'Z';
} else {
return $string.'.'.$fraction.'Z';
}
}
}
<?php
/*
This code is part of FusionDirectory (http://www.fusiondirectory.org/)
Copyright (C) 2020 FusionDirectory
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
declare(strict_types=1);
namespace FusionDirectory\Ldap;
class OID
{
public const CONTROLS = [
LDAP_CONTROL_MANAGEDSAIT => [
'desc' => 'Manage DSA IT',
'rfc' => 3296,
],
LDAP_CONTROL_PROXY_AUTHZ => [
'desc' => 'Proxied Authorization',
'rfc' => 4370,
],
LDAP_CONTROL_SUBENTRIES => [
'desc' => 'Subentries',
'rfc' => 3672,
],
LDAP_CONTROL_VALUESRETURNFILTER => [
'desc' => 'Filter returned values',
'rfc' => 3876,
],
LDAP_CONTROL_ASSERT => [
'desc' => 'Assertion',
'rfc' => 4528,
],
LDAP_CONTROL_PRE_READ => [
'desc' => 'Pre read',
'rfc' => 4527,
],
LDAP_CONTROL_POST_READ => [
'desc' => 'Post read',
'rfc' => 4527,
],
LDAP_CONTROL_SORTREQUEST => [
'desc' => 'Sort request',
'rfc' => 2891,
],
LDAP_CONTROL_SORTRESPONSE => [
'desc' => 'Sort response',
'rfc' => 2891,
],
LDAP_CONTROL_PAGEDRESULTS => [
'desc' => 'Paged results',
'rfc' => 2696,
],
'2.16.840.1.113730.3.4.16' => [
'desc' => 'Authorization Identity Request',
'rfc' => 3829,
],
'2.16.840.1.113730.3.4.15' => [
'desc' => 'Authorization Identity Response',
'rfc' => 3829,
],
LDAP_CONTROL_SYNC => [
'desc' => 'Content Synchronization Operation',
'rfc' => 4533,
],
LDAP_CONTROL_SYNC_STATE => [
'desc' => 'Content Synchronization Operation State',
'rfc' => 4533,
],
LDAP_CONTROL_SYNC_DONE => [
'desc' => 'Content Synchronization Operation Done',
'rfc' => 4533,
],
LDAP_CONTROL_DONTUSECOPY => [
'desc' => 'Don\'t Use Copy',
'rfc' => 6171,
],
/* LDAP_CONTROL_PASSWORDPOLICYREQUEST and LDAP_CONTROL_PASSWORDPOLICYRESPONSE are the same */
LDAP_CONTROL_PASSWORDPOLICYREQUEST => [
'desc' => 'Password Policy',
],
LDAP_CONTROL_X_INCREMENTAL_VALUES => [
'desc' => 'Active Directory Incremental Values',
],
LDAP_CONTROL_X_DOMAIN_SCOPE => [
'desc' => 'Active Directory Domain Scope',
],
LDAP_CONTROL_X_PERMISSIVE_MODIFY => [
'desc' => 'Active Directory Permissive Modify',
],
LDAP_CONTROL_X_SEARCH_OPTIONS => [
'desc' => 'Active Directory Search Options',
],
LDAP_CONTROL_X_TREE_DELETE => [
'desc' => 'Active Directory Tree Delete',
],
LDAP_CONTROL_X_EXTENDED_DN => [
'desc' => 'Active Directory Extended DN',
],
LDAP_CONTROL_VLVREQUEST => [
'desc' => 'Virtual List View Request',
],
LDAP_CONTROL_VLVRESPONSE => [
'desc' => 'Virtual List View Response',
],
];
public const LDAP_EXOP_CANCEL = '1.3.6.1.1.8';
public const EXOPS = [
LDAP_EXOP_START_TLS => [
'desc' => 'Start TLS',
'rfc' => 4511,
],
LDAP_EXOP_MODIFY_PASSWD => [
'desc' => 'Modify password',
'rfc' => 3062,
],
LDAP_EXOP_REFRESH => [
'desc' => 'Refresh',
'rfc' => 2589,
],
LDAP_EXOP_WHO_AM_I => [
'desc' => 'WHOAMI',
'rfc' => 4532,
],
LDAP_EXOP_TURN => [
'desc' => 'Turn',
'rfc' => 4531,
],
OID::LDAP_EXOP_CANCEL => [
'desc' => 'Cancel operation',
'rfc' => 3909,
],
];
public const LDAP_FEATURE_MODIFYINCREMENT = '1.3.6.1.1.14';
public const LDAP_FEATURE_ALLOPERATIONALATTRIBUTES = '1.3.6.1.4.1.4203.1.5.1';
public const LDAP_FEATURE_RETURNALLATTRIBUTES = '1.3.6.1.4.1.4203.1.5.2';
public const LDAP_FEATURE_ABSOLUTEFILTERS = '1.3.6.1.4.1.4203.1.5.3';
public const LDAP_FEATURE_LANGUAGETAG = '1.3.6.1.4.1.4203.1.5.4';
public const LDAP_FEATURE_RANGEMATCHING = '1.3.6.1.4.1.4203.1.5.5';
public const FEATURES = [
OID::LDAP_FEATURE_MODIFYINCREMENT => [
'desc' => 'Modify-Increment Extension',
'rfc' => 4525,
],
OID::LDAP_FEATURE_ALLOPERATIONALATTRIBUTES => [
'desc' => 'All Operational Attributes',
'rfc' => 3673,
],
OID::LDAP_FEATURE_RETURNALLATTRIBUTES => [
'desc' => 'Return of All Attributes of an Object Class',
'rfc' => 4529,
],
OID::LDAP_FEATURE_ABSOLUTEFILTERS => [
'desc' => 'Absolute True and False Filters',
'rfc' => 4526,
],
OID::LDAP_FEATURE_LANGUAGETAG => [
'desc' => 'Language Tag Options',
'rfc' => 3866,
],
OID::LDAP_FEATURE_RANGEMATCHING => [
'desc' => 'Language Range Matching of Attributes',
'rfc' => 3866,
],
];
}
<?php
/**
* PSR4 compliant autoloader
*
* Adapted from https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader-examples.md
*
* This code is under MIT License.
*
* @param string $class The fully-qualified class name.
*/
spl_autoload_register(function (string $class): void {
// project-specific namespace prefix
$prefix = 'FusionDirectory\\Ldap\\';
// base directory for the namespace prefix
$base_dir = __DIR__ . '/';
// does the class use the namespace prefix?
$len = strlen($prefix);
if (strncmp($prefix, $class, $len) !== 0) {
// no, move to the next registered autoloader
return;
}
// get the relative class name
$relative_class = substr($class, $len);
// replace the namespace prefix with the base directory, replace namespace
// separators with directory separators in the relative class name, append
// with .php
$file = $base_dir . str_replace('\\', '/', $relative_class) . '.php';
// if the file exists, require it
if (file_exists($file)) {
require $file;
}
});
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment