Compare commits
1 Commits
master
...
BRANCH-1.0
Author | SHA1 | Date | |
---|---|---|---|
|
d24bc5a4ea |
@ -1,10 +0,0 @@
|
||||
.dockerignore
|
||||
.editorconfig
|
||||
.env.testing
|
||||
.git*
|
||||
docker/
|
||||
package.json
|
||||
package-lock.json
|
||||
phpunit.xml
|
||||
webpack.mix.js
|
||||
yarn.lock
|
@ -1,18 +0,0 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_size = 4
|
||||
indent_style = tab
|
||||
insert_final_newline = false
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[*.{yml,yaml}]
|
||||
indent_size = 2
|
||||
|
||||
[docker-compose.yml]
|
||||
indent_size = 4
|
51
.env.example
51
.env.example
@ -1,51 +0,0 @@
|
||||
APP_NAME=Laravel
|
||||
APP_ENV=production
|
||||
APP_KEY=
|
||||
APP_DEBUG=true
|
||||
APP_URL=http://localhost
|
||||
|
||||
LOG_CHANNEL=stack
|
||||
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=127.0.0.1
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=laravel
|
||||
DB_USERNAME=root
|
||||
DB_PASSWORD=
|
||||
|
||||
BROADCAST_DRIVER=log
|
||||
CACHE_DRIVER=file
|
||||
QUEUE_CONNECTION=sync
|
||||
SESSION_DRIVER=file
|
||||
SESSION_LIFETIME=120
|
||||
|
||||
REDIS_HOST=127.0.0.1
|
||||
REDIS_PASSWORD=null
|
||||
REDIS_PORT=6379
|
||||
|
||||
MAIL_DRIVER=smtp
|
||||
MAIL_HOST=smtp.mailtrap.io
|
||||
MAIL_PORT=2525
|
||||
MAIL_USERNAME=null
|
||||
MAIL_PASSWORD=null
|
||||
MAIL_ENCRYPTION=null
|
||||
MAIL_FROM_ADDRESS=null
|
||||
MAIL_FROM_NAME="${APP_NAME}"
|
||||
|
||||
AWS_ACCESS_KEY_ID=
|
||||
AWS_SECRET_ACCESS_KEY=
|
||||
AWS_DEFAULT_REGION=us-east-1
|
||||
AWS_BUCKET=
|
||||
|
||||
PUSHER_APP_ID=
|
||||
PUSHER_APP_KEY=
|
||||
PUSHER_APP_SECRET=
|
||||
PUSHER_APP_CLUSTER=mt1
|
||||
|
||||
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
|
||||
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
|
||||
|
||||
LDAP_HOST=
|
||||
LDAP_BASE_DN=
|
||||
LDAP_USERNAME=
|
||||
LDAP_PASSWORD=
|
51
.env.testing
51
.env.testing
@ -1,51 +0,0 @@
|
||||
APP_NAME=Laravel
|
||||
APP_ENV=dev
|
||||
APP_KEY=base64:KvIecx8zoy6RjcbJM8s98ZKs9IDGUHFVqBRn3Awfmso=
|
||||
APP_DEBUG=true
|
||||
APP_URL=http://localhost
|
||||
|
||||
LOG_CHANNEL=stack
|
||||
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=127.0.0.1
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=homestead
|
||||
DB_USERNAME=homestead
|
||||
DB_PASSWORD=secret
|
||||
|
||||
BROADCAST_DRIVER=log
|
||||
CACHE_DRIVER=file
|
||||
QUEUE_CONNECTION=sync
|
||||
SESSION_DRIVER=file
|
||||
SESSION_LIFETIME=120
|
||||
|
||||
REDIS_HOST=127.0.0.1
|
||||
REDIS_PASSWORD=null
|
||||
REDIS_PORT=6379
|
||||
|
||||
MAIL_DRIVER=smtp
|
||||
MAIL_HOST=smtp.mailtrap.io
|
||||
MAIL_PORT=2525
|
||||
MAIL_USERNAME=null
|
||||
MAIL_PASSWORD=null
|
||||
MAIL_ENCRYPTION=null
|
||||
|
||||
AWS_ACCESS_KEY_ID=
|
||||
AWS_SECRET_ACCESS_KEY=
|
||||
AWS_DEFAULT_REGION=us-east-1
|
||||
AWS_BUCKET=
|
||||
|
||||
PUSHER_APP_ID=
|
||||
PUSHER_APP_KEY=
|
||||
PUSHER_APP_SECRET=
|
||||
PUSHER_APP_CLUSTER=mt1
|
||||
|
||||
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
|
||||
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
|
||||
|
||||
LDAP_HOST=test_ldap
|
||||
LDAP_PORT=389
|
||||
LDAP_BASE_DN="dc=Test"
|
||||
LDAP_USERNAME="cn=admin,dc=Test"
|
||||
LDAP_PASSWORD="test"
|
||||
LDAP_CACHE=false
|
5
.gitattributes
vendored
5
.gitattributes
vendored
@ -1,5 +0,0 @@
|
||||
* text=auto
|
||||
*.css linguist-vendored
|
||||
*.scss linguist-vendored
|
||||
*.js linguist-vendored
|
||||
CHANGELOG.md export-ignore
|
13
.github/FUNDING.yml
vendored
13
.github/FUNDING.yml
vendored
@ -1,13 +0,0 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: [leenooks]
|
||||
patreon: # Replace with a single Patreon username
|
||||
open_collective: # Replace with a single Open Collective username
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
liberapay: # Replace with a single Liberapay username
|
||||
issuehunt: # Replace with a single IssueHunt username
|
||||
otechie: # Replace with a single Otechie username
|
||||
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
|
||||
custom: ['https://www.buymeacoffee.com/dege']
|
38
.github/ISSUE_TEMPLATE/bug_report.md
vendored
38
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -1,38 +0,0 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem. Also include any logs or backtrace information
|
||||
|
||||
**LDAP Server details (please complete the following information):**
|
||||
- OS: [e.g. iOS]
|
||||
- Server Name [e.g. OpenLDAP, Windows AD,...]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Smartphone (please complete the following information):**
|
||||
- Device: [e.g. iPhone6]
|
||||
- OS: [e.g. iOS8.1]
|
||||
- Browser [e.g. stock browser, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
19
.gitignore
vendored
19
.gitignore
vendored
@ -1,19 +0,0 @@
|
||||
/node_modules
|
||||
/public/hot
|
||||
/public/storage
|
||||
/storage/*.key
|
||||
/vendor
|
||||
.env
|
||||
.env.backup
|
||||
.phpunit.result.cache
|
||||
Homestead.json
|
||||
Homestead.yaml
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
public/css/app.css
|
||||
public/js/app.js
|
||||
public/js/vendor.js
|
||||
public/js/manifest.js
|
||||
public/fonts/vendor
|
||||
public/images/vendor
|
||||
public/mix-manifest.json
|
@ -1,38 +0,0 @@
|
||||
stages:
|
||||
- test
|
||||
- build
|
||||
- build-manifest
|
||||
|
||||
variables:
|
||||
DOCKER_HOST: tcp://docker:2375
|
||||
VERSION: latest
|
||||
VERSIONARCH: ${VERSION}-${ARCH}
|
||||
|
||||
# This folder is cached between builds
|
||||
# http://docs.gitlab.com/ce/ci/yaml/README.html#cache
|
||||
cache:
|
||||
key: ${CI_COMMIT_REF_SLUG}
|
||||
paths:
|
||||
- public/css/app.css
|
||||
- public/js/app.js
|
||||
- public/js/manifest.js
|
||||
- public/js/vendor.js
|
||||
- public/*/vendor/
|
||||
- node_modules/
|
||||
- vendor/
|
||||
|
||||
image: docker:latest
|
||||
services:
|
||||
- docker:dind
|
||||
|
||||
before_script:
|
||||
- docker info && docker version
|
||||
- echo "$CI_JOB_TOKEN" | docker login -u "$CI_REGISTRY_USER" "$CI_REGISTRY" --password-stdin
|
||||
- if [ -n "$GITHUB_TOKEN" ]; then cat $GITHUB_TOKEN |base64 -d > auth.json; fi
|
||||
|
||||
include:
|
||||
- .gitlab-test.yml
|
||||
- .gitlab-docker-x86_64.yml
|
||||
- .gitlab-docker-armv7l.yml
|
||||
- .gitlab-docker-arm64.yml
|
||||
- .gitlab-docker-manifest.yml
|
@ -1,18 +0,0 @@
|
||||
arm64:build:
|
||||
variables:
|
||||
ARCH: arm64
|
||||
|
||||
stage: build
|
||||
|
||||
script:
|
||||
- if [ -f init ]; then chmod 500 init; fi
|
||||
- echo -n ${CI_COMMIT_SHORT_SHA} > VERSION
|
||||
- rm -rf node_modules database/seeds database/schema database/factories/*
|
||||
- docker build -f docker/Dockerfile -t ${CI_REGISTRY_IMAGE}:${VERSIONARCH} .
|
||||
- docker push ${CI_REGISTRY_IMAGE}:${VERSIONARCH}
|
||||
|
||||
tags:
|
||||
- docker
|
||||
- arm64
|
||||
only:
|
||||
- master
|
@ -1,18 +0,0 @@
|
||||
armv7l:build:
|
||||
variables:
|
||||
ARCH: armv7l
|
||||
|
||||
stage: build
|
||||
|
||||
script:
|
||||
- if [ -f init ]; then chmod 500 init; fi
|
||||
- echo -n ${CI_COMMIT_SHORT_SHA} > VERSION
|
||||
- rm -rf node_modules database/seeds database/schema database/factories/*
|
||||
- docker build -f docker/Dockerfile -t ${CI_REGISTRY_IMAGE}:${VERSIONARCH} .
|
||||
- docker push ${CI_REGISTRY_IMAGE}:${VERSIONARCH}
|
||||
|
||||
tags:
|
||||
- docker
|
||||
- armv7l
|
||||
only:
|
||||
- master
|
@ -1,10 +0,0 @@
|
||||
x86_64:build-manifest:
|
||||
stage: build-manifest
|
||||
script:
|
||||
- docker manifest create ${CI_REGISTRY_IMAGE}:${VERSION} ${CI_REGISTRY_IMAGE}:${VERSION}-x86_64 ${CI_REGISTRY_IMAGE}:${VERSION}-armv7l ${CI_REGISTRY_IMAGE}:${VERSION}-arm64
|
||||
- docker manifest push --purge ${CI_REGISTRY_IMAGE}:${VERSION}
|
||||
tags:
|
||||
- docker
|
||||
- x86_64
|
||||
only:
|
||||
- master
|
@ -1,18 +0,0 @@
|
||||
x86_64:build:
|
||||
variables:
|
||||
ARCH: x86_64
|
||||
|
||||
stage: build
|
||||
|
||||
script:
|
||||
- if [ -f init ]; then chmod 500 init; fi
|
||||
- echo -n ${CI_COMMIT_SHORT_SHA} > VERSION
|
||||
- rm -rf node_modules database/seeds database/schema database/factories/*
|
||||
- docker build -f docker/Dockerfile -t ${CI_REGISTRY_IMAGE}:${VERSIONARCH} .
|
||||
- docker push ${CI_REGISTRY_IMAGE}:${VERSIONARCH}
|
||||
|
||||
tags:
|
||||
- docker
|
||||
- x86_64
|
||||
only:
|
||||
- master
|
@ -1,52 +0,0 @@
|
||||
test:
|
||||
image: ${CI_REGISTRY}/leenooks/php:8.3-fpm-ldap-test
|
||||
|
||||
stage: test
|
||||
|
||||
# NOTE: This service is dependant on project file configuration, which is not there if the cache was deleted
|
||||
# resulting in the testing to fail on the first run.
|
||||
services:
|
||||
- name: osixia/openldap:latest
|
||||
alias: test_ldap
|
||||
command: ["--loglevel","debug"]
|
||||
|
||||
variables:
|
||||
LDAP_SEED_INTERNAL_LDIF_PATH: "${CI_PROJECT_DIR}/tests/server/openldap/data"
|
||||
LDAP_SEED_INTERNAL_SCHEMA_PATH: "${CI_PROJECT_DIR}/tests/server/openldap/schema"
|
||||
LDAP_BASE_DN: "dc=Test"
|
||||
LDAP_DOMAIN: "Test"
|
||||
LDAP_ADMIN_PASSWORD: test
|
||||
#CI_DEBUG_SERVICES: "true"
|
||||
|
||||
tags:
|
||||
- php
|
||||
only:
|
||||
- master
|
||||
|
||||
before_script:
|
||||
- mv .env.testing .env
|
||||
|
||||
# Install npm and dependancies
|
||||
- apk add --no-cache npm
|
||||
- npm i
|
||||
- npm run prod
|
||||
|
||||
# Install Composer and project dependencies.
|
||||
- mkdir -p ${COMPOSER_HOME}
|
||||
- if [ -n "$GITHUB_TOKEN" ]; then cat $GITHUB_TOKEN |base64 -d > ${COMPOSER_HOME}/auth.json; fi
|
||||
- composer install
|
||||
|
||||
# Generate an application key. Re-cache.
|
||||
- php artisan key:generate
|
||||
|
||||
script:
|
||||
# Sleep if we need to, in case we want to jump in and see what is going on during the test
|
||||
- if [ -n "$DEBUG_PAUSE" ]; then echo "Pausing for $DEBUG_PAUSE seconds, so you can jump into the containers"; sleep $DEBUG_PAUSE; fi
|
||||
# run laravel tests
|
||||
- XDEBUG_MODE=coverage php vendor/bin/phpunit --coverage-text --colors=never
|
||||
|
||||
# run frontend tests
|
||||
# if you have any task for testing frontend
|
||||
# set it in your package.json script
|
||||
# comment this out if you don't have a frontend test
|
||||
# npm test
|
23
INSTALL
Normal file
23
INSTALL
Normal file
@ -0,0 +1,23 @@
|
||||
For install instructions in non-English languages, see the wiki:
|
||||
http://wiki.phpldapadmin.info
|
||||
|
||||
* Requirements
|
||||
|
||||
phpLDAPadmin requires the following:
|
||||
a. A web server (Apache, IIS, etc).
|
||||
b. PHP 4.1.0 or newer (with LDAP support)
|
||||
|
||||
* To install
|
||||
|
||||
1. Unpack the archive (if you're reading this, you already did that).
|
||||
2. Put the resulting 'phpldapadmin' directory somewhere in your webroot.
|
||||
3. Copy 'config.php.example' to 'config.php' and edit to taste (this is in the config/ directory).
|
||||
4. Then, point your browser to the phpldapadmin directory.
|
||||
|
||||
* For additional help
|
||||
|
||||
See the wiki:
|
||||
http://wiki.phpldapadmin.info
|
||||
|
||||
Join our mailing list:
|
||||
https://lists.sourceforge.net/lists/listinfo/phpldapadmin-devel
|
50
README.md
50
README.md
@ -1,50 +0,0 @@
|
||||
# phpLDAPadmin
|
||||
phpLDAPadmin is a web based LDAP data management tool for system administrators. It is commonly known and referred by many as "PLA".
|
||||
|
||||
PLA is designed to be compliant with LDAP RFCs, enabling it to be used with any LDAP server.
|
||||
If you come across an LDAP server, where PLA exhibits problems, please open an issue with full details of the problem so that we can have it fixed.
|
||||
|
||||
For up to date information on PLA, please head to the [wiki](https://github.com/leenooks/phpLDAPadmin/wiki).
|
||||
|
||||
> **NOTE**: GIT **master** is currently in active development, and as such functionality may be missing, broken or not working as expected.
|
||||
>
|
||||
> If you are after a working version of PLA, please use one of the tagged releases.
|
||||
|
||||
## Demo
|
||||
If you havent seen PLA in action, you can head here to the [demo](https://demo.phpldapadmin.org) site.
|
||||
|
||||
## Running the docker image
|
||||
PLA v2 is available via docker for preview. (PLA v2 is still under heavy development.)
|
||||
|
||||
The container is the same one used for the demo site - but you'll be able to point it to your local LDAP server and see how things work.
|
||||
|
||||
Take a look at the [Docker Container](https://github.com/leenooks/phpLDAPadmin/wiki/Docker-Container) page for more details.
|
||||
|
||||
> Please let me know if you have any troubles with the container image, eg: usage of the container itself, or usage when it is pointing to your LDAP server.
|
||||
>
|
||||
> Open an issue (details below) with enough information for me to be able to recreate the problem. An `LDIF` will be invaluable if it is not handling data correctly.
|
||||
|
||||
## Getting Help
|
||||
The best place to get help with PLA (new and old) is on [Stack Overflow](https://stackoverflow.com/tags/phpldapadmin/info).
|
||||
|
||||
## Found a bug?
|
||||
If you have found a bug, and can provide detailed instructions so that it can be reproduced, please open an [issue](https://github.com/leenooks/phpLDAPadmin/issues) and provide those details.
|
||||
|
||||
Before opening a ticket, please check to see if it hasnt already been reported, and if it has, please provide any additional information that will help it be fixed.
|
||||
|
||||
*TIP*: Issues opened with:
|
||||
|
||||
* details enabling the problem to be reproduced,
|
||||
* including (if appropriate) an LDIF with the data that exhibits the problem,
|
||||
* a patch (or a git pull request) to fix the problem
|
||||
|
||||
will be looked at first :)
|
||||
|
||||
## THANK YOU
|
||||
Over the years, many, many, many people have supported PLA with either their time, their coding or with financial donations.
|
||||
I have tried to send an email to acknowledge each contribution, and if you havent seen anything personally from me, I am sorry, but please know that I do appreciate all the help I get, in whatever form it is provided.
|
||||
|
||||
Again, Thank You.
|
||||
|
||||
## License
|
||||
[LICENSE](LICENSE)
|
3
app/.gitignore
vendored
3
app/.gitignore
vendored
@ -1,3 +0,0 @@
|
||||
q*
|
||||
!public/
|
||||
!.gitignore
|
@ -1,996 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP;
|
||||
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
use App\Classes\LDAP\Schema\AttributeType;
|
||||
|
||||
/**
|
||||
* Represents an attribute of an LDAP Object
|
||||
*/
|
||||
class Attribute implements \Countable, \ArrayAccess
|
||||
{
|
||||
// Attribute Name
|
||||
protected string $name;
|
||||
|
||||
protected ?AttributeType $schema = NULL;
|
||||
|
||||
/*
|
||||
# Source of this attribute definition
|
||||
protected $source;
|
||||
*/
|
||||
|
||||
// Current and Old Values
|
||||
protected Collection $values;
|
||||
|
||||
// Is this attribute an internal attribute
|
||||
protected bool $is_internal = FALSE;
|
||||
|
||||
// Is this attribute the RDN?
|
||||
protected bool $is_rdn = FALSE;
|
||||
|
||||
// Objectclasses that require this attribute
|
||||
protected Collection $required_by;
|
||||
|
||||
// MIN/MAX number of values
|
||||
protected int $min_values_count = 0;
|
||||
protected int $max_values_count = 0;
|
||||
|
||||
// RFC3866 Language Tags
|
||||
protected Collection $lang_tags;
|
||||
|
||||
// The old values for this attribute - helps with isDirty() to determine if there is an update pending
|
||||
protected Collection $oldValues;
|
||||
|
||||
/*
|
||||
# Has the attribute been modified
|
||||
protected $modified = false;
|
||||
# Is the attribute being deleted because of an object class removal
|
||||
protected $forcedelete = false;
|
||||
# Is the attribute visible
|
||||
protected $visible = false;
|
||||
protected $forcehide = false;
|
||||
# Is the attribute modifiable
|
||||
protected $readonly = false;
|
||||
# LDAP attribute type MUST/MAY
|
||||
protected $ldaptype = null;
|
||||
# Attribute property type (eg password, select, multiselect)
|
||||
protected $type = '';
|
||||
# Attribute value to keep unique
|
||||
protected $unique = false;
|
||||
|
||||
# Display parameters
|
||||
protected $display = '';
|
||||
protected $icon = '';
|
||||
protected $hint = '';
|
||||
# Helper details
|
||||
protected $helper = array();
|
||||
protected $helpervalue = array();
|
||||
# Onchange details
|
||||
protected $onchange = array();
|
||||
# Show spacer after this attribute is rendered
|
||||
protected $spacer = false;
|
||||
protected $verify = false;
|
||||
|
||||
# Component size
|
||||
protected $size = 0;
|
||||
# Value max length
|
||||
protected $maxlength = 0;
|
||||
# Text Area sizings
|
||||
protected $cols = 0;
|
||||
protected $rows = 0;
|
||||
|
||||
# Public for sorting
|
||||
public $page = 1;
|
||||
public $order = 255;
|
||||
public $ordersort = 255;
|
||||
|
||||
# Schema Aliases for this attribute (stored in lowercase)
|
||||
protected $aliases = array();
|
||||
|
||||
# Configuration for automatically generated values
|
||||
protected $autovalue = array();
|
||||
protected $postvalue = array();
|
||||
*/
|
||||
|
||||
public function __construct(string $name,array $values)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->values = collect($values);
|
||||
$this->lang_tags = collect();
|
||||
$this->required_by = collect();
|
||||
$this->oldValues = collect($values);
|
||||
|
||||
// No need to load our schema for internal attributes
|
||||
if (! $this->is_internal)
|
||||
$this->schema = (new Server)->schema('attributetypes',$name);
|
||||
|
||||
/*
|
||||
# Should this attribute be hidden
|
||||
if ($server->isAttrHidden($this->name))
|
||||
$this->forcehide = true;
|
||||
|
||||
# Should this attribute value be read only
|
||||
if ($server->isAttrReadOnly($this->name))
|
||||
$this->readonly = true;
|
||||
|
||||
# Should this attribute value be unique
|
||||
if ($server->isAttrUnique($this->name))
|
||||
$this->unique = true;
|
||||
*/
|
||||
}
|
||||
|
||||
public function __get(string $key): mixed
|
||||
{
|
||||
return match ($key) {
|
||||
// List all the attributes
|
||||
'attributes' => $this->attributes(),
|
||||
// Can this attribute have more values
|
||||
'can_addvalues' => $this->schema && (! $this->schema->is_single_value) && ((! $this->max_values_count) || ($this->values->count() < $this->max_values_count)),
|
||||
// Schema attribute description
|
||||
'description' => $this->schema ? $this->schema->{$key} : NULL,
|
||||
// Attribute hints
|
||||
'hints' => $this->hints(),
|
||||
// Can this attribute be edited
|
||||
'is_editable' => $this->schema ? $this->schema->{$key} : NULL,
|
||||
// Is this an internal attribute
|
||||
'is_internal' => isset($this->{$key}) && $this->{$key},
|
||||
// Is this attribute the RDN
|
||||
'is_rdn' => $this->is_rdn,
|
||||
// We prefer the name as per the schema if it exists
|
||||
'name' => $this->schema ? $this->schema->{$key} : $this->{$key},
|
||||
// Attribute name in lower case
|
||||
'name_lc' => strtolower($this->name),
|
||||
// Old Values
|
||||
'old_values' => $this->oldValues,
|
||||
// Attribute values
|
||||
'values' => $this->values,
|
||||
|
||||
default => throw new \Exception('Unknown key:' . $key),
|
||||
};
|
||||
}
|
||||
|
||||
public function __set(string $key,mixed $values): void
|
||||
{
|
||||
switch ($key) {
|
||||
case 'value':
|
||||
$this->values = collect($values);
|
||||
break;
|
||||
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function addValue(string $value): void
|
||||
{
|
||||
$this->values->push($value);
|
||||
}
|
||||
|
||||
public function count(): int
|
||||
{
|
||||
return $this->values->count();
|
||||
}
|
||||
|
||||
public function offsetExists(mixed $offset): bool
|
||||
{
|
||||
return ! is_null($this->values->get($offset));
|
||||
}
|
||||
|
||||
public function offsetGet(mixed $offset): mixed
|
||||
{
|
||||
return $this->values->get($offset);
|
||||
}
|
||||
|
||||
public function offsetSet(mixed $offset, mixed $value): void
|
||||
{
|
||||
// We cannot set new values using array syntax
|
||||
}
|
||||
|
||||
public function offsetUnset(mixed $offset): void
|
||||
{
|
||||
// We cannot clear values using array syntax
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the hints about this attribute, ie: RDN, Required, etc
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function hints(): array
|
||||
{
|
||||
$result = collect();
|
||||
|
||||
// Is this Attribute an RDN
|
||||
if ($this->is_rdn)
|
||||
$result->put(__('rdn'),__('This attribute is required for the RDN'));
|
||||
|
||||
// If this attribute name is an alias for the schema attribute name
|
||||
// @todo
|
||||
|
||||
// objectClasses requiring this attribute
|
||||
// eg: $result->put('required','Required by objectClasses: a,b');
|
||||
if ($this->required_by->count())
|
||||
$result->put(__('required'),sprintf('%s: %s',__('Required Attribute by ObjectClass(es)'),$this->required_by->join(',')));
|
||||
|
||||
// This attribute has language tags
|
||||
if ($this->lang_tags->count())
|
||||
$result->put(__('language tags'),sprintf('%s: %d',__('This Attribute has Language Tags'),$this->lang_tags->count()));
|
||||
|
||||
return $result->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if this attribute has changes
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isDirty(): bool
|
||||
{
|
||||
if ($this->oldValues->count() !== $this->values->count())
|
||||
return TRUE;
|
||||
|
||||
return $this->values->diff($this->oldValues)->count() !== 0;
|
||||
}
|
||||
|
||||
public function oldValues(array $array): void
|
||||
{
|
||||
$this->oldValues = collect($array);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the attribute value
|
||||
*
|
||||
* @param bool $edit
|
||||
* @param bool $old
|
||||
* @param bool $new
|
||||
* @return View
|
||||
*/
|
||||
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE): View
|
||||
{
|
||||
return view('components.attribute')
|
||||
->with('o',$this)
|
||||
->with('edit',$edit)
|
||||
->with('old',$old)
|
||||
->with('new',$new);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the objectclasses that require this attribute
|
||||
*
|
||||
* @param Collection $oc
|
||||
* @return Collection
|
||||
*/
|
||||
public function required_by(Collection $oc): Collection
|
||||
{
|
||||
return $this->required_by = ($this->schema
|
||||
? $oc->intersect($this->schema->required_by_object_classes)
|
||||
: collect());
|
||||
}
|
||||
|
||||
/**
|
||||
* If this attribute has RFC3866 Language Tags, this will enable those values to be captured
|
||||
*
|
||||
* @param string $tag
|
||||
* @param array $value
|
||||
* @return void
|
||||
*/
|
||||
public function setLangTag(string $tag,array $value): void
|
||||
{
|
||||
$this->lang_tags->put($tag,$value);
|
||||
}
|
||||
|
||||
public function setRDN(): void
|
||||
{
|
||||
$this->is_rdn = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of the attribute.
|
||||
*
|
||||
* @param boolean $lower - Return the attribute in normal or lower case (default lower)
|
||||
* @param boolean $real - Return the real attribute name (with ;binary, or just the name)
|
||||
* @return string Attribute name
|
||||
*
|
||||
public function getName($lower=true,$real=false) {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs,$this->name);
|
||||
|
||||
if ($real)
|
||||
return $lower ? strtolower($this->name) : $this->name;
|
||||
else
|
||||
return $lower ? strtolower($this->real_attr_name()) : $this->real_attr_name();
|
||||
}
|
||||
|
||||
public function getValues() {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->values);
|
||||
|
||||
return $this->values;
|
||||
}
|
||||
|
||||
public function getOldValues() {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->oldvalues);
|
||||
|
||||
return $this->oldvalues;
|
||||
}
|
||||
|
||||
public function getValueCount() {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs,$this->values);
|
||||
|
||||
return count($this->values);
|
||||
}
|
||||
|
||||
public function getSource() {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->source);
|
||||
|
||||
return $this->source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Autovalue is called after the attribute is initialised, and thus the values from the ldap server will be set.
|
||||
*
|
||||
public function autoValue($new_val) {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
|
||||
|
||||
if ($this->values)
|
||||
return;
|
||||
|
||||
$this->values = $new_val;
|
||||
}
|
||||
|
||||
public function initValue($new_val) {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
|
||||
|
||||
if ($this->values || $this->oldvalues) {
|
||||
debug_dump(array('new_val'=>$new_val,'this'=>$this));
|
||||
debug_dump_backtrace('new and/or old values are set',1);
|
||||
}
|
||||
|
||||
$this->values = $new_val;
|
||||
}
|
||||
|
||||
public function clearValue() {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
|
||||
|
||||
$this->values = array();
|
||||
}
|
||||
|
||||
public function setOldValue($val) {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs);
|
||||
|
||||
$this->oldvalues = $val;
|
||||
}
|
||||
|
||||
public function setValue($new_val) {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
|
||||
|
||||
if ($this->values) {
|
||||
if ($this->values == $new_val)
|
||||
return;
|
||||
|
||||
if ($this->oldvalues) {
|
||||
debug_dump($this);
|
||||
debug_dump_backtrace('old values are set',1);
|
||||
} else
|
||||
$this->oldvalues = $this->values;
|
||||
}
|
||||
|
||||
if ($new_val == $this->values)
|
||||
return;
|
||||
|
||||
$this->values = $new_val;
|
||||
$this->justModified();
|
||||
}
|
||||
|
||||
public function addValue($new_val,$i=-1) {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
|
||||
|
||||
if ($i < 0)
|
||||
$i = $this->getValueCount();
|
||||
|
||||
$old_val = $this->getValue($i);
|
||||
if (is_null($old_val) || ($old_val != $new_val))
|
||||
$this->justModified();
|
||||
|
||||
$this->values[$i] = $new_val;
|
||||
}
|
||||
|
||||
public function delValue($i=-1) {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
|
||||
|
||||
if ($i < 0)
|
||||
$this->setValue(array());
|
||||
|
||||
if (! $this->hasBeenModified())
|
||||
$this->oldvalues = $this->values;
|
||||
|
||||
if (isset($this->values[$i])) {
|
||||
unset($this->values[$i]);
|
||||
$this->values = array_values($this->values);
|
||||
$this->justModified();
|
||||
}
|
||||
}
|
||||
|
||||
public function justModified() {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
|
||||
|
||||
$this->modified = true;
|
||||
}
|
||||
|
||||
public function hasBeenModified() {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->modified);
|
||||
|
||||
return $this->modified;
|
||||
}
|
||||
|
||||
public function isForceDelete() {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->forcedelete);
|
||||
|
||||
return $this->forcedelete;
|
||||
}
|
||||
|
||||
public function setForceDelete() {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
|
||||
|
||||
$this->forcedelete = true;
|
||||
$this->oldvalues = $this->values;
|
||||
$this->values = array();
|
||||
$this->justModified();
|
||||
}
|
||||
|
||||
public function isRequired() {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
|
||||
|
||||
if ($this->getMinValueCount() > 0)
|
||||
return true;
|
||||
elseif ($this->ldaptype == 'must')
|
||||
return true;
|
||||
elseif ($this->isRDN())
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
public function isMay() {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
|
||||
|
||||
if (($this->ldaptype == 'may') && ! $this->isRequired())
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
public function setType($type) {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs);
|
||||
|
||||
$this->type = strtolower($type);
|
||||
}
|
||||
|
||||
public function getType() {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->type);
|
||||
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
public function setLDAPtype($type) {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs);
|
||||
|
||||
$this->ldaptype = strtolower($type);
|
||||
}
|
||||
|
||||
public function getLDAPtype() {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->ldaptype);
|
||||
|
||||
return $this->ldaptype;
|
||||
}
|
||||
|
||||
public function setProperties($properties) {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
|
||||
|
||||
foreach ($properties as $index => $value) {
|
||||
if ($index == 'maxvalnb') {
|
||||
$this->setMaxValueCount($value);
|
||||
continue;
|
||||
|
||||
} elseif ($index == 'minvalnb') {
|
||||
$this->setMinValueCount($value);
|
||||
continue;
|
||||
|
||||
} elseif ($index == 'maxlength') {
|
||||
$this->setMinValueCount($value);
|
||||
continue;
|
||||
|
||||
} elseif ($index == 'hidden') {
|
||||
$this->visible = $value;
|
||||
continue;
|
||||
|
||||
} elseif (in_array($index,array('cols','rows'))) {
|
||||
# @todo To be implemented
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isset($this->$index))
|
||||
$this->$index = $value;
|
||||
else {
|
||||
debug_dump($this);
|
||||
debug_dump_backtrace(sprintf('Unknown property (%s) with value (%s) for (%s)',$index,$value,$this->getName()),1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function setRequired() {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
|
||||
|
||||
if ($this->getMinValueCount() <= 0)
|
||||
$this->setMinValueCount(1);
|
||||
}
|
||||
|
||||
public function setOptional() {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs);
|
||||
|
||||
$this->setMinValueCount(0);
|
||||
}
|
||||
|
||||
public function isReadOnly() {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->readonly);
|
||||
|
||||
return $this->readonly;
|
||||
}
|
||||
|
||||
public function setReadOnly() {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
|
||||
|
||||
$this->readonly = true;
|
||||
}
|
||||
|
||||
public function isMultiple() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function isVisible() {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
|
||||
|
||||
return $this->visible && (! $this->forcehide);
|
||||
}
|
||||
|
||||
public function hide() {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
|
||||
|
||||
$this->visible = false;
|
||||
}
|
||||
|
||||
public function show() {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
|
||||
|
||||
$this->visible = true;
|
||||
}
|
||||
|
||||
public function haveFriendlyName() {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
|
||||
|
||||
return $_SESSION[APPCONFIG]->haveFriendlyName($this);
|
||||
}
|
||||
|
||||
public function getFriendlyName() {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->display);
|
||||
|
||||
if ($this->display)
|
||||
return $this->display;
|
||||
else
|
||||
return $_SESSION[APPCONFIG]->getFriendlyName($this);
|
||||
}
|
||||
|
||||
public function setDescription($description) {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs);
|
||||
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
public function getDescription() {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->description);
|
||||
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
public function setIcon($icon) {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs);
|
||||
|
||||
$this->icon = $icon;
|
||||
}
|
||||
|
||||
public function getIcon() {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->icon);
|
||||
|
||||
return $this->icon ? sprintf('%s/%s',IMGDIR,$this->icon) : '';
|
||||
}
|
||||
|
||||
public function getHint() {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->hint);
|
||||
|
||||
return $this->hint;
|
||||
}
|
||||
|
||||
public function setHint($hint) {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs);
|
||||
|
||||
$this->hint = $hint;
|
||||
}
|
||||
|
||||
public function getMaxLength() {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->maxlength);
|
||||
|
||||
return $this->maxlength;
|
||||
}
|
||||
|
||||
public function setMaxLength($maxlength) {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs);
|
||||
|
||||
$this->maxlength = $maxlength;
|
||||
}
|
||||
|
||||
public function getSize() {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->size);
|
||||
|
||||
return $this->size;
|
||||
}
|
||||
|
||||
public function setSize($size) {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs);
|
||||
|
||||
$this->size = $size;
|
||||
}
|
||||
|
||||
public function getSpacer() {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->spacer);
|
||||
|
||||
return $this->spacer;
|
||||
}
|
||||
|
||||
public function getPage() {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->page);
|
||||
|
||||
return $this->page;
|
||||
}
|
||||
public function setPage($page) {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs);
|
||||
|
||||
$this->page = $page;
|
||||
}
|
||||
|
||||
public function getOnChange() {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->onchange);
|
||||
|
||||
return $this->onchange;
|
||||
}
|
||||
|
||||
public function getHelper() {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->helper);
|
||||
|
||||
return $this->helper;
|
||||
}
|
||||
|
||||
public function getHelperValue() {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->helpervalue);
|
||||
|
||||
return $this->helpervalue;
|
||||
}
|
||||
|
||||
public function getVerify() {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->verify);
|
||||
|
||||
return $this->verify;
|
||||
}
|
||||
|
||||
/**
|
||||
* Capture all the LDAP details we are interested in
|
||||
*
|
||||
* @param sattr Schema Attribute
|
||||
*
|
||||
private function setLDAPdetails($sattr) {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
|
||||
|
||||
# By default, set this as a MAY attribute, later processing should make it a MUST attribute if it is.
|
||||
if (! $this->ldaptype)
|
||||
$this->ldaptype = 'may';
|
||||
|
||||
# Store our Aliases
|
||||
foreach ($sattr->getAliases() as $alias)
|
||||
array_push($this->aliases,strtolower($alias));
|
||||
|
||||
if ($sattr->getIsSingleValue())
|
||||
$this->setMaxValueCount(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of aliases for this Attribute (as defined by the schema)
|
||||
* This list will be lowercase.
|
||||
*
|
||||
public function getAliases() {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->aliases);
|
||||
|
||||
return $this->aliases;
|
||||
}
|
||||
|
||||
public function getAutoValue() {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->autovalue);
|
||||
|
||||
return $this->autovalue;
|
||||
}
|
||||
|
||||
public function getPostValue() {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->postvalue);
|
||||
|
||||
return $this->postvalue;
|
||||
}
|
||||
|
||||
public function setPostValue($postvalue) {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs);
|
||||
|
||||
$this->postvalue = $postvalue;
|
||||
}
|
||||
|
||||
public function setXML($values) {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
|
||||
|
||||
# Mostly all the time, this should be an array
|
||||
if (is_array($values))
|
||||
foreach ($values as $index => $value)
|
||||
switch ($index) {
|
||||
# Helpers should be accompanied with a <post> attribute.
|
||||
case 'helper':
|
||||
if (! isset($values['post']) && ! $_SESSION[APPCONFIG]->getValue('appearance','hide_template_warning'))
|
||||
system_message(array(
|
||||
'title'=>sprintf('%s [<i>%s</i>]',_('Missing [post] setting in XML file'),$index),
|
||||
'body'=>_('[helper] needs an accompanying [post] action.'),
|
||||
'type'=>'warn'));
|
||||
|
||||
if (isset($value['value']) && ! is_array($value['value']) && preg_match('/^=php\.(\w+)\((.*)\)$/',$value['value'],$matches)) {
|
||||
$this->helpervalue['function'] = $matches[1];
|
||||
$this->helpervalue['args'] = $matches[2];
|
||||
|
||||
unset ($value['value']);
|
||||
}
|
||||
|
||||
foreach ($value as $i => $detail) {
|
||||
if (! in_array($i,array('default','display','id','value'))) {
|
||||
if (! $_SESSION[APPCONFIG]->getValue('appearance','hide_template_warning'))
|
||||
system_message(array(
|
||||
'title'=>sprintf('%s [<i>%s</i>]',_('Unknown XML setting'),$i),
|
||||
'body'=>sprintf('%s <small>[%s]</small>',_('Unknown XML type setting for helper will be ignored.'),$detail),
|
||||
'type'=>'warn'));
|
||||
|
||||
unset($value[$i]);
|
||||
}
|
||||
}
|
||||
|
||||
$this->$index = $value;
|
||||
|
||||
break;
|
||||
|
||||
case 'hidden': $value ? $this->visible = false : $this->visible = true;
|
||||
break;
|
||||
|
||||
case 'spacer': $value ? $this->$index = true : $this->$index = false;
|
||||
break;
|
||||
|
||||
# Essentially, we ignore type, it is used to select an Attribute type in the Factory. But we'll generated a warning if there is an unknown type.
|
||||
case 'type':
|
||||
if (! in_array($value,array('password','multiselect','select','textarea')) && ! $_SESSION[APPCONFIG]->getValue('appearance','hide_template_warning'))
|
||||
system_message(array(
|
||||
'title'=>sprintf('%s [<i>%s</i>]',_('Unknown XML setting'),$index),
|
||||
'body'=>sprintf('%s <small>[%s]</small>',_('Unknown XML type setting will be ignored.'),$value),
|
||||
'type'=>'warn'));
|
||||
|
||||
break;
|
||||
|
||||
case 'post':
|
||||
if (preg_match('/^=php\.(\w+)\((.*)\)$/',$value,$matches)) {
|
||||
$this->postvalue['function'] = $matches[1];
|
||||
$this->postvalue['args'] = $matches[2];
|
||||
|
||||
} else
|
||||
if (! $_SESSION[APPCONFIG]->getValue('appearance','hide_template_warning'))
|
||||
system_message(array(
|
||||
'title'=>sprintf('%s [<i>%s</i>]',_('Unknown XML setting'),$index),
|
||||
'body'=>sprintf('%s <small>[%s]</small>',_('Unknown XML type setting will be ignored.'),$value),
|
||||
'type'=>'warn'));
|
||||
|
||||
case 'value':
|
||||
if (is_array($value))
|
||||
foreach ($value as $x => $y) {
|
||||
if (! $this->haveMoreValues()) {
|
||||
system_message(array(
|
||||
'title'=>_('Automatically removed attribute values from template'),
|
||||
'body'=>sprintf('%s <small>[%s]</small>',_('Template defines more values than can be accepted by attribute.'),$this->getName(true)),
|
||||
'type'=>'warn'));
|
||||
|
||||
$this->clearValue();
|
||||
|
||||
break;
|
||||
|
||||
} else
|
||||
$this->addValue($x,$y);
|
||||
}
|
||||
|
||||
else
|
||||
# Check to see if the value is auto generated.
|
||||
if (preg_match('/^=php\.(\w+)\((.*)\)$/',$value,$matches)) {
|
||||
$this->autovalue['function'] = $matches[1];
|
||||
$this->autovalue['args'] = $matches[2];
|
||||
|
||||
# We'll add a hint too
|
||||
if (! $this->hint)
|
||||
$this->hint = _('Automatically determined');
|
||||
|
||||
} else
|
||||
$this->addValue($value);
|
||||
|
||||
break;
|
||||
|
||||
# Queries
|
||||
case 'ordersort':
|
||||
|
||||
# Creation/Editing Templates
|
||||
case 'cols':
|
||||
case 'default':
|
||||
case 'display':
|
||||
case 'hint':
|
||||
case 'icon':
|
||||
case 'maxlength':
|
||||
case 'onchange':
|
||||
case 'order':
|
||||
case 'page':
|
||||
case 'readonly':
|
||||
case 'rows':
|
||||
case 'size':
|
||||
case 'values':
|
||||
case 'verify': $this->$index = $value;
|
||||
break;
|
||||
|
||||
case 'max':
|
||||
if ($this->getMaxValueCount() == -1)
|
||||
$this->setMaxValueCount($value);
|
||||
|
||||
default:
|
||||
if (! $_SESSION[APPCONFIG]->getValue('appearance','hide_template_warning'))
|
||||
system_message(array(
|
||||
'title'=>sprintf('%s [<i>%s</i>]',_('Unknown XML setting'),$index),
|
||||
'body'=>sprintf('%s <small>[%s]</small>',_('Unknown attribute setting will be ignored.'),serialize($value)),
|
||||
'type'=>'warn'));
|
||||
}
|
||||
|
||||
elseif (is_string($values) && (strlen($values) > 0))
|
||||
$this->values = array($values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the values removed in an attribute.
|
||||
*
|
||||
public function getRemovedValues() {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
|
||||
|
||||
return array_diff($this->getOldValues(),$this->getValues());
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the values removed in an attribute.
|
||||
*
|
||||
public function getAddedValues() {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
|
||||
|
||||
return array_diff($this->getValues(),$this->getOldValues());
|
||||
}
|
||||
|
||||
/**
|
||||
* Prunes off anything after the ";" in an attr name. This is useful for
|
||||
* attributes that may have ";binary" appended to their names. With
|
||||
* real_attr_name(), you can more easily fetch these attributes' schema
|
||||
* with their "real" attribute name.
|
||||
*
|
||||
* @param string $attr_name The name of the attribute to examine.
|
||||
* @return string
|
||||
*
|
||||
private function real_attr_name() {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->name);
|
||||
|
||||
return preg_replace('/;.*$/U','',$this->name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this attribute need supporting JS
|
||||
*
|
||||
public function needJS($type=null) {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
|
||||
|
||||
if (is_null($type)) {
|
||||
foreach (array('focus','blur','validate') as $type)
|
||||
if ($this->needJS($type))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
||||
} elseif ($type == 'focus') {
|
||||
# We dont have any focus javascript routines.
|
||||
return false;
|
||||
|
||||
} elseif ($type == 'blur') {
|
||||
if ($this->onchange || $this->isRequired())
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
|
||||
} elseif ($type == 'validate') {
|
||||
if ($this->isRequired())
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
|
||||
} else
|
||||
debug_dump_backtrace(sprintf('Unknown JS request %s',$type),1);
|
||||
}
|
||||
*/
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP\Attribute;
|
||||
|
||||
use App\Classes\LDAP\Attribute;
|
||||
|
||||
/**
|
||||
* Represents an attribute whose values are binary
|
||||
*/
|
||||
class Binary extends Attribute
|
||||
{
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP\Attribute\Binary;
|
||||
|
||||
use Illuminate\Contracts\View\View;
|
||||
|
||||
use App\Classes\LDAP\Attribute\Binary;
|
||||
use App\Traits\MD5Updates;
|
||||
|
||||
/**
|
||||
* Represents an JpegPhoto Attribute
|
||||
*/
|
||||
final class JpegPhoto extends Binary
|
||||
{
|
||||
use MD5Updates;
|
||||
|
||||
public function __construct(string $name,array $values)
|
||||
{
|
||||
parent::__construct($name,$values);
|
||||
|
||||
$this->internal = FALSE;
|
||||
}
|
||||
|
||||
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE): View
|
||||
{
|
||||
return view('components.attribute.binary.jpegphoto')
|
||||
->with('o',$this)
|
||||
->with('edit',$edit)
|
||||
->with('old',$old)
|
||||
->with('new',$new)
|
||||
->with('f',new \finfo);
|
||||
}
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP\Attribute;
|
||||
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
use App\Classes\LDAP\Attribute;
|
||||
|
||||
/**
|
||||
* This factory is used to return LDAP attributes as an object
|
||||
*
|
||||
* If there is no specific Attribute defined, then the default Attribute::class is return
|
||||
*/
|
||||
class Factory
|
||||
{
|
||||
private const LOGKEY = 'LAf';
|
||||
|
||||
/**
|
||||
* Map of attributes to appropriate class
|
||||
*/
|
||||
public const map = [
|
||||
'createtimestamp' => Internal\Timestamp::class,
|
||||
'creatorsname' => Internal\DN::class,
|
||||
'contextcsn' => Internal\CSN::class,
|
||||
'entrycsn' => Internal\CSN::class,
|
||||
'entrydn' => Internal\DN::class,
|
||||
'entryuuid' => Internal\UUID::class,
|
||||
'gidnumber' => GidNumber::class,
|
||||
'hassubordinates' => Internal\HasSubordinates::class,
|
||||
'jpegphoto' => Binary\JpegPhoto::class,
|
||||
'modifytimestamp' => Internal\Timestamp::class,
|
||||
'modifiersname' => Internal\DN::class,
|
||||
'objectclass' => ObjectClass::class,
|
||||
'structuralobjectclass' => Internal\StructuralObjectClass::class,
|
||||
'subschemasubentry' => Internal\SubschemaSubentry::class,
|
||||
'supportedcontrol' => Schema\OID::class,
|
||||
'supportedextension' => Schema\OID::class,
|
||||
'supportedfeatures' => Schema\OID::class,
|
||||
'supportedsaslmechanisms' => Schema\Mechanisms::class,
|
||||
'userpassword' => Password::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* Create the new Object for an attribute
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param array $values
|
||||
* @return Attribute
|
||||
*/
|
||||
public static function create(string $attribute,array $values): Attribute
|
||||
{
|
||||
$class = Arr::get(self::map,strtolower($attribute),Attribute::class);
|
||||
Log::debug(sprintf('%s:Creating LDAP Attribute [%s] as [%s]',static::LOGKEY,$attribute,$class));
|
||||
|
||||
return new $class($attribute,$values);
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP\Attribute;
|
||||
|
||||
use App\Classes\LDAP\Attribute;
|
||||
|
||||
/**
|
||||
* Represents an GidNumber Attribute
|
||||
*/
|
||||
final class GidNumber extends Attribute
|
||||
{
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP\Attribute;
|
||||
|
||||
use Illuminate\Contracts\View\View;
|
||||
|
||||
use App\Classes\LDAP\Attribute;
|
||||
|
||||
/**
|
||||
* Represents an attribute whose values are internal
|
||||
*/
|
||||
abstract class Internal extends Attribute
|
||||
{
|
||||
protected bool $is_internal = TRUE;
|
||||
|
||||
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE): View
|
||||
{
|
||||
// @note Internal attributes cannot be edited
|
||||
return view('components.attribute.internal')
|
||||
->with('o',$this);
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP\Attribute\Internal;
|
||||
|
||||
use App\Classes\LDAP\Attribute\Internal;
|
||||
|
||||
/**
|
||||
* Represents an CSN Attribute
|
||||
*/
|
||||
final class CSN extends Internal
|
||||
{
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP\Attribute\Internal;
|
||||
|
||||
use App\Classes\LDAP\Attribute\Internal;
|
||||
|
||||
/**
|
||||
* Represents an DN Attribute
|
||||
*/
|
||||
final class DN extends Internal
|
||||
{
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP\Attribute\Internal;
|
||||
|
||||
use App\Classes\LDAP\Attribute\Internal;
|
||||
|
||||
/**
|
||||
* Represents an HasSubordinates Attribute
|
||||
*/
|
||||
final class HasSubordinates extends Internal
|
||||
{
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP\Attribute\Internal;
|
||||
|
||||
use App\Classes\LDAP\Attribute\Internal;
|
||||
|
||||
/**
|
||||
* Represents an StructuralObjectClass Attribute
|
||||
*/
|
||||
final class StructuralObjectClass extends Internal
|
||||
{
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP\Attribute\Internal;
|
||||
|
||||
use App\Classes\LDAP\Attribute\Internal;
|
||||
|
||||
/**
|
||||
* Represents an SubschemaSubentry Attribute
|
||||
*/
|
||||
final class SubschemaSubentry extends Internal
|
||||
{
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP\Attribute\Internal;
|
||||
|
||||
use Illuminate\Contracts\View\View;
|
||||
|
||||
use App\Classes\LDAP\Attribute\Internal;
|
||||
|
||||
/**
|
||||
* Represents an attribute whose values are timestamps
|
||||
*/
|
||||
final class Timestamp extends Internal
|
||||
{
|
||||
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE): View
|
||||
{
|
||||
// @note Internal attributes cannot be edited
|
||||
return view('components.attribute.internal.timestamp')
|
||||
->with('o',$this);
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP\Attribute\Internal;
|
||||
|
||||
use App\Classes\LDAP\Attribute\Internal;
|
||||
|
||||
/**
|
||||
* Represents an UUID Attribute
|
||||
*/
|
||||
final class UUID extends Internal
|
||||
{
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP\Attribute;
|
||||
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
use App\Classes\LDAP\{Attribute,Server};
|
||||
|
||||
/**
|
||||
* Represents an ObjectClass Attribute
|
||||
*/
|
||||
final class ObjectClass extends Attribute
|
||||
{
|
||||
// Which of the values is the structural object class
|
||||
protected Collection $structural;
|
||||
|
||||
public function __construct(string $name,array $values)
|
||||
{
|
||||
parent::__construct($name,$values);
|
||||
|
||||
$this->structural = collect();
|
||||
|
||||
// Determine which of the values is the structural objectclass
|
||||
foreach ($values as $oc) {
|
||||
if ((new Server)->schema('objectclasses',$oc)->isStructural())
|
||||
$this->structural->push($oc);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is a specific value the structural objectclass
|
||||
*
|
||||
* @param string $value
|
||||
* @return bool
|
||||
*/
|
||||
public function isStructural(string $value): bool
|
||||
{
|
||||
return $this->structural->search($value) !== FALSE;
|
||||
}
|
||||
|
||||
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE): View
|
||||
{
|
||||
return view('components.attribute.objectclass')
|
||||
->with('o',$this)
|
||||
->with('edit',$edit)
|
||||
->with('old',$old)
|
||||
->with('new',$new);
|
||||
}
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP\Attribute;
|
||||
|
||||
use Illuminate\Contracts\View\View;
|
||||
|
||||
use App\Classes\LDAP\Attribute;
|
||||
use App\Traits\MD5Updates;
|
||||
|
||||
/**
|
||||
* Represents an attribute whose values are passwords
|
||||
*/
|
||||
final class Password extends Attribute
|
||||
{
|
||||
use MD5Updates;
|
||||
|
||||
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE): View
|
||||
{
|
||||
return view('components.attribute.password')
|
||||
->with('o',$this)
|
||||
->with('edit',$edit)
|
||||
->with('old',$old)
|
||||
->with('new',$new);
|
||||
}
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP\Attribute;
|
||||
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
|
||||
use App\Classes\LDAP\Attribute;
|
||||
|
||||
/**
|
||||
* Represents an attribute whose values are schema related
|
||||
*/
|
||||
abstract class Schema extends Attribute
|
||||
{
|
||||
protected bool $internal = TRUE;
|
||||
|
||||
protected static function _get(string $filename,string $string,string $key): ?string
|
||||
{
|
||||
$array = Cache::remember($filename,86400,function() use ($filename) {
|
||||
try {
|
||||
$f = fopen($filename,'r');
|
||||
|
||||
} catch (\Exception $e) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
$result = collect();
|
||||
|
||||
while (! feof($f)) {
|
||||
$line = trim(fgets($f));
|
||||
|
||||
if (! $line OR preg_match('/^#/',$line))
|
||||
continue;
|
||||
|
||||
$fields = explode(':',$line);
|
||||
|
||||
$result->put($x=Arr::get($fields,0),[
|
||||
'title'=>Arr::get($fields,1,$x),
|
||||
'ref'=>Arr::get($fields,2),
|
||||
'desc'=>Arr::get($fields,3,__('No description available, can you help with one?')),
|
||||
]);
|
||||
}
|
||||
fclose($f);
|
||||
|
||||
return $result;
|
||||
});
|
||||
|
||||
return Arr::get(($array ? $array->get($string) : []),$key);
|
||||
}
|
||||
|
||||
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE): View
|
||||
{
|
||||
// @note Schema attributes cannot be edited
|
||||
return view('components.attribute.internal')
|
||||
->with('o',$this);
|
||||
}
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP\Attribute\Schema;
|
||||
|
||||
use Illuminate\Contracts\View\View;
|
||||
|
||||
use App\Classes\LDAP\Attribute\Schema;
|
||||
|
||||
/**
|
||||
* Represents a Mechanisms Attribute
|
||||
*/
|
||||
final class Mechanisms extends Schema
|
||||
{
|
||||
/**
|
||||
* Given an SASL Mechanism name, returns a verbose description of the Mechanism.
|
||||
* This function parses ldap_supported_saslmechanisms.txt and looks up the specified
|
||||
* Mechanism, and returns the verbose message defined in that file.
|
||||
*
|
||||
* <code>
|
||||
* "SCRAM-SHA-1" => array:3 [▼
|
||||
* "title" => "Salted Challenge Response Authentication Mechanism (SCRAM) SHA1"
|
||||
* "ref" => "RFC 5802"
|
||||
* "desc" => "This specification describes a family of authentication mechanisms called the Salted Challenge Response Authentication Mechanism (SCRAM) which addresses the req ▶"
|
||||
* ]
|
||||
* </code>
|
||||
*
|
||||
* @param string $string The SASL Mechanism (ie, "SCRAM-SHA-1") of interest.
|
||||
* @param string $key The title|ref|desc to return
|
||||
* @return string|NULL
|
||||
*/
|
||||
public static function get(string $string,string $key): ?string
|
||||
{
|
||||
return parent::_get(config_path('ldap_supported_saslmechanisms.txt'),$string,$key);
|
||||
}
|
||||
|
||||
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE): View
|
||||
{
|
||||
// @note Schema attributes cannot be edited
|
||||
return view('components.attribute.schema.mechanisms')
|
||||
->with('o',$this);
|
||||
}
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP\Attribute\Schema;
|
||||
|
||||
use Illuminate\Contracts\View\View;
|
||||
|
||||
use App\Classes\LDAP\Attribute\Schema;
|
||||
|
||||
/**
|
||||
* Represents an OID Attribute
|
||||
*/
|
||||
final class OID extends Schema
|
||||
{
|
||||
/**
|
||||
* Given an LDAP OID number, returns a verbose description of the OID.
|
||||
* This function parses ldap_supported_oids.txt and looks up the specified
|
||||
* OID, and returns the verbose message defined in that file.
|
||||
*
|
||||
* <code>
|
||||
* "1.3.6.1.4.1.4203.1.5.1" => array:3 [
|
||||
* [title] => All Operational Attribute
|
||||
* [ref] => RFC 3673
|
||||
* [desc] => An LDAP extension which clients may use to request the return of all operational attributes.
|
||||
* ]
|
||||
* </code>
|
||||
*
|
||||
* @param string $string The OID number (ie, "1.3.6.1.4.1.4203.1.5.1") of the OID of interest.
|
||||
* @param string $key The title|ref|desc to return
|
||||
* @return string|null
|
||||
* @testedby TranslateOidTest::testRootDSE()
|
||||
*/
|
||||
public static function get(string $string,string $key): ?string
|
||||
{
|
||||
return parent::_get(config_path('ldap_supported_oids.txt'),$string,$key);
|
||||
}
|
||||
|
||||
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE): View
|
||||
{
|
||||
// @note Schema attributes cannot be edited
|
||||
return view('components.attribute.schema.oid')
|
||||
->with('o',$this);
|
||||
}
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP;
|
||||
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use LdapRecord\Query\Collection;
|
||||
|
||||
/**
|
||||
* Export Class
|
||||
*
|
||||
* This abstract classes provides all the common methods and variables for the
|
||||
* export classes.
|
||||
*/
|
||||
abstract class Export
|
||||
{
|
||||
// Line Break
|
||||
protected string $br = "\r\n";
|
||||
|
||||
// Item(s) being Exported
|
||||
protected Collection $items;
|
||||
|
||||
// Type of export
|
||||
protected const type = 'Unknown';
|
||||
|
||||
public function __construct(Collection $items)
|
||||
{
|
||||
$this->items = $items;
|
||||
}
|
||||
|
||||
abstract public function __toString(): string;
|
||||
|
||||
protected function header()
|
||||
{
|
||||
$output = '';
|
||||
|
||||
$output .= sprintf('# %s %s',__(static::type.' for'),($x=$this->items->first())).$this->br;
|
||||
$output .= sprintf('# %s: %s (%s)',
|
||||
__('Server'),
|
||||
$x->getConnection()->getConfiguration()->get('name'),
|
||||
$x->getConnection()->getLdapConnection()->getHost()).$this->br;
|
||||
//$output .= sprintf('# %s: %s',__('Search Scope'),$this->scope).$this->br;
|
||||
//$output .= sprintf('# %s: %s',__('Search Filter'),$this->entry->dn).$this->br;
|
||||
$output .= sprintf('# %s: %s',__('Total Entries'),$this->items->count()).$this->br;
|
||||
$output .= '#'.$this->br;
|
||||
$output .= sprintf('# %s %s (%s) on %s',__('Generated by'),config('app.name'),config('app.url'),date('F j, Y g:i a')).$this->br;
|
||||
$output .= sprintf('# %s %s',__('Exported by'),Auth::user() ?: 'Anonymous').$this->br;
|
||||
$output .= sprintf('# %s: %s',__('Version'),config('app.version')).$this->br;
|
||||
|
||||
$output .= $this->br;
|
||||
|
||||
return $output;
|
||||
}
|
||||
}
|
@ -1,78 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP\Export;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
use App\Classes\LDAP\Export;
|
||||
|
||||
/**
|
||||
* Export from LDAP using an LDIF format
|
||||
*/
|
||||
class LDIF extends Export
|
||||
{
|
||||
// The maximum length of the ldif line
|
||||
private int $line_length = 76;
|
||||
protected const type = 'LDIF Export';
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
$result = parent::header();
|
||||
$result .= 'version: 1';
|
||||
$result .= $this->br;
|
||||
|
||||
$c = 1;
|
||||
foreach ($this->items as $o) {
|
||||
if ($c > 1)
|
||||
$result .= $this->br;
|
||||
|
||||
$title = (string)$o;
|
||||
if (strlen($title) > $this->line_length)
|
||||
$title = Str::of($title)->limit($this->line_length-3-5,'...'.substr($title,-5));
|
||||
|
||||
$result .= sprintf('# %s %s: %s',__('Entry'),$c++,$title).$this->br;
|
||||
|
||||
// Display DN
|
||||
$result .= $this->multiLineDisplay(
|
||||
Str::isAscii($o)
|
||||
? sprintf('dn: %s',$o)
|
||||
: sprintf('dn:: %s',base64_encode($o))
|
||||
,$this->br);
|
||||
|
||||
// Display Attributes
|
||||
foreach ($o->getObjects() as $ao) {
|
||||
foreach ($ao->values as $value) {
|
||||
$result .= $this->multiLineDisplay(
|
||||
Str::isAscii($value)
|
||||
? sprintf('%s: %s',$ao->name,$value)
|
||||
: sprintf('%s:: %s',$ao->name,base64_encode($value))
|
||||
,$this->br);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to wrap LDIF lines
|
||||
*
|
||||
* @param string $str The line to be wrapped if needed.
|
||||
*/
|
||||
private function multiLineDisplay(string $str,string $br): string
|
||||
{
|
||||
$length_string = strlen($str);
|
||||
$length_max = $this->line_length;
|
||||
|
||||
$output = '';
|
||||
while ($length_string > $length_max) {
|
||||
$output .= substr($str,0,$length_max).$br;
|
||||
$str = ' '.substr($str,$length_max);
|
||||
$length_string = strlen($str);
|
||||
}
|
||||
|
||||
$output .= $str.$br;
|
||||
|
||||
return $output;
|
||||
}
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
use App\Exceptions\Import\GeneralException;
|
||||
use App\Exceptions\Import\ObjectExistsException;
|
||||
use App\Ldap\Entry;
|
||||
|
||||
/**
|
||||
* Import Class
|
||||
*
|
||||
* This abstract classes provides all the common methods and variables for the
|
||||
* import classes.
|
||||
*/
|
||||
abstract class Import
|
||||
{
|
||||
// Valid LDIF commands
|
||||
protected const LDAP_IMPORT_ADD = 1;
|
||||
protected const LDAP_IMPORT_DELETE = 2;
|
||||
protected const LDAP_IMPORT_MODRDN = 3;
|
||||
protected const LDAP_IMPORT_MODDN = 4;
|
||||
protected const LDAP_IMPORT_MODIFY = 5;
|
||||
|
||||
protected const LDAP_ACTIONS = [
|
||||
'add' => self::LDAP_IMPORT_ADD,
|
||||
'delete' => self::LDAP_IMPORT_DELETE,
|
||||
'modrdn' => self::LDAP_IMPORT_MODRDN,
|
||||
'moddn' => self::LDAP_IMPORT_MODDN,
|
||||
'modify' => self::LDAP_IMPORT_MODIFY,
|
||||
];
|
||||
|
||||
// The import data to process
|
||||
protected string $input;
|
||||
// The attributes the server knows about
|
||||
protected Collection $server_attributes;
|
||||
|
||||
public function __construct(string $input) {
|
||||
$this->input = $input;
|
||||
$this->server_attributes = config('server')->schema('attributetypes');
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to commit an entry and return the result.
|
||||
*
|
||||
* @param Entry $o
|
||||
* @param int $action
|
||||
* @return Collection
|
||||
* @throws GeneralException
|
||||
* @throws ObjectExistsException
|
||||
*/
|
||||
final protected function commit(Entry $o,int $action): Collection
|
||||
{
|
||||
switch ($action) {
|
||||
case static::LDAP_IMPORT_ADD:
|
||||
try {
|
||||
$o->save();
|
||||
|
||||
} catch (\Exception $e) {
|
||||
return collect([
|
||||
'dn'=>$o->getDN(),
|
||||
'result'=>sprintf('%d: %s (%s)',
|
||||
($x=$e->getDetailedError())->getErrorCode(),
|
||||
$x->getErrorMessage(),
|
||||
$x->getDiagnosticMessage(),
|
||||
)
|
||||
]);
|
||||
}
|
||||
|
||||
return collect(['dn'=>$o->getDN(),'result'=>__('Created')]);
|
||||
|
||||
default:
|
||||
throw new GeneralException('Unhandled action during commit: '.$action);
|
||||
}
|
||||
}
|
||||
|
||||
abstract public function process(): Collection;
|
||||
}
|
@ -1,233 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP\Import;
|
||||
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Nette\NotImplementedException;
|
||||
|
||||
use App\Classes\LDAP\Import;
|
||||
use App\Exceptions\Import\{GeneralException,VersionException};
|
||||
use App\Ldap\Entry;
|
||||
|
||||
/**
|
||||
* Import LDIF to LDAP using an LDIF format
|
||||
*
|
||||
* The LDIF spec is described by RFC2849
|
||||
* http://www.ietf.org/rfc/rfc2849.txt
|
||||
*/
|
||||
class LDIF extends Import
|
||||
{
|
||||
private const LOGKEY = 'ILF';
|
||||
|
||||
public function process(): Collection
|
||||
{
|
||||
$c = 0;
|
||||
$action = NULL;
|
||||
$attribute = NULL;
|
||||
$base64encoded = FALSE;
|
||||
$o = NULL;
|
||||
$value = '';
|
||||
$version = NULL;
|
||||
$result = collect();
|
||||
|
||||
// @todo When renaming DNs, the hotlink should point to the new entry on success, or the old entry on failure.
|
||||
foreach (preg_split('/(\r?\n|\r)/',$this->input) as $line) {
|
||||
$c++;
|
||||
Log::debug(sprintf('%s: LDIF Line [%s]',self::LOGKEY,$line));
|
||||
$line = trim($line);
|
||||
|
||||
// If the line starts with a comment, ignore it
|
||||
if (preg_match('/^#/',$line))
|
||||
continue;
|
||||
|
||||
// If we have a blank line, then that completes this command
|
||||
if (! $line) {
|
||||
if (! is_null($o)) {
|
||||
// Add the last attribute;
|
||||
$o->addAttribute($attribute,$base64encoded ? base64_decode($value) : $value);
|
||||
|
||||
Log::debug(sprintf('%s: Committing Entry [%s]',self::LOGKEY,$o->getDN()));
|
||||
|
||||
// Commit
|
||||
$result->push($this->commit($o,$action));
|
||||
$result->last()->put('line',$c);
|
||||
|
||||
$o = NULL;
|
||||
$action = NULL;
|
||||
$base64encoded = FALSE;
|
||||
$attribute = NULL;
|
||||
$value = '';
|
||||
|
||||
// Else its a blank line
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$m = [];
|
||||
preg_match('/^([a-zA-Z0-9;-]+)(:+)\s+(.*)$/',$line,$m);
|
||||
|
||||
switch ($x=Arr::get($m,1)) {
|
||||
case 'changetype':
|
||||
if ($m[2] !== ':')
|
||||
throw new GeneralException(sprintf('ChangeType cannot be base64 encoded set at [%d]. (line %d)',$version,$c));
|
||||
|
||||
switch ($m[3]) {
|
||||
// if (preg_match('/^changetype:[ ]*(delete|add|modrdn|moddn|modify)/i',$lines[0])) {
|
||||
default:
|
||||
throw new NotImplementedException(sprintf('Unknown change type [%s]? (line %d)',$m[3],$c));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'version':
|
||||
if (! is_null($version))
|
||||
throw new VersionException(sprintf('Version has already been set at [%d]. (line %d)',$version,$c));
|
||||
|
||||
if ($m[2] !== ':')
|
||||
throw new VersionException(sprintf('Version cannot be base64 encoded set at [%d]. (line %d)',$version,$c));
|
||||
|
||||
$version = (int)$m[3];
|
||||
break;
|
||||
|
||||
// Treat it as an attribute
|
||||
default:
|
||||
// If $m is NULL, then this is the 2nd (or more) line of a base64 encoded value
|
||||
if (! $m) {
|
||||
$value .= $line;
|
||||
Log::debug(sprintf('%s: Attribute [%s] adding [%s] (%d)',self::LOGKEY,$attribute,$line,$c));
|
||||
|
||||
// add to last attr value
|
||||
continue 2;
|
||||
}
|
||||
|
||||
// We are ready to create the entry or add the attribute
|
||||
if ($attribute) {
|
||||
if ($attribute === 'dn') {
|
||||
if (! is_null($o))
|
||||
throw new GeneralException(sprintf('Previous Entry not complete? (line %d)',$c));
|
||||
|
||||
$dn = $base64encoded ? base64_decode($value) : $value;
|
||||
Log::debug(sprintf('%s: Creating new entry:',self::LOGKEY,$dn));
|
||||
//$o = Entry::find($dn);
|
||||
|
||||
// If it doesnt exist, we'll create it
|
||||
//if (! $o) {
|
||||
$o = new Entry;
|
||||
$o->setDn($dn);
|
||||
//}
|
||||
|
||||
$action = self::LDAP_IMPORT_ADD;
|
||||
|
||||
} else {
|
||||
Log::debug(sprintf('%s: Adding Attribute [%s] value [%s] (%d)',self::LOGKEY,$attribute,$value,$c));
|
||||
|
||||
if ($value)
|
||||
$o->addAttribute($attribute,$base64encoded ? base64_decode($value) : $value);
|
||||
else
|
||||
throw new GeneralException(sprintf('Attribute has no value [%s] (line %d)',$attribute,$c));
|
||||
}
|
||||
}
|
||||
|
||||
// Start of a new attribute
|
||||
$base64encoded = ($m[2] === '::');
|
||||
// @todo Need to parse attributes with ';' options
|
||||
$attribute = $m[1];
|
||||
$value = $m[3];
|
||||
|
||||
Log::debug(sprintf('%s: New Attribute [%s] with [%s] (%d)',self::LOGKEY,$attribute,$value,$c));
|
||||
}
|
||||
|
||||
if ($version !== 1)
|
||||
throw new VersionException('LDIF import cannot handle version: '.($version ?: __('NOT DEFINED')));
|
||||
}
|
||||
|
||||
// We may still have a pending action
|
||||
if ($action) {
|
||||
// Add the last attribute;
|
||||
$o->addAttribute($attribute,$base64encoded ? base64_decode($value) : $value);
|
||||
|
||||
Log::debug(sprintf('%s: Committing Entry [%s]',self::LOGKEY,$o->getDN()));
|
||||
|
||||
// Commit
|
||||
$result->push($this->commit($o,$action));
|
||||
$result->last()->put('line',$c);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function readEntry() {
|
||||
static $haveVersion = false;
|
||||
|
||||
if ($lines = $this->nextLines()) {
|
||||
|
||||
$server = $this->getServer();
|
||||
|
||||
# The first line should be the DN
|
||||
if (preg_match('/^dn:/',$lines[0])) {
|
||||
list($text,$dn) = $this->getAttrValue(array_shift($lines));
|
||||
|
||||
# The second line should be our changetype
|
||||
if (preg_match('/^changetype:[ ]*(delete|add|modrdn|moddn|modify)/i',$lines[0])) {
|
||||
$attrvalue = $this->getAttrValue($lines[0]);
|
||||
$changetype = $attrvalue[1];
|
||||
array_shift($lines);
|
||||
|
||||
} else
|
||||
$changetype = 'add';
|
||||
|
||||
$this->template = new Template($this->server_id,null,null,$changetype);
|
||||
|
||||
switch ($changetype) {
|
||||
case 'add':
|
||||
$rdn = get_rdn($dn);
|
||||
$container = $server->getContainer($dn);
|
||||
|
||||
$this->template->setContainer($container);
|
||||
$this->template->accept();
|
||||
|
||||
$this->getAddDetails($lines);
|
||||
$this->template->setRDNAttributes($rdn);
|
||||
|
||||
return $this->template;
|
||||
|
||||
break;
|
||||
|
||||
case 'modify':
|
||||
if (! $server->dnExists($dn))
|
||||
return $this->error(sprintf('%s %s',_('DN does not exist'),$dn),$lines);
|
||||
|
||||
$this->template->setDN($dn);
|
||||
$this->template->accept(false,true);
|
||||
|
||||
return $this->getModifyDetails($lines);
|
||||
|
||||
break;
|
||||
|
||||
case 'moddn':
|
||||
case 'modrdn':
|
||||
if (! $server->dnExists($dn))
|
||||
return $this->error(sprintf('%s %s',_('DN does not exist'),$dn),$lines);
|
||||
|
||||
$this->template->setDN($dn);
|
||||
$this->template->accept();
|
||||
|
||||
return $this->getModRDNAttributes($lines);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
if (! $server->dnExists($dn))
|
||||
return $this->error(_('Unkown change type'),$lines);
|
||||
}
|
||||
|
||||
} else
|
||||
return $this->error(_('A valid dn line is required'),$lines);
|
||||
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
}
|
@ -1,598 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP\Schema;
|
||||
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* Represents an LDAP AttributeType
|
||||
*
|
||||
* @package phpLDAPadmin
|
||||
* @subpackage Schema
|
||||
*/
|
||||
final class AttributeType extends Base {
|
||||
// The attribute from which this attribute inherits (if any)
|
||||
private ?string $sup_attribute = NULL;
|
||||
|
||||
// Array of AttributeTypes which inherit from this one
|
||||
private Collection $children;
|
||||
|
||||
// The equality rule used
|
||||
private ?string $equality = NULL;
|
||||
|
||||
// The ordering of the attributeType
|
||||
private ?string $ordering = NULL;
|
||||
|
||||
// Supports substring matching?
|
||||
private ?string $sub_str_rule = NULL;
|
||||
|
||||
// The full syntax string, ie 1.2.3.4{16}
|
||||
private ?string $syntax = NULL;
|
||||
private ?string $syntax_oid = NULL;
|
||||
|
||||
// boolean: is single valued only?
|
||||
private bool $is_single_value = FALSE;
|
||||
|
||||
// boolean: is collective?
|
||||
private bool $is_collective = FALSE;
|
||||
|
||||
// boolean: can use modify?
|
||||
private bool $is_no_user_modification = FALSE;
|
||||
|
||||
// The usage string set by the LDAP schema
|
||||
private ?string $usage = NULL;
|
||||
|
||||
// An array of alias attribute names, strings
|
||||
private Collection $aliases;
|
||||
|
||||
// The max number of characters this attribute can be
|
||||
private ?int $max_length = NULL;
|
||||
|
||||
// A string description of the syntax type (taken from the LDAPSyntaxes)
|
||||
/**
|
||||
* @deprecated - reference syntaxes directly if possible
|
||||
* @var string
|
||||
*/
|
||||
private ?string $type = NULL;
|
||||
|
||||
// An array of objectClasses which use this attributeType (must be set by caller)
|
||||
private Collection $used_in_object_classes;
|
||||
|
||||
// A list of object class names that require this attribute type.
|
||||
private Collection $required_by_object_classes;
|
||||
|
||||
// This attribute has been forced a MAY attribute by the configuration.
|
||||
private bool $forced_as_may = FALSE;
|
||||
|
||||
/**
|
||||
* Creates a new AttributeType object from a raw LDAP AttributeType string.
|
||||
*
|
||||
* eg: ( 2.5.4.0 NAME 'objectClass' DESC 'RFC4512: object classes of the entity' EQUALITY objectIdentifierMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )
|
||||
*/
|
||||
public function __construct(string $line) {
|
||||
Log::debug(sprintf('Parsing AttributeType [%s]',$line));
|
||||
|
||||
parent::__construct($line);
|
||||
|
||||
$strings = preg_split('/[\s,]+/',$line,-1,PREG_SPLIT_DELIM_CAPTURE);
|
||||
|
||||
// Init
|
||||
$this->children = collect();
|
||||
$this->aliases = collect();
|
||||
$this->used_in_object_classes = collect();
|
||||
$this->required_by_object_classes = collect();
|
||||
|
||||
for ($i=0; $i < count($strings); $i++) {
|
||||
switch ($strings[$i]) {
|
||||
case '(':
|
||||
case ')':
|
||||
break;
|
||||
|
||||
case 'NAME':
|
||||
// @note Some schema's return a (' instead of a ( '
|
||||
if ($strings[$i+1] != '(' && ! preg_match('/^\(/',$strings[$i+1])) {
|
||||
do {
|
||||
$this->name .= (strlen($this->name) ? ' ' : '').$strings[++$i];
|
||||
|
||||
} while (! preg_match("/\'$/s",$strings[$i]));
|
||||
|
||||
// This attribute has no aliases
|
||||
//$this->aliases = collect();
|
||||
|
||||
} else {
|
||||
$i++;
|
||||
|
||||
do {
|
||||
// In case we came here becaues of a ('
|
||||
if (preg_match('/^\(/',$strings[$i]))
|
||||
$strings[$i] = preg_replace('/^\(/','',$strings[$i]);
|
||||
else
|
||||
$i++;
|
||||
|
||||
$this->name .= (strlen($this->name) ? ' ' : '').$strings[++$i];
|
||||
|
||||
} while (! preg_match("/\'$/s",$strings[$i]));
|
||||
|
||||
// Add alias names for this attribute
|
||||
while ($strings[++$i] != ')') {
|
||||
$alias = $strings[$i];
|
||||
$alias = preg_replace("/^\'(.*)\'$/",'$1',$alias);
|
||||
$this->addAlias($alias);
|
||||
}
|
||||
}
|
||||
|
||||
$this->name = preg_replace("/^\'(.*)\'$/",'$1',$this->name);
|
||||
|
||||
Log::debug(sprintf('- Case NAME returned (%s)',$this->name),['aliases'=>$this->aliases]);
|
||||
break;
|
||||
|
||||
case 'DESC':
|
||||
do {
|
||||
$this->description .= (strlen($this->description) ? ' ' : '').$strings[++$i];
|
||||
|
||||
} while (! preg_match("/\'$/s",$strings[$i]));
|
||||
|
||||
$this->description = preg_replace("/^\'(.*)\'$/",'$1',$this->description);
|
||||
|
||||
Log::debug(sprintf('- Case DESC returned (%s)',$this->description));
|
||||
break;
|
||||
|
||||
case 'OBSOLETE':
|
||||
$this->is_obsolete = TRUE;
|
||||
|
||||
Log::debug(sprintf('- Case OBSOLETE returned (%s)',$this->is_obsolete));
|
||||
break;
|
||||
|
||||
case 'SUP':
|
||||
$i++;
|
||||
$this->sup_attribute = preg_replace("/^\'(.*)\'$/",'$1',$strings[$i]);
|
||||
|
||||
Log::debug(sprintf('- Case SUP returned (%s)',$this->sup_attribute));
|
||||
break;
|
||||
|
||||
case 'EQUALITY':
|
||||
$this->equality = $strings[++$i];
|
||||
|
||||
Log::debug(sprintf('- Case EQUALITY returned (%s)',$this->equality));
|
||||
break;
|
||||
|
||||
case 'ORDERING':
|
||||
$this->ordering = $strings[++$i];
|
||||
|
||||
Log::debug(sprintf('- Case ORDERING returned (%s)',$this->ordering));
|
||||
break;
|
||||
|
||||
case 'SUBSTR':
|
||||
$this->sub_str_rule = $strings[++$i];
|
||||
|
||||
Log::debug(sprintf('- Case SUBSTR returned (%s)',$this->sub_str_rule));
|
||||
break;
|
||||
|
||||
case 'SYNTAX':
|
||||
$this->syntax = $strings[++$i];
|
||||
$this->syntax_oid = preg_replace('/{\d+}$/','',$this->syntax);
|
||||
Log::debug(sprintf('/ Evaluating SYNTAX returned (%s) [%s]',$this->syntax,$this->syntax_oid));
|
||||
|
||||
// Does this SYNTAX string specify a max length (ie, 1.2.3.4{16})
|
||||
$m = [];
|
||||
if (preg_match('/{(\d+)}$/',$this->syntax,$m))
|
||||
$this->max_length = $m[1];
|
||||
else
|
||||
$this->max_length = NULL;
|
||||
|
||||
if ($i < count($strings) - 1 && $strings[$i+1] == '{')
|
||||
do {
|
||||
$this->name .= ' '.$strings[++$i];
|
||||
} while ($strings[$i] != '}');
|
||||
|
||||
$this->syntax = preg_replace("/^\'(.*)\'$/",'$1',$this->syntax);
|
||||
$this->syntax_oid = preg_replace("/^\'(.*)\'$/",'$1',$this->syntax_oid);
|
||||
|
||||
Log::debug(sprintf('- Case SYNTAX returned (%s) [%s] {%d}',$this->syntax,$this->syntax_oid,$this->max_length));
|
||||
break;
|
||||
|
||||
case 'SINGLE-VALUE':
|
||||
$this->is_single_value = TRUE;
|
||||
|
||||
Log::debug(sprintf('- Case SINGLE-VALUE returned (%s)',$this->is_single_value));
|
||||
break;
|
||||
|
||||
case 'COLLECTIVE':
|
||||
$this->is_collective = TRUE;
|
||||
|
||||
Log::debug(sprintf('- Case COLLECTIVE returned (%s)',$this->is_collective));
|
||||
break;
|
||||
|
||||
case 'NO-USER-MODIFICATION':
|
||||
$this->is_no_user_modification = TRUE;
|
||||
|
||||
Log::debug(sprintf('- Case NO-USER-MODIFICATION returned (%s)',$this->is_no_user_modification));
|
||||
break;
|
||||
|
||||
case 'USAGE':
|
||||
$this->usage = $strings[++$i];
|
||||
|
||||
Log::debug(sprintf('- Case USAGE returned (%s)',$this->usage));
|
||||
break;
|
||||
|
||||
// @note currently not captured
|
||||
case 'X-ORDERED':
|
||||
Log::error(sprintf('- Case X-ORDERED returned (%s)',$strings[++$i]));
|
||||
break;
|
||||
|
||||
// @note currently not captured
|
||||
case 'X-ORIGIN':
|
||||
$value = '';
|
||||
|
||||
do {
|
||||
$value .= (strlen($value) ? ' ' : '').$strings[++$i];
|
||||
|
||||
} while (! preg_match("/\'$/s",$strings[$i]));
|
||||
|
||||
Log::error(sprintf('- Case X-ORIGIN returned (%s)',$value));
|
||||
break;
|
||||
|
||||
default:
|
||||
if (preg_match('/[\d\.]+/i',$strings[$i]) && ($i === 1)) {
|
||||
$this->oid = $strings[$i];
|
||||
Log::debug(sprintf('- Case default returned (%s)',$this->oid));
|
||||
|
||||
} elseif ($strings[$i])
|
||||
Log::alert(sprintf('! Case default discovered a value NOT parsed (%s)',$strings[$i]),['line'=>$line]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function __clone()
|
||||
{
|
||||
// When we clone, we need to break the reference too
|
||||
$this->aliases = clone $this->aliases;
|
||||
}
|
||||
|
||||
public function __get(string $key): mixed
|
||||
{
|
||||
switch ($key) {
|
||||
case 'aliases': return $this->aliases;
|
||||
case 'children': return $this->children;
|
||||
case 'forced_as_may': return $this->forced_as_may;
|
||||
case 'is_collective': return $this->is_collective;
|
||||
case 'is_editable': return ! $this->is_no_user_modification;
|
||||
case 'is_no_user_modification': return $this->is_no_user_modification;
|
||||
case 'is_single_value': return $this->is_single_value;
|
||||
case 'equality': return $this->equality;
|
||||
case 'max_length': return $this->max_length;
|
||||
case 'ordering': return $this->ordering;
|
||||
case 'required_by_object_classes': return $this->required_by_object_classes;
|
||||
case 'sub_str_rule': return $this->sub_str_rule;
|
||||
case 'sup_attribute': return $this->sup_attribute;
|
||||
case 'syntax': return $this->syntax;
|
||||
case 'syntax_oid': return $this->syntax_oid;
|
||||
case 'type': return $this->type;
|
||||
case 'usage': return $this->usage;
|
||||
case 'used_in_object_classes': return $this->used_in_object_classes;
|
||||
case 'validation': return Arr::get(config('ldap.validation'),$this->name_lc);
|
||||
|
||||
default: return parent::__get($key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an attribute name to the alias array.
|
||||
*
|
||||
* @param string $alias The name of a new attribute to add to this attribute's list of aliases.
|
||||
*/
|
||||
public function addAlias(string $alias): void
|
||||
{
|
||||
$this->aliases->push($alias);
|
||||
}
|
||||
|
||||
/**
|
||||
* Children of this attribute type that inherit from this one
|
||||
*
|
||||
* @param string $child
|
||||
* @return void
|
||||
*/
|
||||
public function addChild(string $child): void
|
||||
{
|
||||
$this->children->push($child);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an objectClass name to this attribute's list of "required by" objectClasses,
|
||||
* that is the list of objectClasses which must have this attribute.
|
||||
*
|
||||
* @param string $name The name of the objectClass to add.
|
||||
*/
|
||||
public function addRequiredByObjectClass(string $name): void
|
||||
{
|
||||
if ($this->required_by_object_classes->search($name) === FALSE)
|
||||
$this->required_by_object_classes->push($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an objectClass name to this attribute's list of "used in" objectClasses,
|
||||
* that is the list of objectClasses which provide this attribute.
|
||||
*
|
||||
* @param string $name The name of the objectClass to add.
|
||||
*/
|
||||
public function addUsedInObjectClass(string $name): void
|
||||
{
|
||||
if ($this->used_in_object_classes->search($name) === FALSE)
|
||||
$this->used_in_object_classes->push($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the names of attributes that are an alias for this attribute (if any).
|
||||
*
|
||||
* @return Collection An array of names of attributes which alias this attribute or
|
||||
* an empty array if no attribute aliases this object.
|
||||
* @deprecated use class->aliases
|
||||
*/
|
||||
public function getAliases(): Collection
|
||||
{
|
||||
return $this->aliases;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this attribute's equality string
|
||||
*
|
||||
* @return string
|
||||
* @deprecated use $this->equality
|
||||
*/
|
||||
public function getEquality()
|
||||
{
|
||||
return $this->equality;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether this attribute is collective.
|
||||
*
|
||||
* @return boolean Returns TRUE if this attribute is collective and FALSE otherwise.
|
||||
* @deprecated use $this->is_collective
|
||||
*/
|
||||
public function getIsCollective(): bool
|
||||
{
|
||||
return $this->is_collective;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether this attribute is not modifiable by users.
|
||||
*
|
||||
* @return boolean Returns TRUE if this attribute is not modifiable by users.
|
||||
* @deprecated use $this->is_no_user_modification
|
||||
*/
|
||||
public function getIsNoUserModification(): bool
|
||||
{
|
||||
return $this->is_no_user_modification;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether this attribute is single-valued. If this attribute only supports single values, TRUE
|
||||
* is returned. If this attribute supports multiple values, FALSE is returned.
|
||||
*
|
||||
* @return boolean Returns TRUE if this attribute is single-valued or FALSE otherwise.
|
||||
* @deprecated use class->is_single_value
|
||||
*/
|
||||
public function getIsSingleValue(): bool
|
||||
{
|
||||
return $this->is_single_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this attribute's the maximum length. If no maximum is defined by the LDAP server, NULL is returned.
|
||||
*
|
||||
* @return int The maximum length (in characters) of this attribute or NULL if no maximum is specified.
|
||||
* @deprecated use $this->max_length;
|
||||
*/
|
||||
public function getMaxLength()
|
||||
{
|
||||
return $this->max_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this attribute's ordering specification.
|
||||
*
|
||||
* @return string
|
||||
* @deprecated use $this->ordering
|
||||
*/
|
||||
public function getOrdering(): string
|
||||
{
|
||||
return $this->ordering;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of "required by" objectClasses, that is the list of objectClasses
|
||||
* which provide must have attribute.
|
||||
*
|
||||
* @return array An array of names of objectclasses (strings) which provide this attribute
|
||||
*/
|
||||
public function getRequiredByObjectClasses() {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',9,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->required_by_object_classes);
|
||||
|
||||
return $this->required_by_object_classes;
|
||||
}
|
||||
/**
|
||||
* Gets this attribute's substring matching specification
|
||||
*
|
||||
* @return string
|
||||
* @deprecated use $this->sub_str_rule;
|
||||
*/
|
||||
public function getSubstr() {
|
||||
return $this->sub_str_rule;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this attribute's parent attribute (if any). If this attribute does not
|
||||
* inherit from another attribute, NULL is returned.
|
||||
*
|
||||
* @return string
|
||||
* @deprecated use $class->sup_attribute directly
|
||||
*/
|
||||
public function getSupAttribute() {
|
||||
return $this->sup_attribute;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this attribute's syntax OID. Differs from getSyntaxString() in that this
|
||||
* function only returns the actual OID with any length specification removed.
|
||||
* Ie, if the syntax string is "1.2.3.4{16}", this function only retruns
|
||||
* "1.2.3.4".
|
||||
*
|
||||
* @return string The syntax OID string.
|
||||
* @deprecated use $this->syntax_oid;
|
||||
*/
|
||||
public function getSyntaxOID()
|
||||
{
|
||||
return $this->syntax_oid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this attribute's raw syntax string (ie: "1.2.3.4{16}").
|
||||
*
|
||||
* @return string The raw syntax string
|
||||
*/
|
||||
public function getSyntaxString() {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',9,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->syntax);
|
||||
|
||||
return $this->syntax;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this attribute's type
|
||||
*
|
||||
* @return string The attribute's type.
|
||||
* @deprecated use $this->type;
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this attribute's usage string as defined by the LDAP server
|
||||
*
|
||||
* @return string
|
||||
* @deprecated use $this->usage
|
||||
*/
|
||||
public function getUsage()
|
||||
{
|
||||
return $this->usage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of "used in" objectClasses, that is the list of objectClasses
|
||||
* which provide this attribute.
|
||||
*
|
||||
* @return Collection An array of names of objectclasses (strings) which provide this attribute
|
||||
* @deprecated use $this->used_in_object_classes
|
||||
*/
|
||||
public function getUsedInObjectClasses(): Collection
|
||||
{
|
||||
return $this->used_in_object_classes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the specified attribute is an alias for this one (based on this attribute's alias list).
|
||||
*
|
||||
* @param string $attr_name The name of the attribute to check.
|
||||
* @return boolean TRUE if the specified attribute is an alias for this one, or FALSE otherwise.
|
||||
*/
|
||||
public function isAliasFor($attr_name) {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',9,0,__FILE__,__LINE__,__METHOD__,$fargs);
|
||||
|
||||
foreach ($this->aliases as $alias_attr_name)
|
||||
if (strcasecmp($alias_attr_name,$attr_name) == 0)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
* @deprecated use $this->forced_as_may
|
||||
*/
|
||||
public function isForceMay(): bool
|
||||
{
|
||||
return $this->forced_as_may;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an attribute name from this attribute's alias array.
|
||||
*
|
||||
* @param string $alias The name of the attribute to remove.
|
||||
*/
|
||||
public function removeAlias(string $alias): void
|
||||
{
|
||||
if (($x=$this->aliases->search($alias)) !== FALSE)
|
||||
$this->aliases->forget($x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a list of object classes, determine if this is a required attribute
|
||||
*
|
||||
* @param Collection $oc List of objectclasses to compare.
|
||||
* @return Collection
|
||||
*/
|
||||
public function required_by(Collection $oc): Collection
|
||||
{
|
||||
return $oc->diff($this->required_by_object_classes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this attribute's list of aliases.
|
||||
*
|
||||
* @param Collection $aliases The array of alias names (strings)
|
||||
* @deprecated use $this->aliases =
|
||||
*/
|
||||
public function setAliases(Collection $aliases): void
|
||||
{
|
||||
$this->aliases = $aliases;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will mark this attribute as a forced MAY attribute
|
||||
*/
|
||||
public function setForceMay() {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',9,1,__FILE__,__LINE__,__METHOD__,$fargs);
|
||||
|
||||
$this->forced_as_may = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether this attribute is single-valued.
|
||||
*
|
||||
* @param boolean $is
|
||||
*/
|
||||
public function setIsSingleValue(bool $is): void
|
||||
{
|
||||
$this->is_single_value = $is;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this attribute's SUP attribute (ie, the attribute from which this attribute inherits).
|
||||
*
|
||||
* @param string $attr The name of the new parent (SUP) attribute
|
||||
*/
|
||||
public function setSupAttribute(string $attr): void
|
||||
{
|
||||
$this->sup_attribute = trim($attr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this attribute's type.
|
||||
*
|
||||
* @param string $type The new type.
|
||||
*/
|
||||
public function setType($type) {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',9,1,__FILE__,__LINE__,__METHOD__,$fargs);
|
||||
|
||||
$this->type = $type;
|
||||
}
|
||||
}
|
@ -1,120 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP\Schema;
|
||||
|
||||
use App\Exceptions\InvalidUsage;
|
||||
|
||||
/**
|
||||
* Generic parent class for all schema items.
|
||||
*
|
||||
* A schema item is an ObjectClass, an AttributeBype, a MatchingRule, or a Syntax.
|
||||
* All schema items have at least two things in common: An OID and a Description.
|
||||
*/
|
||||
abstract class Base {
|
||||
// Record the LDAP String
|
||||
private string $line;
|
||||
|
||||
// The schema item's name.
|
||||
protected ?string $name = NULL;
|
||||
|
||||
// The OID of this schema item.
|
||||
protected string $oid;
|
||||
|
||||
# The description of this schema item.
|
||||
protected ?string $description = NULL;
|
||||
|
||||
// Boolean value indicating whether this objectClass is obsolete
|
||||
private bool $is_obsolete = FALSE;
|
||||
|
||||
public function __construct(string $line)
|
||||
{
|
||||
$this->line = $line;
|
||||
}
|
||||
|
||||
public function __get(string $key): mixed
|
||||
{
|
||||
switch ($key) {
|
||||
case 'description': return $this->description;
|
||||
case 'is_obsolete': return $this->is_obsolete;
|
||||
case 'line': return $this->line;
|
||||
case 'name': return $this->name;
|
||||
case 'name_lc': return strtolower($this->name);
|
||||
case 'oid': return $this->oid;
|
||||
|
||||
default:
|
||||
throw new InvalidUsage('Unknown key:'.$key);
|
||||
}
|
||||
}
|
||||
|
||||
public function __isset(string $key): bool
|
||||
{
|
||||
return isset($this->{$key});
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @deprecated replace with $class->description
|
||||
*/
|
||||
public function getDescription(): string
|
||||
{
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether this item is flagged as obsolete by the LDAP server.
|
||||
*
|
||||
* @deprecated replace with $this->is_obsolete
|
||||
*/
|
||||
public function getIsObsolete(): bool
|
||||
{
|
||||
return $this->is_obsolete;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the objects name.
|
||||
*
|
||||
* @param boolean $lower Return the name in lower case (default)
|
||||
* @return string The name
|
||||
* @deprecated use object->name
|
||||
*/
|
||||
public function getName(bool $lower=TRUE): string
|
||||
{
|
||||
return $lower ? strtolower($this->name) : $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the objects name.
|
||||
*
|
||||
* @return string The name
|
||||
* @deprecated use object->oid
|
||||
*/
|
||||
public function getOID(): string
|
||||
{
|
||||
return $this->oid;
|
||||
}
|
||||
|
||||
public function setDescription(string $desc): void
|
||||
{
|
||||
$this->description = $desc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this attribute's name.
|
||||
*
|
||||
* @param string $name The new name to give this attribute.
|
||||
*/
|
||||
public function setName($name): void
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
public function setOID(string $oid): void
|
||||
{
|
||||
$this->oid = $oid;
|
||||
}
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP\Schema;
|
||||
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* Represents an LDAP Syntax
|
||||
*
|
||||
* @package phpLDAPadmin
|
||||
* @subpackage Schema
|
||||
*/
|
||||
final class LDAPSyntax extends Base {
|
||||
// Is human readable?
|
||||
private ?bool $is_not_human_readable = NULL;
|
||||
|
||||
// Binary transfer required?
|
||||
private ?bool $binary_transfer_required = NULL;
|
||||
|
||||
/**
|
||||
* Creates a new Syntax object from a raw LDAP syntax string.
|
||||
*/
|
||||
public function __construct(string $line) {
|
||||
Log::debug(sprintf('Parsing LDAPSyntax [%s]',$line));
|
||||
|
||||
parent::__construct($line);
|
||||
|
||||
$strings = preg_split('/[\s,]+/',$line,-1,PREG_SPLIT_DELIM_CAPTURE);
|
||||
|
||||
for ($i=0; $i<count($strings); $i++) {
|
||||
switch($strings[$i]) {
|
||||
case '(':
|
||||
case ')':
|
||||
break;
|
||||
|
||||
case 'DESC':
|
||||
do {
|
||||
$this->description .= (strlen($this->description) ? ' ' : '').$strings[++$i];
|
||||
|
||||
} while (! preg_match("/\'$/s",$strings[$i]));
|
||||
|
||||
$this->description = preg_replace("/^\'(.*)\'$/",'$1',$this->description);
|
||||
|
||||
Log::debug(sprintf('- Case DESC returned (%s)',$this->description));
|
||||
break;
|
||||
|
||||
case 'X-BINARY-TRANSFER-REQUIRED':
|
||||
$this->binary_transfer_required = (str_replace("'",'',$strings[++$i]) === 'TRUE');
|
||||
|
||||
Log::debug(sprintf('- Case X-BINARY-TRANSFER-REQUIRED returned (%s)',$this->binary_transfer_required));
|
||||
break;
|
||||
|
||||
case 'X-NOT-HUMAN-READABLE':
|
||||
$this->is_not_human_readable = (str_replace("'",'',$strings[++$i]) === 'TRUE');
|
||||
|
||||
Log::debug(sprintf('- Case X-NOT-HUMAN-READABLE returned (%s)',$this->is_not_human_readable));
|
||||
break;
|
||||
|
||||
default:
|
||||
if (preg_match('/[\d\.]+/i',$strings[$i]) && ($i === 1)) {
|
||||
$this->oid = $strings[$i];
|
||||
Log::debug(sprintf('- Case default returned (%s)',$this->oid));
|
||||
|
||||
} elseif ($strings[$i])
|
||||
Log::alert(sprintf('! Case default discovered a value NOT parsed (%s)',$strings[$i]),['line'=>$line]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function __get(string $key): mixed
|
||||
{
|
||||
switch ($key) {
|
||||
case 'binary_transfer_required': return $this->binary_transfer_required;
|
||||
case 'is_not_human_readable': return $this->is_not_human_readable;
|
||||
|
||||
default: return parent::__get($key);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,142 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP\Schema;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* Represents an LDAP MatchingRule
|
||||
*
|
||||
* @package phpLDAPadmin
|
||||
* @subpackage Schema
|
||||
*/
|
||||
final class MatchingRule extends Base {
|
||||
// This rule's syntax OID
|
||||
private ?string $syntax = NULL;
|
||||
|
||||
// An array of attribute names who use this MatchingRule
|
||||
private Collection $used_by_attrs;
|
||||
|
||||
/**
|
||||
* Creates a new MatchingRule object from a raw LDAP MatchingRule string.
|
||||
*/
|
||||
function __construct(string $line) {
|
||||
Log::debug(sprintf('Parsing MatchingRule [%s]',$line));
|
||||
|
||||
parent::__construct($line);
|
||||
|
||||
$strings = preg_split('/[\s,]+/',$line,-1,PREG_SPLIT_DELIM_CAPTURE);
|
||||
|
||||
// Init
|
||||
$this->used_by_attrs = collect();
|
||||
|
||||
for ($i=0; $i<count($strings); $i++) {
|
||||
switch ($strings[$i]) {
|
||||
case '(':
|
||||
case ')':
|
||||
break;
|
||||
|
||||
case 'NAME':
|
||||
if ($strings[$i+1] != '(') {
|
||||
do {
|
||||
$this->name .= (strlen($this->name) ? ' ' : '').$strings[++$i];
|
||||
|
||||
} while (! preg_match("/\'$/s",$strings[$i]));
|
||||
|
||||
} else {
|
||||
$i++;
|
||||
|
||||
do {
|
||||
$this->name .= (strlen($this->name) ? ' ' : '').$strings[++$i];
|
||||
|
||||
} while (! preg_match("/\'$/s",$strings[$i]));
|
||||
|
||||
do {
|
||||
$i++;
|
||||
|
||||
} while (! preg_match('/\)+\)?/',$strings[$i]));
|
||||
}
|
||||
|
||||
$this->name = preg_replace("/^\'/",'',$this->name);
|
||||
$this->name = preg_replace("/\'$/",'',$this->name);
|
||||
|
||||
Log::debug(sprintf(sprintf('- Case NAME returned (%s)',$this->name)));
|
||||
break;
|
||||
|
||||
case 'DESC':
|
||||
do {
|
||||
$this->description .= (strlen($this->description) ? ' ' : '').$strings[++$i];
|
||||
|
||||
} while (! preg_match("/\'$/s",$strings[$i]));
|
||||
|
||||
$this->description = preg_replace("/^\'(.*)\'$/",'$1',$this->description);
|
||||
|
||||
Log::debug(sprintf('- Case DESC returned (%s)',$this->description));
|
||||
break;
|
||||
|
||||
case 'OBSOLETE':
|
||||
$this->is_obsolete = TRUE;
|
||||
|
||||
Log::debug(sprintf('- Case OBSOLETE returned (%s)',$this->is_obsolete));
|
||||
break;
|
||||
|
||||
case 'SYNTAX':
|
||||
$this->syntax = $strings[++$i];
|
||||
|
||||
Log::debug(sprintf('- Case SYNTAX returned (%s)',$this->syntax));
|
||||
break;
|
||||
|
||||
default:
|
||||
if (preg_match('/[\d\.]+/i',$strings[$i]) && ($i === 1)) {
|
||||
$this->oid = $strings[$i];
|
||||
Log::debug(sprintf('- Case default returned (%s)',$this->oid));
|
||||
|
||||
} elseif ($strings[$i])
|
||||
Log::alert(sprintf('! Case default discovered a value NOT parsed (%s)',$strings[$i]),['line'=>$line]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function __get(string $key): mixed
|
||||
{
|
||||
switch ($key) {
|
||||
case 'syntax': return $this->syntax;
|
||||
case 'used_by_attrs': return $this->used_by_attrs;
|
||||
|
||||
default: return parent::__get($key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an attribute name to the list of attributes who use this MatchingRule
|
||||
*/
|
||||
public function addUsedByAttr(string $name): void
|
||||
{
|
||||
$name = trim($name);
|
||||
|
||||
if ($this->used_by_attrs->search($name) === FALSE)
|
||||
$this->used_by_attrs->push($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an array of attribute names (strings) which use this MatchingRule
|
||||
*
|
||||
* @return array The array of attribute names (strings).
|
||||
* @deprecated use $this->used_by_attrs
|
||||
*/
|
||||
public function getUsedByAttrs()
|
||||
{
|
||||
return $this->used_by_attrs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the list of used_by_attrs to the array specified by $attrs;
|
||||
*
|
||||
* @param Collection $attrs The array of attribute names (strings) which use this MatchingRule
|
||||
*/
|
||||
public function setUsedByAttrs(Collection $attrs): void
|
||||
{
|
||||
$this->used_by_attrs = $attrs;
|
||||
}
|
||||
}
|
@ -1,99 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP\Schema;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* Represents an LDAP schema matchingRuleUse entry
|
||||
*
|
||||
* @package phpLDAPadmin
|
||||
* @subpackage Schema
|
||||
*/
|
||||
final class MatchingRuleUse extends Base {
|
||||
// An array of attribute names who use this MatchingRule
|
||||
private Collection $used_by_attrs;
|
||||
|
||||
function __construct(string $line) {
|
||||
Log::debug(sprintf('Parsing MatchingRuleUse [%s]',$line));
|
||||
|
||||
parent::__construct($line);
|
||||
|
||||
$strings = preg_split('/[\s,]+/',$line,-1,PREG_SPLIT_DELIM_CAPTURE);
|
||||
|
||||
// Init
|
||||
$this->used_by_attrs = collect();
|
||||
|
||||
for ($i=0; $i<count($strings); $i++) {
|
||||
switch ($strings[$i]) {
|
||||
case '(':
|
||||
case ')':
|
||||
break;
|
||||
|
||||
case 'NAME':
|
||||
if ($strings[$i+1] != '(') {
|
||||
do {
|
||||
$this->name .= (strlen($this->name) ? ' ' : '').$strings[++$i];
|
||||
|
||||
} while (! preg_match("/\'$/s",$strings[$i]));
|
||||
|
||||
} else {
|
||||
$i++;
|
||||
|
||||
do {
|
||||
$this->name .= (strlen($this->name) ? ' ' : '').$strings[++$i];
|
||||
|
||||
} while (! preg_match("/\'$/s",$strings[$i]));
|
||||
|
||||
do {
|
||||
$i++;
|
||||
|
||||
} while (! preg_match('/\)+\)?/',$strings[$i]));
|
||||
}
|
||||
|
||||
$this->name = preg_replace("/^\'(.*)\'$/",'$1',$this->name);
|
||||
|
||||
Log::debug(sprintf(sprintf('- Case NAME returned (%s)',$this->name)));
|
||||
break;
|
||||
|
||||
case 'APPLIES':
|
||||
if ($strings[$i+1] != '(') {
|
||||
// Has a single attribute name
|
||||
$this->used_by_attrs = collect($strings[++$i]);
|
||||
|
||||
} else {
|
||||
// Has multiple attribute names
|
||||
while ($strings[++$i] != ')') {
|
||||
$new_attr = $strings[++$i];
|
||||
$new_attr = preg_replace("/^\'(.*)\'$/",'$1',$new_attr);
|
||||
|
||||
$this->used_by_attrs->push($new_attr);
|
||||
}
|
||||
}
|
||||
|
||||
Log::debug(sprintf('- Case APPLIES returned (%s)',$this->used_by_attrs->join(',')));
|
||||
break;
|
||||
|
||||
default:
|
||||
if (preg_match('/[\d\.]+/i',$strings[$i]) && ($i === 1)) {
|
||||
$this->oid = $strings[$i];
|
||||
Log::debug(sprintf('- Case default returned (%s)',$this->oid));
|
||||
|
||||
} elseif ($strings[$i])
|
||||
Log::alert(sprintf('! Case default discovered a value NOT parsed (%s)',$strings[$i]),['line'=>$line]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an array of attribute names (strings) which use this MatchingRuleUse object.
|
||||
*
|
||||
* @return array The array of attribute names (strings).
|
||||
* @deprecated use $this->used_by_attrs
|
||||
*/
|
||||
public function getUsedByAttrs()
|
||||
{
|
||||
return $this->used_by_attrs;
|
||||
}
|
||||
}
|
@ -1,540 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP\Schema;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
use App\Classes\LDAP\Server;
|
||||
use App\Exceptions\InvalidUsage;
|
||||
use App\Ldap\Entry;
|
||||
|
||||
/**
|
||||
* Represents an LDAP Schema objectClass
|
||||
*
|
||||
* @package phpLDAPadmin
|
||||
* @subpackage Schema
|
||||
*/
|
||||
final class ObjectClass extends Base {
|
||||
// The server ID that this objectclass belongs to.
|
||||
private Server $server;
|
||||
|
||||
// Array of objectClass names from which this objectClass inherits
|
||||
private Collection $sup_classes;
|
||||
|
||||
// One of STRUCTURAL, ABSTRACT, or AUXILIARY
|
||||
private int $type;
|
||||
|
||||
// Arrays of attribute names that this objectClass requires
|
||||
private Collection $must_attrs;
|
||||
|
||||
// Arrays of attribute names that this objectClass allows, but does not require
|
||||
private Collection $may_attrs;
|
||||
|
||||
// Arrays of attribute names that this objectClass has been forced to MAY attrs, due to configuration
|
||||
private Collection $may_force;
|
||||
|
||||
// Array of objectClasses which inherit from this one
|
||||
private Collection $child_objectclasses;
|
||||
|
||||
private bool $is_obsolete;
|
||||
|
||||
/* ObjectClass Types */
|
||||
private const OC_STRUCTURAL = 0x01;
|
||||
private const OC_ABSTRACT = 0x02;
|
||||
private const OC_AUXILIARY = 0x03;
|
||||
|
||||
/**
|
||||
* Creates a new ObjectClass object given a raw LDAP objectClass string.
|
||||
*
|
||||
* eg: ( 2.5.6.0 NAME 'top' DESC 'top of the superclass chain' ABSTRACT MUST objectClass )
|
||||
*/
|
||||
public function __construct(string $line,Server $server)
|
||||
{
|
||||
parent::__construct($line);
|
||||
|
||||
Log::debug(sprintf('Parsing ObjectClass [%s]',$line));
|
||||
|
||||
$strings = preg_split('/[\s,]+/',$line,-1,PREG_SPLIT_DELIM_CAPTURE);
|
||||
|
||||
// Init
|
||||
$this->server = $server;
|
||||
$this->may_attrs = collect();
|
||||
$this->may_force = collect();
|
||||
$this->must_attrs = collect();
|
||||
$this->sup_classes = collect();
|
||||
$this->child_objectclasses = collect();
|
||||
|
||||
for ($i=0; $i < count($strings); $i++) {
|
||||
switch ($strings[$i]) {
|
||||
case '(':
|
||||
case ')':
|
||||
break;
|
||||
|
||||
case 'NAME':
|
||||
if ($strings[$i+1] != '(') {
|
||||
do {
|
||||
$this->name .= (strlen($this->name) ? ' ' : '').$strings[++$i];
|
||||
|
||||
} while (! preg_match('/\'$/s',$strings[$i]));
|
||||
|
||||
} else {
|
||||
$i++;
|
||||
|
||||
do {
|
||||
$this->name .= (strlen($this->name) ? ' ' : '').$strings[++$i];
|
||||
|
||||
} while (! preg_match('/\'$/s',$strings[$i]));
|
||||
|
||||
do {
|
||||
$i++;
|
||||
} while (! preg_match('/\)+\)?/',$strings[$i]));
|
||||
}
|
||||
|
||||
$this->name = preg_replace("/^\'(.*)\'$/",'$1',$this->name);
|
||||
|
||||
Log::debug(sprintf(sprintf('- Case NAME returned (%s)',$this->name)));
|
||||
break;
|
||||
|
||||
case 'DESC':
|
||||
do {
|
||||
$this->description .= (strlen($this->description) ? ' ' : '').$strings[++$i];
|
||||
|
||||
} while (! preg_match('/\'$/s',$strings[$i]));
|
||||
|
||||
$this->description = preg_replace("/^\'(.*)\'$/",'$1',$this->description);
|
||||
|
||||
Log::debug(sprintf('- Case DESC returned (%s)',$this->description));
|
||||
break;
|
||||
|
||||
case 'OBSOLETE':
|
||||
$this->is_obsolete = TRUE;
|
||||
|
||||
Log::debug(sprintf('- Case OBSOLETE returned (%s)',$this->is_obsolete));
|
||||
break;
|
||||
|
||||
case 'SUP':
|
||||
if ($strings[$i+1] != '(') {
|
||||
$this->sup_classes->push(preg_replace("/'/",'',$strings[++$i]));
|
||||
|
||||
} else {
|
||||
$i++;
|
||||
|
||||
do {
|
||||
$i++;
|
||||
|
||||
if ($strings[$i] != '$')
|
||||
$this->sup_classes->push(preg_replace("/'/",'',$strings[$i]));
|
||||
|
||||
} while (! preg_match('/\)+\)?/',$strings[$i+1]));
|
||||
}
|
||||
|
||||
Log::debug(sprintf('- Case SUP returned (%s)',$this->sup_classes->join(',')));
|
||||
break;
|
||||
|
||||
case 'ABSTRACT':
|
||||
$this->type = self::OC_ABSTRACT;
|
||||
|
||||
Log::debug(sprintf('- Case ABSTRACT returned (%s)',$this->type));
|
||||
break;
|
||||
|
||||
case 'STRUCTURAL':
|
||||
$this->type = self::OC_STRUCTURAL;
|
||||
|
||||
Log::debug(sprintf('- Case STRUCTURAL returned (%s)',$this->type));
|
||||
break;
|
||||
|
||||
case 'AUXILIARY':
|
||||
$this->type = self::OC_AUXILIARY;
|
||||
|
||||
Log::debug(sprintf('- Case AUXILIARY returned (%s)',$this->type));
|
||||
break;
|
||||
|
||||
case 'MUST':
|
||||
$attrs = collect();
|
||||
|
||||
$i = $this->parseList(++$i,$strings,$attrs);
|
||||
|
||||
Log::debug(sprintf('= parseList returned %d (%s)',$i,$attrs->join(',')));
|
||||
|
||||
foreach ($attrs as $string) {
|
||||
$attr = new ObjectClassAttribute($string,$this->name);
|
||||
|
||||
if ($server->isForceMay($attr->getName())) {
|
||||
$this->may_force->push($attr);
|
||||
$this->may_attrs->push($attr);
|
||||
|
||||
} else
|
||||
$this->must_attrs->push($attr);
|
||||
}
|
||||
|
||||
Log::debug(sprintf('- Case MUST returned (%s) (%s)',$this->must_attrs->join(','),$this->may_force->join(',')));
|
||||
break;
|
||||
|
||||
case 'MAY':
|
||||
$attrs = collect();
|
||||
|
||||
$i = $this->parseList(++$i,$strings,$attrs);
|
||||
|
||||
Log::debug(sprintf('parseList returned %d (%s)',$i,$attrs->join(',')));
|
||||
|
||||
foreach ($attrs as $string) {
|
||||
$attr = new ObjectClassAttribute($string,$this->name);
|
||||
$this->may_attrs->push($attr);
|
||||
}
|
||||
|
||||
Log::debug(sprintf('- Case MAY returned (%s)',$this->may_attrs->join(',')));
|
||||
break;
|
||||
|
||||
default:
|
||||
if (preg_match('/[\d\.]+/i',$strings[$i]) && ($i === 1)) {
|
||||
$this->oid = $strings[$i];
|
||||
Log::debug(sprintf('- Case default returned (%s)',$this->oid));
|
||||
|
||||
} elseif ($strings[$i])
|
||||
Log::alert(sprintf('! Case default discovered a value NOT parsed (%s)',$strings[$i]),['line'=>$line]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function __get(string $key): mixed
|
||||
{
|
||||
switch ($key) {
|
||||
case 'attributes':
|
||||
return $this->getAllAttrs();
|
||||
|
||||
case 'sup':
|
||||
return $this->sup_classes;
|
||||
|
||||
case 'type_name':
|
||||
switch ($this->type) {
|
||||
case self::OC_STRUCTURAL: return 'Structural';
|
||||
case self::OC_ABSTRACT: return 'Abstract';
|
||||
case self::OC_AUXILIARY: return 'Auxiliary';
|
||||
default:
|
||||
throw new InvalidUsage('Unknown ObjectClass Type: '.$this->type);
|
||||
}
|
||||
|
||||
default: return parent::__get($key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of attributes that this objectClass provides
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getAllAttrs(): Collection
|
||||
{
|
||||
return $this->getMustAttrs()->merge($this->getMayAttrs());
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an objectClass to the list of objectClasses that inherit
|
||||
* from this objectClass.
|
||||
*
|
||||
* @param String $name The name of the objectClass to add
|
||||
*/
|
||||
public function addChildObjectClass(string $name): void
|
||||
{
|
||||
if ($this->child_objectclasses->search($name) === FALSE) {
|
||||
$this->child_objectclasses->push($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the array of objectClass names which inherit from this objectClass.
|
||||
*
|
||||
* @return Collection Names of objectClasses which inherit from this objectClass.
|
||||
* @deprecated use $this->child_objectclasses
|
||||
*/
|
||||
public function getChildObjectClasses(): Collection
|
||||
{
|
||||
return $this->child_objectclasses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Behaves identically to addMustAttrs, but it operates on the MAY
|
||||
* attributes of this objectClass.
|
||||
*
|
||||
* @param array $attr An array of attribute names (strings) to add.
|
||||
*/
|
||||
private function addMayAttrs(array $attr): void
|
||||
{
|
||||
if (! is_array($attr) || ! count($attr))
|
||||
return;
|
||||
|
||||
$this->may_attrs = $this->may_attrs->merge($attr)->unique();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the specified array of attributes to this objectClass' list of
|
||||
* MUST attributes. The resulting array of must attributes will contain
|
||||
* unique members.
|
||||
*
|
||||
* @param array $attr An array of attribute names (strings) to add.
|
||||
*/
|
||||
private function addMustAttrs(array $attr): void
|
||||
{
|
||||
if (! is_array($attr) || ! count($attr))
|
||||
return;
|
||||
|
||||
$this->must_attrs = $this->must_attrs->merge($attr)->unique();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
* @deprecated use $this->may_force
|
||||
*/
|
||||
public function getForceMayAttrs(): Collection
|
||||
{
|
||||
return $this->may_force;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an array of AttributeType objects that entries of this ObjectClass may define.
|
||||
* This differs from getMayAttrNames in that it returns an array of AttributeType objects
|
||||
*
|
||||
* @param bool $parents Also get the may attrs of our parents.
|
||||
* @return Collection The array of allowed AttributeType objects.
|
||||
*
|
||||
* @throws InvalidUsage
|
||||
* @see getMustAttrNames
|
||||
* @see getMustAttrs
|
||||
* @see getMayAttrNames
|
||||
* @see AttributeType
|
||||
*/
|
||||
public function getMayAttrs(bool $parents=FALSE): Collection
|
||||
{
|
||||
// If we dont need our parents, then we'll just return ours.
|
||||
if (! $parents)
|
||||
return $this->may_attrs->sortBy(function($item) { return strtolower($item->name.$item->source); });
|
||||
|
||||
$attrs = $this->may_attrs;
|
||||
|
||||
foreach ($this->getParents() as $object_class) {
|
||||
$sc = $this->server->schema('objectclasses',$object_class);
|
||||
$attrs = $attrs->merge($sc->getMayAttrs($parents));
|
||||
}
|
||||
|
||||
// Remove any duplicates
|
||||
$attrs = $attrs->unique(function($item) { return $item->name; });
|
||||
|
||||
// Return a sorted list
|
||||
return $attrs->sortBy(function($item) { return strtolower($item->name.$item->source); });
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an array of attribute names (strings) that entries of this ObjectClass must define.
|
||||
* This differs from getMayAttrs in that it returns an array of strings rather than
|
||||
* array of AttributeType objects
|
||||
*
|
||||
* @param bool $parents An array of ObjectClass objects to use when traversing
|
||||
* the inheritance tree. This presents some what of a bootstrapping problem
|
||||
* as we must fetch all objectClasses to determine through inheritance which
|
||||
* attributes this objectClass provides.
|
||||
* @return Collection The array of allowed attribute names (strings).
|
||||
*
|
||||
* @throws InvalidUsage
|
||||
* @see getMustAttrs
|
||||
* @see getMayAttrs
|
||||
* @see getMustAttrNames
|
||||
*/
|
||||
public function getMayAttrNames(bool $parents=FALSE): Collection
|
||||
{
|
||||
return $this->getMayAttrs($parents)->ppluck('name');
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an array of AttributeType objects that entries of this ObjectClass must define.
|
||||
* This differs from getMustAttrNames in that it returns an array of AttributeType objects
|
||||
*
|
||||
* @param bool $parents Also get the must attrs of our parents.
|
||||
* @return Collection The array of required AttributeType objects.
|
||||
*
|
||||
* @throws InvalidUsage
|
||||
* @see getMustAttrNames
|
||||
* @see getMayAttrs
|
||||
* @see getMayAttrNames
|
||||
*/
|
||||
public function getMustAttrs(bool $parents=FALSE): Collection
|
||||
{
|
||||
// If we dont need our parents, then we'll just return ours.
|
||||
if (! $parents)
|
||||
return $this->must_attrs->sortBy(function($item) { return strtolower($item->name.$item->source); });
|
||||
|
||||
$attrs = $this->must_attrs;
|
||||
|
||||
foreach ($this->getParents() as $object_class) {
|
||||
$sc = $this->server->schema('objectclasses',$object_class);
|
||||
$attrs = $attrs->merge($sc->getMustAttrs($parents));
|
||||
}
|
||||
|
||||
// Remove any duplicates
|
||||
$attrs = $attrs->unique(function($item) { return $item->name; });
|
||||
|
||||
// Return a sorted list
|
||||
return $attrs->sortBy(function($item) { return strtolower($item->name.$item->source); });
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an array of attribute names (strings) that entries of this ObjectClass must define.
|
||||
* This differs from getMustAttrs in that it returns an array of strings rather than
|
||||
* array of AttributeType objects
|
||||
*
|
||||
* @param bool $parents An array of ObjectClass objects to use when traversing
|
||||
* the inheritance tree. This presents some what of a bootstrapping problem
|
||||
* as we must fetch all objectClasses to determine through inheritance which
|
||||
* attributes this objectClass provides.
|
||||
* @return Collection The array of allowed attribute names (strings).
|
||||
*
|
||||
* @throws InvalidUsage
|
||||
* @see getMustAttrs
|
||||
* @see getMayAttrs
|
||||
* @see getMayAttrNames
|
||||
*/
|
||||
public function getMustAttrNames(bool $parents=FALSE): Collection
|
||||
{
|
||||
return $this->getMustAttrs($parents)->ppluck('name');
|
||||
}
|
||||
|
||||
/**
|
||||
* This will return all our parent ObjectClass Objects
|
||||
*/
|
||||
public function getParents(): Collection
|
||||
{
|
||||
// If the only class is 'top', then we have no more parents
|
||||
if (($this->sup_classes->count() === 1) && (strtolower($this->sup_classes->first()) === 'top'))
|
||||
return collect();
|
||||
|
||||
$result = collect();
|
||||
|
||||
foreach ($this->sup_classes as $object_class) {
|
||||
$result->push($object_class);
|
||||
|
||||
$oc = $this->server->schema('objectclasses',$object_class);
|
||||
|
||||
if ($oc)
|
||||
$result = $result->merge($oc->getParents());
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the objectClass names from which this objectClass inherits.
|
||||
*
|
||||
* @return Collection An array of objectClass names (strings)
|
||||
* @deprecated use $this->sup_classes;
|
||||
*/
|
||||
public function getSupClasses(): Collection
|
||||
{
|
||||
return $this->sup_classes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type of this objectClass: STRUCTURAL, ABSTRACT, or AUXILIARY.
|
||||
*
|
||||
* @deprecated use $this->type_name
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if an array is listed in the may_force attrs
|
||||
*/
|
||||
public function isForceMay(string $attr): bool
|
||||
{
|
||||
return $this->may_force->ppluck('name')->contains($attr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return if this objectClass is related to $oclass
|
||||
*
|
||||
* @param array $oclass ObjectClasses that this attribute may be related to
|
||||
* @return bool
|
||||
* @throws InvalidUsage
|
||||
*/
|
||||
public function isRelated(array $oclass): bool
|
||||
{
|
||||
// If I am in the array, we'll just return false
|
||||
if (in_array_ignore_case($this->name,$oclass))
|
||||
return FALSE;
|
||||
|
||||
foreach ($oclass as $object_class) {
|
||||
$oc = $this->server->schema('objectclasses',$object_class);
|
||||
|
||||
if ($oc->isStructural() && in_array_ignore_case($this->name,$oc->getParents()))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
public function isStructural(): bool
|
||||
{
|
||||
return $this->type === self::OC_STRUCTURAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an LDAP schema list
|
||||
*
|
||||
* A list starts with a ( followed by a list of attributes separated by $ terminated by )
|
||||
* The first token can therefore be a ( or a (NAME or a (NAME)
|
||||
* The last token can therefore be a ) or NAME)
|
||||
* The last token may be terminated by more than one bracket
|
||||
*/
|
||||
private function parseList(int $i,array $strings,Collection &$attrs): int
|
||||
{
|
||||
$string = $strings[$i];
|
||||
|
||||
if (! preg_match('/^\(/',$string)) {
|
||||
// A bareword only - can be terminated by a ) if the last item
|
||||
if (preg_match('/\)+$/',$string))
|
||||
$string = preg_replace('/\)+$/','',$string);
|
||||
|
||||
$attrs->push($string);
|
||||
|
||||
} elseif (preg_match('/^\(.*\)$/',$string)) {
|
||||
$string = preg_replace('/^\(/','',$string);
|
||||
$string = preg_replace('/\)+$/','',$string);
|
||||
|
||||
$attrs->push($string);
|
||||
|
||||
} else {
|
||||
// Handle the opening cases first
|
||||
if ($string === '(') {
|
||||
$i++;
|
||||
|
||||
} elseif (preg_match('/^\(./',$string)) {
|
||||
$string = preg_replace('/^\(/','',$string);
|
||||
$attrs->push($string);
|
||||
$i++;
|
||||
}
|
||||
|
||||
// Token is either a name, a $ or a ')'
|
||||
// NAME can be terminated by one or more ')'
|
||||
while (! preg_match('/\)+$/',$strings[$i])) {
|
||||
$string = $strings[$i];
|
||||
|
||||
if ($string === '$') {
|
||||
$i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (preg_match('/\)$/',$string))
|
||||
$string = preg_replace('/\)+$/','',$string);
|
||||
else
|
||||
$i++;
|
||||
|
||||
$attrs->push($string);
|
||||
}
|
||||
}
|
||||
|
||||
$attrs = $attrs->sort();
|
||||
|
||||
return $i;
|
||||
}
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP\Schema;
|
||||
|
||||
/**
|
||||
* A simple class for representing AttributeTypes used only by the ObjectClass class.
|
||||
*
|
||||
* Users should never instantiate this class. It represents an attribute internal to
|
||||
* an ObjectClass. If PHP supported inner-classes and variable permissions, this would
|
||||
* be interior to class ObjectClass and flagged private. The reason this class is used
|
||||
* and not the "real" class AttributeType is because this class supports the notion of
|
||||
* a "source" objectClass, meaning that it keeps track of which objectClass originally
|
||||
* specified it. This class is therefore used by the class ObjectClass to determine
|
||||
* inheritance.
|
||||
*/
|
||||
final class ObjectClassAttribute extends Base {
|
||||
// This Attribute's root.
|
||||
private string $source;
|
||||
|
||||
/**
|
||||
* Creates a new ObjectClassAttribute with specified name and source objectClass.
|
||||
*
|
||||
* @param string $name the name of the new attribute.
|
||||
* @param string $source the name of the ObjectClass which specifies this attribute.
|
||||
*/
|
||||
public function __construct($name,$source)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->source = $source;
|
||||
}
|
||||
|
||||
public function __get(string $key): mixed
|
||||
{
|
||||
switch ($key) {
|
||||
case 'source':
|
||||
return $this->source;
|
||||
|
||||
default: return parent::__get($key);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,551 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Exception;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Config;
|
||||
use Illuminate\Support\Facades\Cookie;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
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;
|
||||
use App\Ldap\Entry;
|
||||
|
||||
final class Server
|
||||
{
|
||||
// This servers schema 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 = [
|
||||
'objectclasses',
|
||||
'attributetypes',
|
||||
'ldapsyntaxes',
|
||||
'matchingrules',
|
||||
];
|
||||
|
||||
public function __get(string $key): mixed
|
||||
{
|
||||
switch ($key) {
|
||||
case 'attributetypes': return $this->attributetypes;
|
||||
case 'ldapsyntaxes': return $this->ldapsyntaxes;
|
||||
case 'matchingrules': return $this->matchingrules;
|
||||
case 'objectclasses': return $this->objectclasses;
|
||||
|
||||
default:
|
||||
throw new Exception('Unknown key:'.$key);
|
||||
}
|
||||
}
|
||||
|
||||
/* 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();
|
||||
* @todo Need to allow for the scenario if the baseDN is not readable by ACLs
|
||||
*/
|
||||
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:
|
||||
// Since we failed authentication, we should delete our auth cookie
|
||||
if (Cookie::has('password_encrypt')) {
|
||||
Log::alert('Clearing user credentials and logging out');
|
||||
|
||||
Cookie::queue(Cookie::forget('password_encrypt'));
|
||||
Cookie::queue(Cookie::forget('username_encrypt'));
|
||||
|
||||
Session::invalidate();
|
||||
}
|
||||
|
||||
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 LDAPCollection|NULL
|
||||
*/
|
||||
public function children(string $dn): ?LDAPCollection
|
||||
{
|
||||
return ($x=(new Entry)
|
||||
->query()
|
||||
->cache(Carbon::now()->addSeconds(Config::get('ldap.cache.time')))
|
||||
->select(['*','hassubordinates'])
|
||||
->setDn($dn)
|
||||
->list()
|
||||
->get()) ? $x : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a DN from the server
|
||||
*
|
||||
* @param string $dn
|
||||
* @param array $attrs
|
||||
* @return Entry|null
|
||||
*/
|
||||
public function fetch(string $dn,array $attrs=['*','+']): ?Entry
|
||||
{
|
||||
return ($x=(new Entry)
|
||||
->query()
|
||||
->cache(Carbon::now()->addSeconds(Config::get('ldap.cache.time')))
|
||||
->select($attrs)
|
||||
->find($dn)) ? $x : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function determines if the specified attribute is contained in the force_may list
|
||||
* as configured in config.php.
|
||||
*
|
||||
* @return boolean True if the specified attribute is configured to be force as a may attribute
|
||||
*/
|
||||
public function isForceMay($attr_name): bool
|
||||
{
|
||||
return in_array($attr_name,config('pla.force_may',[]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this server support RFC3666 language tags
|
||||
* OID: 1.3.6.1.4.1.4203.1.5.4
|
||||
*
|
||||
* @return bool
|
||||
* @throws ObjectNotFoundException
|
||||
*/
|
||||
public function isLanguageTags(): bool
|
||||
{
|
||||
return in_array('1.3.6.1.4.1.4203.1.5.4',$this->rootDSE()->supportedfeatures);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the server's schema
|
||||
*
|
||||
* @param string $item Schema Item to Fetch
|
||||
* @param string|null $key
|
||||
* @return Collection|Base|NULL
|
||||
* @throws InvalidUsage
|
||||
*/
|
||||
public function schema(string $item,string $key=NULL): Collection|Base|NULL
|
||||
{
|
||||
// Ensure our item to fetch is lower case
|
||||
$item = strtolower($item);
|
||||
if ($key)
|
||||
$key = strtolower($key);
|
||||
|
||||
// This error message is not localized as only developers should ever see it
|
||||
if (! in_array($item,self::schema_types))
|
||||
throw new InvalidUsage('Invalid request to fetch schema: '.$item);
|
||||
|
||||
$result = Cache::remember('schema'.$item,config('ldap.cache.time'),function() use ($item) {
|
||||
// First pass if we have already retrieved the schema item
|
||||
switch ($item) {
|
||||
case 'attributetypes':
|
||||
if (isset($this->attributetypes))
|
||||
return $this->attributetypes;
|
||||
else
|
||||
$this->attributetypes = collect();
|
||||
|
||||
break;
|
||||
|
||||
case 'ldapsyntaxes':
|
||||
if (isset($this->ldapsyntaxes))
|
||||
return $this->ldapsyntaxes;
|
||||
else
|
||||
$this->ldapsyntaxes = collect();
|
||||
|
||||
break;
|
||||
|
||||
case 'matchingrules':
|
||||
if (isset($this->matchingrules))
|
||||
return $this->matchingrules;
|
||||
else
|
||||
$this->matchingrules = collect();
|
||||
|
||||
break;
|
||||
|
||||
/*
|
||||
case 'matchingruleuse':
|
||||
if (isset($this->matchingruleuse))
|
||||
return is_null($key) ? $this->matchingruleuse : $this->matchingruleuse->get($key);
|
||||
else
|
||||
$this->matchingruleuse = collect();
|
||||
|
||||
break;
|
||||
*/
|
||||
|
||||
case 'objectclasses':
|
||||
if (isset($this->objectclasses))
|
||||
return $this->objectclasses;
|
||||
else
|
||||
$this->objectclasses = collect();
|
||||
|
||||
break;
|
||||
|
||||
// Shouldnt get here
|
||||
default:
|
||||
throw new InvalidUsage('Invalid request to fetch schema: '.$item);
|
||||
}
|
||||
|
||||
// Try to get the schema DN from the specified entry.
|
||||
$schema_dn = $this->schemaDN();
|
||||
$schema = $this->fetch($schema_dn);
|
||||
|
||||
switch ($item) {
|
||||
case 'attributetypes':
|
||||
Log::debug('Attribute Types');
|
||||
// build the array of attribueTypes
|
||||
//$syntaxes = $this->SchemaSyntaxes($dn);
|
||||
|
||||
foreach ($schema->{$item} as $line) {
|
||||
if (is_null($line) || ! strlen($line))
|
||||
continue;
|
||||
|
||||
$o = new AttributeType($line);
|
||||
$this->attributetypes->put($o->name_lc,$o);
|
||||
|
||||
/*
|
||||
if (isset($syntaxes[$attr->getSyntaxOID()])) {
|
||||
$syntax = $syntaxes[$attr->getSyntaxOID()];
|
||||
$attr->setType($syntax->getDescription());
|
||||
}
|
||||
$this->attributetypes[$attr->getName()] = $attr;
|
||||
*/
|
||||
|
||||
/**
|
||||
* bug 856832: create an entry in the $attrs_oid array too. This
|
||||
* will be a ref to the $attrs entry for maintenance and performance
|
||||
* reasons
|
||||
*/
|
||||
//$attrs_oid[$attr->getOID()] = &$attrs[$attr->getName()];
|
||||
}
|
||||
|
||||
// go back and add data from aliased attributeTypes
|
||||
foreach ($this->attributetypes as $o) {
|
||||
/* foreach of the attribute's aliases, create a new entry in the attrs array
|
||||
* with its name set to the alias name, and all other data copied.*/
|
||||
|
||||
if ($o->aliases->count()) {
|
||||
Log::debug(sprintf('\ Attribute [%s] has the following aliases [%s]',$o->name,$o->aliases->join(',')));
|
||||
|
||||
foreach ($o->aliases as $alias) {
|
||||
$new_attr = clone $o;
|
||||
$new_attr->setName($alias);
|
||||
$new_attr->addAlias($o->name);
|
||||
$new_attr->removeAlias($alias);
|
||||
|
||||
$this->attributetypes->put(strtolower($alias),$new_attr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now go through and reference the parent/child relationships
|
||||
foreach ($this->attributetypes as $o)
|
||||
if ($o->sup_attribute) {
|
||||
$parent = strtolower($o->sup_attribute);
|
||||
|
||||
if ($this->attributetypes->has($parent) !== FALSE)
|
||||
$this->attributetypes[$parent]->addChild($o->name);
|
||||
}
|
||||
|
||||
// go through any children and add details if the child doesnt have them (ie, cn inherits name)
|
||||
// @todo This doesnt traverse children properly, so children of children may not get the settings they should
|
||||
foreach ($this->attributetypes as $parent) {
|
||||
foreach ($parent->children as $child) {
|
||||
$child = strtolower($child);
|
||||
|
||||
/* only overwrite the child's SINGLE-VALUE property if the parent has it set, and the child doesnt
|
||||
* (note: All LDAP attributes default to multi-value if not explicitly set SINGLE-VALUE) */
|
||||
if (! is_null($parent->is_single_value) && is_null($this->attributetypes[$child]->is_single_value))
|
||||
$this->attributetypes[$child]->setIsSingleValue($parent->is_single_value);
|
||||
}
|
||||
}
|
||||
|
||||
// Add the used in and required_by values.
|
||||
foreach ($this->schema('objectclasses') as $object_class) {
|
||||
$must_attrs = $object_class->getMustAttrNames();
|
||||
$may_attrs = $object_class->getMayAttrNames();
|
||||
$oclass_attrs = $must_attrs->merge($may_attrs)->unique();
|
||||
|
||||
// Add Used In.
|
||||
foreach ($oclass_attrs as $attr_name)
|
||||
if ($this->attributetypes->has(strtolower($attr_name)))
|
||||
$this->attributetypes[strtolower($attr_name)]->addUsedInObjectClass($object_class->name);
|
||||
|
||||
// Add Required By.
|
||||
foreach ($must_attrs as $attr_name)
|
||||
if ($this->attributetypes->has(strtolower($attr_name)))
|
||||
$this->attributetypes[strtolower($attr_name)]->addRequiredByObjectClass($object_class->name);
|
||||
|
||||
// Force May
|
||||
foreach ($object_class->getForceMayAttrs() as $attr_name)
|
||||
if ($this->attributetypes->has(strtolower($attr_name->name)))
|
||||
$this->attributetypes[strtolower($attr_name->name)]->setForceMay();
|
||||
}
|
||||
|
||||
return $this->attributetypes;
|
||||
|
||||
case 'ldapsyntaxes':
|
||||
Log::debug('LDAP Syntaxes');
|
||||
|
||||
foreach ($schema->{$item} as $line) {
|
||||
if (is_null($line) || ! strlen($line))
|
||||
continue;
|
||||
|
||||
$o = new LDAPSyntax($line);
|
||||
$this->ldapsyntaxes->put(strtolower($o->oid),$o);
|
||||
}
|
||||
|
||||
return $this->ldapsyntaxes;
|
||||
|
||||
case 'matchingrules':
|
||||
Log::debug('Matching Rules');
|
||||
$this->matchingruleuse = collect();
|
||||
|
||||
foreach ($schema->{$item} as $line) {
|
||||
if (is_null($line) || ! strlen($line))
|
||||
continue;
|
||||
|
||||
$o = new MatchingRule($line);
|
||||
$this->matchingrules->put($o->name_lc,$o);
|
||||
}
|
||||
|
||||
/*
|
||||
* For each MatchingRuleUse entry, add the attributes who use it to the
|
||||
* MatchingRule in the $rules array.
|
||||
*/
|
||||
if ($schema->matchingruleuse) {
|
||||
foreach ($schema->matchingruleuse as $line) {
|
||||
if (is_null($line) || ! strlen($line))
|
||||
continue;
|
||||
|
||||
$o = new MatchingRuleUse($line);
|
||||
$this->matchingruleuse->put($o->name_lc,$o);
|
||||
|
||||
if ($this->matchingrules->has($o->name_lc) !== FALSE)
|
||||
$this->matchingrules[$o->name_lc]->setUsedByAttrs($o->getUsedByAttrs());
|
||||
}
|
||||
|
||||
} else {
|
||||
/* No MatchingRuleUse entry in the subschema, so brute-forcing
|
||||
* the reverse-map for the "$rule->getUsedByAttrs()" data.*/
|
||||
foreach ($this->schema('attributetypes') as $attr) {
|
||||
$rule_key = strtolower($attr->getEquality());
|
||||
|
||||
if ($this->matchingrules->has($rule_key) !== FALSE)
|
||||
$this->matchingrules[$rule_key]->addUsedByAttr($attr->name);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->matchingrules;
|
||||
|
||||
case 'objectclasses':
|
||||
Log::debug('Object Classes');
|
||||
|
||||
foreach ($schema->{$item} as $line) {
|
||||
if (is_null($line) || ! strlen($line))
|
||||
continue;
|
||||
|
||||
$o = new ObjectClass($line,$this);
|
||||
$this->objectclasses->put($o->name_lc,$o);
|
||||
}
|
||||
|
||||
// Now go through and reference the parent/child relationships
|
||||
foreach ($this->objectclasses as $o)
|
||||
foreach ($o->getSupClasses() as $parent) {
|
||||
$parent = strtolower($parent);
|
||||
if ($this->objectclasses->has($parent) !== FALSE)
|
||||
$this->objectclasses[$parent]->addChildObjectClass($o->name);
|
||||
}
|
||||
|
||||
return $this->objectclasses;
|
||||
}
|
||||
});
|
||||
|
||||
return is_null($key) ? $result : $result->get($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an OID, return the ldapsyntax for the OID
|
||||
*
|
||||
* @param string $oid
|
||||
* @return LDAPSyntax|null
|
||||
* @throws InvalidUsage
|
||||
*/
|
||||
public function schemaSyntaxName(string $oid): ?LDAPSyntax
|
||||
{
|
||||
return $this->schema('ldapsyntaxes',$oid);
|
||||
}
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console;
|
||||
|
||||
use Illuminate\Console\Scheduling\Schedule;
|
||||
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||
|
||||
class Kernel extends ConsoleKernel
|
||||
{
|
||||
/**
|
||||
* The Artisan commands provided by your application.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $commands = [
|
||||
//
|
||||
];
|
||||
|
||||
/**
|
||||
* Define the application's command schedule.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Schedule $schedule
|
||||
* @return void
|
||||
*/
|
||||
protected function schedule(Schedule $schedule)
|
||||
{
|
||||
// $schedule->command('inspire')->hourly();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the commands for the application.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function commands()
|
||||
{
|
||||
$this->load(__DIR__.'/Commands');
|
||||
|
||||
require base_path('routes/console.php');
|
||||
}
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Exceptions;
|
||||
|
||||
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||
use Throwable;
|
||||
|
||||
class Handler extends ExceptionHandler
|
||||
{
|
||||
/**
|
||||
* A list of exception types with their corresponding custom log levels.
|
||||
*
|
||||
* @var array<class-string<\Throwable>, \Psr\Log\LogLevel::*>
|
||||
*/
|
||||
protected $levels = [
|
||||
//
|
||||
];
|
||||
|
||||
/**
|
||||
* A list of the exception types that are not reported.
|
||||
*
|
||||
* @var array<int, class-string<\Throwable>>
|
||||
*/
|
||||
protected $dontReport = [
|
||||
//
|
||||
];
|
||||
|
||||
/**
|
||||
* A list of the inputs that are never flashed to the session on validation exceptions.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $dontFlash = [
|
||||
'current_password',
|
||||
'password',
|
||||
'password_confirmation',
|
||||
];
|
||||
|
||||
/**
|
||||
* Register the exception handling callbacks for the application.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
$this->reportable(function (Throwable $e) {
|
||||
//
|
||||
});
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Exceptions\Import;
|
||||
|
||||
use Exception;
|
||||
|
||||
class AttributeException extends Exception {}
|
@ -1,7 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Exceptions\Import;
|
||||
|
||||
use Exception;
|
||||
|
||||
class GeneralException extends Exception {}
|
@ -1,7 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Exceptions\Import;
|
||||
|
||||
use Exception;
|
||||
|
||||
class ObjectExistsException extends Exception {}
|
@ -1,7 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Exceptions\Import;
|
||||
|
||||
use Exception;
|
||||
|
||||
class VersionException extends Exception {}
|
@ -1,10 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
class InvalidUsage extends Exception
|
||||
{
|
||||
//
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\Crypt;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
use App\Classes\LDAP\Server;
|
||||
|
||||
class APIController extends Controller
|
||||
{
|
||||
/**
|
||||
* Get the LDAP server BASE DNs
|
||||
*
|
||||
* @return Collection
|
||||
* @throws LdapRecord\Query\ObjectNotFoundException
|
||||
*/
|
||||
public function bases(): Collection
|
||||
{
|
||||
$base = Server::baseDNs() ?: collect();
|
||||
|
||||
return $base->transform(function($item) {
|
||||
return [
|
||||
'title'=>$item->getRdn(),
|
||||
'item'=>$item->getDNSecure(),
|
||||
'lazy'=>TRUE,
|
||||
'icon'=>'fa-fw fas fa-sitemap',
|
||||
'tooltip'=>$item->getDn(),
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return Collection
|
||||
*/
|
||||
public function children(Request $request): Collection
|
||||
{
|
||||
$levels = $request->query('depth',1);
|
||||
$dn = Crypt::decryptString($request->query('key'));
|
||||
Log::debug(sprintf('%s: Query [%s] - Levels [%d]',__METHOD__,$dn,$levels));
|
||||
|
||||
return (config('server'))
|
||||
->children($dn)
|
||||
->transform(function($item) {
|
||||
return [
|
||||
'title'=>$item->getRdn(),
|
||||
'item'=>$item->getDNSecure(),
|
||||
'icon'=>$item->icon(),
|
||||
'lazy'=>Arr::get($item->getAttribute('hassubordinates'),0) == 'TRUE',
|
||||
'tooltip'=>$item->getDn(),
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
public function schema_view(Request $request)
|
||||
{
|
||||
$server = new Server;
|
||||
|
||||
switch($request->type) {
|
||||
case 'objectclasses':
|
||||
return view('fragment.schema.objectclasses')
|
||||
->with('objectclasses',$server->schema('objectclasses')->sortBy(function($item) { return strtolower($item->name); }));
|
||||
|
||||
case 'attributetypes':
|
||||
return view('fragment.schema.attributetypes')
|
||||
->with('server',$server)
|
||||
->with('attributetypes',$server->schema('attributetypes')->sortBy(function($item) { return strtolower($item->name); }));
|
||||
|
||||
case 'ldapsyntaxes':
|
||||
return view('fragment.schema.ldapsyntaxes')
|
||||
->with('ldapsyntaxes',$server->schema('ldapsyntaxes')->sortBy(function($item) { return strtolower($item->description); }));
|
||||
|
||||
case 'matchingrules':
|
||||
return view('fragment.schema.matchingrules')
|
||||
->with('matchingrules',$server->schema('matchingrules')->sortBy(function($item) { return strtolower($item->name); }));
|
||||
|
||||
default:
|
||||
abort(404);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,104 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use Illuminate\Foundation\Auth\AuthenticatesUsers;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Cookie;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
|
||||
class LoginController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Login Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller handles authenticating users for the application and
|
||||
| redirecting them to your home screen. The controller uses a trait
|
||||
| to conveniently provide its functionality to your applications.
|
||||
|
|
||||
*/
|
||||
|
||||
use AuthenticatesUsers;
|
||||
|
||||
/**
|
||||
* Where to redirect users after login.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = RouteServiceProvider::HOME;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('guest')->except('logout');
|
||||
}
|
||||
|
||||
protected function credentials(Request $request): array
|
||||
{
|
||||
return [
|
||||
login_attr_name() => $request->get(login_attr_name()),
|
||||
'password' => $request->get('password'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* We need to delete our encrypted username/password cookies
|
||||
*
|
||||
* @note The rest of this function is the same as a normal laravel logout as in AuthenticatesUsers::class
|
||||
* @param Request $request
|
||||
* @return \Illuminate\Contracts\Foundation\Application|JsonResponse|\Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|mixed
|
||||
*/
|
||||
public function logout(Request $request)
|
||||
{
|
||||
// Delete our LDAP authentication cookies
|
||||
Cookie::queue(Cookie::forget('username_encrypt'));
|
||||
Cookie::queue(Cookie::forget('password_encrypt'));
|
||||
|
||||
$this->guard()->logout();
|
||||
|
||||
$request->session()->invalidate();
|
||||
|
||||
$request->session()->regenerateToken();
|
||||
|
||||
if ($response = $this->loggedOut($request)) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
return $request->wantsJson()
|
||||
? new JsonResponse([], 204)
|
||||
: redirect('/');
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Show our themed login page
|
||||
*/
|
||||
public function showLoginForm()
|
||||
{
|
||||
$login_note = '';
|
||||
|
||||
if (file_exists('login_note.txt'))
|
||||
$login_note = file_get_contents('login_note.txt');
|
||||
|
||||
return view('architect::auth.login')->with('login_note',$login_note);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the login username to be used by the controller.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function username()
|
||||
{
|
||||
return login_attr_name();
|
||||
}
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
|
||||
class Controller extends BaseController
|
||||
{
|
||||
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
|
||||
}
|
@ -1,309 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Crypt;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Facades\Redirect;
|
||||
use LdapRecord\Exceptions\InsufficientAccessException;
|
||||
use LdapRecord\LdapRecordException;
|
||||
use LdapRecord\Query\ObjectNotFoundException;
|
||||
|
||||
use App\Classes\LDAP\{Attribute,Server};
|
||||
use App\Classes\LDAP\Import\LDIF as LDIFImport;
|
||||
use App\Classes\LDAP\Export\LDIF as LDIFExport;
|
||||
use App\Exceptions\Import\{GeneralException,VersionException};
|
||||
use App\Exceptions\InvalidUsage;
|
||||
use App\Http\Requests\{EntryRequest,ImportRequest};
|
||||
use App\Ldap\Entry;
|
||||
use App\View\Components\AttributeType;
|
||||
use Nette\NotImplementedException;
|
||||
|
||||
class HomeController extends Controller
|
||||
{
|
||||
private function bases()
|
||||
{
|
||||
$base = Server::baseDNs() ?: collect();
|
||||
|
||||
return $base->transform(function($item) {
|
||||
return [
|
||||
'title'=>$item->getRdn(),
|
||||
'item'=>$item->getDNSecure(),
|
||||
'lazy'=>TRUE,
|
||||
'icon'=>'fa-fw fas fa-sitemap',
|
||||
'tooltip'=>$item->getDn(),
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Debug Page
|
||||
*
|
||||
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function debug()
|
||||
{
|
||||
return view('debug');
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a specific DN
|
||||
*
|
||||
* @param Request $request
|
||||
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function dn_frame(Request $request)
|
||||
{
|
||||
$dn = Crypt::decryptString($request->post('key'));
|
||||
|
||||
$page_actions = collect(['edit'=>TRUE,'copy'=>TRUE]);
|
||||
|
||||
return view('frames.dn')
|
||||
->with('o',config('server')->fetch($dn))
|
||||
->with('dn',$dn)
|
||||
->with('page_actions',$page_actions);
|
||||
}
|
||||
|
||||
public function entry_export(Request $request,string $id)
|
||||
{
|
||||
$dn = Crypt::decryptString($id);
|
||||
|
||||
$result = (new Entry)
|
||||
->query()
|
||||
//->cache(Carbon::now()->addSeconds(Config::get('ldap.cache.time')))
|
||||
//->select(['*'])
|
||||
->setDn($dn)
|
||||
->recursive()
|
||||
->get();
|
||||
|
||||
return view('fragment.export')
|
||||
->with('result',new LDIFExport($result));
|
||||
}
|
||||
|
||||
public function entry_newattr(string $id)
|
||||
{
|
||||
$x = new AttributeType(new Attribute($id,[]),TRUE);
|
||||
return $x->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a confirmation to update a DN
|
||||
*
|
||||
* @param EntryRequest $request
|
||||
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Foundation\Application|\Illuminate\Http\RedirectResponse
|
||||
* @throws ObjectNotFoundException
|
||||
*/
|
||||
public function entry_pending_update(EntryRequest $request)
|
||||
{
|
||||
$dn = Crypt::decryptString($request->dn);
|
||||
|
||||
$o = config('server')->fetch($dn);
|
||||
|
||||
foreach ($request->except(['_token','dn']) as $key => $value)
|
||||
$o->{$key} = array_filter($value);
|
||||
|
||||
if (! $o->getDirty())
|
||||
return back()
|
||||
->withInput()
|
||||
->with('note',__('No attributes changed'));
|
||||
|
||||
return view('update')
|
||||
->with('bases',$this->bases())
|
||||
->with('dn',$dn)
|
||||
->with('o',$o);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a DN entry
|
||||
*
|
||||
* @param EntryRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws ObjectNotFoundException
|
||||
*/
|
||||
public function entry_update(EntryRequest $request)
|
||||
{
|
||||
$dn = Crypt::decryptString($request->dn);
|
||||
|
||||
$o = config('server')->fetch($dn);
|
||||
|
||||
foreach ($request->except(['_token','dn']) as $key => $value)
|
||||
$o->{$key} = array_filter($value);
|
||||
|
||||
if (! $dirty=$o->getDirty())
|
||||
return back()
|
||||
->withInput()
|
||||
->with('note',__('No attributes changed'));
|
||||
|
||||
try {
|
||||
$o->update($request->except(['_token','dn']));
|
||||
|
||||
} catch (InsufficientAccessException $e) {
|
||||
$request->flash();
|
||||
|
||||
switch ($x=$e->getDetailedError()->getErrorCode()) {
|
||||
case 50:
|
||||
return Redirect::to('/')
|
||||
->withInput()
|
||||
->withErrors(sprintf('%s: %s (%s)',__('LDAP Server Error Code'),$x,__($e->getDetailedError()->getErrorMessage())));
|
||||
|
||||
default:
|
||||
abort(599,$e->getDetailedError()->getErrorMessage());
|
||||
}
|
||||
|
||||
} catch (LdapRecordException $e) {
|
||||
$request->flash();
|
||||
|
||||
switch ($x=$e->getDetailedError()->getErrorCode()) {
|
||||
case 8:
|
||||
return Redirect::to('/')
|
||||
->withInput()
|
||||
->withErrors(sprintf('%s: %s (%s)',__('LDAP Server Error Code'),$x,__($e->getDetailedError()->getErrorMessage())));
|
||||
|
||||
default:
|
||||
abort(599,$e->getDetailedError()->getErrorMessage());
|
||||
}
|
||||
}
|
||||
|
||||
return Redirect::to('/')
|
||||
->withInput()
|
||||
->with('success',__('Entry updated'))
|
||||
->with('updated',$dirty);
|
||||
}
|
||||
|
||||
/**
|
||||
* Application home page
|
||||
*/
|
||||
public function home()
|
||||
{
|
||||
if (old('dn'))
|
||||
return view('frame')
|
||||
->with('subframe','dn')
|
||||
->with('bases',$this->bases())
|
||||
->with('o',config('server')->fetch($dn=Crypt::decryptString(old('dn'))))
|
||||
->with('dn',$dn);
|
||||
|
||||
elseif (old('frame'))
|
||||
return view('frame')
|
||||
->with('subframe',old('frame'))
|
||||
->with('bases',$this->bases());
|
||||
|
||||
else
|
||||
return view('home')
|
||||
->with('bases',$this->bases())
|
||||
->with('server',config('ldap.connections.default.name'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the incoming LDIF file or LDIF text
|
||||
*
|
||||
* @param ImportRequest $request
|
||||
* @param string $type
|
||||
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Foundation\Application
|
||||
* @throws GeneralException
|
||||
* @throws VersionException
|
||||
*/
|
||||
public function import(ImportRequest $request,string $type)
|
||||
{
|
||||
switch ($type) {
|
||||
case 'ldif':
|
||||
$import = new LDIFImport($x=($request->text ?: $request->file->get()));
|
||||
break;
|
||||
|
||||
default:
|
||||
abort(404,'Unknown import type: '.$type);
|
||||
}
|
||||
|
||||
try {
|
||||
$result = $import->process();
|
||||
|
||||
} catch (NotImplementedException $e) {
|
||||
abort(555,$e->getMessage());
|
||||
|
||||
} catch (\Exception $e) {
|
||||
abort(598,$e->getMessage());
|
||||
}
|
||||
|
||||
return view('frame')
|
||||
->with('subframe','import_result')
|
||||
->with('bases',$this->bases())
|
||||
->with('result',$result)
|
||||
->with('ldif',htmlspecialchars($x));
|
||||
}
|
||||
|
||||
public function import_frame()
|
||||
{
|
||||
return view('frames.import');
|
||||
}
|
||||
|
||||
/**
|
||||
* LDAP Server INFO
|
||||
*
|
||||
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function info()
|
||||
{
|
||||
return view('frames.info')
|
||||
->with('s',config('server'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
$s = config('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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort the attributes
|
||||
*
|
||||
* @param Collection $attrs
|
||||
* @return Collection
|
||||
*/
|
||||
private function sortAttrs(Collection $attrs): Collection
|
||||
{
|
||||
return $attrs->sortKeys();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the image for the logged in user or anonymous
|
||||
*
|
||||
* @param Request $request
|
||||
* @return mixed
|
||||
*/
|
||||
public function user_image(Request $request)
|
||||
{
|
||||
$image = NULL;
|
||||
$content = NULL;
|
||||
|
||||
if (Auth::check()) {
|
||||
$image = Arr::get(Auth::user()->getAttribute('jpegphoto'),0);
|
||||
$content = 'image/jpeg';
|
||||
}
|
||||
|
||||
if (! $image) {
|
||||
$image = File::get('../resources/images/user-secret-solid.svg');
|
||||
$content = 'image/svg+xml';
|
||||
}
|
||||
|
||||
return response($image)
|
||||
->header('Content-Type',$content);
|
||||
}
|
||||
}
|
@ -1,82 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http;
|
||||
|
||||
use Illuminate\Foundation\Http\Kernel as HttpKernel;
|
||||
|
||||
use App\Http\Middleware\{ApplicationSession,CheckUpdate,SwapinAuthUser};
|
||||
|
||||
class Kernel extends HttpKernel
|
||||
{
|
||||
/**
|
||||
* The application's global HTTP middleware stack.
|
||||
*
|
||||
* These middleware are run during every request to your application.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $middleware = [
|
||||
// \App\Http\Middleware\TrustHosts::class,
|
||||
\App\Http\Middleware\TrustProxies::class,
|
||||
\Illuminate\Http\Middleware\HandleCors::class,
|
||||
\App\Http\Middleware\CheckForMaintenanceMode::class,
|
||||
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
|
||||
\App\Http\Middleware\TrimStrings::class,
|
||||
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* The application's route middleware groups.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $middlewareGroups = [
|
||||
'web' => [
|
||||
\App\Http\Middleware\EncryptCookies::class,
|
||||
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
|
||||
\Illuminate\Session\Middleware\StartSession::class,
|
||||
ApplicationSession::class,
|
||||
SwapinAuthUser::class,
|
||||
\Illuminate\Session\Middleware\AuthenticateSession::class,
|
||||
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
|
||||
\App\Http\Middleware\VerifyCsrfToken::class,
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
\Laravel\Passport\Http\Middleware\CreateFreshApiToken::class,
|
||||
CheckUpdate::class,
|
||||
],
|
||||
|
||||
'api' => [
|
||||
'throttle:60,1',
|
||||
\App\Http\Middleware\EncryptCookies::class,
|
||||
SwapinAuthUser::class,
|
||||
ApplicationSession::class,
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* The application's route middleware.
|
||||
*
|
||||
* These middleware may be assigned to groups or used individually.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $middlewareAliases = [
|
||||
'auth' => \App\Http\Middleware\Authenticate::class,
|
||||
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
|
||||
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
|
||||
'can' => \Illuminate\Auth\Middleware\Authorize::class,
|
||||
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
|
||||
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
|
||||
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
|
||||
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
|
||||
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
|
||||
|
||||
'localize' => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRoutes::class,
|
||||
'localizationRedirect' => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRedirectFilter::class,
|
||||
'localeSessionRedirect' => \Mcamara\LaravelLocalization\Middleware\LocaleSessionRedirect::class,
|
||||
'localeCookieRedirect' => \Mcamara\LaravelLocalization\Middleware\LocaleCookieRedirect::class,
|
||||
'localeViewPath' => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationViewPath::class
|
||||
];
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Classes\LDAP\Server;
|
||||
use App\Ldap\User;
|
||||
use Closure;
|
||||
|
||||
/**
|
||||
* This sets up our application session with any required values, ultimately for cache optimisation reasons
|
||||
*/
|
||||
class ApplicationSession
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request,Closure $next)
|
||||
{
|
||||
\Config::set('server',new Server);
|
||||
|
||||
view()->share('user', auth()->user() ?: new User);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Auth\Middleware\Authenticate as Middleware;
|
||||
|
||||
class Authenticate extends Middleware
|
||||
{
|
||||
/**
|
||||
* Get the path the user should be redirected to when they are not authenticated.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return string|null
|
||||
*/
|
||||
protected function redirectTo($request)
|
||||
{
|
||||
if (! $request->expectsJson()) {
|
||||
return route('login');
|
||||
}
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode as Middleware;
|
||||
|
||||
class CheckForMaintenanceMode extends Middleware
|
||||
{
|
||||
/**
|
||||
* The URIs that should be reachable while maintenance mode is enabled.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $except = [
|
||||
//
|
||||
];
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use GuzzleHttp\Client;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class CheckUpdate
|
||||
{
|
||||
private const UPDATE_SERVER = 'https://version.phpldapadmin.org';
|
||||
private const UPDATE_TIME = 60*60*6;
|
||||
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
\Config::set('update_available',Cache::get('upstream_version'));
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle tasks after the response has been sent to the browser.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function terminate()
|
||||
{
|
||||
Cache::remember('upstream_version',self::UPDATE_TIME,function() {
|
||||
// CURL call to URL to see if there is a new version
|
||||
Log::debug(sprintf('CU_:Checking for updates for [%s]',config('app.version')));
|
||||
|
||||
$client = new Client;
|
||||
|
||||
try {
|
||||
|
||||
$response = $client->request('POST',sprintf('%s/%s',self::UPDATE_SERVER,strtolower(config('app.version'))));
|
||||
|
||||
if ($response->getStatusCode() === 200) {
|
||||
$result = json_decode($response->getBody());
|
||||
|
||||
Log::debug(sprintf('CU_:- Update server returned...'),['update'=>$result]);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
} catch (\Exception $e) {
|
||||
Log::debug(sprintf('CU_:- Exception connecting to update server'),['e'=>get_class($e)]);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
});
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Cookie\Middleware\EncryptCookies as Middleware;
|
||||
|
||||
class EncryptCookies extends Middleware
|
||||
{
|
||||
/**
|
||||
* The names of the cookies that should not be encrypted.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $except = [
|
||||
//
|
||||
];
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Closure;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class RedirectIfAuthenticated
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @param string|null $guard
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next, $guard = null)
|
||||
{
|
||||
if (Auth::guard($guard)->check()) {
|
||||
return redirect(RouteServiceProvider::HOME);
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Config;
|
||||
use Illuminate\Support\Facades\Cookie;
|
||||
// use Illuminate\Support\Facades\Crypt;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
// use Illuminate\Support\Facades\Session;
|
||||
use LdapRecord\Container;
|
||||
|
||||
use App\Ldap\Connection;
|
||||
|
||||
class SwapinAuthUser
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
|
||||
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
$key = config('ldap.default');
|
||||
|
||||
/*
|
||||
// Rebuild our connection with the authenticated user.
|
||||
if (Session::has('username_encrypt') && Session::has('password_encrypt')) {
|
||||
Config::set('ldap.connections.'.$key.'.username',Crypt::decryptString(Session::get('username_encrypt')));
|
||||
Config::set('ldap.connections.'.$key.'.password',Crypt::decryptString(Session::get('password_encrypt')));
|
||||
|
||||
} else
|
||||
*/
|
||||
|
||||
if (Cookie::has('username_encrypt') && Cookie::has('password_encrypt')) {
|
||||
Config::set('ldap.connections.'.$key.'.username',Cookie::get('username_encrypt'));
|
||||
Config::set('ldap.connections.'.$key.'.password',Cookie::get('password_encrypt'));
|
||||
|
||||
Log::debug('Swapping out configured LDAP credentials with the user\'s cookie.');
|
||||
}
|
||||
|
||||
// We need to override our Connection object so that we can store and retrieve the logged in user and swap out the credentials to use them.
|
||||
Container::getInstance()->addConnection(new Connection(config('ldap.connections.'.$key)),$key);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\TrimStrings as Middleware;
|
||||
|
||||
class TrimStrings extends Middleware
|
||||
{
|
||||
/**
|
||||
* The names of the attributes that should not be trimmed.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $except = [
|
||||
'password',
|
||||
'password_confirmation',
|
||||
];
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Http\Middleware\TrustHosts as Middleware;
|
||||
|
||||
class TrustHosts extends Middleware
|
||||
{
|
||||
/**
|
||||
* Get the host patterns that should be trusted.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function hosts()
|
||||
{
|
||||
return [
|
||||
$this->allSubdomainsOfApplicationUrl(),
|
||||
];
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Http\Middleware\TrustProxies as Middleware;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class TrustProxies extends Middleware
|
||||
{
|
||||
/**
|
||||
* The trusted proxies for this application.
|
||||
*
|
||||
* @var array<int, string>|string|null
|
||||
*/
|
||||
protected $proxies;
|
||||
|
||||
/**
|
||||
* The headers that should be used to detect proxies.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $headers =
|
||||
Request::HEADER_X_FORWARDED_FOR |
|
||||
Request::HEADER_X_FORWARDED_HOST |
|
||||
Request::HEADER_X_FORWARDED_PORT |
|
||||
Request::HEADER_X_FORWARDED_PROTO |
|
||||
Request::HEADER_X_FORWARDED_AWS_ELB;
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
|
||||
|
||||
class VerifyCsrfToken extends Middleware
|
||||
{
|
||||
/**
|
||||
* The URIs that should be excluded from CSRF verification.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $except = [
|
||||
//
|
||||
];
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class EntryRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return config('server')
|
||||
->schema('attributetypes')
|
||||
->intersectByKeys($this->request)
|
||||
->transform(function($item) { return $item->validation; })
|
||||
->filter()
|
||||
->flatMap(function($item) { return $item; })
|
||||
->toArray();
|
||||
}
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class ImportRequest extends FormRequest
|
||||
{
|
||||
public function authorize()
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'frame' => 'required|string|in:import',
|
||||
'file' => 'nullable|extensions:ldif|required_without:text',
|
||||
'text'=> 'nullable|prohibits:file|string|min:16',
|
||||
];
|
||||
}
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Ldap;
|
||||
|
||||
use LdapRecord\Connection as ConnectionBase;
|
||||
use LdapRecord\LdapInterface;
|
||||
|
||||
class Connection extends ConnectionBase
|
||||
{
|
||||
|
||||
public function __construct($config = [], LdapInterface $ldap = null)
|
||||
{
|
||||
parent::__construct($config,$ldap);
|
||||
|
||||
// We need to override this so that we use our own Guard, that stores the users credentials in the session
|
||||
$this->authGuardResolver = function () {
|
||||
return new Guard($this->ldap, $this->configuration);
|
||||
};
|
||||
}
|
||||
}
|
@ -1,423 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Ldap;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Crypt;
|
||||
use LdapRecord\Support\Arr;
|
||||
use LdapRecord\Models\Model;
|
||||
use LdapRecord\Query\Model\Builder;
|
||||
|
||||
use App\Classes\LDAP\Attribute;
|
||||
use App\Classes\LDAP\Attribute\Factory;
|
||||
use App\Classes\LDAP\Export\LDIF;
|
||||
use App\Exceptions\Import\AttributeException;
|
||||
|
||||
class Entry extends Model
|
||||
{
|
||||
private Collection $objects;
|
||||
private bool $noObjectAttributes = FALSE;
|
||||
|
||||
/* OVERRIDES */
|
||||
|
||||
public function __construct(array $attributes = [])
|
||||
{
|
||||
$this->objects = collect();
|
||||
|
||||
parent::__construct($attributes);
|
||||
}
|
||||
|
||||
public function discardChanges(): static
|
||||
{
|
||||
parent::discardChanges();
|
||||
|
||||
// If we are discharging changes, we need to reset our $objects;
|
||||
$this->objects = $this->getAttributesAsObjects($this->attributes);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function overrides getAttributes to use our collection of Attribute objects instead of the models attributes.
|
||||
*
|
||||
* @return array
|
||||
* @note $this->attributes may not be updated with changes
|
||||
*/
|
||||
public function getAttributes(): array
|
||||
{
|
||||
return $this->objects->map(function($item) { return $item->values->toArray(); })->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the new and old values for a given key are equivalent.
|
||||
*/
|
||||
protected function originalIsEquivalent(string $key): bool
|
||||
{
|
||||
$key = $this->normalizeAttributeKey($key);
|
||||
|
||||
if ((! array_key_exists($key, $this->original)) && (! $this->objects->has($key))) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
$current = $this->attributes[$key];
|
||||
$original = $this->objects->get($key)->values;
|
||||
|
||||
if ($current === $original) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return ! $this->getObject($key)->isDirty();
|
||||
}
|
||||
|
||||
public static function query(bool $noattrs=false): Builder
|
||||
{
|
||||
$o = new static;
|
||||
|
||||
if ($noattrs)
|
||||
$o->noObjectAttributes();
|
||||
|
||||
return $o->newQuery();
|
||||
}
|
||||
|
||||
/**
|
||||
* As attribute values are updated, or new ones created, we need to mirror that
|
||||
* into our $objects
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return $this
|
||||
*/
|
||||
public function setAttribute(string $key, mixed $value): static
|
||||
{
|
||||
parent::setAttribute($key,$value);
|
||||
|
||||
$key = $this->normalizeAttributeKey($key);
|
||||
|
||||
if ((! $this->objects->get($key)) && $value) {
|
||||
$o = new Attribute($key,[]);
|
||||
$o->value = $value;
|
||||
|
||||
$this->objects->put($key,$o);
|
||||
|
||||
} elseif ($this->objects->get($key)) {
|
||||
$this->objects->get($key)->value = $this->attributes[$key];
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* We'll shadow $this->attributes to $this->objects - a collection of Attribute objects
|
||||
*
|
||||
* Using the objects, it'll make it easier to work with attribute values
|
||||
*
|
||||
* @param array $attributes
|
||||
* @return $this
|
||||
*/
|
||||
public function setRawAttributes(array $attributes = []): static
|
||||
{
|
||||
parent::setRawAttributes($attributes);
|
||||
|
||||
// We only set our objects on DN entries (otherwise we might get into a recursion loop if this is the schema DN)
|
||||
if ($this->dn && (! in_array($this->dn,Arr::get($this->attributes,'subschemasubentry',[])))) {
|
||||
$this->objects = $this->getAttributesAsObjects($this->attributes);
|
||||
|
||||
} else {
|
||||
$this->objects = collect();
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/* ATTRIBUTES */
|
||||
|
||||
/**
|
||||
* Return a key to use for sorting
|
||||
*
|
||||
* @todo This should be the DN in reverse order
|
||||
* @return string
|
||||
*/
|
||||
public function getSortKeyAttribute(): string
|
||||
{
|
||||
return $this->getDn();
|
||||
}
|
||||
|
||||
/* METHODS */
|
||||
|
||||
public function addAttribute(string $key,mixed $value): void
|
||||
{
|
||||
$key = $this->normalizeAttributeKey($key);
|
||||
|
||||
if (config('server')->schema('attributetypes')->has($key) === FALSE)
|
||||
throw new AttributeException('Schema doesnt have attribute [%s]',$key);
|
||||
|
||||
if ($x=$this->objects->get($key)) {
|
||||
$x->addValue($value);
|
||||
|
||||
} else {
|
||||
$this->objects->put($key,Attribute\Factory::create($key,Arr::wrap($value)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert all our attribute values into an array of Objects
|
||||
*
|
||||
* @param array $attributes
|
||||
* @return Collection
|
||||
*/
|
||||
protected function getAttributesAsObjects(array $attributes): Collection
|
||||
{
|
||||
$result = collect();
|
||||
|
||||
foreach ($attributes as $attribute => $value) {
|
||||
// If the attribute name has language tags
|
||||
$matches = [];
|
||||
if (preg_match('/^([a-zA-Z]+)(;([a-zA-Z-;]+))+/',$attribute,$matches)) {
|
||||
$attribute = $matches[1];
|
||||
|
||||
// If the attribute doesnt exist we'll create it
|
||||
$o = Arr::get($result,$attribute,Factory::create($attribute,[]));
|
||||
$o->setLangTag($matches[3],$value);
|
||||
|
||||
} else {
|
||||
$o = Factory::create($attribute,$value);
|
||||
}
|
||||
|
||||
if (! $result->has($attribute)) {
|
||||
// Set the rdn flag
|
||||
if (preg_match('/^'.$attribute.'=/i',$this->dn))
|
||||
$o->setRDN();
|
||||
|
||||
// Set required flag
|
||||
$o->required_by(collect($this->getAttribute('objectclass')));
|
||||
|
||||
// Store our original value to know if this attribute has changed
|
||||
if ($x=Arr::get($this->original,$attribute))
|
||||
$o->oldValues($x);
|
||||
|
||||
$result->put($attribute,$o);
|
||||
}
|
||||
}
|
||||
|
||||
$sort = collect(config('ldap.attr_display_order',[]))->transform(function($item) { return strtolower($item); });
|
||||
|
||||
// Order the attributes
|
||||
$result = $result->sortBy([function(Attribute $a,Attribute $b) use ($sort): int {
|
||||
if ($a === $b)
|
||||
return 0;
|
||||
|
||||
// Check if $a/$b are in the configuration to be sorted first, if so get it's key
|
||||
$a_key = $sort->search($a->name_lc);
|
||||
$b_key = $sort->search($b->name_lc);
|
||||
|
||||
// If the keys were not in the sort list, set the key to be the count of elements (ie: so it is last to be sorted)
|
||||
if ($a_key === FALSE)
|
||||
$a_key = $sort->count()+1;
|
||||
|
||||
if ($b_key === FALSE)
|
||||
$b_key = $sort->count()+1;
|
||||
|
||||
// Case where neither $a, nor $b are in ldap.attr_display_order, $a_key = $b_key = one greater than num elements.
|
||||
// So we sort them alphabetically
|
||||
if ($a_key === $b_key)
|
||||
return strcasecmp($a->name,$b->name);
|
||||
|
||||
// Case where at least one attribute or its friendly name is in $attrs_display_order
|
||||
// return -1 if $a before $b in $attrs_display_order
|
||||
return ($a_key < $b_key) ? -1 : 1;
|
||||
} ]);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of available attributes - as per the objectClass entry of the record
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getAvailableAttributes(): Collection
|
||||
{
|
||||
$result = collect();
|
||||
|
||||
foreach ($this->objectclass as $oc)
|
||||
$result = $result->merge(config('server')->schema('objectclasses',$oc)->attributes);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a secure version of the DN
|
||||
* @return string
|
||||
*/
|
||||
public function getDNSecure(): string
|
||||
{
|
||||
return Crypt::encryptString($this->getDn());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of LDAP internal attributes
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getInternalAttributes(): Collection
|
||||
{
|
||||
return $this->objects->filter(function($item) {
|
||||
return $item->is_internal;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an attribute as an object
|
||||
*
|
||||
* @param string $key
|
||||
* @return Attribute|null
|
||||
*/
|
||||
public function getObject(string $key): Attribute|null
|
||||
{
|
||||
return $this->objects->get($this->normalizeAttributeKey($key));
|
||||
}
|
||||
|
||||
public function getObjects(): Collection
|
||||
{
|
||||
// In case we havent built our objects yet (because they werent available while determining the schema DN)
|
||||
if ((! $this->objects->count()) && $this->attributes)
|
||||
$this->objects = $this->getAttributesAsObjects($this->attributes);
|
||||
|
||||
return $this->objects;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of attributes without any values
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getMissingAttributes(): Collection
|
||||
{
|
||||
return $this->getAvailableAttributes()->diff($this->getVisibleAttributes());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return this list of user attributes
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getVisibleAttributes(): Collection
|
||||
{
|
||||
return $this->objects->filter(function($item) {
|
||||
return ! $item->is_internal;
|
||||
});
|
||||
}
|
||||
|
||||
public function hasAttribute(int|string $key): bool
|
||||
{
|
||||
return $this->objects->has($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Export this record
|
||||
*
|
||||
* @param string $method
|
||||
* @param string $scope
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function export(string $method,string $scope): string
|
||||
{
|
||||
// @todo To implement
|
||||
switch ($scope) {
|
||||
case 'base':
|
||||
case 'one':
|
||||
case 'sub':
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new \Exception('Export scope unknown:'.$scope);
|
||||
}
|
||||
|
||||
switch ($method) {
|
||||
case 'ldif':
|
||||
return new LDIF(collect($this));
|
||||
|
||||
default:
|
||||
throw new \Exception('Export method not implemented:'.$method);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an icon for a DN based on objectClass
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function icon(): string
|
||||
{
|
||||
$objectclasses = array_map('strtolower',$this->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('posixgroup',$objectclasses) ||
|
||||
in_array('groupofnames',$objectclasses) ||
|
||||
in_array('groupofuniquenames',$objectclasses) ||
|
||||
in_array('group',$objectclasses))
|
||||
|
||||
return 'fas fa-users';
|
||||
|
||||
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('alias',$objectclasses))
|
||||
return 'fas fa-theater-masks';
|
||||
|
||||
elseif (in_array('country',$objectclasses))
|
||||
return sprintf('flag %s',strtolower(Arr::get($this->c,0)));
|
||||
|
||||
elseif (in_array('device',$objectclasses))
|
||||
return 'fas fa-mobile-alt';
|
||||
|
||||
elseif (in_array('document',$objectclasses))
|
||||
return 'fas fa-file-alt';
|
||||
|
||||
elseif (in_array('iphost',$objectclasses))
|
||||
return 'fas fa-wifi';
|
||||
|
||||
elseif (in_array('room',$objectclasses))
|
||||
return 'fas fa-door-open';
|
||||
|
||||
elseif (in_array('server',$objectclasses))
|
||||
return 'fas fa-server';
|
||||
|
||||
elseif (in_array('openldaprootdse',$objectclasses))
|
||||
return 'fas fa-info';
|
||||
|
||||
// Default
|
||||
return 'fa-fw fas fa-cog';
|
||||
}
|
||||
|
||||
/**
|
||||
* Dont convert our $this->attributes to $this->objects when creating a new Entry::class
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function noObjectAttributes(): static
|
||||
{
|
||||
$this->noObjectAttributes = TRUE;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Ldap;
|
||||
|
||||
use Illuminate\Support\Facades\Cookie;
|
||||
// use Illuminate\Support\Facades\Crypt;
|
||||
use LdapRecord\Auth\Guard as GuardBase;
|
||||
|
||||
class Guard extends GuardBase
|
||||
{
|
||||
public function attempt(string $username, string $password, bool $stayBound = false): bool
|
||||
{
|
||||
if ($result = parent::attempt($username,$password,$stayBound)) {
|
||||
/*
|
||||
* We can either use our session or cookies to store this. If using session, then Http/Kernel needs to be
|
||||
* updated to start a session for API calls.
|
||||
// We need to store our password so that we can swap in the user in during SwapinAuthUser::class middleware
|
||||
request()->session()->put('username_encrypt',Crypt::encryptString($username));
|
||||
request()->session()->put('password_encrypt',Crypt::encryptString($password));
|
||||
*/
|
||||
|
||||
// For our API calls, we store the cookie - which our cookies are already encrypted
|
||||
Cookie::queue('username_encrypt',$username);
|
||||
Cookie::queue('password_encrypt',$password);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Ldap;
|
||||
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use Illuminate\Support\Str;
|
||||
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
|
||||
{
|
||||
/**
|
||||
* Retrieve a user by the given credentials.
|
||||
*
|
||||
* @param array $credentials
|
||||
*
|
||||
* @return Model|null
|
||||
* @throws \LdapRecord\Query\ObjectNotFoundException
|
||||
*/
|
||||
public function findByCredentials(array $credentials = []): ?Model
|
||||
{
|
||||
if (empty($credentials)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// For DN based logins
|
||||
if (! empty($credentials['dn']))
|
||||
return $this->query()->find($credentials['dn']);
|
||||
|
||||
// Look for a user using all our baseDNs
|
||||
foreach (Server::baseDNs() as $base) {
|
||||
$query = $this->query()->setBaseDn($base);
|
||||
|
||||
foreach ($credentials as $key => $value) {
|
||||
if (Str::contains($key, $this->bypassCredentialKeys)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_array($value) || $value instanceof Arrayable) {
|
||||
$query->whereIn($key, $value);
|
||||
} else {
|
||||
$query->where($key, $value);
|
||||
}
|
||||
}
|
||||
|
||||
if (! is_null($user = $query->first())) {
|
||||
event(new DiscoveredWithCredentials($user));
|
||||
|
||||
return $user;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a user by their object GUID.
|
||||
*
|
||||
* @param string $guid
|
||||
*
|
||||
* @return Model|null
|
||||
* @throws \LdapRecord\Query\ObjectNotFoundException
|
||||
*/
|
||||
public function findByGuid($guid): ?Model
|
||||
{
|
||||
// Look for a user using all our baseDNs
|
||||
foreach (Server::baseDNs() as $base) {
|
||||
$user = $this->query()->setBaseDn($base)->findByGuid($guid);
|
||||
|
||||
if ($user)
|
||||
return $user;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Ldap\Rules;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model as Eloquent;
|
||||
use LdapRecord\Laravel\Auth\Rule;
|
||||
use LdapRecord\Models\Model as LdapRecord;
|
||||
|
||||
/**
|
||||
* User must have this objectClass to login
|
||||
*
|
||||
* This is overridden by LDAP_LOGIN_OBJECTCLASS
|
||||
* @see User::$objectClasses
|
||||
*/
|
||||
class LoginObjectclassRule implements Rule
|
||||
{
|
||||
public function passes(LdapRecord $user, Eloquent $model = null): bool
|
||||
{
|
||||
if ($x=config('ldap.login.objectclass')) {
|
||||
return count(array_intersect($user->objectclass,$x));
|
||||
|
||||
// Otherwise allow the user to login
|
||||
} else {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Ldap;
|
||||
|
||||
use Laravel\Passport\HasApiTokens;
|
||||
use LdapRecord\Models\OpenLDAP\User as Model;
|
||||
|
||||
use App\Ldap\Rules\LoginObjectclassRule;
|
||||
|
||||
class User extends Model
|
||||
{
|
||||
use HasApiTokens;
|
||||
|
||||
/**
|
||||
* The object classes of the LDAP model.
|
||||
*
|
||||
* @note We set this to an empty array so that any objectclass can login
|
||||
* @see LoginObjectclassRule::class
|
||||
*/
|
||||
public static array $objectClasses = [
|
||||
];
|
||||
|
||||
/* METHODS */
|
||||
|
||||
public function getDn(): string
|
||||
{
|
||||
return $this->exists ? parent::getDn() : 'Anonymous';
|
||||
}
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use LdapRecord\Configuration\DomainConfiguration;
|
||||
use LdapRecord\Laravel\LdapRecord;
|
||||
|
||||
use App\Ldap\LdapUserRepository;
|
||||
|
||||
class AppServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Register any application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
// Add a new option available to be set in the configuration:
|
||||
DomainConfiguration::extend('name', $default = null);
|
||||
|
||||
// Use our LdapUserRepository to support multiple baseDN querying
|
||||
LdapRecord::locateUsersUsing(LdapUserRepository::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Bootstrap any application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
$this->loadViewsFrom(__DIR__.'/../../resources/themes/architect/views/','architect');
|
||||
|
||||
// Enable pluck on collections to work on private values
|
||||
Collection::macro('ppluck', function ($attr) {
|
||||
return $this->map(function (object $item) use ($attr) {
|
||||
return $item->{$attr};
|
||||
})->values();
|
||||
});
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
|
||||
|
||||
class AuthServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* The model to policy mappings for the application.
|
||||
*
|
||||
* @var array<class-string, class-string>
|
||||
*/
|
||||
protected $policies = [
|
||||
// 'App\Models\Model' => 'App\Policies\ModelPolicy',
|
||||
];
|
||||
|
||||
/**
|
||||
* Register any authentication / authorization services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\Facades\Broadcast;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class BroadcastServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Bootstrap any application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
Broadcast::routes();
|
||||
|
||||
require base_path('routes/channels.php');
|
||||
}
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Auth\Events\Registered;
|
||||
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
|
||||
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
|
||||
use Illuminate\Support\Facades\Event;
|
||||
|
||||
class EventServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* The event listener mappings for the application.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $listen = [];
|
||||
|
||||
/**
|
||||
* Register any events for your application.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
parent::boot();
|
||||
|
||||
//
|
||||
}
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Cache\RateLimiting\Limit;
|
||||
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\RateLimiter;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
class RouteServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* The path to the "home" route for your application.
|
||||
*
|
||||
* Typically, users are redirected here after authentication.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public const HOME = '/';
|
||||
|
||||
/**
|
||||
* Define your route model bindings, pattern filters, and other route configuration.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
$this->configureRateLimiting();
|
||||
|
||||
$this->routes(function () {
|
||||
Route::middleware('api')
|
||||
->prefix('api')
|
||||
->group(base_path('routes/api.php'));
|
||||
|
||||
Route::middleware('web')
|
||||
->group(base_path('routes/web.php'));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the rate limiters for the application.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function configureRateLimiting()
|
||||
{
|
||||
RateLimiter::for('api', function (Request $request) {
|
||||
return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
|
||||
});
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Determine if a value has changed by comparing its MD5 value
|
||||
*/
|
||||
namespace App\Traits;
|
||||
|
||||
use Illuminate\Support\Arr;
|
||||
|
||||
trait MD5Updates
|
||||
{
|
||||
public function isDirty(): bool
|
||||
{
|
||||
if (! parent::isDirty())
|
||||
return TRUE;
|
||||
|
||||
foreach ($this->values->diff($this->oldValues) as $key => $value)
|
||||
if (md5(Arr::get($this->oldValues,$key)) !== $value)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\View\Components;
|
||||
|
||||
use Illuminate\View\Component;
|
||||
|
||||
use App\Classes\LDAP\Attribute as LDAPAttribute;
|
||||
|
||||
class Attribute extends Component
|
||||
{
|
||||
public LDAPAttribute $o;
|
||||
public bool $edit;
|
||||
public bool $new;
|
||||
public bool $old;
|
||||
|
||||
/**
|
||||
* Create a new component instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(LDAPAttribute $o,bool $edit,bool $old=FALSE,bool $new=FALSE)
|
||||
{
|
||||
$this->o = $o;
|
||||
$this->edit = $edit;
|
||||
$this->old = $old;
|
||||
$this->new = $new;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the view / contents that represent the component.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View|\Closure|string
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
return $this->o->render($this->edit,$this->old,$this->new);
|
||||
}
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\View\Components;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\View\Component;
|
||||
|
||||
use App\Classes\LDAP\Attribute as LDAPAttribute;
|
||||
|
||||
class AttributeType extends Component
|
||||
{
|
||||
public LDAPAttribute $o;
|
||||
public bool $new;
|
||||
|
||||
/**
|
||||
* Create a new component instance.
|
||||
*/
|
||||
public function __construct(LDAPAttribute $o,bool $new=FALSE)
|
||||
{
|
||||
$this->o = $o;
|
||||
$this->new = $new;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the view / contents that represent the component.
|
||||
*/
|
||||
public function render(): View|Closure|string
|
||||
{
|
||||
return view('components.attribute-type')
|
||||
->with('o',$this->o)
|
||||
->with('new',$this->new);
|
||||
}
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Arr;
|
||||
|
||||
function login_attr_description(): string
|
||||
{
|
||||
return Arr::get(config('ldap.login.attr'),login_attr_name());
|
||||
}
|
||||
|
||||
function login_attr_name(): string
|
||||
{
|
||||
return key(config('ldap.login.attr'));
|
||||
}
|
53
artisan
53
artisan
@ -1,53 +0,0 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
define('LARAVEL_START', microtime(true));
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Register The Auto Loader
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Composer provides a convenient, automatically generated class loader
|
||||
| for our application. We just need to utilize it! We'll require it
|
||||
| into the script here so that we do not have to worry about the
|
||||
| loading of any of our classes manually. It's great to relax.
|
||||
|
|
||||
*/
|
||||
|
||||
require __DIR__.'/vendor/autoload.php';
|
||||
|
||||
$app = require_once __DIR__.'/bootstrap/app.php';
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Run The Artisan Application
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| When we run the console application, the current CLI command will be
|
||||
| executed in this console and the response sent back to a terminal
|
||||
| or another output device for the developers. Here goes nothing!
|
||||
|
|
||||
*/
|
||||
|
||||
$kernel = $app->make(Illuminate\Contracts\Console\Kernel::class);
|
||||
|
||||
$status = $kernel->handle(
|
||||
$input = new Symfony\Component\Console\Input\ArgvInput,
|
||||
new Symfony\Component\Console\Output\ConsoleOutput
|
||||
);
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Shutdown The Application
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Once Artisan has finished running, we will fire off the shutdown events
|
||||
| so that any final work may be done by the application before we shut
|
||||
| down the process. This is the last thing to happen to the request.
|
||||
|
|
||||
*/
|
||||
|
||||
$kernel->terminate($input, $status);
|
||||
|
||||
exit($status);
|
@ -1,55 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Create The Application
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The first thing we will do is create a new Laravel application instance
|
||||
| which serves as the "glue" for all the components of Laravel, and is
|
||||
| the IoC container for the system binding all of the various parts.
|
||||
|
|
||||
*/
|
||||
|
||||
$app = new Illuminate\Foundation\Application(
|
||||
$_ENV['APP_BASE_PATH'] ?? dirname(__DIR__)
|
||||
);
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Bind Important Interfaces
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Next, we need to bind some important interfaces into the container so
|
||||
| we will be able to resolve them when needed. The kernels serve the
|
||||
| incoming requests to this application from both the web and CLI.
|
||||
|
|
||||
*/
|
||||
|
||||
$app->singleton(
|
||||
Illuminate\Contracts\Http\Kernel::class,
|
||||
App\Http\Kernel::class
|
||||
);
|
||||
|
||||
$app->singleton(
|
||||
Illuminate\Contracts\Console\Kernel::class,
|
||||
App\Console\Kernel::class
|
||||
);
|
||||
|
||||
$app->singleton(
|
||||
Illuminate\Contracts\Debug\ExceptionHandler::class,
|
||||
App\Exceptions\Handler::class
|
||||
);
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Return The Application
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This script returns the application instance. The instance is given to
|
||||
| the calling script so we can separate the building of the instances
|
||||
| from the actual running of the application and sending responses.
|
||||
|
|
||||
*/
|
||||
|
||||
return $app;
|
2
bootstrap/cache/.gitignore
vendored
2
bootstrap/cache/.gitignore
vendored
@ -1,2 +0,0 @@
|
||||
*
|
||||
!.gitignore
|
@ -1,65 +0,0 @@
|
||||
{
|
||||
"name": "laravel/laravel",
|
||||
"type": "project",
|
||||
"description": "The Laravel Framework.",
|
||||
"keywords": ["framework","laravel"],
|
||||
"license": "MIT",
|
||||
"require": {
|
||||
"ext-fileinfo": "*",
|
||||
"ext-ldap": "*",
|
||||
"php": "^8.1|8.2",
|
||||
"directorytree/ldaprecord-laravel": "^3.0",
|
||||
"guzzlehttp/guzzle": "^7.2",
|
||||
"laravel/framework": "^10.0",
|
||||
"laravel/passport": "^11.0",
|
||||
"laravel/ui": "^4.0",
|
||||
"mcamara/laravel-localization": "^1.7"
|
||||
},
|
||||
"require-dev": {
|
||||
"barryvdh/laravel-debugbar": "^3.5",
|
||||
"fakerphp/faker": "^1.9.1",
|
||||
"mockery/mockery": "^1.4.4",
|
||||
"nunomaduro/collision": "^7.10",
|
||||
"phpunit/phpunit": "^10.0",
|
||||
"spatie/laravel-ignition": "^2.4"
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"app/helpers.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"App\\": "app/",
|
||||
"Database\\Factories\\": "database/factories/",
|
||||
"Database\\Seeders\\": "database/seeders/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Tests\\": "tests/"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"post-autoload-dump": [
|
||||
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
|
||||
"@php artisan package:discover --ansi"
|
||||
],
|
||||
"post-root-package-install": [
|
||||
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
|
||||
],
|
||||
"post-create-project-cmd": [
|
||||
"@php artisan key:generate --ansi"
|
||||
]
|
||||
},
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"dont-discover": []
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"optimize-autoloader": true,
|
||||
"preferred-install": "dist",
|
||||
"sort-packages": true
|
||||
},
|
||||
"minimum-stability": "stable",
|
||||
"prefer-stable": true
|
||||
}
|
9231
composer.lock
generated
9231
composer.lock
generated
File diff suppressed because it is too large
Load Diff
203
config/app.php
203
config/app.php
@ -1,203 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Facade;
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Application Name
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This value is the name of your application. This value is used when the
|
||||
| framework needs to place the application's name in a notification or
|
||||
| any other location as required by the application or its packages.
|
||||
|
|
||||
*/
|
||||
|
||||
'name' => 'PLA',
|
||||
'name_html_long' => '<b>php</b>LDAPadmin',
|
||||
'version' => (trim(file_get_contents(__DIR__.'/../public/VERSION')) ?? 'UNKNOWN').'-'.(trim(file_get_contents(__DIR__.'/../VERSION')) ?? 'UNKNOWN'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Application Environment
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This value determines the "environment" your application is currently
|
||||
| running in. This may determine how you prefer to configure various
|
||||
| services the application utilizes. Set this in your ".env" file.
|
||||
|
|
||||
*/
|
||||
|
||||
'env' => env('APP_ENV', 'production'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Application Debug Mode
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| When your application is in debug mode, detailed error messages with
|
||||
| stack traces will be shown on every error that occurs within your
|
||||
| application. If disabled, a simple generic error page is shown.
|
||||
|
|
||||
*/
|
||||
|
||||
'debug' => (bool) env('APP_DEBUG', false),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Application URL
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This URL is used by the console to properly generate URLs when using
|
||||
| the Artisan command line tool. You should set this to the root of
|
||||
| your application so that it is used when running Artisan tasks.
|
||||
|
|
||||
*/
|
||||
|
||||
'url' => env('APP_URL', 'http://localhost'),
|
||||
|
||||
'asset_url' => env('ASSET_URL', null),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Application Timezone
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may specify the default timezone for your application, which
|
||||
| will be used by the PHP date and date-time functions. We have gone
|
||||
| ahead and set this to a sensible default for you out of the box.
|
||||
|
|
||||
*/
|
||||
|
||||
'timezone' => 'UTC',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Application Locale Configuration
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The application locale determines the default locale that will be used
|
||||
| by the translation service provider. You are free to set this value
|
||||
| to any of the locales which will be supported by the application.
|
||||
|
|
||||
*/
|
||||
|
||||
'locale' => 'en',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Application Fallback Locale
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The fallback locale determines the locale to use when the current one
|
||||
| is not available. You may change the value to correspond to any of
|
||||
| the language folders that are provided through your application.
|
||||
|
|
||||
*/
|
||||
|
||||
'fallback_locale' => 'en',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Faker Locale
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This locale will be used by the Faker PHP library when generating fake
|
||||
| data for your database seeds. For example, this will be used to get
|
||||
| localized telephone numbers, street address information and more.
|
||||
|
|
||||
*/
|
||||
|
||||
'faker_locale' => 'en_US',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Encryption Key
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This key is used by the Illuminate encrypter service and should be set
|
||||
| to a random, 32 character string, otherwise these encrypted strings
|
||||
| will not be safe. Please do this before deploying an application!
|
||||
|
|
||||
*/
|
||||
|
||||
'key' => env('APP_KEY'),
|
||||
|
||||
'cipher' => 'AES-256-CBC',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Autoloaded Service Providers
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The service providers listed here will be automatically loaded on the
|
||||
| request to your application. Feel free to add your own services to
|
||||
| this array to grant expanded functionality to your applications.
|
||||
|
|
||||
*/
|
||||
|
||||
'providers' => [
|
||||
|
||||
/*
|
||||
* Laravel Framework Service Providers...
|
||||
*/
|
||||
Illuminate\Auth\AuthServiceProvider::class,
|
||||
Illuminate\Broadcasting\BroadcastServiceProvider::class,
|
||||
Illuminate\Bus\BusServiceProvider::class,
|
||||
Illuminate\Cache\CacheServiceProvider::class,
|
||||
Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class,
|
||||
Illuminate\Cookie\CookieServiceProvider::class,
|
||||
Illuminate\Database\DatabaseServiceProvider::class,
|
||||
Illuminate\Encryption\EncryptionServiceProvider::class,
|
||||
Illuminate\Filesystem\FilesystemServiceProvider::class,
|
||||
Illuminate\Foundation\Providers\FoundationServiceProvider::class,
|
||||
Illuminate\Hashing\HashServiceProvider::class,
|
||||
Illuminate\Mail\MailServiceProvider::class,
|
||||
Illuminate\Notifications\NotificationServiceProvider::class,
|
||||
Illuminate\Pagination\PaginationServiceProvider::class,
|
||||
Illuminate\Pipeline\PipelineServiceProvider::class,
|
||||
Illuminate\Queue\QueueServiceProvider::class,
|
||||
Illuminate\Redis\RedisServiceProvider::class,
|
||||
Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
|
||||
Illuminate\Session\SessionServiceProvider::class,
|
||||
Illuminate\Translation\TranslationServiceProvider::class,
|
||||
Illuminate\Validation\ValidationServiceProvider::class,
|
||||
Illuminate\View\ViewServiceProvider::class,
|
||||
|
||||
/*
|
||||
* Package Service Providers...
|
||||
*/
|
||||
|
||||
/*
|
||||
* Application Service Providers...
|
||||
*/
|
||||
App\Providers\AppServiceProvider::class,
|
||||
App\Providers\AuthServiceProvider::class,
|
||||
// App\Providers\BroadcastServiceProvider::class,
|
||||
App\Providers\EventServiceProvider::class,
|
||||
App\Providers\RouteServiceProvider::class,
|
||||
|
||||
/*
|
||||
* Other Service Providers...
|
||||
*/
|
||||
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Class Aliases
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This array of class aliases will be registered when this application
|
||||
| is started. However, feel free to register as many as you wish as
|
||||
| the aliases are "lazy" loaded so they don't hinder performance.
|
||||
|
|
||||
*/
|
||||
|
||||
'aliases' => Facade::defaultAliases()->merge([
|
||||
// 'ExampleClass' => App\Example\ExampleClass::class,
|
||||
])->toArray(),
|
||||
|
||||
];
|
125
config/auth.php
125
config/auth.php
@ -1,125 +0,0 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Authentication Defaults
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This option controls the default authentication "guard" and password
|
||||
| reset options for your application. You may change these defaults
|
||||
| as required, but they're a perfect start for most applications.
|
||||
|
|
||||
*/
|
||||
|
||||
'defaults' => [
|
||||
'guard' => 'web',
|
||||
'passwords' => 'users',
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Authentication Guards
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Next, you may define every authentication guard for your application.
|
||||
| Of course, a great default configuration has been defined for you
|
||||
| here which uses session storage and the Eloquent user provider.
|
||||
|
|
||||
| All authentication drivers have a user provider. This defines how the
|
||||
| users are actually retrieved out of your database or other storage
|
||||
| mechanisms used by this application to persist your user's data.
|
||||
|
|
||||
| Supported: "session", "token"
|
||||
|
|
||||
*/
|
||||
|
||||
'guards' => [
|
||||
'web' => [
|
||||
'driver' => 'session',
|
||||
'provider' => 'ldap',
|
||||
],
|
||||
|
||||
'api' => [
|
||||
'driver' => 'passport',
|
||||
'provider' => 'users',
|
||||
'hash' => false,
|
||||
],
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| User Providers
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| All authentication drivers have a user provider. This defines how the
|
||||
| users are actually retrieved out of your database or other storage
|
||||
| mechanisms used by this application to persist your user's data.
|
||||
|
|
||||
| If you have multiple user tables or models you may configure multiple
|
||||
| sources which represent each model / table. These sources may then
|
||||
| be assigned to any extra authentication guards you have defined.
|
||||
|
|
||||
| Supported: "database", "eloquent"
|
||||
|
|
||||
*/
|
||||
|
||||
'providers' => [
|
||||
'users' => [
|
||||
'driver' => 'ldap',
|
||||
'model' => App\Ldap\User::class,
|
||||
],
|
||||
|
||||
// 'users' => [
|
||||
// 'driver' => 'database',
|
||||
// 'table' => 'users',
|
||||
// ],
|
||||
|
||||
'ldap' => [
|
||||
'driver' => 'ldap',
|
||||
'model' => App\Ldap\User::class,
|
||||
'rules' => [
|
||||
App\Ldap\Rules\LoginObjectclassRule::class,
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Resetting Passwords
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| You may specify multiple password reset configurations if you have more
|
||||
| than one user table or model in the application and you want to have
|
||||
| separate password reset settings based on the specific user types.
|
||||
|
|
||||
| The expire time is the number of minutes that the reset token should be
|
||||
| considered valid. This security feature keeps tokens short-lived so
|
||||
| they have less time to be guessed. You may change this as needed.
|
||||
|
|
||||
*/
|
||||
|
||||
'passwords' => [
|
||||
'users' => [
|
||||
'provider' => 'users',
|
||||
'table' => 'password_resets',
|
||||
'expire' => 60,
|
||||
'throttle' => 60,
|
||||
],
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Password Confirmation Timeout
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may define the amount of seconds before a password confirmation
|
||||
| times out and the user is prompted to re-enter their password via the
|
||||
| confirmation screen. By default, the timeout lasts for three hours.
|
||||
|
|
||||
*/
|
||||
|
||||
'password_timeout' => 10800,
|
||||
|
||||
];
|
@ -1,59 +0,0 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Default Broadcaster
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This option controls the default broadcaster that will be used by the
|
||||
| framework when an event needs to be broadcast. You may set this to
|
||||
| any of the connections defined in the "connections" array below.
|
||||
|
|
||||
| Supported: "pusher", "redis", "log", "null"
|
||||
|
|
||||
*/
|
||||
|
||||
'default' => env('BROADCAST_DRIVER', 'null'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Broadcast Connections
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may define all of the broadcast connections that will be used
|
||||
| to broadcast events to other systems or over websockets. Samples of
|
||||
| each available type of connection are provided inside this array.
|
||||
|
|
||||
*/
|
||||
|
||||
'connections' => [
|
||||
|
||||
'pusher' => [
|
||||
'driver' => 'pusher',
|
||||
'key' => env('PUSHER_APP_KEY'),
|
||||
'secret' => env('PUSHER_APP_SECRET'),
|
||||
'app_id' => env('PUSHER_APP_ID'),
|
||||
'options' => [
|
||||
'cluster' => env('PUSHER_APP_CLUSTER'),
|
||||
'useTLS' => true,
|
||||
],
|
||||
],
|
||||
|
||||
'redis' => [
|
||||
'driver' => 'redis',
|
||||
'connection' => 'default',
|
||||
],
|
||||
|
||||
'log' => [
|
||||
'driver' => 'log',
|
||||
],
|
||||
|
||||
'null' => [
|
||||
'driver' => 'null',
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
];
|
104
config/cache.php
104
config/cache.php
@ -1,104 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Default Cache Store
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This option controls the default cache connection that gets used while
|
||||
| using this caching library. This connection is used when another is
|
||||
| not explicitly specified when executing a given caching function.
|
||||
|
|
||||
| Supported: "apc", "array", "database", "file",
|
||||
| "memcached", "redis", "dynamodb"
|
||||
|
|
||||
*/
|
||||
|
||||
'default' => env('CACHE_DRIVER', 'file'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Cache Stores
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may define all of the cache "stores" for your application as
|
||||
| well as their drivers. You may even define multiple stores for the
|
||||
| same cache driver to group types of items stored in your caches.
|
||||
|
|
||||
*/
|
||||
|
||||
'stores' => [
|
||||
|
||||
'apc' => [
|
||||
'driver' => 'apc',
|
||||
],
|
||||
|
||||
'array' => [
|
||||
'driver' => 'array',
|
||||
'serialize' => false,
|
||||
],
|
||||
|
||||
'database' => [
|
||||
'driver' => 'database',
|
||||
'table' => 'cache',
|
||||
'connection' => null,
|
||||
],
|
||||
|
||||
'file' => [
|
||||
'driver' => 'file',
|
||||
'path' => storage_path('framework/cache/data'),
|
||||
],
|
||||
|
||||
'memcached' => [
|
||||
'driver' => 'memcached',
|
||||
'persistent_id' => env('MEMCACHED_PERSISTENT_ID'),
|
||||
'sasl' => [
|
||||
env('MEMCACHED_USERNAME'),
|
||||
env('MEMCACHED_PASSWORD'),
|
||||
],
|
||||
'options' => [
|
||||
// Memcached::OPT_CONNECT_TIMEOUT => 2000,
|
||||
],
|
||||
'servers' => [
|
||||
[
|
||||
'host' => env('MEMCACHED_HOST', '127.0.0.1'),
|
||||
'port' => env('MEMCACHED_PORT', 11211),
|
||||
'weight' => 100,
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
'redis' => [
|
||||
'driver' => 'redis',
|
||||
'connection' => 'cache',
|
||||
],
|
||||
|
||||
'dynamodb' => [
|
||||
'driver' => 'dynamodb',
|
||||
'key' => env('AWS_ACCESS_KEY_ID'),
|
||||
'secret' => env('AWS_SECRET_ACCESS_KEY'),
|
||||
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
|
||||
'table' => env('DYNAMODB_CACHE_TABLE', 'cache'),
|
||||
'endpoint' => env('DYNAMODB_ENDPOINT'),
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Cache Key Prefix
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| When utilizing a RAM based store such as APC or Memcached, there might
|
||||
| be other applications utilizing the same cache. So, we'll specify a
|
||||
| value to get prefixed to all our keys so we can avoid collisions.
|
||||
|
|
||||
*/
|
||||
|
||||
'prefix' => env('CACHE_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_cache'),
|
||||
|
||||
];
|
@ -6,7 +6,6 @@
|
||||
|
||||
/**
|
||||
* The phpLDAPadmin config file
|
||||
* See: http://phpldapadmin.sourceforge.net/wiki/index.php/Config.php
|
||||
*
|
||||
* This is where you can customise some of the phpLDAPadmin defaults
|
||||
* that are defined in config_default.php.
|
||||
@ -14,11 +13,11 @@
|
||||
* To override a default, use the $config->custom variable to do so.
|
||||
* For example, the default for defining the language in config_default.php
|
||||
*
|
||||
* $this->default->appearance['language'] = array(
|
||||
* $this->default->appearance['lang'] = array(
|
||||
* 'desc'=>'Language',
|
||||
* 'default'=>'auto');
|
||||
*
|
||||
* to override this, use $config->custom->appearance['language'] = 'en_EN';
|
||||
* to override this, use $config->custom->appearance['lang'] = 'en';
|
||||
*
|
||||
* This file is also used to configure your LDAP server connections.
|
||||
*
|
||||
@ -36,34 +35,30 @@
|
||||
* version of phpLDAPadmin.
|
||||
*/
|
||||
|
||||
/*********************************************
|
||||
* Useful important configuration overrides *
|
||||
*********************************************/
|
||||
/*********************************************/
|
||||
/* Useful important configuration overrides */
|
||||
/*********************************************/
|
||||
|
||||
/* If you are asked to put PLA in debug mode, this is how you do it: */
|
||||
/* If you are asked to put pla in debug mode, this is how you do it: */
|
||||
# $config->custom->debug['level'] = 255;
|
||||
# $config->custom->debug['syslog'] = true;
|
||||
# $config->custom->debug['file'] = '/tmp/pla_debug.log';
|
||||
|
||||
/* phpLDAPadmin can encrypt the content of sensitive cookies if you set this
|
||||
to a big random string. */
|
||||
// $config->custom->session['blowfish'] = null;
|
||||
|
||||
/* If your auth_type is http, you can override your HTTP Authentication Realm. */
|
||||
// $config->custom->session['http_realm'] = sprintf('%s %s',app_name(),'login');
|
||||
$config->custom->session['blowfish'] = '';
|
||||
|
||||
/* The language setting. If you set this to 'auto', phpLDAPadmin will attempt
|
||||
to determine your language automatically.
|
||||
If PLA doesnt show (all) strings in your language, then you can do some
|
||||
translation at http://translations.launchpad.net/phpldapadmin and download
|
||||
the translation files, replacing those provided with PLA.
|
||||
(We'll pick up the translations before making the next release too!) */
|
||||
to determine your language automatically. Otherwise, available lanaguages
|
||||
are: 'ct', 'de', 'en', 'es', 'fr', 'it', 'nl', and 'ru'
|
||||
Localization is not complete yet, but most strings have been translated.
|
||||
Please help by writing language files. See lang/en.php for an example. */
|
||||
// $config->custom->appearance['language'] = 'auto';
|
||||
|
||||
/* The temporary storage directory where we will put jpegPhoto data
|
||||
This directory must be readable and writable by your web server. */
|
||||
// $config->custom->jpeg['tmpdir'] = '/tmp'; // Example for Unix systems
|
||||
# $config->custom->jpeg['tmpdir'] = 'c:\\temp'; // Example for Windows systems
|
||||
// $config->custom->jpeg['tmpdir'] = "/tmp"; // Example for Unix systems
|
||||
# $config->custom->jpeg['tmpdir'] = "c:\\temp"; // Example for Windows systems
|
||||
|
||||
/* Set this to (bool)true if you do NOT want a random salt used when
|
||||
calling crypt(). Instead, use the first two letters of the user's
|
||||
@ -71,246 +66,63 @@
|
||||
environments. */
|
||||
# $config->custom->password['no_random_crypt_salt'] = true;
|
||||
|
||||
/* PHP script timeout control. If php runs longer than this many seconds then
|
||||
PHP will stop with an Maximum Execution time error. Increase this value from
|
||||
the default if queries to your LDAP server are slow. The default is either
|
||||
30 seconds or the setting of max_exection_time if this is null. */
|
||||
// $config->custom->session['timelimit'] = 30;
|
||||
|
||||
/* Our local timezone
|
||||
This is to make sure that when we ask the system for the current time, we
|
||||
get the right local time. If this is not set, all time() calculations will
|
||||
assume UTC if you have not set PHP date.timezone. */
|
||||
// $config->custom->appearance['timezone'] = null;
|
||||
# $config->custom->appearance['timezone'] = 'Australia/Melbourne';
|
||||
|
||||
/*********************************************
|
||||
* Commands *
|
||||
*********************************************/
|
||||
|
||||
/* Command availability ; if you don't authorize a command the command
|
||||
links will not be shown and the command action will not be permitted.
|
||||
For better security, set also ACL in your ldap directory. */
|
||||
/*
|
||||
$config->custom->commands['cmd'] = array(
|
||||
'entry_internal_attributes_show' => true,
|
||||
'entry_refresh' => true,
|
||||
'oslinks' => true,
|
||||
'switch_template' => true
|
||||
);
|
||||
|
||||
$config->custom->commands['script'] = array(
|
||||
'add_attr_form' => true,
|
||||
'add_oclass_form' => true,
|
||||
'add_value_form' => true,
|
||||
'collapse' => true,
|
||||
'compare' => true,
|
||||
'compare_form' => true,
|
||||
'copy' => true,
|
||||
'copy_form' => true,
|
||||
'create' => true,
|
||||
'create_confirm' => true,
|
||||
'delete' => true,
|
||||
'delete_attr' => true,
|
||||
'delete_form' => true,
|
||||
'draw_tree_node' => true,
|
||||
'expand' => true,
|
||||
'export' => true,
|
||||
'export_form' => true,
|
||||
'import' => true,
|
||||
'import_form' => true,
|
||||
'login' => true,
|
||||
'logout' => true,
|
||||
'login_form' => true,
|
||||
'mass_delete' => true,
|
||||
'mass_edit' => true,
|
||||
'mass_update' => true,
|
||||
'modify_member_form' => true,
|
||||
'monitor' => true,
|
||||
'purge_cache' => true,
|
||||
'query_engine' => true,
|
||||
'rename' => true,
|
||||
'rename_form' => true,
|
||||
'rdelete' => true,
|
||||
'refresh' => true,
|
||||
'schema' => true,
|
||||
'server_info' => true,
|
||||
'show_cache' => true,
|
||||
'template_engine' => true,
|
||||
'update_confirm' => true,
|
||||
'update' => true
|
||||
);
|
||||
*/
|
||||
|
||||
/*********************************************
|
||||
* Appearance *
|
||||
*********************************************/
|
||||
|
||||
/* If you want to choose the appearance of the tree, specify a class name which
|
||||
inherits from the Tree class. */
|
||||
// $config->custom->appearance['tree'] = 'AJAXTree';
|
||||
# $config->custom->appearance['tree'] = 'HTMLTree';
|
||||
|
||||
/* Just show your custom templates. */
|
||||
// $config->custom->appearance['custom_templates_only'] = false;
|
||||
|
||||
/* Disable the default template. */
|
||||
// $config->custom->appearance['disable_default_template'] = false;
|
||||
|
||||
/* Hide the warnings for invalid objectClasses/attributes in templates. */
|
||||
// $config->custom->appearance['hide_template_warning'] = false;
|
||||
|
||||
/* Set to true if you would like to hide header and footer parts. */
|
||||
// $config->custom->appearance['minimalMode'] = false;
|
||||
|
||||
/* Configure what objects are shown in left hand tree */
|
||||
// $config->custom->appearance['tree_filter'] = '(objectclass=*)';
|
||||
|
||||
/* The height and width of the tree. If these values are not set, then
|
||||
no tree scroll bars are provided. */
|
||||
// $config->custom->appearance['tree_height'] = null;
|
||||
# $config->custom->appearance['tree_height'] = 600;
|
||||
// $config->custom->appearance['tree_width'] = null;
|
||||
# $config->custom->appearance['tree_width'] = 250;
|
||||
/*********************************************/
|
||||
/* Define your LDAP servers in this section */
|
||||
/*********************************************/
|
||||
|
||||
/* Confirm create and update operations, allowing you to review the changes
|
||||
and optionally skip attributes during the create/update operation. */
|
||||
// $config->custom->confirm['create'] = true;
|
||||
// $config->custom->confirm['update'] = true;
|
||||
|
||||
/* Confirm copy operations, and treat them like create operations. This allows
|
||||
you to edit the attributes (thus changing any that might conflict with
|
||||
uniqueness) before creating the new entry. */
|
||||
// $config->custom->confirm['copy'] = true;
|
||||
|
||||
/*********************************************
|
||||
* User-friendly attribute translation *
|
||||
*********************************************/
|
||||
|
||||
/* Use this array to map attribute names to user friendly names. For example, if
|
||||
you don't want to see "facsimileTelephoneNumber" but rather "Fax". */
|
||||
// $config->custom->appearance['friendly_attrs'] = array();
|
||||
$config->custom->appearance['friendly_attrs'] = array(
|
||||
'facsimileTelephoneNumber' => 'Fax',
|
||||
'gid' => 'Group',
|
||||
'mail' => 'Email',
|
||||
'telephoneNumber' => 'Telephone',
|
||||
'uid' => 'User Name',
|
||||
'userPassword' => 'Password'
|
||||
);
|
||||
|
||||
/*********************************************
|
||||
* Hidden attributes *
|
||||
*********************************************/
|
||||
|
||||
/* You may want to hide certain attributes from being edited. If you want to
|
||||
hide attributes from the user, you should use your LDAP servers ACLs.
|
||||
NOTE: The user must be able to read the hide_attrs_exempt entry to be
|
||||
excluded. */
|
||||
// $config->custom->appearance['hide_attrs'] = array();
|
||||
# $config->custom->appearance['hide_attrs'] = array('objectClass');
|
||||
|
||||
/* Members of this list will be exempt from the hidden attributes. */
|
||||
// $config->custom->appearance['hide_attrs_exempt'] = null;
|
||||
# $config->custom->appearance['hide_attrs_exempt'] = 'cn=PLA UnHide,ou=Groups,c=AU';
|
||||
|
||||
/*********************************************
|
||||
* Read-only attributes *
|
||||
*********************************************/
|
||||
|
||||
/* You may want to phpLDAPadmin to display certain attributes as read only,
|
||||
meaning that users will not be presented a form for modifying those
|
||||
attributes, and they will not be allowed to be modified on the "back-end"
|
||||
either. You may configure this list here:
|
||||
NOTE: The user must be able to read the readonly_attrs_exempt entry to be
|
||||
excluded. */
|
||||
// $config->custom->appearance['readonly_attrs'] = array();
|
||||
|
||||
/* Members of this list will be exempt from the readonly attributes. */
|
||||
// $config->custom->appearance['readonly_attrs_exempt'] = null;
|
||||
# $config->custom->appearance['readonly_attrs_exempt'] = 'cn=PLA ReadWrite,ou=Groups,c=AU';
|
||||
|
||||
/*********************************************
|
||||
* Group attributes *
|
||||
*********************************************/
|
||||
|
||||
/* Add "modify group members" link to the attribute. */
|
||||
// $config->custom->modify_member['groupattr'] = array('member','uniqueMember','memberUid','sudoUser');
|
||||
|
||||
/* Configure filter for member search. This only applies to "modify group members" feature */
|
||||
// $config->custom->modify_member['filter'] = '(objectclass=Person)';
|
||||
|
||||
/* Attribute that is added to the group member attribute. */
|
||||
// $config->custom->modify_member['attr'] = 'dn';
|
||||
|
||||
|
||||
/* For Posix attributes */
|
||||
// $config->custom->modify_member['posixattr'] = 'uid';
|
||||
// $config->custom->modify_member['posixfilter'] = '(uid=*)';
|
||||
// $config->custom->modify_member['posixgroupattr'] = 'memberUid';
|
||||
|
||||
/*********************************************
|
||||
* Define your LDAP servers in this section *
|
||||
*********************************************/
|
||||
|
||||
$servers = new Datastore();
|
||||
|
||||
/* $servers->NewServer('ldap_pla') must be called before each new LDAP server
|
||||
declaration. */
|
||||
$servers->newServer('ldap_pla');
|
||||
$i=0;
|
||||
$ldapservers = new LDAPServers;
|
||||
|
||||
/* A convenient name that will appear in the tree viewer and throughout
|
||||
phpLDAPadmin to identify this LDAP server to users. */
|
||||
$servers->setValue('server','name','My LDAP Server');
|
||||
$ldapservers->SetValue($i,'server','name','My LDAP Server');
|
||||
|
||||
/* Examples:
|
||||
'ldap.example.com',
|
||||
'ldaps://ldap.example.com/',
|
||||
'ldapi://%2fusr%local%2fvar%2frun%2fldapi'
|
||||
(Unix socket at /usr/local/var/run/ldap) */
|
||||
// $servers->setValue('server','host','127.0.0.1');
|
||||
// $ldapservers->SetValue($i,'server','host','127.0.0.1');
|
||||
|
||||
/* The port your LDAP server listens on (no quotes). 389 is standard. */
|
||||
// $servers->setValue('server','port',389);
|
||||
// $ldapservers->SetValue($i,'server','port','389');
|
||||
|
||||
/* Array of base DNs of your LDAP server. Leave this blank to have phpLDAPadmin
|
||||
auto-detect it for you. */
|
||||
// $servers->setValue('server','base',array(''));
|
||||
// $ldapservers->SetValue($i,'server','base',array(''));
|
||||
|
||||
/* Five options for auth_type:
|
||||
/* Three options for auth_type:
|
||||
1. 'cookie': you will login via a web form, and a client-side cookie will
|
||||
store your login dn and password.
|
||||
2. 'session': same as cookie but your login dn and password are stored on the
|
||||
web server in a persistent session variable.
|
||||
3. 'http': same as session but your login dn and password are retrieved via
|
||||
HTTP authentication.
|
||||
4. 'config': specify your login dn and password here in this config file. No
|
||||
3. 'config': specify your login dn and password here in this config file. No
|
||||
login will be required to use phpLDAPadmin for this server.
|
||||
5. 'sasl': login will be taken from the webserver's kerberos authentication.
|
||||
Currently only GSSAPI has been tested (using mod_auth_kerb).
|
||||
|
||||
Choose wisely to protect your authentication information appropriately for
|
||||
your situation. If you choose 'cookie', your cookie contents will be
|
||||
encrypted using blowfish and the secret your specify above as
|
||||
session['blowfish']. */
|
||||
// $servers->setValue('login','auth_type','session');
|
||||
// $ldapservers->SetValue($i,'server','auth_type','cookie');
|
||||
|
||||
/* The DN of the user for phpLDAPadmin to bind with. For anonymous binds or
|
||||
'cookie','session' or 'sasl' auth_types, LEAVE THE LOGIN_DN AND LOGIN_PASS
|
||||
BLANK. If you specify a login_attr in conjunction with a cookie or session
|
||||
auth_type, then you can also specify the bind_id/bind_pass here for searching
|
||||
the directory for users (ie, if your LDAP server does not allow anonymous
|
||||
binds. */
|
||||
// $servers->setValue('login','bind_id','');
|
||||
# $servers->setValue('login','bind_id','cn=Manager,dc=example,dc=com');
|
||||
'cookie' or 'session' auth_types, LEAVE THE LOGIN_DN AND LOGIN_PASS BLANK. If
|
||||
you specify a login_attr in conjunction with a cookie or session auth_type,
|
||||
then you can also specify the login_dn/login_pass here for searching the
|
||||
directory for users (ie, if your LDAP server does not allow anonymous binds. */
|
||||
// $ldapservers->SetValue($i,'login','dn','');
|
||||
# $ldapservers->SetValue($i,'login','dn','cn=Manager,dc=example,dc=com');
|
||||
|
||||
/* Your LDAP password. If you specified an empty bind_id above, this MUST also
|
||||
/* Your LDAP password. If you specified an empty login_dn above, this MUST also
|
||||
be blank. */
|
||||
// $servers->setValue('login','bind_pass','');
|
||||
# $servers->setValue('login','bind_pass','secret');
|
||||
// $ldapservers->SetValue($i,'login','pass','');
|
||||
# $ldapservers->SetValue($i,'login','pass','secret');
|
||||
|
||||
/* Use TLS (Transport Layer Security) to connect to the LDAP server. */
|
||||
// $servers->setValue('server','tls',false);
|
||||
// $ldapservers->SetValue($i,'server','tls',false);
|
||||
|
||||
/************************************
|
||||
* SASL Authentication *
|
||||
@ -319,27 +131,22 @@ $servers->setValue('server','name','My LDAP Server');
|
||||
/* Enable SASL authentication LDAP SASL authentication requires PHP 5.x
|
||||
configured with --with-ldap-sasl=DIR. If this option is disabled (ie, set to
|
||||
false), then all other sasl options are ignored. */
|
||||
# $servers->setValue('login','auth_type','sasl');
|
||||
// $ldapservers->SetValue($i,'server','sasl_auth',false);
|
||||
|
||||
/* SASL GSSAPI auth mechanism (requires auth_type of sasl) */
|
||||
// $servers->setValue('sasl','mech','GSSAPI');
|
||||
|
||||
/* SASL PLAIN support... this mech converts simple binds to SASL
|
||||
PLAIN binds using any auth_type (or other bind_id/pass) as credentials.
|
||||
NOTE: auth_type must be simple auth compatible (ie not sasl) */
|
||||
# $servers->setValue('sasl','mech','PLAIN');
|
||||
/* SASL auth mechanism */
|
||||
// $ldapservers->SetValue($i,'server','sasl_mech','PLAIN');
|
||||
|
||||
/* SASL authentication realm name */
|
||||
// $servers->setValue('sasl','realm','');
|
||||
# $servers->setValue('sasl','realm','EXAMPLE.COM');
|
||||
// $ldapservers->SetValue($i,'server','sasl_realm','');
|
||||
# $ldapservers->SetValue($i,'server','sasl_realm',"example.com");
|
||||
|
||||
/* SASL authorization ID name
|
||||
If this option is undefined, authorization id will be computed from bind DN,
|
||||
using authz_id_regex and authz_id_replacement. */
|
||||
// $servers->setValue('sasl','authz_id', null);
|
||||
using sasl_authz_id_regex and sasl_authz_id_replacement. */
|
||||
// $ldapservers->SetValue($i,'server','sasl_authz_id', null);
|
||||
|
||||
/* SASL authorization id regex and replacement
|
||||
When authz_id property is not set (default), phpLDAPAdmin will try to
|
||||
When sasl_authz_id property is not set (default), phpLDAPAdmin will try to
|
||||
figure out authorization id by itself from bind distinguished name (DN).
|
||||
|
||||
This procedure is done by calling preg_replace() php function in the
|
||||
@ -351,18 +158,24 @@ $servers->setValue('server','name','My LDAP Server');
|
||||
For info about pcre regexes, see:
|
||||
- pcre(3), perlre(3)
|
||||
- http://www.php.net/preg_replace */
|
||||
// $servers->setValue('sasl','authz_id_regex',null);
|
||||
// $servers->setValue('sasl','authz_id_replacement',null);
|
||||
# $servers->setValue('sasl','authz_id_regex','/^uid=([^,]+)(.+)/i');
|
||||
# $servers->setValue('sasl','authz_id_replacement','$1');
|
||||
// $ldapservers->SetValue($i,'server','sasl_authz_id_regex',null);
|
||||
// $ldapservers->SetValue($i,'server','sasl_authz_id_replacement',null);
|
||||
# $ldapservers->SetValue($i,'server','sasl_authz_id_regex','/^uid=([^,]+)(.+)/i');
|
||||
# $ldapservers->SetValue($i,'server','sasl_authz_id_replacement','$1');
|
||||
|
||||
/* SASL auth security props.
|
||||
See http://beepcore-tcl.sourceforge.net/tclsasl.html#anchor5 for explanation. */
|
||||
// $servers->setValue('sasl','props',null);
|
||||
See http://beepcore-tcl.sourceforge.net/tclsasl.html#anchor5 for explanation.
|
||||
*/
|
||||
// $ldapservers->SetValue($i,'server','sasl_props',null);
|
||||
|
||||
/* If the link between your web server and this LDAP server is slow, it is
|
||||
recommended that you set 'low_bandwidth' to true. This will enable
|
||||
phpLDAPadmin to forego some "fancy" features to conserve bandwidth. */
|
||||
// $ldapservers->SetValue($i,'server','low_bandwidth',false);
|
||||
|
||||
/* Default password hashing algorithm. One of md5, ssha, sha, md5crpyt, smd5,
|
||||
blowfish, crypt or leave blank for now default algorithm. */
|
||||
// $servers->setValue('appearance','pla_password_hash','md5');
|
||||
// $ldapservers->SetValue($i,'appearance','password_hash','md5');
|
||||
|
||||
/* If you specified 'cookie' or 'session' as the auth_type above, you can
|
||||
optionally specify here an attribute to use when logging in. If you enter
|
||||
@ -370,45 +183,35 @@ $servers->setValue('server','name','My LDAP Server');
|
||||
and log in as that user.
|
||||
Leave blank or specify 'dn' to use full DN for logging in. Note also that if
|
||||
your LDAP server requires you to login to perform searches, you can enter the
|
||||
DN to use when searching in 'bind_id' and 'bind_pass' above. */
|
||||
// $servers->setValue('login','attr','dn');
|
||||
DN to use when searching in 'login_dn' and 'login_pass' above. You may also
|
||||
specify 'string', in which case you can provide a string to use for logging
|
||||
users in. See 'login_string' directly below. */
|
||||
// $ldapservers->SetValue($i,'login','attr','dn');
|
||||
|
||||
/* Base DNs to used for logins. If this value is not set, then the LDAP server
|
||||
Base DNs are used. */
|
||||
// $servers->setValue('login','base',array());
|
||||
/* If you specified 'cookie' or 'session' as the auth_type above, and you
|
||||
specified 'string' for 'login_attr' above, you must provide a string here for
|
||||
logging users in. If, for example, I have a lot of user entries with DNs like
|
||||
"uid=dsmith,ou=People,dc=example,dc=com", then I can specify a string
|
||||
"uid=<username>,ou=People,dc=example,dc=com" and my users can login with
|
||||
their user names alone, ie: "dsmith" in this case. */
|
||||
# $ldapservers->SetValue($i,'login','string','uid=<username>,ou=People,dc=example,dc=com');
|
||||
|
||||
/* If login_attr was set to 'dn', it is possible to specify a template string to
|
||||
build the DN from. Use '%s' where user input should be inserted. A user may
|
||||
still enter the complete DN. In this case the template will not be used. */
|
||||
// $servers->setValue('login','bind_dn_template',null);
|
||||
# $servers->setValue('login','bind_dn_template','cn=%s,ou=people,dc=example,dc=com');
|
||||
|
||||
/* If you specified something different from 'dn', for example 'uid', as the
|
||||
login_attr above, you can optionally specify here to fall back to
|
||||
authentication with dn.
|
||||
This is useful, when users should be able to log in with their uid, but
|
||||
the ldap administrator wants to log in with his root-dn, that does not
|
||||
necessarily have the uid attribute.
|
||||
When using this feature, login_class is ignored. */
|
||||
// $servers->setValue('login','fallback_dn',false);
|
||||
/* If 'login_attr' is used above such that phpLDAPadmin will search for your DN
|
||||
at login, you may restrict the search to a specific objectClass. EG, set this
|
||||
to 'posixAccount' or 'inetOrgPerson', depending upon your setup. */
|
||||
// $ldapservers->SetValue($i,'login','class',null);
|
||||
|
||||
/* Specify true If you want phpLDAPadmin to not display or permit any
|
||||
modification to the LDAP server. */
|
||||
// $servers->setValue('server','read_only',false);
|
||||
// $ldapservers->SetValue($i,'server','read_only',false);
|
||||
|
||||
/* Specify false if you do not want phpLDAPadmin to draw the 'Create new' links
|
||||
in the tree viewer. */
|
||||
// $servers->setValue('appearance','show_create',true);
|
||||
|
||||
/* Set to true if you would like to initially open the first level of each tree. */
|
||||
// $servers->setValue('appearance','open_tree',false);
|
||||
|
||||
/* Set to true to display authorization ID in place of login dn (PHP 7.2+) */
|
||||
// $servers->setValue('appearance','show_authz',false);
|
||||
// $ldapservers->SetValue($i,'appearance','show_create',true);
|
||||
|
||||
/* This feature allows phpLDAPadmin to automatically determine the next
|
||||
available uidNumber for a new entry. */
|
||||
// $servers->setValue('auto_number','enable',true);
|
||||
// $ldapservers->SetValue($i,'auto_number','enable',true);
|
||||
|
||||
/* The mechanism to use when finding the next available uidNumber. Two possible
|
||||
values: 'uidpool' or 'search'.
|
||||
@ -416,86 +219,65 @@ $servers->setValue('server','name','My LDAP Server');
|
||||
blindly lookup the next available uidNumber. The 'search' mechanism searches
|
||||
for entries with a uidNumber value and finds the first available uidNumber
|
||||
(slower). */
|
||||
// $servers->setValue('auto_number','mechanism','search');
|
||||
// $ldapservers->SetValue($i,'auto_number','mechanism','search');
|
||||
|
||||
/* The DN of the search base when the 'search' mechanism is used above. */
|
||||
# $servers->setValue('auto_number','search_base','ou=People,dc=example,dc=com');
|
||||
# $ldapservers->SetValue($i,'auto_number','search_base','ou=People,dc=example,dc=com');
|
||||
|
||||
/* The minimum number to use when searching for the next available number
|
||||
(only when 'search' is used for auto_number. */
|
||||
// $servers->setValue('auto_number','min',array('uidNumber'=>1000,'gidNumber'=>500));
|
||||
/* The minimum number to use when searching for the next available UID number
|
||||
(only when 'search' is used for auto_uid_number_mechanism' */
|
||||
// $ldapservers->SetValue($i,'auto_number','min','1000');
|
||||
|
||||
/* The DN of the uidPool entry when 'uidpool' mechanism is used above. */
|
||||
# $servers[$i]['auto_uid_number_uid_pool_dn'] = 'cn=uidPool,dc=example,dc=com';
|
||||
|
||||
/* If you set this, then phpldapadmin will bind to LDAP with this user ID when
|
||||
searching for the uidnumber. The idea is, this user id would have full
|
||||
(readonly) access to uidnumber in your ldap directory (the logged in user
|
||||
may not), so that you can be guaranteed to get a unique uidnumber for your
|
||||
directory. */
|
||||
// $servers->setValue('auto_number','dn',null);
|
||||
// $ldapservers->SetValue($i,'auto_number','dn',null);
|
||||
|
||||
/* The password for the dn above. */
|
||||
// $servers->setValue('auto_number','pass',null);
|
||||
// $ldapservers->SetValue($i,'auto_number','pass',null);
|
||||
|
||||
/* Enable anonymous bind login. */
|
||||
// $servers->setValue('login','anon_bind',true);
|
||||
// $ldapservers->SetValue($i,'login','anon_bind',true);
|
||||
|
||||
/* Use customized page with prefix when available. */
|
||||
# $servers->setValue('custom','pages_prefix','custom_');
|
||||
# $ldapservers->SetValue($i,'custom','pages_prefix','custom_');
|
||||
|
||||
/* If you set this, then phpldapadmin will bind to LDAP with this user when
|
||||
testing for unique attributes (as set in unique_attrs array). If you want to
|
||||
enforce unique attributes, than this id should have full (readonly) access
|
||||
to the attributes in question (the logged in user may not have enough access)
|
||||
*/
|
||||
// $ldapservers->SetValue($i,'unique_attrs','dn',null);
|
||||
|
||||
/* The password for the dn above */
|
||||
// $ldapservers->SetValue($i,'unique_attrs','pass',null);
|
||||
|
||||
/* If you set this, then only these DNs are allowed to log in. This array can
|
||||
contain individual users, groups or ldap search filter(s). Keep in mind that
|
||||
the user has not authenticated yet, so this will be an anonymous search to
|
||||
the LDAP server, so make your ACLs allow these searches to return results! */
|
||||
# $servers->setValue('login','allowed_dns',array(
|
||||
# $ldapservers->SetValue($i,'login','allowed_dns',array(
|
||||
# 'uid=stran,ou=People,dc=example,dc=com',
|
||||
# '(&(gidNumber=811)(objectClass=groupOfNames))',
|
||||
# '(|(uidNumber=200)(uidNumber=201))',
|
||||
# 'cn=callcenter,ou=Group,dc=example,dc=com'));
|
||||
|
||||
/* Set this if you dont want this LDAP server to show in the tree */
|
||||
// $servers->setValue('server','visible',true);
|
||||
|
||||
/* Set this if you want to hide the base DNs that dont exist instead of
|
||||
displaying the message "The base entry doesnt exist, create it?"
|
||||
// $servers->setValue('server','hide_noaccess_base',false);
|
||||
# $servers->setValue('server','hide_noaccess_base',true);
|
||||
// $ldapservers->SetValue($i,'appearance','visible',true);
|
||||
|
||||
/* This is the time out value in minutes for the server. After as many minutes
|
||||
of inactivity you will be automatically logged out. If not set, the default
|
||||
value will be ( session_cache_expire()-1 ) */
|
||||
# $servers->setValue('login','timeout',30);
|
||||
# $ldapservers->SetValue($i,'login','timeout',30);
|
||||
|
||||
/* Set this if you want phpldapadmin to perform rename operation on entry which
|
||||
has children. Certain servers are known to allow it, certain are not. */
|
||||
// $servers->setValue('server','branch_rename',false);
|
||||
|
||||
/* If you set this, then phpldapadmin will show these attributes as
|
||||
internal attributes, even if they are not defined in your schema. */
|
||||
// $servers->setValue('server','custom_sys_attrs',array(''));
|
||||
# $servers->setValue('server','custom_sys_attrs',array('passwordExpirationTime','passwordAllowChangeTime'));
|
||||
|
||||
/* If you set this, then phpldapadmin will show these attributes on
|
||||
objects, even if they are not defined in your schema. */
|
||||
// $servers->setValue('server','custom_attrs',array(''));
|
||||
# $servers->setValue('server','custom_attrs',array('nsRoleDN','nsRole','nsAccountLock'));
|
||||
|
||||
/*********************************************
|
||||
* Unique attributes *
|
||||
*********************************************/
|
||||
|
||||
/* You may want phpLDAPadmin to enforce some attributes to have unique values
|
||||
(ie: not belong to other entries in your tree. This (together with
|
||||
'unique','dn' and 'unique','pass' option will not let updates to
|
||||
occur with other attributes have the same value. */
|
||||
# $servers->setValue('unique','attrs',array('mail','uid','uidNumber'));
|
||||
|
||||
/* If you set this, then phpldapadmin will bind to LDAP with this user ID when
|
||||
searching for attribute uniqueness. The idea is, this user id would have full
|
||||
(readonly) access to your ldap directory (the logged in user may not), so
|
||||
that you can be guaranteed to get a unique uidnumber for your directory. */
|
||||
// $servers->setValue('unique','dn',null);
|
||||
|
||||
/* The password for the dn above. */
|
||||
// $servers->setValue('unique','pass',null);
|
||||
has children. Certain servers are known to allow it, certain are not */
|
||||
// $ldapservers->SetValue($i,'server','branch_rename',false);
|
||||
|
||||
/**************************************************************************
|
||||
* If you want to configure additional LDAP servers, do so below. *
|
||||
@ -504,65 +286,171 @@ $servers->setValue('server','name','My LDAP Server');
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
$servers->newServer('ldap_pla');
|
||||
$servers->setValue('server','name','LDAP Server');
|
||||
$servers->setValue('server','host','127.0.0.1');
|
||||
$servers->setValue('server','port',389);
|
||||
$servers->setValue('server','base',array(''));
|
||||
$servers->setValue('login','auth_type','cookie');
|
||||
$servers->setValue('login','bind_id','');
|
||||
$servers->setValue('login','bind_pass','');
|
||||
$servers->setValue('server','tls',false);
|
||||
$i++;
|
||||
$ldapservers->SetValue($i,'server','name','LDAP Server');
|
||||
$ldapservers->SetValue($i,'server','host','127.0.0.1');
|
||||
$ldapservers->SetValue($i,'server','port','389');
|
||||
$ldapservers->SetValue($i,'server','base',array(''));
|
||||
$ldapservers->SetValue($i,'server','auth_type','cookie');
|
||||
$ldapservers->SetValue($i,'login','dn','');
|
||||
$ldapservers->SetValue($i,'login','pass','');
|
||||
$ldapservers->SetValue($i,'server','tls',false);
|
||||
$ldapservers->SetValue($i,'server','low_bandwidth',false);
|
||||
$ldapservers->SetValue($i,'appearance','password_hash','md5');
|
||||
$ldapservers->SetValue($i,'login','attr','dn');
|
||||
$ldapservers->SetValue($i,'login','string',null);
|
||||
$ldapservers->SetValue($i,'login','class',null);
|
||||
$ldapservers->SetValue($i,'server','read_only',false);
|
||||
$ldapservers->SetValue($i,'appearance','show_create',true);
|
||||
$ldapservers->SetValue($i,'auto_number','enable',true);
|
||||
$ldapservers->SetValue($i,'auto_number','mechanism','search');
|
||||
$ldapservers->SetValue($i,'auto_number','search_base',null);
|
||||
$ldapservers->SetValue($i,'auto_number','min','1000');
|
||||
$ldapservers->SetValue($i,'auto_number','dn',null);
|
||||
$ldapservers->SetValue($i,'auto_number','pass',null);
|
||||
$ldapservers->SetValue($i,'login','anon_bind',true);
|
||||
$ldapservers->SetValue($i,'custom','pages_prefix','custom_');
|
||||
$ldapservers->SetValue($i,'unique_attrs','dn',null);
|
||||
$ldapservers->SetValue($i,'unique_attrs','pass',null);
|
||||
|
||||
# SASL auth
|
||||
$servers->setValue('login','auth_type','sasl');
|
||||
$servers->setValue('sasl','mech','GSSAPI');
|
||||
$servers->setValue('sasl','realm','EXAMPLE.COM');
|
||||
$servers->setValue('sasl','authz_id',null);
|
||||
$servers->setValue('sasl','authz_id_regex','/^uid=([^,]+)(.+)/i');
|
||||
$servers->setValue('sasl','authz_id_replacement','$1');
|
||||
$servers->setValue('sasl','props',null);
|
||||
|
||||
$servers->setValue('appearance','pla_password_hash','md5');
|
||||
$servers->setValue('login','attr','dn');
|
||||
$servers->setValue('login','fallback_dn',false);
|
||||
$servers->setValue('login','class',null);
|
||||
$servers->setValue('server','read_only',false);
|
||||
$servers->setValue('appearance','show_create',true);
|
||||
|
||||
$servers->setValue('auto_number','enable',true);
|
||||
$servers->setValue('auto_number','mechanism','search');
|
||||
$servers->setValue('auto_number','search_base',null);
|
||||
$servers->setValue('auto_number','min',array('uidNumber'=>1000,'gidNumber'=>500));
|
||||
$servers->setValue('auto_number','dn',null);
|
||||
$servers->setValue('auto_number','pass',null);
|
||||
|
||||
$servers->setValue('login','anon_bind',true);
|
||||
$servers->setValue('custom','pages_prefix','custom_');
|
||||
$servers->setValue('unique','attrs',array('mail','uid','uidNumber'));
|
||||
$servers->setValue('unique','dn',null);
|
||||
$servers->setValue('unique','pass',null);
|
||||
|
||||
$servers->setValue('server','visible',true);
|
||||
$servers->setValue('login','timeout',30);
|
||||
$servers->setValue('server','branch_rename',false);
|
||||
$servers->setValue('server','custom_sys_attrs',array('passwordExpirationTime','passwordAllowChangeTime'));
|
||||
$servers->setValue('server','custom_attrs',array('nsRoleDN','nsRole','nsAccountLock'));
|
||||
$servers->setValue('server','force_may',array('uidNumber','gidNumber','sambaSID'));
|
||||
$ldapservers->SetValue($i,'server','sasl_auth',true);
|
||||
$ldapservers->SetValue($i,'server','sasl_mech','PLAIN');
|
||||
$ldapservers->SetValue($i,'server','sasl_realm','EXAMPLE.COM');
|
||||
$ldapservers->SetValue($i,'server','sasl_authz_id',null);
|
||||
$ldapservers->SetValue($i,'server','sasl_authz_id_regex','/^uid=([^,]+)(.+)/i');
|
||||
$ldapservers->SetValue($i,'server','sasl_authz_id_replacement','$1');
|
||||
$ldapservers->SetValue($i,'server','sasl_props',null);
|
||||
*/
|
||||
|
||||
/*********************************************/
|
||||
/* User-friendly attribute translation */
|
||||
/*********************************************/
|
||||
|
||||
/***********************************************************************************
|
||||
* If you want to configure Google reCAPTCHA on autentication form, do so below. *
|
||||
* Remove the commented lines and use this section as a template for all *
|
||||
* reCAPTCHA v2 Generate on https://www.google.com/recaptcha/ *
|
||||
* *
|
||||
* IMPORTANT: Select reCAPTCHA v2 on Type of reCAPTCHA *
|
||||
***********************************************************************************/
|
||||
/* Use this array to map attribute names to user friendly names. For example, if
|
||||
you don't want to see "facsimileTelephoneNumber" but rather "Fax". */
|
||||
$friendly_attrs = array();
|
||||
|
||||
$friendly_attrs['facsimileTelephoneNumber'] = 'Fax';
|
||||
$friendly_attrs['telephoneNumber'] = 'Phone';
|
||||
|
||||
$config->custom->session['reCAPTCHA-enable'] = false;
|
||||
$config->custom->session['reCAPTCHA-key-site'] = '<put-here-key-site>';
|
||||
$config->custom->session['reCAPTCHA-key-server'] = '<put-here-key-server>';
|
||||
/*********************************************/
|
||||
/* Support for attrs display order */
|
||||
/*********************************************/
|
||||
|
||||
/* Use this array if you want to have your attributes displayed in a specific
|
||||
order. You can use default attribute names or their fridenly names.
|
||||
For example, "sn" will be displayed right after "givenName". All the other
|
||||
attributes that are not specified in this array will be displayed after in
|
||||
alphabetical order. */
|
||||
# $attrs_display_order = array(
|
||||
# 'givenName',
|
||||
# 'sn',
|
||||
# 'cn',
|
||||
# 'displayName',
|
||||
# 'uid',
|
||||
# 'uidNumber',
|
||||
# 'gidNumber',
|
||||
# 'homeDirectory',
|
||||
# 'mail',
|
||||
# 'userPassword'
|
||||
# );
|
||||
|
||||
/*********************************************/
|
||||
/* Hidden attributes */
|
||||
/*********************************************/
|
||||
|
||||
/* You may want to hide certain attributes from being displayed in the editor
|
||||
screen. Do this by adding the desired attributes to this list (and uncomment
|
||||
it). This only affects the editor screen. Attributes will still be visible in
|
||||
the schema browser and elsewhere. An example is provided below:
|
||||
NOTE: The user must be able to read the hidden_except_dn entry to be
|
||||
excluded. */
|
||||
# $hidden_attrs = array( 'jpegPhoto', 'objectClass' );
|
||||
# $hidden_except_dn = "cn=PLA UnHide,ou=Groups,c=AU";
|
||||
|
||||
/* Hidden attributes in read-only mode. If undefined, it will be equal to
|
||||
$hidden_attrs. */
|
||||
# $hidden_attrs_ro = array(
|
||||
# 'objectClass','shadowWarning', 'shadowLastChange', 'shadowMax',
|
||||
# 'shadowFlag', 'shadowInactive', 'shadowMin', 'shadowExpire');
|
||||
|
||||
/** **/
|
||||
/** Read-only attributes **/
|
||||
/** **/
|
||||
|
||||
/* You may want to phpLDAPadmin to display certain attributes as read only,
|
||||
meaning that users will not be presented a form for modifying those
|
||||
attributes, and they will not be allowed to be modified on the "back-end"
|
||||
either. You may configure this list here:
|
||||
NOTE: The user must be able to read the read_only_except_dn entry to be
|
||||
excluded. */
|
||||
# $read_only_attrs = array( 'objectClass' );
|
||||
# $read_only_except_dn = "cn=PLA ReadWrite,ou=Groups,c=AU";
|
||||
|
||||
/* An example of how to specify multiple read-only attributes: */
|
||||
# $read_only_attrs = array( 'jpegPhoto', 'objectClass', 'someAttribute' );
|
||||
|
||||
/*********************************************/
|
||||
/* Unique attributes */
|
||||
/*********************************************/
|
||||
|
||||
/* You may want phpLDAPadmin to enforce some attributes to have unique values
|
||||
(ie: not belong to other entries in your tree. This (together with
|
||||
unique_attrs['dn'] and unique_attrs['pass'] option will not let updates to
|
||||
occur with other attributes have the same value.
|
||||
NOTE: Currently the unique_attrs is NOT enforced when copying a dn. (Need to
|
||||
present a user with the option of changing the unique attributes. */
|
||||
# $unique_attrs = array('uid','uidNumber','mail');
|
||||
|
||||
/*********************************************/
|
||||
/* Group attributes */
|
||||
/*********************************************/
|
||||
|
||||
/* Add "modify group members" link to the attribute. */
|
||||
// $config->custom->modify_member['groupattr'] = array('member','uniqueMember','memberUid')
|
||||
|
||||
/* Configure filter for member search. This only applies to "modify group members" feature */
|
||||
// $config->custom->modify_member['filter'] = '(objectclass=Person)';
|
||||
|
||||
/* Attribute that is added to the group member attribute. */
|
||||
// $config->custom->modify_member['attr'] = 'dn';
|
||||
|
||||
/*********************************************/
|
||||
/* Predefined Queries (canned views) */
|
||||
/*********************************************/
|
||||
|
||||
/* To make searching easier, you may setup predefined queries below: */
|
||||
$q=0;
|
||||
$queries = array();
|
||||
|
||||
/* The name that will appear in the simple search form */
|
||||
$queries[$q]['name'] = 'User List';
|
||||
|
||||
/* The base to search on */
|
||||
$queries[$q]['base'] = 'dc=example,dc=com';
|
||||
|
||||
/* The search scope (sub, base, one) */
|
||||
$queries[$q]['scope'] = 'sub';
|
||||
|
||||
/* The LDAP filter to use */
|
||||
$queries[$q]['filter'] = '(&(objectClass=posixAccount)(uid=*))';
|
||||
|
||||
/* The attributes to return */
|
||||
$queries[$q]['attributes'] = 'cn, uid, homeDirectory, telephonenumber, jpegphoto';
|
||||
|
||||
/* If you want to configure more pre-defined queries, copy and paste the above (including the "$q++;") */
|
||||
$q++;
|
||||
$queries[$q]['name'] = 'Samba Users';
|
||||
$queries[$q]['base'] = 'dc=example,dc=com';
|
||||
$queries[$q]['scope'] = 'sub';
|
||||
$queries[$q]['filter'] = '(&(|(objectClass=sambaAccount)(objectClass=sambaSamAccount))(objectClass=posixAccount)(!(uid=*$)))';
|
||||
$queries[$q]['attributes'] = 'uid, smbHome, uidNumber';
|
||||
|
||||
$q++;
|
||||
$queries[$q]['name'] = 'Samba Computers';
|
||||
$queries[$q]['base'] = 'dc=example,dc=com';
|
||||
$queries[$q]['scope'] = 'sub';
|
||||
$queries[$q]['filter'] = '(&(objectClass=sambaAccount)(uid=*$))';
|
||||
$queries[$q]['attributes'] = 'uid, homeDirectory';
|
||||
?>
|
||||
|
@ -1,34 +0,0 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Cross-Origin Resource Sharing (CORS) Configuration
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may configure your settings for cross-origin resource sharing
|
||||
| or "CORS". This determines what cross-origin operations may execute
|
||||
| in web browsers. You are free to adjust these settings as needed.
|
||||
|
|
||||
| To learn more: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
|
||||
|
|
||||
*/
|
||||
|
||||
'paths' => ['api/*', 'sanctum/csrf-cookie'],
|
||||
|
||||
'allowed_methods' => ['*'],
|
||||
|
||||
'allowed_origins' => ['*'],
|
||||
|
||||
'allowed_origins_patterns' => [],
|
||||
|
||||
'allowed_headers' => ['*'],
|
||||
|
||||
'exposed_headers' => [],
|
||||
|
||||
'max_age' => 0,
|
||||
|
||||
'supports_credentials' => false,
|
||||
|
||||
];
|
@ -1,147 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Default Database Connection Name
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may specify which of the database connections below you wish
|
||||
| to use as your default connection for all database work. Of course
|
||||
| you may use many connections at once using the Database library.
|
||||
|
|
||||
*/
|
||||
|
||||
'default' => env('DB_CONNECTION', 'mysql'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Database Connections
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here are each of the database connections setup for your application.
|
||||
| Of course, examples of configuring each database platform that is
|
||||
| supported by Laravel is shown below to make development simple.
|
||||
|
|
||||
|
|
||||
| All database work in Laravel is done through the PHP PDO facilities
|
||||
| so make sure you have the driver for your particular database of
|
||||
| choice installed on your machine before you begin development.
|
||||
|
|
||||
*/
|
||||
|
||||
'connections' => [
|
||||
|
||||
'sqlite' => [
|
||||
'driver' => 'sqlite',
|
||||
'url' => env('DATABASE_URL'),
|
||||
'database' => env('DB_DATABASE', database_path('database.sqlite')),
|
||||
'prefix' => '',
|
||||
'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true),
|
||||
],
|
||||
|
||||
'mysql' => [
|
||||
'driver' => 'mysql',
|
||||
'url' => env('DATABASE_URL'),
|
||||
'host' => env('DB_HOST', '127.0.0.1'),
|
||||
'port' => env('DB_PORT', '3306'),
|
||||
'database' => env('DB_DATABASE', 'forge'),
|
||||
'username' => env('DB_USERNAME', 'forge'),
|
||||
'password' => env('DB_PASSWORD', ''),
|
||||
'unix_socket' => env('DB_SOCKET', ''),
|
||||
'charset' => 'utf8mb4',
|
||||
'collation' => 'utf8mb4_unicode_ci',
|
||||
'prefix' => '',
|
||||
'prefix_indexes' => true,
|
||||
'strict' => true,
|
||||
'engine' => null,
|
||||
'options' => extension_loaded('pdo_mysql') ? array_filter([
|
||||
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
|
||||
]) : [],
|
||||
],
|
||||
|
||||
'pgsql' => [
|
||||
'driver' => 'pgsql',
|
||||
'url' => env('DATABASE_URL'),
|
||||
'host' => env('DB_HOST', '127.0.0.1'),
|
||||
'port' => env('DB_PORT', '5432'),
|
||||
'database' => env('DB_DATABASE', 'forge'),
|
||||
'username' => env('DB_USERNAME', 'forge'),
|
||||
'password' => env('DB_PASSWORD', ''),
|
||||
'charset' => 'utf8',
|
||||
'prefix' => '',
|
||||
'prefix_indexes' => true,
|
||||
'schema' => 'public',
|
||||
'sslmode' => 'prefer',
|
||||
],
|
||||
|
||||
'sqlsrv' => [
|
||||
'driver' => 'sqlsrv',
|
||||
'url' => env('DATABASE_URL'),
|
||||
'host' => env('DB_HOST', 'localhost'),
|
||||
'port' => env('DB_PORT', '1433'),
|
||||
'database' => env('DB_DATABASE', 'forge'),
|
||||
'username' => env('DB_USERNAME', 'forge'),
|
||||
'password' => env('DB_PASSWORD', ''),
|
||||
'charset' => 'utf8',
|
||||
'prefix' => '',
|
||||
'prefix_indexes' => true,
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Migration Repository Table
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This table keeps track of all the migrations that have already run for
|
||||
| your application. Using this information, we can determine which of
|
||||
| the migrations on disk haven't actually been run in the database.
|
||||
|
|
||||
*/
|
||||
|
||||
'migrations' => 'migrations',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Redis Databases
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Redis is an open source, fast, and advanced key-value store that also
|
||||
| provides a richer body of commands than a typical key-value system
|
||||
| such as APC or Memcached. Laravel makes it easy to dig right in.
|
||||
|
|
||||
*/
|
||||
|
||||
'redis' => [
|
||||
|
||||
'client' => env('REDIS_CLIENT', 'phpredis'),
|
||||
|
||||
'options' => [
|
||||
'cluster' => env('REDIS_CLUSTER', 'redis'),
|
||||
'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
|
||||
],
|
||||
|
||||
'default' => [
|
||||
'url' => env('REDIS_URL'),
|
||||
'host' => env('REDIS_HOST', '127.0.0.1'),
|
||||
'password' => env('REDIS_PASSWORD', null),
|
||||
'port' => env('REDIS_PORT', '6379'),
|
||||
'database' => env('REDIS_DB', '0'),
|
||||
],
|
||||
|
||||
'cache' => [
|
||||
'url' => env('REDIS_URL'),
|
||||
'host' => env('REDIS_HOST', '127.0.0.1'),
|
||||
'password' => env('REDIS_PASSWORD', null),
|
||||
'port' => env('REDIS_PORT', '6379'),
|
||||
'database' => env('REDIS_CACHE_DB', '1'),
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
];
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user