Compare commits
2 Commits
master
...
documentat
Author | SHA1 | Date | |
---|---|---|---|
|
88f3c8faa7 | ||
|
8c46ecf6c9 |
@ -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.
|
|
22
.gitignore
vendored
22
.gitignore
vendored
@ -1,19 +1,3 @@
|
|||||||
/node_modules
|
config/config.php
|
||||||
/public/hot
|
queries/custom_*
|
||||||
/public/storage
|
templates/*/custom_*
|
||||||
/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://phpldapadmin.sourceforge.net
|
||||||
|
|
||||||
|
* Requirements
|
||||||
|
|
||||||
|
phpLDAPadmin requires the following:
|
||||||
|
a. A web server (Apache, IIS, etc).
|
||||||
|
b. PHP 5.0.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://phpldapadmin.sourceforge.net
|
||||||
|
|
||||||
|
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,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'),
|
|
||||||
|
|
||||||
];
|
|
@ -36,9 +36,9 @@
|
|||||||
* version of phpLDAPadmin.
|
* 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['level'] = 255;
|
||||||
@ -49,15 +49,11 @@
|
|||||||
to a big random string. */
|
to a big random string. */
|
||||||
// $config->custom->session['blowfish'] = null;
|
// $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');
|
|
||||||
|
|
||||||
/* The language setting. If you set this to 'auto', phpLDAPadmin will attempt
|
/* The language setting. If you set this to 'auto', phpLDAPadmin will attempt
|
||||||
to determine your language automatically.
|
to determine your language automatically. Otherwise, available lanaguages
|
||||||
If PLA doesnt show (all) strings in your language, then you can do some
|
are: 'ct', 'de', 'en', 'es', 'fr', 'it', 'nl', and 'ru'
|
||||||
translation at http://translations.launchpad.net/phpldapadmin and download
|
Localization is not complete yet, but most strings have been translated.
|
||||||
the translation files, replacing those provided with PLA.
|
Please help by writing language files. See lang/en.php for an example. */
|
||||||
(We'll pick up the translations before making the next release too!) */
|
|
||||||
// $config->custom->appearance['language'] = 'auto';
|
// $config->custom->appearance['language'] = 'auto';
|
||||||
|
|
||||||
/* The temporary storage directory where we will put jpegPhoto data
|
/* The temporary storage directory where we will put jpegPhoto data
|
||||||
@ -84,9 +80,9 @@
|
|||||||
// $config->custom->appearance['timezone'] = null;
|
// $config->custom->appearance['timezone'] = null;
|
||||||
# $config->custom->appearance['timezone'] = 'Australia/Melbourne';
|
# $config->custom->appearance['timezone'] = 'Australia/Melbourne';
|
||||||
|
|
||||||
/*********************************************
|
/*********************************************/
|
||||||
* Commands *
|
/* Commands */
|
||||||
*********************************************/
|
/*********************************************/
|
||||||
|
|
||||||
/* Command availability ; if you don't authorize a command the command
|
/* Command availability ; if you don't authorize a command the command
|
||||||
links will not be shown and the command action will not be permitted.
|
links will not be shown and the command action will not be permitted.
|
||||||
@ -142,9 +138,9 @@ $config->custom->commands['script'] = array(
|
|||||||
);
|
);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*********************************************
|
/*********************************************/
|
||||||
* Appearance *
|
/* Appearance */
|
||||||
*********************************************/
|
/*********************************************/
|
||||||
|
|
||||||
/* If you want to choose the appearance of the tree, specify a class name which
|
/* If you want to choose the appearance of the tree, specify a class name which
|
||||||
inherits from the Tree class. */
|
inherits from the Tree class. */
|
||||||
@ -160,9 +156,6 @@ $config->custom->commands['script'] = array(
|
|||||||
/* Hide the warnings for invalid objectClasses/attributes in templates. */
|
/* Hide the warnings for invalid objectClasses/attributes in templates. */
|
||||||
// $config->custom->appearance['hide_template_warning'] = false;
|
// $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 */
|
/* Configure what objects are shown in left hand tree */
|
||||||
// $config->custom->appearance['tree_filter'] = '(objectclass=*)';
|
// $config->custom->appearance['tree_filter'] = '(objectclass=*)';
|
||||||
|
|
||||||
@ -173,19 +166,9 @@ $config->custom->commands['script'] = array(
|
|||||||
// $config->custom->appearance['tree_width'] = null;
|
// $config->custom->appearance['tree_width'] = null;
|
||||||
# $config->custom->appearance['tree_width'] = 250;
|
# $config->custom->appearance['tree_width'] = 250;
|
||||||
|
|
||||||
/* Confirm create and update operations, allowing you to review the changes
|
/*********************************************/
|
||||||
and optionally skip attributes during the create/update operation. */
|
/* User-friendly attribute translation */
|
||||||
// $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
|
/* Use this array to map attribute names to user friendly names. For example, if
|
||||||
you don't want to see "facsimileTelephoneNumber" but rather "Fax". */
|
you don't want to see "facsimileTelephoneNumber" but rather "Fax". */
|
||||||
@ -199,9 +182,9 @@ $config->custom->appearance['friendly_attrs'] = array(
|
|||||||
'userPassword' => 'Password'
|
'userPassword' => 'Password'
|
||||||
);
|
);
|
||||||
|
|
||||||
/*********************************************
|
/*********************************************/
|
||||||
* Hidden attributes *
|
/* Hidden attributes */
|
||||||
*********************************************/
|
/*********************************************/
|
||||||
|
|
||||||
/* You may want to hide certain attributes from being edited. If you want to
|
/* 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.
|
hide attributes from the user, you should use your LDAP servers ACLs.
|
||||||
@ -214,9 +197,9 @@ $config->custom->appearance['friendly_attrs'] = array(
|
|||||||
// $config->custom->appearance['hide_attrs_exempt'] = null;
|
// $config->custom->appearance['hide_attrs_exempt'] = null;
|
||||||
# $config->custom->appearance['hide_attrs_exempt'] = 'cn=PLA UnHide,ou=Groups,c=AU';
|
# $config->custom->appearance['hide_attrs_exempt'] = 'cn=PLA UnHide,ou=Groups,c=AU';
|
||||||
|
|
||||||
/*********************************************
|
/*********************************************/
|
||||||
* Read-only attributes *
|
/* Read-only attributes */
|
||||||
*********************************************/
|
/*********************************************/
|
||||||
|
|
||||||
/* You may want to phpLDAPadmin to display certain attributes as read only,
|
/* You may want to phpLDAPadmin to display certain attributes as read only,
|
||||||
meaning that users will not be presented a form for modifying those
|
meaning that users will not be presented a form for modifying those
|
||||||
@ -230,12 +213,12 @@ $config->custom->appearance['friendly_attrs'] = array(
|
|||||||
// $config->custom->appearance['readonly_attrs_exempt'] = null;
|
// $config->custom->appearance['readonly_attrs_exempt'] = null;
|
||||||
# $config->custom->appearance['readonly_attrs_exempt'] = 'cn=PLA ReadWrite,ou=Groups,c=AU';
|
# $config->custom->appearance['readonly_attrs_exempt'] = 'cn=PLA ReadWrite,ou=Groups,c=AU';
|
||||||
|
|
||||||
/*********************************************
|
/*********************************************/
|
||||||
* Group attributes *
|
/* Group attributes */
|
||||||
*********************************************/
|
/*********************************************/
|
||||||
|
|
||||||
/* Add "modify group members" link to the attribute. */
|
/* Add "modify group members" link to the attribute. */
|
||||||
// $config->custom->modify_member['groupattr'] = array('member','uniqueMember','memberUid','sudoUser');
|
// $config->custom->modify_member['groupattr'] = array('member','uniqueMember','memberUid');
|
||||||
|
|
||||||
/* Configure filter for member search. This only applies to "modify group members" feature */
|
/* Configure filter for member search. This only applies to "modify group members" feature */
|
||||||
// $config->custom->modify_member['filter'] = '(objectclass=Person)';
|
// $config->custom->modify_member['filter'] = '(objectclass=Person)';
|
||||||
@ -243,15 +226,37 @@ $config->custom->appearance['friendly_attrs'] = array(
|
|||||||
/* Attribute that is added to the group member attribute. */
|
/* Attribute that is added to the group member attribute. */
|
||||||
// $config->custom->modify_member['attr'] = 'dn';
|
// $config->custom->modify_member['attr'] = 'dn';
|
||||||
|
|
||||||
|
|
||||||
/* For Posix attributes */
|
/* For Posix attributes */
|
||||||
// $config->custom->modify_member['posixattr'] = 'uid';
|
// $config->custom->modify_member['posixattr'] = 'uid';
|
||||||
// $config->custom->modify_member['posixfilter'] = '(uid=*)';
|
// $config->custom->modify_member['posixfilter'] = '(uid=*)';
|
||||||
// $config->custom->modify_member['posixgroupattr'] = 'memberUid';
|
// $config->custom->modify_member['posixgroupattr'] = 'memberUid';
|
||||||
|
|
||||||
/*********************************************
|
/*********************************************/
|
||||||
* Define your LDAP servers in this section *
|
/* 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. */
|
||||||
|
// $config->custom->appearance['attr_display_order'] = array();
|
||||||
|
# $config->custom->appearance['attr_display_order'] = array(
|
||||||
|
# 'givenName',
|
||||||
|
# 'sn',
|
||||||
|
# 'cn',
|
||||||
|
# 'displayName',
|
||||||
|
# 'uid',
|
||||||
|
# 'uidNumber',
|
||||||
|
# 'gidNumber',
|
||||||
|
# 'homeDirectory',
|
||||||
|
# 'mail',
|
||||||
|
# 'userPassword'
|
||||||
|
# );
|
||||||
|
|
||||||
|
/*********************************************/
|
||||||
|
/* Define your LDAP servers in this section */
|
||||||
|
/*********************************************/
|
||||||
|
|
||||||
$servers = new Datastore();
|
$servers = new Datastore();
|
||||||
|
|
||||||
@ -277,7 +282,7 @@ $servers->setValue('server','name','My LDAP Server');
|
|||||||
auto-detect it for you. */
|
auto-detect it for you. */
|
||||||
// $servers->setValue('server','base',array(''));
|
// $servers->setValue('server','base',array(''));
|
||||||
|
|
||||||
/* Five options for auth_type:
|
/* Four options for auth_type:
|
||||||
1. 'cookie': you will login via a web form, and a client-side cookie will
|
1. 'cookie': you will login via a web form, and a client-side cookie will
|
||||||
store your login dn and password.
|
store your login dn and password.
|
||||||
2. 'session': same as cookie but your login dn and password are stored on the
|
2. 'session': same as cookie but your login dn and password are stored on the
|
||||||
@ -286,8 +291,6 @@ $servers->setValue('server','name','My LDAP Server');
|
|||||||
HTTP authentication.
|
HTTP authentication.
|
||||||
4. 'config': specify your login dn and password here in this config file. No
|
4. 'config': specify your login dn and password here in this config file. No
|
||||||
login will be required to use phpLDAPadmin for this server.
|
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
|
Choose wisely to protect your authentication information appropriately for
|
||||||
your situation. If you choose 'cookie', your cookie contents will be
|
your situation. If you choose 'cookie', your cookie contents will be
|
||||||
@ -296,11 +299,10 @@ $servers->setValue('server','name','My LDAP Server');
|
|||||||
// $servers->setValue('login','auth_type','session');
|
// $servers->setValue('login','auth_type','session');
|
||||||
|
|
||||||
/* The DN of the user for phpLDAPadmin to bind with. For anonymous binds or
|
/* 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
|
'cookie' or 'session' auth_types, LEAVE THE LOGIN_DN AND LOGIN_PASS BLANK. If
|
||||||
BLANK. If you specify a login_attr in conjunction with a cookie or session
|
you specify a login_attr in conjunction with a cookie or session auth_type,
|
||||||
auth_type, then you can also specify the bind_id/bind_pass here for searching
|
then you can also specify the bind_id/bind_pass here for searching the
|
||||||
the directory for users (ie, if your LDAP server does not allow anonymous
|
directory for users (ie, if your LDAP server does not allow anonymous binds. */
|
||||||
binds. */
|
|
||||||
// $servers->setValue('login','bind_id','');
|
// $servers->setValue('login','bind_id','');
|
||||||
# $servers->setValue('login','bind_id','cn=Manager,dc=example,dc=com');
|
# $servers->setValue('login','bind_id','cn=Manager,dc=example,dc=com');
|
||||||
|
|
||||||
@ -319,27 +321,22 @@ $servers->setValue('server','name','My LDAP Server');
|
|||||||
/* Enable SASL authentication LDAP SASL authentication requires PHP 5.x
|
/* Enable SASL authentication LDAP SASL authentication requires PHP 5.x
|
||||||
configured with --with-ldap-sasl=DIR. If this option is disabled (ie, set to
|
configured with --with-ldap-sasl=DIR. If this option is disabled (ie, set to
|
||||||
false), then all other sasl options are ignored. */
|
false), then all other sasl options are ignored. */
|
||||||
# $servers->setValue('login','auth_type','sasl');
|
// $servers->setValue('server','sasl_auth',false);
|
||||||
|
|
||||||
/* SASL GSSAPI auth mechanism (requires auth_type of sasl) */
|
/* SASL auth mechanism */
|
||||||
// $servers->setValue('sasl','mech','GSSAPI');
|
// $servers->setValue('server','sasl_mech','PLAIN');
|
||||||
|
|
||||||
/* 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 authentication realm name */
|
/* SASL authentication realm name */
|
||||||
// $servers->setValue('sasl','realm','');
|
// $servers->setValue('server','sasl_realm','');
|
||||||
# $servers->setValue('sasl','realm','EXAMPLE.COM');
|
# $servers->setValue('server','sasl_realm','example.com');
|
||||||
|
|
||||||
/* SASL authorization ID name
|
/* SASL authorization ID name
|
||||||
If this option is undefined, authorization id will be computed from bind DN,
|
If this option is undefined, authorization id will be computed from bind DN,
|
||||||
using authz_id_regex and authz_id_replacement. */
|
using sasl_authz_id_regex and sasl_authz_id_replacement. */
|
||||||
// $servers->setValue('sasl','authz_id', null);
|
// $servers->setValue('server','sasl_authz_id', null);
|
||||||
|
|
||||||
/* SASL authorization id regex and replacement
|
/* 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).
|
figure out authorization id by itself from bind distinguished name (DN).
|
||||||
|
|
||||||
This procedure is done by calling preg_replace() php function in the
|
This procedure is done by calling preg_replace() php function in the
|
||||||
@ -351,18 +348,18 @@ $servers->setValue('server','name','My LDAP Server');
|
|||||||
For info about pcre regexes, see:
|
For info about pcre regexes, see:
|
||||||
- pcre(3), perlre(3)
|
- pcre(3), perlre(3)
|
||||||
- http://www.php.net/preg_replace */
|
- http://www.php.net/preg_replace */
|
||||||
// $servers->setValue('sasl','authz_id_regex',null);
|
// $servers->setValue('server','sasl_authz_id_regex',null);
|
||||||
// $servers->setValue('sasl','authz_id_replacement',null);
|
// $servers->setValue('server','sasl_authz_id_replacement',null);
|
||||||
# $servers->setValue('sasl','authz_id_regex','/^uid=([^,]+)(.+)/i');
|
# $servers->setValue('server','sasl_authz_id_regex','/^uid=([^,]+)(.+)/i');
|
||||||
# $servers->setValue('sasl','authz_id_replacement','$1');
|
# $servers->setValue('server','sasl_authz_id_replacement','$1');
|
||||||
|
|
||||||
/* SASL auth security props.
|
/* SASL auth security props.
|
||||||
See http://beepcore-tcl.sourceforge.net/tclsasl.html#anchor5 for explanation. */
|
See http://beepcore-tcl.sourceforge.net/tclsasl.html#anchor5 for explanation. */
|
||||||
// $servers->setValue('sasl','props',null);
|
// $servers->setValue('server','sasl_props',null);
|
||||||
|
|
||||||
/* Default password hashing algorithm. One of md5, ssha, sha, md5crpyt, smd5,
|
/* Default password hashing algorithm. One of md5, ssha, sha, md5crpyt, smd5,
|
||||||
blowfish, crypt or leave blank for now default algorithm. */
|
blowfish, crypt or leave blank for now default algorithm. */
|
||||||
// $servers->setValue('appearance','pla_password_hash','md5');
|
// $servers->setValue('appearance','password_hash','md5');
|
||||||
|
|
||||||
/* If you specified 'cookie' or 'session' as the auth_type above, you can
|
/* 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
|
optionally specify here an attribute to use when logging in. If you enter
|
||||||
@ -370,18 +367,18 @@ $servers->setValue('server','name','My LDAP Server');
|
|||||||
and log in as that user.
|
and log in as that user.
|
||||||
Leave blank or specify 'dn' to use full DN for logging in. Note also that if
|
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
|
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. */
|
DN to use when searching in 'bind_id' and 'bind_pass' above.
|
||||||
// $servers->setValue('login','attr','dn');
|
// $servers->setValue('login','attr','dn');
|
||||||
|
|
||||||
/* Base DNs to used for logins. If this value is not set, then the LDAP server
|
/* Base DNs to used for logins. If this value is not set, then the LDAP server
|
||||||
Base DNs are used. */
|
Base DNs are used. */
|
||||||
// $servers->setValue('login','base',array());
|
// $servers->setValue('login','base',array());
|
||||||
|
|
||||||
/* If login_attr was set to 'dn', it is possible to specify a template string to
|
/* If 'login,attr' is used above such that phpLDAPadmin will search for your DN
|
||||||
build the DN from. Use '%s' where user input should be inserted. A user may
|
at login, you may restrict the search to a specific objectClasses. EG, set this
|
||||||
still enter the complete DN. In this case the template will not be used. */
|
to array('posixAccount') or array('inetOrgPerson',..), depending upon your
|
||||||
// $servers->setValue('login','bind_dn_template',null);
|
setup. */
|
||||||
# $servers->setValue('login','bind_dn_template','cn=%s,ou=people,dc=example,dc=com');
|
// $servers->setValue('login','class',array());
|
||||||
|
|
||||||
/* If you specified something different from 'dn', for example 'uid', as the
|
/* If you specified something different from 'dn', for example 'uid', as the
|
||||||
login_attr above, you can optionally specify here to fall back to
|
login_attr above, you can optionally specify here to fall back to
|
||||||
@ -400,12 +397,6 @@ $servers->setValue('server','name','My LDAP Server');
|
|||||||
in the tree viewer. */
|
in the tree viewer. */
|
||||||
// $servers->setValue('appearance','show_create',true);
|
// $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);
|
|
||||||
|
|
||||||
/* This feature allows phpLDAPadmin to automatically determine the next
|
/* This feature allows phpLDAPadmin to automatically determine the next
|
||||||
available uidNumber for a new entry. */
|
available uidNumber for a new entry. */
|
||||||
// $servers->setValue('auto_number','enable',true);
|
// $servers->setValue('auto_number','enable',true);
|
||||||
@ -422,7 +413,7 @@ $servers->setValue('server','name','My LDAP Server');
|
|||||||
# $servers->setValue('auto_number','search_base','ou=People,dc=example,dc=com');
|
# $servers->setValue('auto_number','search_base','ou=People,dc=example,dc=com');
|
||||||
|
|
||||||
/* The minimum number to use when searching for the next available number
|
/* The minimum number to use when searching for the next available number
|
||||||
(only when 'search' is used for auto_number. */
|
(only when 'search' is used for auto_number */
|
||||||
// $servers->setValue('auto_number','min',array('uidNumber'=>1000,'gidNumber'=>500));
|
// $servers->setValue('auto_number','min',array('uidNumber'=>1000,'gidNumber'=>500));
|
||||||
|
|
||||||
/* If you set this, then phpldapadmin will bind to LDAP with this user ID when
|
/* If you set this, then phpldapadmin will bind to LDAP with this user ID when
|
||||||
@ -454,18 +445,13 @@ $servers->setValue('server','name','My LDAP Server');
|
|||||||
/* Set this if you dont want this LDAP server to show in the tree */
|
/* Set this if you dont want this LDAP server to show in the tree */
|
||||||
// $servers->setValue('server','visible',true);
|
// $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);
|
|
||||||
|
|
||||||
/* This is the time out value in minutes for the server. After as many minutes
|
/* 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
|
of inactivity you will be automatically logged out. If not set, the default
|
||||||
value will be ( session_cache_expire()-1 ) */
|
value will be ( session_cache_expire()-1 ) */
|
||||||
# $servers->setValue('login','timeout',30);
|
# $servers->setValue('login','timeout',30);
|
||||||
|
|
||||||
/* Set this if you want phpldapadmin to perform rename operation on entry which
|
/* 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. */
|
has children. Certain servers are known to allow it, certain are not */
|
||||||
// $servers->setValue('server','branch_rename',false);
|
// $servers->setValue('server','branch_rename',false);
|
||||||
|
|
||||||
/* If you set this, then phpldapadmin will show these attributes as
|
/* If you set this, then phpldapadmin will show these attributes as
|
||||||
@ -478,9 +464,18 @@ $servers->setValue('server','name','My LDAP Server');
|
|||||||
// $servers->setValue('server','custom_attrs',array(''));
|
// $servers->setValue('server','custom_attrs',array(''));
|
||||||
# $servers->setValue('server','custom_attrs',array('nsRoleDN','nsRole','nsAccountLock'));
|
# $servers->setValue('server','custom_attrs',array('nsRoleDN','nsRole','nsAccountLock'));
|
||||||
|
|
||||||
/*********************************************
|
/* These attributes will be forced to MAY attributes and become option in the
|
||||||
* Unique attributes *
|
templates. If they are not defined in the templates, then they wont appear
|
||||||
*********************************************/
|
as per normal template processing. You may want to do this becuase your LDAP
|
||||||
|
server may automatically calculate a default value.
|
||||||
|
In Fedora Directory Server using the DNA Plugin one could ignore uidNumber,
|
||||||
|
gidNumber and sambaSID. */
|
||||||
|
// $servers->setValue('force_may','attrs',array(''));
|
||||||
|
# $servers->setValue('force_may','attrs',array('uidNumber','gidNumber','sambaSID'));
|
||||||
|
|
||||||
|
/*********************************************/
|
||||||
|
/* Unique attributes */
|
||||||
|
/*********************************************/
|
||||||
|
|
||||||
/* You may want phpLDAPadmin to enforce some attributes to have unique values
|
/* You may want phpLDAPadmin to enforce some attributes to have unique values
|
||||||
(ie: not belong to other entries in your tree. This (together with
|
(ie: not belong to other entries in your tree. This (together with
|
||||||
@ -515,15 +510,15 @@ $servers->setValue('login','bind_pass','');
|
|||||||
$servers->setValue('server','tls',false);
|
$servers->setValue('server','tls',false);
|
||||||
|
|
||||||
# SASL auth
|
# SASL auth
|
||||||
$servers->setValue('login','auth_type','sasl');
|
$servers->setValue('server','sasl_auth',true);
|
||||||
$servers->setValue('sasl','mech','GSSAPI');
|
$servers->setValue('server','sasl_mech','PLAIN');
|
||||||
$servers->setValue('sasl','realm','EXAMPLE.COM');
|
$servers->setValue('server','sasl_realm','EXAMPLE.COM');
|
||||||
$servers->setValue('sasl','authz_id',null);
|
$servers->setValue('server','sasl_authz_id',null);
|
||||||
$servers->setValue('sasl','authz_id_regex','/^uid=([^,]+)(.+)/i');
|
$servers->setValue('server','sasl_authz_id_regex','/^uid=([^,]+)(.+)/i');
|
||||||
$servers->setValue('sasl','authz_id_replacement','$1');
|
$servers->setValue('server','sasl_authz_id_replacement','$1');
|
||||||
$servers->setValue('sasl','props',null);
|
$servers->setValue('server','sasl_props',null);
|
||||||
|
|
||||||
$servers->setValue('appearance','pla_password_hash','md5');
|
$servers->setValue('appearance','password_hash','md5');
|
||||||
$servers->setValue('login','attr','dn');
|
$servers->setValue('login','attr','dn');
|
||||||
$servers->setValue('login','fallback_dn',false);
|
$servers->setValue('login','fallback_dn',false);
|
||||||
$servers->setValue('login','class',null);
|
$servers->setValue('login','class',null);
|
||||||
@ -548,21 +543,6 @@ $servers->setValue('login','timeout',30);
|
|||||||
$servers->setValue('server','branch_rename',false);
|
$servers->setValue('server','branch_rename',false);
|
||||||
$servers->setValue('server','custom_sys_attrs',array('passwordExpirationTime','passwordAllowChangeTime'));
|
$servers->setValue('server','custom_sys_attrs',array('passwordExpirationTime','passwordAllowChangeTime'));
|
||||||
$servers->setValue('server','custom_attrs',array('nsRoleDN','nsRole','nsAccountLock'));
|
$servers->setValue('server','custom_attrs',array('nsRoleDN','nsRole','nsAccountLock'));
|
||||||
$servers->setValue('server','force_may',array('uidNumber','gidNumber','sambaSID'));
|
$servers->setValue('force_may','attrs',array('uidNumber','gidNumber','sambaSID'));
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************************
|
|
||||||
* 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 *
|
|
||||||
***********************************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
$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>';
|
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
@ -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'),
|
|
||||||
],
|
|
||||||
|
|
||||||
],
|
|
||||||
|
|
||||||
];
|
|
@ -1,85 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
return [
|
|
||||||
|
|
||||||
/*
|
|
||||||
|--------------------------------------------------------------------------
|
|
||||||
| Default Filesystem Disk
|
|
||||||
|--------------------------------------------------------------------------
|
|
||||||
|
|
|
||||||
| Here you may specify the default filesystem disk that should be used
|
|
||||||
| by the framework. The "local" disk, as well as a variety of cloud
|
|
||||||
| based disks are available to your application. Just store away!
|
|
||||||
|
|
|
||||||
*/
|
|
||||||
|
|
||||||
'default' => env('FILESYSTEM_DRIVER', 'local'),
|
|
||||||
|
|
||||||
/*
|
|
||||||
|--------------------------------------------------------------------------
|
|
||||||
| Default Cloud Filesystem Disk
|
|
||||||
|--------------------------------------------------------------------------
|
|
||||||
|
|
|
||||||
| Many applications store files both locally and in the cloud. For this
|
|
||||||
| reason, you may specify a default "cloud" driver here. This driver
|
|
||||||
| will be bound as the Cloud disk implementation in the container.
|
|
||||||
|
|
|
||||||
*/
|
|
||||||
|
|
||||||
'cloud' => env('FILESYSTEM_CLOUD', 's3'),
|
|
||||||
|
|
||||||
/*
|
|
||||||
|--------------------------------------------------------------------------
|
|
||||||
| Filesystem Disks
|
|
||||||
|--------------------------------------------------------------------------
|
|
||||||
|
|
|
||||||
| Here you may configure as many filesystem "disks" as you wish, and you
|
|
||||||
| may even configure multiple disks of the same driver. Defaults have
|
|
||||||
| been setup for each driver as an example of the required options.
|
|
||||||
|
|
|
||||||
| Supported Drivers: "local", "ftp", "sftp", "s3"
|
|
||||||
|
|
|
||||||
*/
|
|
||||||
|
|
||||||
'disks' => [
|
|
||||||
|
|
||||||
'local' => [
|
|
||||||
'driver' => 'local',
|
|
||||||
'root' => storage_path('app'),
|
|
||||||
],
|
|
||||||
|
|
||||||
'public' => [
|
|
||||||
'driver' => 'local',
|
|
||||||
'root' => storage_path('app/public'),
|
|
||||||
'url' => env('APP_URL').'/storage',
|
|
||||||
'visibility' => 'public',
|
|
||||||
],
|
|
||||||
|
|
||||||
's3' => [
|
|
||||||
'driver' => 's3',
|
|
||||||
'key' => env('AWS_ACCESS_KEY_ID'),
|
|
||||||
'secret' => env('AWS_SECRET_ACCESS_KEY'),
|
|
||||||
'region' => env('AWS_DEFAULT_REGION'),
|
|
||||||
'bucket' => env('AWS_BUCKET'),
|
|
||||||
'url' => env('AWS_URL'),
|
|
||||||
'endpoint' => env('AWS_ENDPOINT'),
|
|
||||||
],
|
|
||||||
|
|
||||||
],
|
|
||||||
|
|
||||||
/*
|
|
||||||
|--------------------------------------------------------------------------
|
|
||||||
| Symbolic Links
|
|
||||||
|--------------------------------------------------------------------------
|
|
||||||
|
|
|
||||||
| Here you may configure the symbolic links that will be created when the
|
|
||||||
| `storage:link` Artisan command is executed. The array keys should be
|
|
||||||
| the locations of the links and the values should be their targets.
|
|
||||||
|
|
|
||||||
*/
|
|
||||||
|
|
||||||
'links' => [
|
|
||||||
public_path('storage') => storage_path('app/public'),
|
|
||||||
],
|
|
||||||
|
|
||||||
];
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user