authLdap
Signed-off-by: Jeff <jeff@gotenzing.com>
Showing
43 changed files
with
2160 additions
and
335 deletions
wp-content/plugins/authLdap/.ci/50-init.ldif
0 → 100644
| 1 | dn: dc=test space,{{ LDAP_BASE_DN }} | ||
| 2 | changetype: add | ||
| 3 | dc: test space | ||
| 4 | description: LDAP Example with space | ||
| 5 | objectClass: dcObject | ||
| 6 | objectClass: organization | ||
| 7 | o: test space | ||
| 8 | |||
| 9 | dn: cn=Manager,{{ LDAP_BASE_DN }} | ||
| 10 | changetype: add | ||
| 11 | cn: Manager | ||
| 12 | objectClass: organizationalRole | ||
| 13 | |||
| 14 | dn: ou=test,{{ LDAP_BASE_DN }} | ||
| 15 | changetype: add | ||
| 16 | objectClass: organizationalUnit | ||
| 17 | ou: test | ||
| 18 | |||
| 19 | dn: uid=user1,{{ LDAP_BASE_DN }} | ||
| 20 | changetype: add | ||
| 21 | objectClass: account | ||
| 22 | objectClass: simpleSecurityObject | ||
| 23 | uid: user1 | ||
| 24 | userPassword: user1 | ||
| 25 | |||
| 26 | dn: cn=group1,{{ LDAP_BASE_DN }} | ||
| 27 | changetype: add | ||
| 28 | objectclass: groupOfUniqueNames | ||
| 29 | cn: group1 | ||
| 30 | uniqueMember: uid=user1,{{ LDAP_BASE_DN }} | ||
| 31 | |||
| 32 | dn: uid=user2,{{ LDAP_BASE_DN }} | ||
| 33 | changetype: add | ||
| 34 | objectClass: account | ||
| 35 | objectClass: simpleSecurityObject | ||
| 36 | uid: user2 | ||
| 37 | userPassword: user2 | ||
| 38 | |||
| 39 | dn: cn=group2,{{ LDAP_BASE_DN }} | ||
| 40 | changetype: add | ||
| 41 | objectclass: groupOfUniqueNames | ||
| 42 | cn: group2 | ||
| 43 | uniqueMember: uid=user2,{{ LDAP_BASE_DN }} | ||
| 44 | |||
| 45 | dn: uid=user3,{{ LDAP_BASE_DN }} | ||
| 46 | changetype: add | ||
| 47 | objectClass: account | ||
| 48 | objectClass: simpleSecurityObject | ||
| 49 | uid: user3 | ||
| 50 | userPassword: user!" | ||
| 51 | |||
| 52 | dn: cn=group3,{{ LDAP_BASE_DN }} | ||
| 53 | changetype: add | ||
| 54 | objectclass: groupOfUniqueNames | ||
| 55 | cn: group3 | ||
| 56 | uniqueMember: uid=user2,{{ LDAP_BASE_DN }} | ||
| 57 | uniqueMember: uid=user3,{{ LDAP_BASE_DN }} | ||
| 58 | |||
| 59 | dn: uid=user 4,{{ LDAP_BASE_DN }} | ||
| 60 | changetype: add | ||
| 61 | objectClass: account | ||
| 62 | objectClass: simpleSecurityObject | ||
| 63 | uid: user 4 | ||
| 64 | userPassword: user!" | ||
| 65 | |||
| 66 | dn: cn=group4,{{ LDAP_BASE_DN }} | ||
| 67 | changetype: add | ||
| 68 | objectclass: groupOfUniqueNames | ||
| 69 | cn: group4 | ||
| 70 | uniqueMember: uid=user 4,{{ LDAP_BASE_DN }} | ||
| 71 | |||
| 72 | dn: uid=user 5,dc=test space,{{ LDAP_BASE_DN }} | ||
| 73 | changetype: add | ||
| 74 | objectClass: account | ||
| 75 | objectClass: simpleSecurityObject | ||
| 76 | uid: user 5 | ||
| 77 | userPassword: user!" | ||
| 78 | |||
| 79 | dn: cn=group5,{{ LDAP_BASE_DN }} | ||
| 80 | changetype: add | ||
| 81 | objectclass: groupOfUniqueNames | ||
| 82 | cn: group5 | ||
| 83 | uniqueMember: uid=user 5,dc=test space,{{ LDAP_BASE_DN }} |
wp-content/plugins/authLdap/.distignore
0 → 100644
| 1 | .ci | ||
| 2 | .github | ||
| 3 | build | ||
| 4 | config | ||
| 5 | dockersetup | ||
| 6 | svn | ||
| 7 | tests | ||
| 8 | vendor | ||
| 9 | wp-app | ||
| 10 | wd-data | ||
| 11 | .distignore | ||
| 12 | .editorconfig | ||
| 13 | .gitignore | ||
| 14 | .phpunit.result.cache | ||
| 15 | .svnAccess | ||
| 16 | .svnAccess.dist | ||
| 17 | build.xml | ||
| 18 | composer.json | ||
| 19 | composer.lock | ||
| 20 | docker-compose.yml | ||
| 21 | GPG_KEY | ||
| 22 | phpunit.xml.dist | ||
| 23 | .git |
wp-content/plugins/authLdap/.editorconfig
0 → 100644
| 1 | name: Deploy to WordPress.org | ||
| 2 | |||
| 3 | env: | ||
| 4 | SLUG: authldap | ||
| 5 | on: | ||
| 6 | release: | ||
| 7 | types: [published] | ||
| 8 | jobs: | ||
| 9 | tag: | ||
| 10 | name: New release | ||
| 11 | runs-on: ubuntu-latest | ||
| 12 | environment: deploy_on_release | ||
| 13 | steps: | ||
| 14 | - name: Checkout code | ||
| 15 | uses: actions/checkout@v2 | ||
| 16 | - name: WordPress Plugin Deploy | ||
| 17 | id: deploy | ||
| 18 | uses: 10up/action-wordpress-plugin-deploy@stable | ||
| 19 | with: | ||
| 20 | generate-zip: true | ||
| 21 | env: | ||
| 22 | SVN_USERNAME: ${{ secrets.SVN_USERNAME }} | ||
| 23 | SVN_PASSWORD: ${{ secrets.SVN_PASSWORD }} | ||
| 24 | - name: Upload release asset | ||
| 25 | uses: actions/upload-release-asset@v1 | ||
| 26 | env: | ||
| 27 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| 28 | with: | ||
| 29 | upload_url: ${{ github.event.release.upload_url }} | ||
| 30 | asset_path: ${{ steps.deploy.outputs.zip-path }} | ||
| 31 | asset_name: ${{ env.SLUG }}.zip | ||
| 32 | asset_content_type: application/zip | ||
| 33 |
| 1 | name: CI | ||
| 2 | on: [push, pull_request] | ||
| 3 | jobs: | ||
| 4 | test: | ||
| 5 | runs-on: ubuntu-latest | ||
| 6 | env: | ||
| 7 | PORT_LDAP: 3389 | ||
| 8 | PORT_LDAPS: 6363 | ||
| 9 | LDAP_ADMIN_PASSWORD: ${{ secrets.LDAP_ADMIN_PASSWORD }} | ||
| 10 | LDAP_LOG_LEVEL: 0 | ||
| 11 | strategy: | ||
| 12 | matrix: | ||
| 13 | # operating-system: [ubuntu-latest, windows-latest, macos-latest] | ||
| 14 | php-versions: [ '7.4', '8.0', '8.1' ] | ||
| 15 | name: Test on ${{ matrix.php-versions }} | ||
| 16 | steps: | ||
| 17 | - uses: actions/checkout@v1 | ||
| 18 | - name: Build the docker-compose stack | ||
| 19 | run: docker-compose -f docker-compose.yml up -d | ||
| 20 | - name: Check running containers | ||
| 21 | run: docker ps -a | ||
| 22 | - name: Check logs | ||
| 23 | run: docker-compose logs openldap | ||
| 24 | - name: Setup PHP | ||
| 25 | uses: shivammathur/setup-php@v2 | ||
| 26 | with: | ||
| 27 | php-version: ${{ matrix.php-versions }} | ||
| 28 | extensions: ldap | ||
| 29 | tools: phive | ||
| 30 | - name: install dependencies | ||
| 31 | run: composer install | ||
| 32 | - name: install tools | ||
| 33 | run: phive install --trust-gpg-keys 4AA394086372C20A phpunit | ||
| 34 | - name: Run Unit-Tests | ||
| 35 | run: ./tools/phpunit --testdox | ||
| 36 | coverage: | ||
| 37 | needs: test | ||
| 38 | runs-on: ubuntu-latest | ||
| 39 | env: | ||
| 40 | PORT_LDAP: 3389 | ||
| 41 | PORT_LDAPS: 6363 | ||
| 42 | LDAP_ADMIN_PASSWORD: ${{ secrets.LDAP_ADMIN_PASSWORD }} | ||
| 43 | LDAP_LOG_LEVEL: 0 | ||
| 44 | continue-on-error: false | ||
| 45 | steps: | ||
| 46 | - name: Checkout | ||
| 47 | uses: actions/checkout@v2 | ||
| 48 | - name: Build the docker-compose stack | ||
| 49 | run: docker-compose -f docker-compose.yml up -d | ||
| 50 | - name: Check running containers | ||
| 51 | run: docker ps -a | ||
| 52 | - name: Setup PHP | ||
| 53 | uses: shivammathur/setup-php@v2 | ||
| 54 | with: | ||
| 55 | php-version: "8.0" | ||
| 56 | coverage: xdebug | ||
| 57 | tools: phive | ||
| 58 | - name: install dependencies | ||
| 59 | run: composer install | ||
| 60 | - name: install tools | ||
| 61 | run: phive install --trust-gpg-keys 4AA394086372C20A phpunit | ||
| 62 | - name: run testsuite | ||
| 63 | run: ./tools/phpunit --testdox --colors=always --coverage-clover clover.xml | ||
| 64 | - name: upload to codecov | ||
| 65 | uses: codecov/codecov-action@v1 | ||
| 66 | with: | ||
| 67 | #token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos | ||
| 68 | files: ./clover.xml # optional | ||
| 69 | #flags: unittests # optional | ||
| 70 | #name: codecov-umbrella # optional | ||
| 71 | #fail_ci_if_error: true # optional (default = false) | ||
| 72 | #verbose: true # optional (default = false) |
wp-content/plugins/authLdap/.phive/phars.xml
0 → 100644
| 1 | <?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | <phive xmlns="https://phar.io/phive"> | ||
| 3 | <phar name="phpunit" version="^9.5.21" installed="9.5.21" location="./tools/phpunit" copy="true"/> | ||
| 4 | <phar name="phpcs" version="^3.7.1" installed="3.7.1" location="./tools/phpcs" copy="true"/> | ||
| 5 | <phar name="phpcbf" version="^3.7.1" installed="3.7.1" location="./tools/phpcbf" copy="true"/> | ||
| 6 | </phive> |
wp-content/plugins/authLdap/.svnAccess.dist
0 → 100644
wp-content/plugins/authLdap/LICENSE.md
0 → 100644
| 1 | Copyright <YEAR> <COPYRIGHT HOLDER> | ||
| 2 | |||
| 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: | ||
| 4 | |||
| 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. | ||
| 6 | |||
| 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| ... | @@ -4,12 +4,12 @@ | ... | @@ -4,12 +4,12 @@ |
| 4 | 4 | ||
| 5 | Use your existing LDAP as authentication-backend for your wordpress! | 5 | Use your existing LDAP as authentication-backend for your wordpress! |
| 6 | 6 | ||
| 7 | [](https://travis-ci.org/heiglandreas/authLdap) | 7 | [](https://github.com/heiglandreas/authLdap/workflows/CI) |
| 8 | [](https://wordpress.org/plugins/authldap/stats/) | 8 | [](https://wordpress.org/plugins/authldap/stats/) |
| 9 | [](https://wordpress.org/plugins/authldap/) | 9 | [](https://wordpress.org/plugins/authldap/) |
| 10 | [](https://wordpress.org/plugins/authldap/) | 10 | [](https://wordpress.org/plugins/authldap/) |
| 11 | [](https://codeclimate.com/github/heiglandreas/authLdap) | 11 | [](https://codeclimate.com/github/heiglandreas/authLdap) |
| 12 | [](https://codeclimate.com/github/heiglandreas/authLdap) | 12 | [](https://codecov.io/gh/heiglandreas/authLdap) |
| 13 | 13 | ||
| 14 | So what are the differences to other Wordpress-LDAP-Authentication-Plugins? | 14 | So what are the differences to other Wordpress-LDAP-Authentication-Plugins? |
| 15 | 15 | ||
| ... | @@ -48,8 +48,8 @@ wonderfull plugin of Alistair Young from http://www.weblogs.uhi.ac.uk/sm00ay/?p= | ... | @@ -48,8 +48,8 @@ wonderfull plugin of Alistair Young from http://www.weblogs.uhi.ac.uk/sm00ay/?p= |
| 48 | * **LDAP Uri** This is the URI where your ldap-backend can be reached. More information are actually on the Configuration page | 48 | * **LDAP Uri** This is the URI where your ldap-backend can be reached. More information are actually on the Configuration page |
| 49 | * **Filter** This is the real McCoy! The filter you define here specifies how a user will be found. Before applying the filter a %s will be replaced with the given username. This means, when a user logs in using ‘foobar’ as username the following happens: | 49 | * **Filter** This is the real McCoy! The filter you define here specifies how a user will be found. Before applying the filter a %s will be replaced with the given username. This means, when a user logs in using ‘foobar’ as username the following happens: |
| 50 | 50 | ||
| 51 | * **uid=%s** check for any LDAP-Entry that has an attribute ‘uid’ with value ‘foobar’ | 51 | * **uid=%1$s** check for any LDAP-Entry that has an attribute ‘uid’ with value ‘foobar’ |
| 52 | * **(&(objectclass=posixAccount)((!(uid=%s)(mail=%s)))** check for any LDAP-Entry that has an attribute ‘objectclass’ with value ‘posixAccout’ and either a UID- or a mail-attribute with value ‘foobar’ | 52 | * **(&(objectclass=posixAccount)(|(uid=%1$s)(mail=%1$s)))** check for any LDAP-Entry that has an attribute ‘objectclass’ with value ‘posixAccout’ and either a UID- or a mail-attribute with value ‘foobar’ |
| 53 | 53 | ||
| 54 | This filter is rather powerfull if used wisely. | 54 | This filter is rather powerfull if used wisely. |
| 55 | 55 | ||
| ... | @@ -92,4 +92,4 @@ wonderfull plugin of Alistair Young from http://www.weblogs.uhi.ac.uk/sm00ay/?p= | ... | @@ -92,4 +92,4 @@ wonderfull plugin of Alistair Young from http://www.weblogs.uhi.ac.uk/sm00ay/?p= |
| 92 | <a href="https://github.com/heiglandreas/authLdap/issues/65">issue 65</a> | 92 | <a href="https://github.com/heiglandreas/authLdap/issues/65">issue 65</a> |
| 93 | where <a href="https://github.com/wtfiwtz">wtfiwtz</a> shows how to implement that feature. | 93 | where <a href="https://github.com/wtfiwtz">wtfiwtz</a> shows how to implement that feature. |
| 94 | </dd> | 94 | </dd> |
| 95 | </dl> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 95 | </dl> | ... | ... |
wp-content/plugins/authLdap/authLdap.css
0 → 100644
wp-content/plugins/authLdap/authLdap.php
0 → 100644
This diff is collapsed.
Click to expand it.
wp-content/plugins/authLdap/build.xml
0 → 100644
| 1 | <?xml version="1.0" encoding="utf-8"?> | ||
| 2 | <project name="ajaxComments" default="build" basedir="."> | ||
| 3 | <php expression="include('vendor/autoload.php')"/> | ||
| 4 | <input propertyName="version">Which version shall be tagged?</input> | ||
| 5 | <!--loadfile property = "version" file = "VERSION"> | ||
| 6 | <filterchain> | ||
| 7 | <striplinebreaks/> | ||
| 8 | </filterchain> | ||
| 9 | </loadfile--> | ||
| 10 | <target name="bumpversion"> | ||
| 11 | <echo>Bumping version to ${version}</echo> | ||
| 12 | <reflexive> | ||
| 13 | <fileset dir="."> | ||
| 14 | <include name="index.php"/> | ||
| 15 | <include name="authLdap.php"/> | ||
| 16 | </fileset> | ||
| 17 | <filterchain> | ||
| 18 | <replaceregexp> | ||
| 19 | <regexp pattern="Version:.*" replace="Version: ${version}"/> | ||
| 20 | </replaceregexp> | ||
| 21 | </filterchain> | ||
| 22 | </reflexive> | ||
| 23 | </target> | ||
| 24 | <target name="build" depends="bumpversion,deploy.git,deploy.svn"/> | ||
| 25 | <target name="sync.svn"> | ||
| 26 | <copy todir="${project.basedir}/svn/trunk"> | ||
| 27 | <fileset dir="${project.basedir}"> | ||
| 28 | <include name="src/**"/> | ||
| 29 | <include name="view/**"/> | ||
| 30 | <include name="authLdap.css"/> | ||
| 31 | <include name="authLdap.php"/> | ||
| 32 | <include name="ldap.php"/> | ||
| 33 | <include name="LICENSE.md"/> | ||
| 34 | <include name="README.md"/> | ||
| 35 | <include name="readme.txt"/> | ||
| 36 | </fileset> | ||
| 37 | </copy> | ||
| 38 | </target> | ||
| 39 | <target name="deploy.svn" depends="sync.svn"> | ||
| 40 | <property override="true" file="${project.basedir}/.svnAccess" prefix="svnaccess" /> | ||
| 41 | <foreach param="dirname" target="svn.addFile"> | ||
| 42 | <fileset dir="${project.basedir}/svn/trunk"> | ||
| 43 | <include name="**/*"/> | ||
| 44 | </fileset> | ||
| 45 | </foreach> | ||
| 46 | <echo message="${svnaccess.username}"/> | ||
| 47 | <exec outputProperty="committedrevision" executable="svn" dir="${project.basedir}/svn/trunk"> | ||
| 48 | <arg value="commit"/> | ||
| 49 | <arg value="--username"/> | ||
| 50 | <arg value="${svnaccess.username}"/> | ||
| 51 | <arg value="--password"/> | ||
| 52 | <arg value="${svnaccess.password}"/> | ||
| 53 | <arg value="--message"/> | ||
| 54 | <arg value="Bumps version to ${version}"/> | ||
| 55 | <arg value="--no-auth-cache"/> | ||
| 56 | <arg value="--quiet"/> | ||
| 57 | </exec> | ||
| 58 | <!--svncommit | ||
| 59 | username="${svnaccess.username}" | ||
| 60 | password="${svnaccess.password}" | ||
| 61 | workingcopy="${project.basedir}/svn" | ||
| 62 | message="Bumps version to ${version}" | ||
| 63 | nocache="true" | ||
| 64 | /--> | ||
| 65 | <echo message="Committed revision: ${committedrevision}"/> | ||
| 66 | </target> | ||
| 67 | |||
| 68 | <target name="svn.addFile"> | ||
| 69 | <trycatch> | ||
| 70 | <try> | ||
| 71 | <svninfo workingcopy="${project.basedir}/svn/trunk/${dirname}"/> | ||
| 72 | </try> | ||
| 73 | <catch> | ||
| 74 | <exec command="svn add ${project.basedir}/svn/trunk/${dirname}"/> | ||
| 75 | <echo>${dirname}</echo> | ||
| 76 | </catch> | ||
| 77 | <finally> | ||
| 78 | |||
| 79 | </finally> | ||
| 80 | </trycatch> | ||
| 81 | <echo>${svn.info}</echo> | ||
| 82 | </target> | ||
| 83 | <target name="deploy.git"> | ||
| 84 | <exec executable="git" dir="."> | ||
| 85 | <arg value="add" /> | ||
| 86 | <arg value="authLdap.php" /> | ||
| 87 | </exec> | ||
| 88 | <exec executable="git" dir="."> | ||
| 89 | <arg value="commit" /> | ||
| 90 | <arg value="-m"/> | ||
| 91 | <arg value="Bumps version to ${version}"/> | ||
| 92 | </exec> | ||
| 93 | <exec executable="git" dir="."> | ||
| 94 | <arg value="tag"/> | ||
| 95 | <arg value="-s"/> | ||
| 96 | <arg value="-m"/> | ||
| 97 | <arg value="Version ${version}"/> | ||
| 98 | <arg value="${version}"/> | ||
| 99 | </exec> | ||
| 100 | <exec executable="git" dir="."> | ||
| 101 | <arg value="push"/> | ||
| 102 | <arg value="--tags"/> | ||
| 103 | <arg value="origin"/> | ||
| 104 | <arg value="master" /> | ||
| 105 | </exec> | ||
| 106 | </target> | ||
| 107 | </project> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
wp-content/plugins/authLdap/composer.json
0 → 100644
| 1 | { | ||
| 2 | "name" : "org_heigl/authldap", | ||
| 3 | "type" : "library", | ||
| 4 | "description": "Enables wordpress-authentication via LDAP", | ||
| 5 | "keywords": ["ldap","authenticate", "auth", "wordpress"], | ||
| 6 | "homepage": "http://github.com/heiglandreas/authLdap", | ||
| 7 | "license": "MIT", | ||
| 8 | "authors": [{ | ||
| 9 | "name": "Andreas Heigl", | ||
| 10 | "email": "andreas@heigl.org", | ||
| 11 | "homepage": "http://andreas.heigl.org", | ||
| 12 | "role": "Developer" | ||
| 13 | }], | ||
| 14 | "require" : { | ||
| 15 | "php": ">=7.4", | ||
| 16 | "ext-ldap": "*" | ||
| 17 | }, | ||
| 18 | "require-dev": { | ||
| 19 | "automattic/wordbless": "^0.3.1" | ||
| 20 | }, | ||
| 21 | "autoload" : { | ||
| 22 | "classmap" : [ | ||
| 23 | "authLdap.php" | ||
| 24 | ], | ||
| 25 | "psr-4" : { | ||
| 26 | "Org_Heigl\\AuthLdap\\" : "src/" | ||
| 27 | } | ||
| 28 | }, | ||
| 29 | "autoload-dev" : { | ||
| 30 | "psr-4" : { | ||
| 31 | "Org_Heigl\\AuthLdapTest\\" : "tests/" | ||
| 32 | } | ||
| 33 | }, | ||
| 34 | "scripts": { | ||
| 35 | "post-update-cmd": "php -r \"copy('vendor/automattic/wordbless/src/dbless-wpdb.php', 'wordpress/wp-content/db.php');\"" | ||
| 36 | }, | ||
| 37 | "config": { | ||
| 38 | "allow-plugins": { | ||
| 39 | "roots/wordpress-core-installer": true | ||
| 40 | } | ||
| 41 | } | ||
| 42 | } |
| 1 | version: "3.5" | ||
| 2 | |||
| 3 | services: | ||
| 4 | wp: | ||
| 5 | # image: authldap:latest | ||
| 6 | build: | ||
| 7 | context: dockersetup | ||
| 8 | dockerfile: Dockerfile_wordpress | ||
| 9 | ports: | ||
| 10 | - 80:80 # change ip if required | ||
| 11 | volumes: | ||
| 12 | - ./config/php.conf.ini:/usr/local/etc/php/conf.d/conf.ini | ||
| 13 | - ./wp-app:/var/www/html # Full wordpress project | ||
| 14 | - .:/var/www/html/wp-content/plugins/authldap # Plugin development | ||
| 15 | #- ./theme-name/trunk/:/var/www/html/wp-content/themes/theme-name # Theme development | ||
| 16 | environment: | ||
| 17 | WORDPRESS_DB_HOST: db | ||
| 18 | WORDPRESS_DB_NAME: "wordpress" | ||
| 19 | WORDPRESS_DB_USER: root | ||
| 20 | WORDPRESS_DB_PASSWORD: "wppasswd" | ||
| 21 | depends_on: | ||
| 22 | - db | ||
| 23 | links: | ||
| 24 | - db | ||
| 25 | |||
| 26 | wpcli: | ||
| 27 | image: wordpress:cli | ||
| 28 | volumes: | ||
| 29 | - ./config/php.conf.ini:/usr/local/etc/php/conf.d/conf.ini | ||
| 30 | - ./wp-app:/var/www/html | ||
| 31 | depends_on: | ||
| 32 | - db | ||
| 33 | - wp | ||
| 34 | |||
| 35 | db: | ||
| 36 | image: mysql:latest # https://hub.docker.com/_/mysql/ - or mariadb https://hub.docker.com/_/mariadb | ||
| 37 | ports: | ||
| 38 | - 3306:3306 # change ip if required | ||
| 39 | command: [ | ||
| 40 | '--default_authentication_plugin=mysql_native_password', | ||
| 41 | '--character-set-server=utf8mb4', | ||
| 42 | '--collation-server=utf8mb4_unicode_ci' | ||
| 43 | ] | ||
| 44 | volumes: | ||
| 45 | - ./wp-data:/docker-entrypoint-initdb.d | ||
| 46 | - db_data:/var/lib/mysql | ||
| 47 | environment: | ||
| 48 | MYSQL_DATABASE: "wordpress" | ||
| 49 | MYSQL_ROOT_PASSWORD: "wppasswd" | ||
| 50 | |||
| 51 | openldap: | ||
| 52 | image: osixia/openldap:latest | ||
| 53 | # build: | ||
| 54 | # context: dockersetup | ||
| 55 | # dockerfile: Dockerfile_ldap | ||
| 56 | ports: | ||
| 57 | - 3389:389 | ||
| 58 | volumes: | ||
| 59 | - ./.ci/50-init.ldif:/container/service/slapd/assets/config/bootstrap/ldif/custom/50-bootstrap.ldif | ||
| 60 | command: "--copy-service --loglevel debug" | ||
| 61 | restart: always | ||
| 62 | environment: | ||
| 63 | LDAP_LOG_LEVEL: "0" | ||
| 64 | LDAP_TLS: "false" | ||
| 65 | LDAP_ADMIN_PASSWORD: "insecure" | ||
| 66 | |||
| 67 | volumes: | ||
| 68 | db_data: |
| 1 | FROM wordpress:latest | ||
| 2 | |||
| 3 | RUN set -x \ | ||
| 4 | && apt-get update \ | ||
| 5 | && apt-get install -y libldap2-dev \ | ||
| 6 | && rm -rf /var/lib/apt/lists/* \ | ||
| 7 | && docker-php-ext-configure ldap --with-libdir=lib/x86_64-linux-gnu/ \ | ||
| 8 | && docker-php-ext-install ldap \ | ||
| 9 | && apt-get purge -y --auto-remove libldap2-dev | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
File mode changed
wp-content/plugins/authLdap/phpcs.xml
0 → 100644
| 1 | <?xml version="1.0"?> | ||
| 2 | <ruleset name="Custom Standard" namespace="MyProject\CS\Standard"> | ||
| 3 | <description>authLdap codestyle</description> | ||
| 4 | <file>./src</file> | ||
| 5 | <file>./authLdap.php</file> | ||
| 6 | <file>./tests</file> | ||
| 7 | |||
| 8 | <arg name="colors"/> | ||
| 9 | <arg value="sp"/> | ||
| 10 | |||
| 11 | <autoload>./vendor/autoload.php</autoload> | ||
| 12 | |||
| 13 | <rule ref="PSR12"> | ||
| 14 | <exclude name="Generic.WhiteSpace.DisallowTabIndent"/> | ||
| 15 | </rule> | ||
| 16 | <rule ref="Generic.WhiteSpace.ScopeIndent"> | ||
| 17 | <properties> | ||
| 18 | <property name="tabIndent" value="true"/> | ||
| 19 | </properties> | ||
| 20 | </rule> | ||
| 21 | |||
| 22 | </ruleset> |
wp-content/plugins/authLdap/phpunit.xml.dist
0 → 100644
| 1 | <?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | <phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
| 3 | bootstrap="tests/bootstrap.php" | ||
| 4 | testdox="true" | ||
| 5 | xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.5/phpunit.xsd" | ||
| 6 | > | ||
| 7 | <coverage> | ||
| 8 | <include> | ||
| 9 | <directory suffix=".php">src</directory> | ||
| 10 | <file>authLdap.php</file> | ||
| 11 | </include> | ||
| 12 | <exclude> | ||
| 13 | <directory>src/Wrapper</directory> | ||
| 14 | </exclude> | ||
| 15 | <report> | ||
| 16 | <html outputDirectory="build/coverage" lowUpperBound="35" highLowerBound="70"/> | ||
| 17 | </report> | ||
| 18 | </coverage> | ||
| 19 | <testsuite name="authLdap Test-Suite"> | ||
| 20 | <directory>tests</directory> | ||
| 21 | </testsuite> | ||
| 22 | <groups> | ||
| 23 | <exclude> | ||
| 24 | <group>disable</group> | ||
| 25 | </exclude> | ||
| 26 | </groups> | ||
| 27 | <logging> | ||
| 28 | <!--log type="coverage-xml" target="../report/coverage.xml"/--> | ||
| 29 | <!--log type="graphviz" target="../report/logfile.dot"/--> | ||
| 30 | <!--log type="json" target="../report/logfile.json"/--> | ||
| 31 | <!--log type="metrics-xml" target="../report/metrics.xml"/--> | ||
| 32 | <!--log type="plain" target="../report/logfile.txt"/--> | ||
| 33 | <!--log type="pmd-xml" target="../report/pmd.xml" cpdMinLines="5" cpdMinMatches="70"/--> | ||
| 34 | <!--log type="tap" target="../report/logfile.tap"/--> | ||
| 35 | <!--log type="test-xml" target="../report/logfile.xml" logIncompleteSkipped="false"/--> | ||
| 36 | <!--log type="testdox-html" target="../report/testdox.html"/--> | ||
| 37 | <!--log type="testdox-text" target="../report/testdox.txt"/--> | ||
| 38 | </logging> | ||
| 39 | </phpunit> |
| 1 | === authLdap === | 1 | === authLdap === |
| 2 | Contributors: heiglandreas | 2 | Contributors: heiglandreas |
| 3 | Tags: ldap, auth | 3 | Tags: ldap, auth, authentication, active directory, AD, openLDAP, Open Directory |
| 4 | Requires at least: 2.5.0 | 4 | Requires at least: 2.5.0 |
| 5 | Tested up to: 4.6.1 | 5 | Tested up to: 5.9.0 |
| 6 | Requires PHP: 7.4 | ||
| 6 | Stable tag: trunk | 7 | Stable tag: trunk |
| 8 | License: MIT | ||
| 9 | License URI: https://opensource.org/licenses/MIT | ||
| 7 | 10 | ||
| 8 | Use your existing LDAP flexible as authentication backend for WordPress | 11 | Use your existing LDAP flexible as authentication backend for WordPress |
| 9 | 12 | ||
| ... | @@ -13,13 +16,9 @@ Use your existing LDAP as authentication-backend for your wordpress! | ... | @@ -13,13 +16,9 @@ Use your existing LDAP as authentication-backend for your wordpress! |
| 13 | 16 | ||
| 14 | So what are the differences to other Wordpress-LDAP-Authentication-Plugins? | 17 | So what are the differences to other Wordpress-LDAP-Authentication-Plugins? |
| 15 | 18 | ||
| 16 | * Flexible: You are totaly free in which LDAP-backend to use. Due to the extensive configuration you can | 19 | * Flexible: You are totaly free in which LDAP-backend to use. Due to the extensive configuration you can freely decide how to do the authentication of your users. It simply depends on your filters |
| 17 | freely decide how to do the authentication of your users. It simply depends on your | 20 | * Independent: As soon as a user logs in, it is added/updated to the Wordpress' user-database to allow wordpress to always use the correct data. You only have to administer your users once. |
| 18 | filters | 21 | * Failsafe: Due to the users being created in Wordpress' User-database they can also log in when the LDAP-backend currently is gone. |
| 19 | * Independent: As soon as a user logs in, it is added/updated to the Wordpress' user-database | ||
| 20 | to allow wordpress to always use the correct data. You only have to administer your users once. | ||
| 21 | * Failsafe: Due to the users being created in Wordpress' User-database they can | ||
| 22 | also log in when the LDAP-backend currently is gone. | ||
| 23 | * Role-Aware: You can map Wordpress' roles to values of an existing LDAP-attribute. | 22 | * Role-Aware: You can map Wordpress' roles to values of an existing LDAP-attribute. |
| 24 | 23 | ||
| 25 | For more Information on the configuration have a look at https://github.com/heiglandreas/authLdap | 24 | For more Information on the configuration have a look at https://github.com/heiglandreas/authLdap |
| ... | @@ -41,6 +40,51 @@ Go to https://github.com/heiglandreas/authLdap | ... | @@ -41,6 +40,51 @@ Go to https://github.com/heiglandreas/authLdap |
| 41 | Please use the issuetracker at https://github.com/heiglandreas/authLdap/issues | 40 | Please use the issuetracker at https://github.com/heiglandreas/authLdap/issues |
| 42 | 41 | ||
| 43 | == Changelog == | 42 | == Changelog == |
| 43 | |||
| 44 | = 2.5.3 = | ||
| 45 | * Fix issue with broken role-assignement in combination with WooCommerce | ||
| 46 | * Fix spelling issue | ||
| 47 | * Allow DN as role-definition | ||
| 48 | |||
| 49 | = 2.5.0 = | ||
| 50 | * Ignore the order of capabilities to tell the role. In addition the filter `editable_roles` can be used to limit the roles | ||
| 51 | |||
| 52 | = 2.4.11 = | ||
| 53 | * Fix issue with running on PHP8.1 | ||
| 54 | |||
| 55 | = 2.4.9 = | ||
| 56 | * Improve group-assignement UI | ||
| 57 | |||
| 58 | = 2.4.8 = | ||
| 59 | * Make textfields in settings-page wider | ||
| 60 | |||
| 61 | = 2.4.7 = | ||
| 62 | * Replace deprecated function | ||
| 63 | * Fix undefined index | ||
| 64 | * Add filter for retrieving other params at login (authLdap_filter_attributes) | ||
| 65 | * Add do_action after successfull login (authLdap_login_successful) | ||
| 66 | |||
| 67 | = 2.4.0 = | ||
| 68 | * Allow to use environment variables for LDAP-URI configuration | ||
| 69 | |||
| 70 | = 2.3.0 = | ||
| 71 | * Allow to not overwrite existing WordPress-Users with LDAP-Users as that can be a security issue. | ||
| 72 | |||
| 73 | = 2.1.0 = | ||
| 74 | * Add search-base for groups. This might come in handy for multisite-instances | ||
| 75 | |||
| 76 | = 2.0.0 = | ||
| 77 | * This new release adds Multi-Site support. It will no longer be possible to use this plugin just in one subsite of a multisite installation! | ||
| 78 | * Adds a warning screen to the config-section when no LDAPextension could be found | ||
| 79 | * Fixes an issue with the max-length of the username | ||
| 80 | |||
| 81 | = 1.5.1 = | ||
| 82 | * Fixes an issue with escaped backslashes and quotes | ||
| 83 | |||
| 84 | = 1.5.0 = | ||
| 85 | * Allows parts of the LDAP-URI to be URLEncoded | ||
| 86 | * Drops support for PHP 5.4 | ||
| 87 | |||
| 44 | = 1.4.20 = | 88 | = 1.4.20 = |
| 45 | * Allows multiple LDAP-servers to be queried (given that they use the same attributes) | 89 | * Allows multiple LDAP-servers to be queried (given that they use the same attributes) |
| 46 | * Fixes issue with URL-Encoded informations (see https://github.com/heiglandreas/authLdap/issues/108) | 90 | * Fixes issue with URL-Encoded informations (see https://github.com/heiglandreas/authLdap/issues/108) |
| ... | @@ -77,7 +121,7 @@ Please use the issuetracker at https://github.com/heiglandreas/authLdap/issues | ... | @@ -77,7 +121,7 @@ Please use the issuetracker at https://github.com/heiglandreas/authLdap/issues |
| 77 | * Fixes PSR2 violations | 121 | * Fixes PSR2 violations |
| 78 | 122 | ||
| 79 | […] | 123 | […] |
| 80 | 124 | ||
| 81 | = 1.2.1 = | 125 | = 1.2.1 = |
| 82 | * Fixed an issue with group-ids | 126 | * Fixed an issue with group-ids |
| 83 | * Moved the code to GitHub (https://github.com/heiglandreas/authLdap) | 127 | * Moved the code to GitHub (https://github.com/heiglandreas/authLdap) | ... | ... |
| 1 | <?php | ||
| 2 | |||
| 3 | /** | ||
| 4 | * Copyright Andrea Heigl <andreas@heigl.org> | ||
| 5 | * | ||
| 6 | * Licenses under the MIT-license. For details see the included file LICENSE.md | ||
| 7 | */ | ||
| 8 | |||
| 9 | declare(strict_types=1); | ||
| 10 | |||
| 11 | namespace Org_Heigl\AuthLdap\Exception; | ||
| 12 | |||
| 13 | use Exception; | ||
| 14 | |||
| 15 | class Error extends Exception | ||
| 16 | { | ||
| 17 | public function __construct($message, $line = null) | ||
| 18 | { | ||
| 19 | parent::__construct($message); | ||
| 20 | if ($line) { | ||
| 21 | $this -> line = $line; | ||
| 22 | } | ||
| 23 | } | ||
| 24 | } |
| 1 | <?php | ||
| 2 | |||
| 3 | /** | ||
| 4 | * Copyright Andreas Heigl <andreas@heigl.org> | ||
| 5 | * | ||
| 6 | * Licenses under the MIT-license. For details see the included file LICENSE.md | ||
| 7 | */ | ||
| 8 | |||
| 9 | declare(strict_types=1); | ||
| 10 | |||
| 11 | namespace Org_Heigl\AuthLdap\Exception; | ||
| 12 | |||
| 13 | use RuntimeException; | ||
| 14 | |||
| 15 | use function sprintf; | ||
| 16 | |||
| 17 | class InvalidLdapUri extends RuntimeException | ||
| 18 | { | ||
| 19 | public static function cannotparse(string $ldapUri): self | ||
| 20 | { | ||
| 21 | return new self(sprintf( | ||
| 22 | '%1$s seems not to be a valid URI', | ||
| 23 | $ldapUri | ||
| 24 | )); | ||
| 25 | } | ||
| 26 | |||
| 27 | public static function wrongSchema(string $uri): self | ||
| 28 | { | ||
| 29 | return new self(sprintf( | ||
| 30 | '%1$s does not start with a valid schema', | ||
| 31 | $uri | ||
| 32 | )); | ||
| 33 | } | ||
| 34 | |||
| 35 | public static function noSchema(string $uri): self | ||
| 36 | { | ||
| 37 | return new self(sprintf( | ||
| 38 | '%1$s does not provide a schema', | ||
| 39 | $uri | ||
| 40 | )); | ||
| 41 | } | ||
| 42 | |||
| 43 | public static function noEnvironmentVariableSet(string $uri): self | ||
| 44 | { | ||
| 45 | return new self(sprintf( | ||
| 46 | 'The environment variable %1$s does not provide a URI', | ||
| 47 | $uri | ||
| 48 | )); | ||
| 49 | } | ||
| 50 | |||
| 51 | public static function noServerProvided(string $uri): self | ||
| 52 | { | ||
| 53 | return new self(sprintf( | ||
| 54 | 'The LDAP-URI %1$s does not provide a server', | ||
| 55 | $uri | ||
| 56 | )); | ||
| 57 | } | ||
| 58 | |||
| 59 | public static function noSearchBaseProvided(string $uri): self | ||
| 60 | { | ||
| 61 | return new self(sprintf( | ||
| 62 | 'The LDAP-URI %1$s does not provide a search-base', | ||
| 63 | $uri | ||
| 64 | )); | ||
| 65 | } | ||
| 66 | |||
| 67 | public static function invalidSearchBaseProvided(string $uri): self | ||
| 68 | { | ||
| 69 | return new self(sprintf( | ||
| 70 | 'The LDAP-URI %1$s does not provide a valid search-base', | ||
| 71 | $uri | ||
| 72 | )); | ||
| 73 | } | ||
| 74 | } |
| 1 | <?php | ||
| 2 | |||
| 3 | /** | ||
| 4 | * Copyright Andreas Heigl <andreas@heigl.org> | ||
| 5 | * | ||
| 6 | * Licenses under the MIT-license. For details see the included file LICENSE.md | ||
| 7 | */ | ||
| 8 | |||
| 9 | declare(strict_types=1); | ||
| 10 | |||
| 11 | namespace Org_Heigl\AuthLdap\Exception; | ||
| 12 | |||
| 13 | use RuntimeException; | ||
| 14 | |||
| 15 | class MissingValidLdapConnection extends Error | ||
| 16 | { | ||
| 17 | public static function get(): self | ||
| 18 | { | ||
| 19 | return new self(sprintf( | ||
| 20 | 'No valid LDAP connection available' | ||
| 21 | )); | ||
| 22 | } | ||
| 23 | } |
| 1 | <?php | ||
| 2 | |||
| 3 | /** | ||
| 4 | * Copyright Andreas Heigl <andreas@heigl.org> | ||
| 5 | * | ||
| 6 | * Licenses under the MIT-license. For details see the included file LICENSE.md | ||
| 7 | */ | ||
| 8 | |||
| 9 | declare(strict_types=1); | ||
| 10 | |||
| 11 | namespace Org_Heigl\AuthLdap\Exception; | ||
| 12 | |||
| 13 | use RuntimeException; | ||
| 14 | |||
| 15 | class SearchUnsuccessfull extends RuntimeException | ||
| 16 | { | ||
| 17 | public static function fromSearchFilter(string $filter): self | ||
| 18 | { | ||
| 19 | return new self(sprintf( | ||
| 20 | 'Search for %1$s was not successfull', | ||
| 21 | $filter | ||
| 22 | )); | ||
| 23 | } | ||
| 24 | } |
| 1 | <?php | 1 | <?php |
| 2 | |||
| 2 | /** | 3 | /** |
| 3 | * Copyright (c) Andreas Heigl<andreas@heigl.org> | 4 | * Copyright (c) Andreas Heigl<andreas@heigl.org> |
| 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy | 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
| ... | @@ -26,23 +27,29 @@ | ... | @@ -26,23 +27,29 @@ |
| 26 | 27 | ||
| 27 | namespace Org_Heigl\AuthLdap; | 28 | namespace Org_Heigl\AuthLdap; |
| 28 | 29 | ||
| 30 | use Exception; | ||
| 31 | use Org_Heigl\AuthLdap\Exception\Error; | ||
| 32 | use Org_Heigl\AuthLdap\Exception\SearchUnsuccessfull; | ||
| 33 | use Org_Heigl\AuthLdap\Manager\Ldap; | ||
| 34 | |||
| 29 | class LdapList | 35 | class LdapList |
| 30 | { | 36 | { |
| 31 | /** | 37 | /** |
| 32 | * @var \LDAP[] | 38 | * @var Ldap[] |
| 33 | */ | 39 | */ |
| 34 | protected $items = []; | 40 | protected $items = []; |
| 35 | 41 | ||
| 36 | public function addLdap(LDAP $ldap) | 42 | public function addLdap(Ldap $ldap) |
| 37 | { | 43 | { |
| 38 | $this->items[] = $ldap; | 44 | $this->items[] = $ldap; |
| 39 | } | 45 | } |
| 40 | 46 | ||
| 41 | public function authenticate($username, $password, $filter = '(uid=%s)') | 47 | public function authenticate($username, $password, $filter = '(uid=%s)') |
| 42 | { | 48 | { |
| 49 | /** @var Ldap $item */ | ||
| 43 | foreach ($this->items as $key => $item) { | 50 | foreach ($this->items as $key => $item) { |
| 44 | if (! $item->authenticate($username, $password, $filter)) { | 51 | if (! $item->authenticate($username, $password, $filter)) { |
| 45 | unset ($this->items[$key]); | 52 | unset($this->items[$key]); |
| 46 | continue; | 53 | continue; |
| 47 | } | 54 | } |
| 48 | return true; | 55 | return true; |
| ... | @@ -65,21 +72,22 @@ class LdapList | ... | @@ -65,21 +72,22 @@ class LdapList |
| 65 | } | 72 | } |
| 66 | 73 | ||
| 67 | if ($allFailed) { | 74 | if ($allFailed) { |
| 68 | throw new AuthLDAP_Exception('No bind successfull'); | 75 | throw new Error('No bind successfull'); |
| 69 | } | 76 | } |
| 77 | |||
| 78 | return true; | ||
| 70 | } | 79 | } |
| 71 | 80 | ||
| 72 | public function search($filter, $attributes = array('uid')) | 81 | public function search($filter, $attributes = array('uid'), $base = '') |
| 73 | { | 82 | { |
| 74 | foreach ($this->items as $item) { | 83 | foreach ($this->items as $item) { |
| 75 | try { | 84 | try { |
| 76 | $result = $item->search($filter, $attributes); | 85 | $result = $item->search($filter, $attributes, $base); |
| 77 | return $result; | 86 | return $result; |
| 78 | } catch (Exception $e) { | 87 | } catch (Exception $e) { |
| 79 | throw $e; | ||
| 80 | } | 88 | } |
| 81 | } | 89 | } |
| 82 | 90 | ||
| 83 | throw new \AuthLDAP_Exception('No Results found'); | 91 | throw SearchUnsuccessfull::fromSearchFilter($filter); |
| 84 | } | 92 | } |
| 85 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 93 | } | ... | ... |
wp-content/plugins/authLdap/src/LdapUri.php
0 → 100644
| 1 | <?php | ||
| 2 | |||
| 3 | /** | ||
| 4 | * Copyright (c) Andreas Heigl<andreas@heigl.org> | ||
| 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| 6 | * of this software and associated documentation files (the "Software"), to deal | ||
| 7 | * in the Software without restriction, including without limitation the rights | ||
| 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| 9 | * copies of the Software, and to permit persons to whom the Software is | ||
| 10 | * furnished to do so, subject to the following conditions: | ||
| 11 | * The above copyright notice and this permission notice shall be included in | ||
| 12 | * all copies or substantial portions of the Software. | ||
| 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| 18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
| 19 | * THE SOFTWARE. | ||
| 20 | * | ||
| 21 | * @author Andreas Heigl<andreas@heigl.org> | ||
| 22 | * @copyright Andreas Heigl | ||
| 23 | * @license http://www.opensource.org/licenses/mit-license.php MIT-License | ||
| 24 | * @since 19.07.2020 | ||
| 25 | * @link http://github.com/heiglandreas/authLDAP | ||
| 26 | */ | ||
| 27 | |||
| 28 | declare(strict_types=1); | ||
| 29 | |||
| 30 | namespace Org_Heigl\AuthLdap; | ||
| 31 | |||
| 32 | use Org_Heigl\AuthLdap\Exception\InvalidLdapUri; | ||
| 33 | |||
| 34 | use function array_map; | ||
| 35 | use function error_get_last; | ||
| 36 | use function getenv; | ||
| 37 | use function is_array; | ||
| 38 | use function is_string; | ||
| 39 | use function parse_url; | ||
| 40 | use function preg_replace_callback; | ||
| 41 | use function rawurlencode; | ||
| 42 | use function strlen; | ||
| 43 | use function strpos; | ||
| 44 | use function substr; | ||
| 45 | use function trim; | ||
| 46 | use function urldecode; | ||
| 47 | |||
| 48 | final class LdapUri | ||
| 49 | { | ||
| 50 | private $server; | ||
| 51 | |||
| 52 | private $scheme; | ||
| 53 | |||
| 54 | private $port = 389; | ||
| 55 | |||
| 56 | private string $baseDn; | ||
| 57 | |||
| 58 | private $username = ''; | ||
| 59 | |||
| 60 | private $password = ''; | ||
| 61 | |||
| 62 | private function __construct(string $uri) | ||
| 63 | { | ||
| 64 | if (!preg_match('/^(ldap|ldaps|env)/', $uri)) { | ||
| 65 | throw InvalidLdapUri::wrongSchema($uri); | ||
| 66 | } | ||
| 67 | |||
| 68 | if (strpos($uri, 'env:') === 0) { | ||
| 69 | $newUri = getenv(substr($uri, 4)); | ||
| 70 | if (false === $newUri) { | ||
| 71 | throw InvalidLdapUri::noEnvironmentVariableSet($uri); | ||
| 72 | } | ||
| 73 | $uri = (string) $newUri; | ||
| 74 | } | ||
| 75 | |||
| 76 | $uri = $this->injectEnvironmentVariables($uri); | ||
| 77 | |||
| 78 | $array = parse_url($uri); | ||
| 79 | if (!is_array($array)) { | ||
| 80 | throw InvalidLdapUri::cannotparse($uri); | ||
| 81 | } | ||
| 82 | |||
| 83 | $url = array_map(static function ($item) { | ||
| 84 | if (is_int($item)) { | ||
| 85 | return $item; | ||
| 86 | } | ||
| 87 | return urldecode($item); | ||
| 88 | }, $array); | ||
| 89 | |||
| 90 | |||
| 91 | if (!isset($url['scheme'])) { | ||
| 92 | throw InvalidLdapUri::noSchema($uri); | ||
| 93 | } | ||
| 94 | if (0 !== strpos($url['scheme'], 'ldap')) { | ||
| 95 | throw InvalidLdapUri::wrongSchema($uri); | ||
| 96 | } | ||
| 97 | if (!isset($url['host'])) { | ||
| 98 | throw InvalidLdapUri::noServerProvided($uri); | ||
| 99 | } | ||
| 100 | if (!isset($url['path'])) { | ||
| 101 | throw InvalidLdapUri::noSearchBaseProvided($uri); | ||
| 102 | } | ||
| 103 | if (1 === strlen($url['path'])) { | ||
| 104 | throw InvalidLdapUri::invalidSearchBaseProvided($uri); | ||
| 105 | } | ||
| 106 | |||
| 107 | $this->server = $url['host']; | ||
| 108 | $this->scheme = $url['scheme']; | ||
| 109 | $this->baseDn = substr($url['path'], 1); | ||
| 110 | if (isset($url['user'])) { | ||
| 111 | $this->username = $url['user']; | ||
| 112 | } | ||
| 113 | if ('' === trim($this->username)) { | ||
| 114 | $this->username = 'anonymous'; | ||
| 115 | } | ||
| 116 | if (isset($url['pass'])) { | ||
| 117 | $this->password = $url['pass']; | ||
| 118 | } | ||
| 119 | if ($this->scheme === 'ldaps' && $this->port = 389) { | ||
| 120 | $this->port = 636; | ||
| 121 | } | ||
| 122 | |||
| 123 | // When someone sets the port in the URL we overwrite whatever is set. | ||
| 124 | // We have to assume they know what they are doing! | ||
| 125 | if (isset($url['port'])) { | ||
| 126 | $this->port = $url['port']; | ||
| 127 | } | ||
| 128 | } | ||
| 129 | |||
| 130 | public static function fromString(string $uri): LdapUri | ||
| 131 | { | ||
| 132 | return new LdapUri($uri); | ||
| 133 | } | ||
| 134 | |||
| 135 | private function injectEnvironmentVariables(string $base): string | ||
| 136 | { | ||
| 137 | return preg_replace_callback('/%env:([^%]+)%/', static function (array $matches) { | ||
| 138 | return rawurlencode(getenv($matches[1])); | ||
| 139 | }, $base); | ||
| 140 | } | ||
| 141 | |||
| 142 | public function toString(): string | ||
| 143 | { | ||
| 144 | return $this->scheme . '://' . $this->server . ':' . $this->port; | ||
| 145 | } | ||
| 146 | |||
| 147 | public function __toString() | ||
| 148 | { | ||
| 149 | return $this->toString(); | ||
| 150 | } | ||
| 151 | |||
| 152 | public function getUsername(): string | ||
| 153 | { | ||
| 154 | return $this->username; | ||
| 155 | } | ||
| 156 | |||
| 157 | public function getPassword(): string | ||
| 158 | { | ||
| 159 | return $this->password; | ||
| 160 | } | ||
| 161 | |||
| 162 | public function getBaseDn(): string | ||
| 163 | { | ||
| 164 | return $this->baseDn; | ||
| 165 | } | ||
| 166 | |||
| 167 | public function isAnonymous(): bool | ||
| 168 | { | ||
| 169 | if ($this->password === '') { | ||
| 170 | return true; | ||
| 171 | } | ||
| 172 | |||
| 173 | if ($this->username === 'anonymous') { | ||
| 174 | return true; | ||
| 175 | } | ||
| 176 | |||
| 177 | return false; | ||
| 178 | } | ||
| 179 | } |
| 1 | <?php | ||
| 2 | |||
| 3 | /** | ||
| 4 | * $Id: ldap.php 381646 2011-05-06 09:37:31Z heiglandreas $ | ||
| 5 | * | ||
| 6 | * authLdap - Authenticate Wordpress against an LDAP-Backend. | ||
| 7 | * Copyright (c) 2008 Andreas Heigl<andreas@heigl.org> | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or | ||
| 10 | * modify it under the terms of the GNU General Public License | ||
| 11 | * as published by the Free Software Foundation; either version 2 | ||
| 12 | * of the License, or (at your option) any later version. | ||
| 13 | * | ||
| 14 | * This program is distributed in the hope that it will be useful, | ||
| 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 17 | * GNU General Public License for more details. | ||
| 18 | * | ||
| 19 | * You should have received a copy of the GNU General Public License | ||
| 20 | * along with this program; if not, write to the Free Software | ||
| 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
| 22 | * | ||
| 23 | * This file handles the basic LDAP-Tasks | ||
| 24 | * | ||
| 25 | * @author Andreas Heigl<andreas@heigl.org> | ||
| 26 | * @package authLdap | ||
| 27 | * @category authLdap | ||
| 28 | * @since 2008 | ||
| 29 | */ | ||
| 30 | |||
| 31 | namespace Org_Heigl\AuthLdap\Manager; | ||
| 32 | |||
| 33 | use Org_Heigl\AuthLdap\Exception\Error; | ||
| 34 | use Org_Heigl\AuthLdap\Exception\MissingValidLdapConnection; | ||
| 35 | use Org_Heigl\AuthLdap\LdapUri; | ||
| 36 | use Org_Heigl\AuthLdap\Wrapper\LdapFactory; | ||
| 37 | use Org_Heigl\AuthLdap\Wrapper\LdapInterface; | ||
| 38 | |||
| 39 | class Ldap | ||
| 40 | { | ||
| 41 | /** | ||
| 42 | * This property contains the connection handle to the ldap-server | ||
| 43 | * | ||
| 44 | * @var LdapInterface|null | ||
| 45 | */ | ||
| 46 | private ?LdapInterface $connection; | ||
| 47 | |||
| 48 | private LdapUri $uri; | ||
| 49 | |||
| 50 | private LdapFactory $factory; | ||
| 51 | |||
| 52 | private $starttls; | ||
| 53 | |||
| 54 | public function __construct(LdapFactory $factory, LdapUri $uri, $starttls = false) | ||
| 55 | { | ||
| 56 | $this->starttls = $starttls; | ||
| 57 | $this->uri = $uri; | ||
| 58 | $this->factory = $factory; | ||
| 59 | $this->connection = null; | ||
| 60 | } | ||
| 61 | |||
| 62 | /** | ||
| 63 | * Connect to the given LDAP-Server | ||
| 64 | */ | ||
| 65 | public function connect(): self | ||
| 66 | { | ||
| 67 | $this->disconnect(); | ||
| 68 | |||
| 69 | $this->connection = $this->factory->createFromLdapUri($this->uri->toString()); | ||
| 70 | $this->connection->setOption(LDAP_OPT_PROTOCOL_VERSION, 3); | ||
| 71 | $this->connection->setOption(LDAP_OPT_REFERRALS, 0); | ||
| 72 | //if configured try to upgrade encryption to tls for ldap connections | ||
| 73 | if ($this->starttls) { | ||
| 74 | $this->connection->startTls(); | ||
| 75 | } | ||
| 76 | return $this; | ||
| 77 | } | ||
| 78 | |||
| 79 | /** | ||
| 80 | * Disconnect from a resource if one is available | ||
| 81 | */ | ||
| 82 | public function disconnect(): self | ||
| 83 | { | ||
| 84 | if (null !== $this->connection) { | ||
| 85 | $this->connection->unbind(); | ||
| 86 | } | ||
| 87 | $this->connection = null; | ||
| 88 | return $this; | ||
| 89 | } | ||
| 90 | |||
| 91 | /** | ||
| 92 | * Bind to an LDAP-Server with the given credentials | ||
| 93 | * | ||
| 94 | * @throws Error | ||
| 95 | */ | ||
| 96 | public function bind(): self | ||
| 97 | { | ||
| 98 | if (!$this->connection) { | ||
| 99 | $this->connect(); | ||
| 100 | } | ||
| 101 | if (null === $this->connection) { | ||
| 102 | throw MissingValidLdapConnection::get(); | ||
| 103 | } | ||
| 104 | if ($this->uri->isAnonymous()) { | ||
| 105 | $bind = $this->connection->bind(); | ||
| 106 | } else { | ||
| 107 | $bind = $this->connection->bind($this->uri->getUsername(), $this->uri->getPassword()); | ||
| 108 | } | ||
| 109 | if (!$bind) { | ||
| 110 | throw new Error('bind was not successfull: ' . $this->connection->error()); | ||
| 111 | } | ||
| 112 | return $this; | ||
| 113 | } | ||
| 114 | |||
| 115 | /** | ||
| 116 | * This method does the actual ldap-serch. | ||
| 117 | * | ||
| 118 | * This is using the filter <var>$filter</var> for retrieving the attributes | ||
| 119 | * <var>$attributes</var> | ||
| 120 | * | ||
| 121 | * @return array<string|int, mixed> | ||
| 122 | * @throws Error | ||
| 123 | */ | ||
| 124 | public function search(string $filter, array $attributes = ['uid'], ?string $base = ''): array | ||
| 125 | { | ||
| 126 | if (null === $this->connection) { | ||
| 127 | throw new Error('No resource handle available'); | ||
| 128 | } | ||
| 129 | if (!$base) { | ||
| 130 | $base = $this->uri->getBaseDn(); | ||
| 131 | } | ||
| 132 | $result = $this->connection->search($base, $filter, $attributes); | ||
| 133 | if ($result === false) { | ||
| 134 | throw new Error('no result found'); | ||
| 135 | } | ||
| 136 | $info = $this->connection->getEntries($result); | ||
| 137 | if ($info === false) { | ||
| 138 | throw new Error('invalid results found'); | ||
| 139 | } | ||
| 140 | return $info; | ||
| 141 | } | ||
| 142 | |||
| 143 | /** | ||
| 144 | * This method authenticates the user <var>$username</var> using the | ||
| 145 | * password <var>$password</var> | ||
| 146 | * | ||
| 147 | * @param string $filter OPTIONAL This parameter defines the Filter to be used | ||
| 148 | * when searchin for the username. This MUST contain the string '%s' which | ||
| 149 | * will be replaced by the vaue given in <var>$username</var> | ||
| 150 | * @throws Error | ||
| 151 | */ | ||
| 152 | public function authenticate(string $username, string $password, string $filter = '(uid=%s)'): bool | ||
| 153 | { | ||
| 154 | $this->connect(); | ||
| 155 | $this->bind(); | ||
| 156 | $res = $this->search(sprintf($filter, $this->factory->escape($username, '', LDAP_ESCAPE_FILTER))); | ||
| 157 | if ($res ['count'] !== 1) { | ||
| 158 | return false; | ||
| 159 | } | ||
| 160 | |||
| 161 | $dn = $res[0]['dn']; | ||
| 162 | return $username && $password && $this->connection->bind($dn, $password); | ||
| 163 | } | ||
| 164 | } |
| 1 | <?php | ||
| 2 | |||
| 3 | /** | ||
| 4 | * Copyright Andreas Heigl <andreas@heigl.org> | ||
| 5 | * | ||
| 6 | * Licenses under the MIT-license. For details see the included file LICENSE.md | ||
| 7 | */ | ||
| 8 | |||
| 9 | declare(strict_types=1); | ||
| 10 | |||
| 11 | namespace Org_Heigl\AuthLdap; | ||
| 12 | |||
| 13 | use WP_User; | ||
| 14 | |||
| 15 | use function array_search; | ||
| 16 | use function in_array; | ||
| 17 | use function var_dump; | ||
| 18 | |||
| 19 | class UserRoleHandler | ||
| 20 | { | ||
| 21 | /** | ||
| 22 | * @param WP_User $user | ||
| 23 | * @param string[] $roles | ||
| 24 | * @return void | ||
| 25 | */ | ||
| 26 | public function addRolesToUser(WP_User $user, $roles) : void | ||
| 27 | { | ||
| 28 | if ($roles === []) { | ||
| 29 | return; | ||
| 30 | } | ||
| 31 | |||
| 32 | if ($user->roles == $roles) { | ||
| 33 | return; | ||
| 34 | } | ||
| 35 | |||
| 36 | // Remove unused roles from existing. | ||
| 37 | foreach ($user->roles as $role) { | ||
| 38 | if (!in_array($role, $roles)) { | ||
| 39 | // Remove unused roles. | ||
| 40 | $user->remove_role($role); | ||
| 41 | continue; | ||
| 42 | } | ||
| 43 | // Remove the existing role from roles. | ||
| 44 | if (($key = array_search($role, $roles)) !== false) { | ||
| 45 | unset($roles[$key]); | ||
| 46 | } | ||
| 47 | } | ||
| 48 | |||
| 49 | // Add new ones if not already assigned. | ||
| 50 | foreach ($roles as $role) { | ||
| 51 | $user->add_role($role); | ||
| 52 | } | ||
| 53 | } | ||
| 54 | } |
| 1 | <?php | ||
| 2 | |||
| 3 | /** | ||
| 4 | * Copyright Andreas Heigl <andreas@heigl.org> | ||
| 5 | * | ||
| 6 | * Licenses under the MIT-license. For details see the included file LICENSE.md | ||
| 7 | */ | ||
| 8 | |||
| 9 | declare(strict_types=1); | ||
| 10 | |||
| 11 | namespace Org_Heigl\AuthLdap\Wrapper; | ||
| 12 | |||
| 13 | use function ldap_bind; | ||
| 14 | use function ldap_connect; | ||
| 15 | use function ldap_error; | ||
| 16 | use function ldap_escape; | ||
| 17 | use function ldap_get_entries; | ||
| 18 | use function ldap_set_option; | ||
| 19 | use function ldap_start_tls; | ||
| 20 | use function ldap_unbind; | ||
| 21 | |||
| 22 | final class Ldap implements LdapInterface | ||
| 23 | { | ||
| 24 | private $connection; | ||
| 25 | |||
| 26 | public function __construct(string $ldapUri) | ||
| 27 | { | ||
| 28 | $this->connection = ldap_connect($ldapUri); | ||
| 29 | } | ||
| 30 | |||
| 31 | public function bind($dn = null, $password = null) | ||
| 32 | { | ||
| 33 | if (null === $dn && null === $password) { | ||
| 34 | return ldap_bind($this->connection); | ||
| 35 | } | ||
| 36 | return ldap_bind($this->connection, $dn, $password); | ||
| 37 | } | ||
| 38 | |||
| 39 | public function unbind() | ||
| 40 | { | ||
| 41 | return ldap_unbind($this->connection); | ||
| 42 | } | ||
| 43 | |||
| 44 | public function setOption($option, $value) | ||
| 45 | { | ||
| 46 | return ldap_set_option($this->connection, $option, $value); | ||
| 47 | } | ||
| 48 | |||
| 49 | public function startTls() | ||
| 50 | { | ||
| 51 | return ldap_start_tls($this->connection); | ||
| 52 | } | ||
| 53 | |||
| 54 | public function error() | ||
| 55 | { | ||
| 56 | return ldap_error($this->connection); | ||
| 57 | } | ||
| 58 | |||
| 59 | public function errno() | ||
| 60 | { | ||
| 61 | return ldap_errno($this->connection); | ||
| 62 | } | ||
| 63 | |||
| 64 | public function search( | ||
| 65 | $base, | ||
| 66 | $filter, | ||
| 67 | array $attributes = [], | ||
| 68 | $attributes_only = 0, | ||
| 69 | $sizelimit = -1, | ||
| 70 | $timelimit = -1 | ||
| 71 | ) { | ||
| 72 | return ldap_search( | ||
| 73 | $this->connection, | ||
| 74 | $base, | ||
| 75 | $filter, | ||
| 76 | $attributes, | ||
| 77 | $attributes_only, | ||
| 78 | $sizelimit, | ||
| 79 | $timelimit | ||
| 80 | ); | ||
| 81 | } | ||
| 82 | |||
| 83 | public function getEntries($search_result) | ||
| 84 | { | ||
| 85 | return ldap_get_entries($this->connection, $search_result); | ||
| 86 | } | ||
| 87 | |||
| 88 | public static function escape(string $value, string $ignore = '', int $flags = 0): string | ||
| 89 | { | ||
| 90 | return ldap_escape($value, $ignore, $flags); | ||
| 91 | } | ||
| 92 | } |
| 1 | <?php | ||
| 2 | |||
| 3 | /** | ||
| 4 | * Copyright Andreas Heigl <andreas@heigl.org> | ||
| 5 | * | ||
| 6 | * Licenses under the MIT-license. For details see the included file LICENSE.md | ||
| 7 | */ | ||
| 8 | |||
| 9 | declare(strict_types=1); | ||
| 10 | |||
| 11 | namespace Org_Heigl\AuthLdap\Wrapper; | ||
| 12 | |||
| 13 | class LdapFactory | ||
| 14 | { | ||
| 15 | public function createFromLdapUri(string $ldapUri): LdapInterface | ||
| 16 | { | ||
| 17 | return new Ldap($ldapUri); | ||
| 18 | } | ||
| 19 | |||
| 20 | public function escape($value, $ignore = '', $flags = 0): string | ||
| 21 | { | ||
| 22 | return Ldap::escape($value, $ignore, $flags); | ||
| 23 | } | ||
| 24 | } |
| 1 | <?php | ||
| 2 | |||
| 3 | /** | ||
| 4 | * Copyright Andreas Heigl <andreas@heigl.org> | ||
| 5 | * | ||
| 6 | * Licenses under the MIT-license. For details see the included file LICENSE.md | ||
| 7 | */ | ||
| 8 | |||
| 9 | declare(strict_types=1); | ||
| 10 | |||
| 11 | namespace Org_Heigl\AuthLdap\Wrapper; | ||
| 12 | |||
| 13 | interface LdapInterface | ||
| 14 | { | ||
| 15 | public function bind($dn = null, $password = null); | ||
| 16 | |||
| 17 | public function unbind(); | ||
| 18 | |||
| 19 | public function setOption($option, $value); | ||
| 20 | |||
| 21 | public function startTls(); | ||
| 22 | |||
| 23 | public function error(); | ||
| 24 | |||
| 25 | public function errno(); | ||
| 26 | |||
| 27 | public function search( | ||
| 28 | $base, | ||
| 29 | $filter, | ||
| 30 | array $attributes = [], | ||
| 31 | $attributes_only = 0, | ||
| 32 | $sizelimit = -1, | ||
| 33 | $timelimit = -1 | ||
| 34 | ); | ||
| 35 | |||
| 36 | public function getEntries($search_result); | ||
| 37 | |||
| 38 | public static function escape(string $value, string $ignore = '', int $flags = 0): string; | ||
| 39 | } |
| 1 | <?php | ||
| 2 | |||
| 3 | /** | ||
| 4 | * Copyright (c) 2016-2016} Andreas Heigl<andreas@heigl.org> | ||
| 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| 6 | * of this software and associated documentation files (the "Software"), to deal | ||
| 7 | * in the Software without restriction, including without limitation the rights | ||
| 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| 9 | * copies of the Software, and to permit persons to whom the Software is | ||
| 10 | * furnished to do so, subject to the following conditions: | ||
| 11 | * The above copyright notice and this permission notice shall be included in | ||
| 12 | * all copies or substantial portions of the Software. | ||
| 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| 18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
| 19 | * THE SOFTWARE. | ||
| 20 | * | ||
| 21 | * @author Andreas Heigl<andreas@heigl.org> | ||
| 22 | * @copyright 2016-2016 Andreas Heigl | ||
| 23 | * @license http://www.opensource.org/licenses/mit-license.php MIT-License | ||
| 24 | * @version 0.0 | ||
| 25 | * @since 07.06.2016 | ||
| 26 | * @link http://github.com/heiglandreas/authLDAP | ||
| 27 | */ | ||
| 28 | |||
| 29 | namespace Org_Heigl\AuthLdapTest; | ||
| 30 | |||
| 31 | use Closure; | ||
| 32 | use Org_Heigl\AuthLdap\Exception\Error; | ||
| 33 | use Org_Heigl\AuthLdap\Exception\SearchUnsuccessfull; | ||
| 34 | use Org_Heigl\AuthLdap\LdapList; | ||
| 35 | use Org_Heigl\AuthLdap\Manager\Ldap; | ||
| 36 | use Org_Heigl\AuthLdap\LdapUri; | ||
| 37 | use Org_Heigl\AuthLdap\Wrapper\LdapFactory; | ||
| 38 | use Org_Heigl\AuthLdap\Wrapper\LdapInterface; | ||
| 39 | use PHPUnit\Framework\Assert; | ||
| 40 | use PHPUnit\Framework\TestCase; | ||
| 41 | |||
| 42 | class LDAPListBaseTest extends TestCase | ||
| 43 | { | ||
| 44 | private $ldapA; | ||
| 45 | |||
| 46 | private $ldapB; | ||
| 47 | |||
| 48 | public function setUp(): void | ||
| 49 | { | ||
| 50 | $this->ldapA = $this->getMockBuilder(Ldap::class)->disableOriginalConstructor()->getMock(); | ||
| 51 | $this->ldapB = $this->getMockBuilder(Ldap::class)->disableOriginalConstructor()->getMock(); | ||
| 52 | Assert::assertNotSame($this->ldapA, $this->ldapB); | ||
| 53 | parent::setUp(); // TODO: Change the autogenerated stub | ||
| 54 | } | ||
| 55 | |||
| 56 | public function addingItemsWorks(): void | ||
| 57 | { | ||
| 58 | $list = new LdapList(); | ||
| 59 | |||
| 60 | $list->addLdap($this->ldapA); | ||
| 61 | $list->addLdap($this->ldapB); | ||
| 62 | |||
| 63 | Assert::assertSame([$this->ldapA, $this->ldapB], $this->getLdaps($list)); | ||
| 64 | } | ||
| 65 | |||
| 66 | public function testFailingBindRemovesItemsFromList(): void | ||
| 67 | { | ||
| 68 | $list = new LdapList(); | ||
| 69 | |||
| 70 | $list->addLdap($this->ldapA); | ||
| 71 | $list->addLdap($this->ldapB); | ||
| 72 | |||
| 73 | $this->ldapA->method('bind')->willThrowException(new Error('throw')); | ||
| 74 | $this->ldapB->method('bind')->willReturn($this->ldapB); | ||
| 75 | |||
| 76 | $list->bind(); | ||
| 77 | |||
| 78 | Assert::assertCount(1, $this->getLdaps($list)); | ||
| 79 | } | ||
| 80 | |||
| 81 | public function testFailingBindInAllConnectorsThrows(): void | ||
| 82 | { | ||
| 83 | $list = new LdapList(); | ||
| 84 | |||
| 85 | $list->addLdap($this->ldapA); | ||
| 86 | $list->addLdap($this->ldapB); | ||
| 87 | |||
| 88 | $this->ldapA->method('bind')->willThrowException(new Error('throw')); | ||
| 89 | $this->ldapB->method('bind')->willThrowException(new Error('throw')); | ||
| 90 | |||
| 91 | $this->expectException(Error::class); | ||
| 92 | $this->expectExceptionMessage('No bind successfull'); | ||
| 93 | |||
| 94 | $list->bind(); | ||
| 95 | |||
| 96 | Assert::assertCount(0, $this->getLdaps($list)); | ||
| 97 | } | ||
| 98 | |||
| 99 | public function testAuthenticatingViaListWorks(): void | ||
| 100 | { | ||
| 101 | $list = new LdapList(); | ||
| 102 | |||
| 103 | $list->addLdap($this->ldapA); | ||
| 104 | $list->addLdap($this->ldapB); | ||
| 105 | |||
| 106 | $this->ldapA->method('authenticate')->willReturn(false); | ||
| 107 | $this->ldapB->method('authenticate')->willReturn(true); | ||
| 108 | |||
| 109 | Assert::assertTrue($list->authenticate('foo', 'bar')); | ||
| 110 | |||
| 111 | Assert::assertCount(1, $this->getLdaps($list)); | ||
| 112 | } | ||
| 113 | |||
| 114 | public function testAuthenticatingViaListFailsWhenNoConnectorAuthenticates(): void | ||
| 115 | { | ||
| 116 | $list = new LdapList(); | ||
| 117 | |||
| 118 | $list->addLdap($this->ldapA); | ||
| 119 | $list->addLdap($this->ldapB); | ||
| 120 | |||
| 121 | $this->ldapA->method('authenticate')->willReturn(false); | ||
| 122 | $this->ldapB->method('authenticate')->willReturn(false); | ||
| 123 | |||
| 124 | Assert::assertFalse($list->authenticate('foo', 'bar')); | ||
| 125 | |||
| 126 | Assert::assertCount(0, $this->getLdaps($list)); | ||
| 127 | } | ||
| 128 | |||
| 129 | public function testSuccessfullSearchInOneConnectorReturnsResult(): void | ||
| 130 | { | ||
| 131 | $list = new LdapList(); | ||
| 132 | |||
| 133 | $list->addLdap($this->ldapA); | ||
| 134 | $list->addLdap($this->ldapB); | ||
| 135 | |||
| 136 | $this->ldapA->method('search')->willThrowException(new Error('Whoot')); | ||
| 137 | $this->ldapB->method('search')->willReturn(['count' => 1, ['dn' => 'foo']]); | ||
| 138 | |||
| 139 | Assert::assertEquals(['count' => 1, ['dn' => 'foo']], $list->search('uid=foo')); | ||
| 140 | } | ||
| 141 | |||
| 142 | public function testUnsuccessfullSearchWillThrow(): void | ||
| 143 | { | ||
| 144 | $list = new LdapList(); | ||
| 145 | |||
| 146 | $list->addLdap($this->ldapA); | ||
| 147 | $list->addLdap($this->ldapB); | ||
| 148 | |||
| 149 | $this->ldapA->method('search')->willThrowException(new Error('Whoot')); | ||
| 150 | $this->ldapB->method('search')->willThrowException(new Error('Whoot2')); | ||
| 151 | |||
| 152 | $this->expectException(SearchUnsuccessfull::class); | ||
| 153 | |||
| 154 | $list->search('uid=foo'); | ||
| 155 | } | ||
| 156 | |||
| 157 | |||
| 158 | private function getLdaps(LdapList $list): array | ||
| 159 | { | ||
| 160 | |||
| 161 | // Courtesy of Marco Pivetta | ||
| 162 | // https://ocramius.github.io/blog/accessing-private-php-class-members-without-reflection/ | ||
| 163 | $sweetsThief = function (LdapList $kitchen) { | ||
| 164 | return $kitchen->items; | ||
| 165 | }; | ||
| 166 | |||
| 167 | // Closure::bind() actually creates a new instance of the closure | ||
| 168 | $sweetsThief = Closure::bind($sweetsThief, null, $list); | ||
| 169 | |||
| 170 | return $sweetsThief($list); | ||
| 171 | } | ||
| 172 | } |
| 1 | <?php | ||
| 2 | |||
| 3 | /** | ||
| 4 | * $Id: LdapTest.php 292156 2010-09-21 19:32:01Z heiglandreas $ | ||
| 5 | * | ||
| 6 | * authLdap - Authenticate Wordpress against an LDAP-Backend. | ||
| 7 | * Copyright (c) 2008 Andreas Heigl<andreas@heigl.org> | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or | ||
| 10 | * modify it under the terms of the GNU General Public License | ||
| 11 | * as published by the Free Software Foundation; either version 2 | ||
| 12 | * of the License, or (at your option) any later version. | ||
| 13 | * | ||
| 14 | * This program is distributed in the hope that it will be useful, | ||
| 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 17 | * GNU General Public License for more details. | ||
| 18 | * | ||
| 19 | * You should have received a copy of the GNU General Public License | ||
| 20 | * along with this program; if not, write to the Free Software | ||
| 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
| 22 | * | ||
| 23 | * This file tests the basic LDAP-Tasks | ||
| 24 | * | ||
| 25 | * @category authLdap | ||
| 26 | * @package authLdap | ||
| 27 | * @subpackage UnitTests | ||
| 28 | * @author Andreas Heigl<andreas@heigl.org> | ||
| 29 | * @copyright 2010 Andreas Heigl<andreas@heigl.org> | ||
| 30 | * @license GPL | ||
| 31 | * @since 21.09.2010 | ||
| 32 | */ | ||
| 33 | |||
| 34 | namespace Org_Heigl\AuthLdapTest; | ||
| 35 | |||
| 36 | use Exception; | ||
| 37 | use Generator; | ||
| 38 | use Org_Heigl\AuthLdap\LdapUri; | ||
| 39 | use Org_Heigl\AuthLdap\Wrapper\LdapFactory; | ||
| 40 | use PHPUnit\Framework\TestCase; | ||
| 41 | use Org_Heigl\AuthLdap\Manager\Ldap; | ||
| 42 | |||
| 43 | class LdapTest extends TestCase | ||
| 44 | { | ||
| 45 | /** | ||
| 46 | * | ||
| 47 | * @dataProvider dpInstantiateLdapClass | ||
| 48 | * @param array $expected | ||
| 49 | * @param array $given | ||
| 50 | */ | ||
| 51 | public function testInstantiateLdapClass($ldapUri, $debug, $startTls) | ||
| 52 | { | ||
| 53 | $ldap = new Ldap(new LdapFactory(), LdapUri::fromString($ldapUri), $debug, $startTls); | ||
| 54 | self::assertInstanceOf(Ldap::class, $ldap); | ||
| 55 | } | ||
| 56 | |||
| 57 | /** | ||
| 58 | * @dataProvider dpExceptionsWhenInstantiatingLdapClass | ||
| 59 | * @param string $expected | ||
| 60 | */ | ||
| 61 | public function testExceptionsWhenInstantiatingLdapClass(string $expected) | ||
| 62 | { | ||
| 63 | self::expectException(Exception::class); | ||
| 64 | new Ldap(new LdapFactory(), LdapUri::fromString($expected)); | ||
| 65 | } | ||
| 66 | |||
| 67 | public function dpInstantiateLdapClass(): Generator | ||
| 68 | { | ||
| 69 | yield [ | ||
| 70 | 'ldap://uid=jondoe,cn=users,cn=example,c=org:secret@ldap.example.org/cn=example,c=org', | ||
| 71 | true, | ||
| 72 | false, | ||
| 73 | [ | ||
| 74 | 'username' => 'uid=jondoe,cn=users,cn=example,c=org', | ||
| 75 | 'password' => 'secret', | ||
| 76 | 'server' => 'ldap.example.org', | ||
| 77 | 'baseDn' => 'cn=example,c=org', | ||
| 78 | 'debug' => true, | ||
| 79 | ], | ||
| 80 | ]; | ||
| 81 | yield [ | ||
| 82 | 'ldap://uid=jondoe,cn=users,cn=example,c=org@ldap.example.org/cn=example,c=org', | ||
| 83 | true, | ||
| 84 | false, | ||
| 85 | [ | ||
| 86 | 'username' => 'uid=jondoe,cn=users,cn=example,c=org', | ||
| 87 | 'password' => '', | ||
| 88 | 'server' => 'ldap.example.org', | ||
| 89 | 'baseDn' => 'cn=example,c=org', | ||
| 90 | 'debug' => true, | ||
| 91 | ], | ||
| 92 | ]; | ||
| 93 | yield [ | ||
| 94 | 'ldap://ldap.example.org/cn=example,c=org', | ||
| 95 | true, | ||
| 96 | false, | ||
| 97 | [ | ||
| 98 | 'username' => 'anonymous', | ||
| 99 | 'password' => '', | ||
| 100 | 'server' => 'ldap.example.org', | ||
| 101 | 'baseDn' => 'cn=example,c=org', | ||
| 102 | 'debug' => true, | ||
| 103 | ], | ||
| 104 | ]; | ||
| 105 | // yield [ | ||
| 106 | // 'ldap://ldap.example.org', | ||
| 107 | // true, | ||
| 108 | // false, | ||
| 109 | // [ | ||
| 110 | // 'username' => 'anonymous', | ||
| 111 | // 'password' => '', | ||
| 112 | // 'server' => 'ldap.example.org', | ||
| 113 | // 'baseDn' => '', | ||
| 114 | // 'debug' => true | ||
| 115 | // ] | ||
| 116 | // ]; | ||
| 117 | yield [ | ||
| 118 | 'ldap://uid=jondoe,cn=users,cn=example,c=org:secret@ldap.example.org/cn=example,c=org', | ||
| 119 | false, | ||
| 120 | false, | ||
| 121 | [ | ||
| 122 | 'username' => 'uid=jondoe,cn=users,cn=example,c=org', | ||
| 123 | 'password' => 'secret', | ||
| 124 | 'server' => 'ldap.example.org', | ||
| 125 | 'baseDn' => 'cn=example,c=org', | ||
| 126 | 'debug' => false, | ||
| 127 | ], | ||
| 128 | ]; | ||
| 129 | yield [ | ||
| 130 | 'ldap://ldap.example.org/cn=test%20example,c=org', | ||
| 131 | false, | ||
| 132 | false, | ||
| 133 | [ | ||
| 134 | 'username' => 'anonymous', | ||
| 135 | 'password' => '', | ||
| 136 | 'server' => 'ldap.example.org', | ||
| 137 | 'baseDn' => 'cn=test example,c=org', | ||
| 138 | 'debug' => false, | ||
| 139 | ], | ||
| 140 | ]; | ||
| 141 | } | ||
| 142 | |||
| 143 | public function dpExceptionsWhenInstantiatingLdapClass(): Generator | ||
| 144 | { | ||
| 145 | yield ['ldap://ldap.example.org']; | ||
| 146 | yield ['ldap://foo:bar@/cn=example,c=org']; | ||
| 147 | yield ['http://ldap.example.org']; | ||
| 148 | yield ['fooBar']; | ||
| 149 | yield ['ldap://ldap.example.org/']; | ||
| 150 | yield ['()123üäö']; | ||
| 151 | } | ||
| 152 | |||
| 153 | public function testThatGroupMappingWorks() | ||
| 154 | { | ||
| 155 | $groups = [ | ||
| 156 | 'count' => 1, | ||
| 157 | 0 => [ | ||
| 158 | 'dn' => 'dn-1', | ||
| 159 | 'count' => 1, | ||
| 160 | 0 => 'group', | ||
| 161 | 'group' => [ | ||
| 162 | 'count' => 2, | ||
| 163 | 0 => 'angličtina@ff.cuni.cz', | ||
| 164 | 1 => 'literatura@ff.cuni.cz', | ||
| 165 | ], | ||
| 166 | ], | ||
| 167 | ]; | ||
| 168 | |||
| 169 | $grp = []; | ||
| 170 | for ($i = 0; $i < $groups ['count']; $i++) { | ||
| 171 | for ($k = 0; $k < $groups[$i][strtolower('group')]['count']; $k++) { | ||
| 172 | $grp[] = $groups[$i][strtolower('group')][$k]; | ||
| 173 | } | ||
| 174 | } | ||
| 175 | |||
| 176 | $this->assertEquals([ | ||
| 177 | 'angličtina@ff.cuni.cz', | ||
| 178 | 'literatura@ff.cuni.cz', | ||
| 179 | ], $grp); | ||
| 180 | |||
| 181 | $role = ''; | ||
| 182 | foreach ( | ||
| 183 | [ | ||
| 184 | 'testrole' => 'literatura@ff.cuni.cz,literatura@ff.cuni.cz', | ||
| 185 | ] as $key => $val | ||
| 186 | ) { | ||
| 187 | $currentGroup = explode(',', $val); | ||
| 188 | // Remove whitespaces around the group-ID | ||
| 189 | $currentGroup = array_map('trim', $currentGroup); | ||
| 190 | if (0 < count(array_intersect($currentGroup, $grp))) { | ||
| 191 | $role = $key; | ||
| 192 | break; | ||
| 193 | } | ||
| 194 | } | ||
| 195 | |||
| 196 | $this->assertEquals('testrole', $role); | ||
| 197 | } | ||
| 198 | } |
| 1 | <?php | ||
| 2 | |||
| 3 | namespace Org_Heigl\AuthLdapTest; | ||
| 4 | |||
| 5 | use Generator; | ||
| 6 | use Org_Heigl\AuthLdap\Exception\InvalidLdapUri; | ||
| 7 | use Org_Heigl\AuthLdap\LdapUri; | ||
| 8 | use PHPUnit\Framework\Assert; | ||
| 9 | use PHPUnit\Framework\TestCase; | ||
| 10 | |||
| 11 | use function getenv; | ||
| 12 | use function putenv; | ||
| 13 | |||
| 14 | class LdapUriTest extends TestCase | ||
| 15 | { | ||
| 16 | public function toStringProvider(): Generator | ||
| 17 | { | ||
| 18 | yield ['ldaps://foo:bar@foo.bar/baz', 'ldaps://foo.bar:636', 'foo', 'bar', 'baz']; | ||
| 19 | yield ['env:LDAP_URI', 'ldaps://foo.bar:636', 'foo', 'bar', 'baz', [ | ||
| 20 | 'LDAP_URI' => 'ldaps://foo:bar@foo.bar/baz', | ||
| 21 | ]]; | ||
| 22 | yield ['ldaps://foo:%env:LDAP_PASSWORD%@foo.bar/baz', 'ldaps://foo.bar:636', 'foo', 'bar', 'baz', [ | ||
| 23 | 'LDAP_PASSWORD' => 'bar', | ||
| 24 | ]]; | ||
| 25 | yield ['ldaps://foo:%env:LDAP_PASSWORD%@foo.bar/baz', 'ldaps://foo.bar:636', 'foo', 'ba r', 'baz', [ | ||
| 26 | 'LDAP_PASSWORD' => 'ba r', | ||
| 27 | ]]; | ||
| 28 | } | ||
| 29 | |||
| 30 | public function fromStringProvider(): Generator | ||
| 31 | { | ||
| 32 | yield ['ldaps://foo:bar@foo.bar/baz', false]; | ||
| 33 | yield ['env:LDAP_URI', false]; | ||
| 34 | yield ['foo:MyLdapUri', true]; | ||
| 35 | } | ||
| 36 | |||
| 37 | /** | ||
| 38 | * @dataProvider toStringProvider | ||
| 39 | */ | ||
| 40 | public function testToString(string $uri, string $result, $user, $password, $baseDn, array $env = []): void | ||
| 41 | { | ||
| 42 | foreach ($env as $key => $value) { | ||
| 43 | putenv("$key=$value"); | ||
| 44 | } | ||
| 45 | $ldapUri = LdapUri::fromString($uri); | ||
| 46 | Assert::assertSame($result, $ldapUri->toString()); | ||
| 47 | Assert::assertSame($user, $ldapUri->getUsername()); | ||
| 48 | Assert::assertSame($password, $ldapUri->getPassword()); | ||
| 49 | Assert::assertSame($baseDn, $ldapUri->getBaseDn()); | ||
| 50 | } | ||
| 51 | |||
| 52 | /** @dataProvider fromStringProvider */ | ||
| 53 | public function testFromString(string $uri, bool $failure = false): void | ||
| 54 | { | ||
| 55 | if ($failure) { | ||
| 56 | self::expectException(InvalidLdapUri::class); | ||
| 57 | } | ||
| 58 | $ldapUri = LdapUri::fromString($uri); | ||
| 59 | self::assertInstanceOf(LdapUri::class, $ldapUri); | ||
| 60 | } | ||
| 61 | |||
| 62 | public function testSettingLdapsWillSetCorrectPort(): void | ||
| 63 | { | ||
| 64 | $uri = LdapUri::fromString('ldaps://example.org/foo'); | ||
| 65 | |||
| 66 | Assert::assertSame('ldaps://example.org:636', $uri->toString()); | ||
| 67 | } | ||
| 68 | |||
| 69 | public function testSettingLdapWillSetCorrectPort(): void | ||
| 70 | { | ||
| 71 | $uri = LdapUri::fromString('ldap://example.org/foo'); | ||
| 72 | |||
| 73 | Assert::assertSame('ldap://example.org:389', $uri->toString()); | ||
| 74 | } | ||
| 75 | |||
| 76 | /** | ||
| 77 | * @dataProvider anonymousProvider | ||
| 78 | */ | ||
| 79 | public function testUriIsAnonymous(string $uri): void | ||
| 80 | { | ||
| 81 | $uri = LdapUri::fromString($uri); | ||
| 82 | Assert::assertTrue($uri->isAnonymous()); | ||
| 83 | } | ||
| 84 | |||
| 85 | public function anonymousProvider(): Generator | ||
| 86 | { | ||
| 87 | yield ['ldaps://test.example.com/dc=com']; | ||
| 88 | yield ['ldaps://foo@test.example.com/dc=com']; | ||
| 89 | yield ['ldaps://%20:password@test.example.com/dc=com']; | ||
| 90 | yield ['ldaps://anonymous:password@test.example.com/dc=com']; | ||
| 91 | } | ||
| 92 | |||
| 93 | public function testMissingSchemaThrows(): void | ||
| 94 | { | ||
| 95 | $this->expectException(InvalidLdapUri::class); | ||
| 96 | |||
| 97 | LdapUri::fromString('ldaps.example.com'); | ||
| 98 | } | ||
| 99 | |||
| 100 | public function testMWrongSchemaThrows(): void | ||
| 101 | { | ||
| 102 | $this->expectException(InvalidLdapUri::class); | ||
| 103 | |||
| 104 | LdapUri::fromString('environ://ldaps.example.com'); | ||
| 105 | } | ||
| 106 | |||
| 107 | public function testMissingHostThrows(): void | ||
| 108 | { | ||
| 109 | $this->expectException(InvalidLdapUri::class); | ||
| 110 | |||
| 111 | LdapUri::fromString('ldaps:/foo=bar'); | ||
| 112 | } | ||
| 113 | |||
| 114 | public function testgettingUriFromEnvironment(): void | ||
| 115 | { | ||
| 116 | putenv('URI=ldaps://example.com/foo'); | ||
| 117 | $uri = LdapUri::fromString('env:URI'); | ||
| 118 | |||
| 119 | Assert::assertSame('ldaps://example.com:636', (string) $uri); | ||
| 120 | Assert::assertSame('foo', $uri->getBaseDn()); | ||
| 121 | } | ||
| 122 | |||
| 123 | public function testgettingUriFromEmptyEnvironment(): void | ||
| 124 | { | ||
| 125 | putenv('URI'); | ||
| 126 | $this->expectException(InvalidLdapUri::class); | ||
| 127 | $uri = LdapUri::fromString('env:URI'); | ||
| 128 | } | ||
| 129 | } |
| 1 | <?php | ||
| 2 | |||
| 3 | /** | ||
| 4 | * Copyright (c) 2016-2016} Andreas Heigl<andreas@heigl.org> | ||
| 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| 6 | * of this software and associated documentation files (the "Software"), to deal | ||
| 7 | * in the Software without restriction, including without limitation the rights | ||
| 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| 9 | * copies of the Software, and to permit persons to whom the Software is | ||
| 10 | * furnished to do so, subject to the following conditions: | ||
| 11 | * The above copyright notice and this permission notice shall be included in | ||
| 12 | * all copies or substantial portions of the Software. | ||
| 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| 18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
| 19 | * THE SOFTWARE. | ||
| 20 | * | ||
| 21 | * @author Andreas Heigl<andreas@heigl.org> | ||
| 22 | * @copyright 2016-2016 Andreas Heigl | ||
| 23 | * @license http://www.opensource.org/licenses/mit-license.php MIT-License | ||
| 24 | * @version 0.0 | ||
| 25 | * @since 07.06.2016 | ||
| 26 | * @link http://github.com/heiglandreas/authLDAP | ||
| 27 | */ | ||
| 28 | |||
| 29 | namespace Org_Heigl\AuthLdapTest\Manager; | ||
| 30 | |||
| 31 | use Org_Heigl\AuthLdap\Exception\Error; | ||
| 32 | use Org_Heigl\AuthLdap\LdapList; | ||
| 33 | use Org_Heigl\AuthLdap\LdapUri; | ||
| 34 | use Org_Heigl\AuthLdap\Manager\Ldap; | ||
| 35 | use Org_Heigl\AuthLdap\Wrapper\Ldap as LdapWrapper; | ||
| 36 | use Org_Heigl\AuthLdap\Wrapper\LdapFactory; | ||
| 37 | use Org_Heigl\AuthLdap\Wrapper\LdapInterface; | ||
| 38 | use PHPUnit\Framework\Assert; | ||
| 39 | use PHPUnit\Framework\TestCase; | ||
| 40 | |||
| 41 | class LDAPBaseTest extends TestCase | ||
| 42 | { | ||
| 43 | private LdapFactory $factory; | ||
| 44 | |||
| 45 | private LdapInterface $wrapper; | ||
| 46 | |||
| 47 | public function setUp(): void | ||
| 48 | { | ||
| 49 | $this->wrapper = $this->getMockBuilder(LdapInterface::class)->getMock(); | ||
| 50 | $this->factory = $this->getMockBuilder(LdapFactory::class)->getMock(); | ||
| 51 | $this->factory->method('createFromLdapUri')->willReturn($this->wrapper); | ||
| 52 | $this->factory->method('escape')->willReturnCallback(function ($value, $ignore, $flags) { | ||
| 53 | return \Org_Heigl\AuthLdap\Wrapper\Ldap::escape($value, $ignore, $flags); | ||
| 54 | }); | ||
| 55 | } | ||
| 56 | |||
| 57 | /** | ||
| 58 | * @dataProvider bindingWithPasswordProvider | ||
| 59 | * @testdox Binding user $user with password $password using a filter $filter works | ||
| 60 | */ | ||
| 61 | public function testThatBindingWithPasswordWorks($user, $password, $filter, $uri) | ||
| 62 | { | ||
| 63 | $uri = LdapUri::fromString($uri); | ||
| 64 | $this->wrapper | ||
| 65 | ->method('bind') | ||
| 66 | ->willReturn(true); | ||
| 67 | |||
| 68 | $this->wrapper | ||
| 69 | ->expects($this->once()) | ||
| 70 | ->method('search') | ||
| 71 | ->with($uri->getBaseDn(), sprintf($filter, $user)); | ||
| 72 | |||
| 73 | $this->wrapper | ||
| 74 | ->method('getEntries') | ||
| 75 | ->willReturn(['count' => 1, 0 => ['dn' => 'foo']]); | ||
| 76 | |||
| 77 | $ldap = new Ldap($this->factory, $uri); | ||
| 78 | $this->assertTrue($ldap->authenticate($user, $password, $filter)); | ||
| 79 | } | ||
| 80 | |||
| 81 | public function bindingWithPasswordProvider() | ||
| 82 | { | ||
| 83 | return [ | ||
| 84 | [ | ||
| 85 | 'user3', | ||
| 86 | 'user!"', | ||
| 87 | 'uid=%s', | ||
| 88 | 'ldap://cn=admin,dc=example,dc=org:insecure@127.0.0.1:3389/dc=example,dc=org' | ||
| 89 | ], [ | ||
| 90 | // 'admin', | ||
| 91 | // 'insecure', | ||
| 92 | // 'cn=%s', | ||
| 93 | // 'ldap://cn=admin,dc=example,dc=org:insecure@127.0.0.1:3389/dc=example,dc=org' | ||
| 94 | // ], [ | ||
| 95 | 'user1', | ||
| 96 | 'user1', | ||
| 97 | 'uid=%s', | ||
| 98 | 'ldap://cn=admin,dc=example,dc=org:insecure@127.0.0.1:3389/dc=example,dc=org' | ||
| 99 | ], [ | ||
| 100 | 'user 4', | ||
| 101 | 'user!"', | ||
| 102 | 'uid=%s', | ||
| 103 | 'ldap://cn=admin,dc=example,dc=org:insecure@127.0.0.1:3389/dc=example,dc=org' | ||
| 104 | ], [ | ||
| 105 | 'user 5', | ||
| 106 | 'user!"', | ||
| 107 | 'uid=%s', | ||
| 108 | 'ldap://cn=admin,dc=example,dc=org:insecure@127.0.0.1:3389/dc=test%20space,dc=example,dc=org' | ||
| 109 | ], | ||
| 110 | ]; | ||
| 111 | } | ||
| 112 | |||
| 113 | /** | ||
| 114 | * @param $uri | ||
| 115 | * @dataProvider initialBindingToLdapServerWorksProvider | ||
| 116 | */ | ||
| 117 | public function testThatInitialBindingWorks($uri) | ||
| 118 | { | ||
| 119 | $this->wrapper | ||
| 120 | ->method('bind') | ||
| 121 | ->willReturn(true); | ||
| 122 | |||
| 123 | $ldap = new LDAP($this->factory, LdapUri::fromString($uri)); | ||
| 124 | $this->assertInstanceof(Ldap::class, $ldap->bind()); | ||
| 125 | } | ||
| 126 | |||
| 127 | /** | ||
| 128 | * @param $uri | ||
| 129 | * @dataProvider initialBindingToLdapServerWorksProvider | ||
| 130 | */ | ||
| 131 | public function testThatInitialBindingToMultipleLdapsWorks($uri) | ||
| 132 | { | ||
| 133 | $this->wrapper->expects($this->once()) | ||
| 134 | ->method('bind') | ||
| 135 | ->with('uid=user 5,dc=test space,dc=example,dc=org', 'user!"') | ||
| 136 | ->willReturn(true); | ||
| 137 | |||
| 138 | $list = new LdapList(); | ||
| 139 | $list->addLDAP(new LDAP($this->factory, LdapUri::fromString($uri))); | ||
| 140 | $this->assertTrue($list->bind()); | ||
| 141 | } | ||
| 142 | |||
| 143 | public function initialBindingToLdapServerWorksProvider() | ||
| 144 | { | ||
| 145 | return [ | ||
| 146 | ['ldap://uid=user%205,dc=test%20space,dc=example,dc=org:user!"' . | ||
| 147 | '@127.0.0.1:3389/dc=test%20space,dc=example,dc=org'], | ||
| 148 | ]; | ||
| 149 | } | ||
| 150 | |||
| 151 | /** | ||
| 152 | * @dataProvider provideUnescapedData | ||
| 153 | */ | ||
| 154 | public function testThatPassedDataIsEscaped($unescaped, $escaped): void | ||
| 155 | { | ||
| 156 | $ldap = new LDAP($this->factory, LdapUri::fromString( | ||
| 157 | 'ldap://cn=admin,dc=example,dc=org:insecure@127.0.0.1:3389/dc=example,dc=org' | ||
| 158 | )); | ||
| 159 | |||
| 160 | $this->wrapper->expects($this->exactly(2)) | ||
| 161 | ->method('bind') | ||
| 162 | ->withConsecutive( | ||
| 163 | ['cn=admin,dc=example,dc=org', 'insecure'], | ||
| 164 | ['foo', 'password'], | ||
| 165 | ) | ||
| 166 | ->willReturnOnConsecutiveCalls(true, true); | ||
| 167 | $this->wrapper->expects($this->once())->method('search')->with( | ||
| 168 | 'dc=example,dc=org', | ||
| 169 | $escaped, | ||
| 170 | ['uid'], | ||
| 171 | ); | ||
| 172 | $this->wrapper->method('getEntries')->willReturn(['count' => 1, 0 => ['dn' => 'foo']]); | ||
| 173 | |||
| 174 | $ldap->authenticate($unescaped, 'password'); | ||
| 175 | } | ||
| 176 | |||
| 177 | public function provideUnescapedData(): array | ||
| 178 | { | ||
| 179 | return [ | ||
| 180 | ['\’foobar', '(uid=\5c’foobar)'], | ||
| 181 | ['XXX;(&(uid=Admin)(userPassword=A*))', '(uid=XXX;\28&\28uid=Admin\29\28userPassword=A\2a\29\29)'], | ||
| 182 | ]; | ||
| 183 | } | ||
| 184 | |||
| 185 | |||
| 186 | public function testSettingStartTls(): void | ||
| 187 | { | ||
| 188 | $ldap = new Ldap($this->factory, LdapUri::fromString('ldap://example.com/foo=bar'), true); | ||
| 189 | |||
| 190 | $this->wrapper->expects($this->once())->method('startTls'); | ||
| 191 | $this->wrapper->method('bind')->willReturn(true); | ||
| 192 | |||
| 193 | $ldap->bind(); | ||
| 194 | } | ||
| 195 | |||
| 196 | |||
| 197 | public function testUnsettingConnectionBeforeBinding(): void | ||
| 198 | { | ||
| 199 | $ldap = new Ldap($this->factory, LdapUri::fromString('ldap://example.com/foo=bar'), true); | ||
| 200 | |||
| 201 | $this->wrapper->method('bind')->willReturn(true); | ||
| 202 | $this->wrapper->expects($this->once())->method('unbind'); | ||
| 203 | |||
| 204 | $ldap->connect(); | ||
| 205 | $ldap->disconnect(); | ||
| 206 | } | ||
| 207 | |||
| 208 | public function testErrorIsThrownOnUnsuccessfullBInd(): void | ||
| 209 | { | ||
| 210 | $ldap = new Ldap($this->factory, LdapUri::fromString('ldap://example.com/foo=bar'), true); | ||
| 211 | |||
| 212 | $this->wrapper->method('bind')->willReturn(false); | ||
| 213 | $this->expectException(Error::class); | ||
| 214 | |||
| 215 | $ldap->bind(); | ||
| 216 | } | ||
| 217 | |||
| 218 | public function testFailingSearchThrowsError(): void | ||
| 219 | { | ||
| 220 | $ldap = new Ldap($this->factory, LdapUri::fromString('ldap://example.com/foo=bar'), true); | ||
| 221 | |||
| 222 | $this->wrapper->method('bind')->willReturn(true); | ||
| 223 | $this->wrapper->method('search')->willReturn(false); | ||
| 224 | |||
| 225 | $this->expectException(Error::class); | ||
| 226 | $this->expectExceptionMessage('no result found'); | ||
| 227 | |||
| 228 | $ldap->bind(); | ||
| 229 | $ldap->search('uid=foo'); | ||
| 230 | } | ||
| 231 | |||
| 232 | public function testFailingSearchResultFetchingThrowsError(): void | ||
| 233 | { | ||
| 234 | $ldap = new Ldap($this->factory, LdapUri::fromString('ldap://example.com/foo=bar'), true); | ||
| 235 | |||
| 236 | $this->wrapper->method('bind')->willReturn(true); | ||
| 237 | $this->wrapper->method('search')->willReturn(true); | ||
| 238 | $this->wrapper->method('getEntries')->willReturn(false); | ||
| 239 | |||
| 240 | $this->expectException(Error::class); | ||
| 241 | $this->expectExceptionMessage('invalid results found'); | ||
| 242 | |||
| 243 | $ldap->bind(); | ||
| 244 | $ldap->search('uid=foo'); | ||
| 245 | } | ||
| 246 | |||
| 247 | public function testSearchingWithoutBindingThrowsError(): void | ||
| 248 | { | ||
| 249 | $ldap = new Ldap($this->factory, LdapUri::fromString('ldap://example.com/foo=bar'), true); | ||
| 250 | |||
| 251 | $this->expectException(Error::class); | ||
| 252 | $this->expectExceptionMessage('No resource handle available'); | ||
| 253 | |||
| 254 | $ldap->search('uid=foo'); | ||
| 255 | } | ||
| 256 | |||
| 257 | public function testAuthenticatingFailsWithNoSearchResults(): void | ||
| 258 | { | ||
| 259 | $ldap = new Ldap($this->factory, LdapUri::fromString('ldap://example.com/foo=bar'), true); | ||
| 260 | |||
| 261 | $this->wrapper->method('bind')->willReturn(true); | ||
| 262 | $this->wrapper->method('search')->willReturn(true); | ||
| 263 | $this->wrapper->method('getEntries')->willReturn(['count' => 0]); | ||
| 264 | |||
| 265 | $ldap->bind(); | ||
| 266 | Assert::assertFalse($ldap->authenticate('foo', 'bar')); | ||
| 267 | } | ||
| 268 | } |
| 1 | <?php | ||
| 2 | |||
| 3 | /** | ||
| 4 | * Copyright Andreas Heigl <andreas@heigl.org> | ||
| 5 | * | ||
| 6 | * Licenses under the MIT-license. For details see the included file LICENSE.md | ||
| 7 | */ | ||
| 8 | |||
| 9 | namespace Org_Heigl\AuthLdapTest; | ||
| 10 | |||
| 11 | use Org_Heigl\AuthLdap\UserRoleHandler; | ||
| 12 | use WorDBless\BaseTestCase; | ||
| 13 | use WP_User; | ||
| 14 | |||
| 15 | class UserRoleHandlerTest extends BaseTestCase | ||
| 16 | { | ||
| 17 | public function testUserRolesAreAssignedAsExpected() : void | ||
| 18 | { | ||
| 19 | $user = new WP_User(1); | ||
| 20 | |||
| 21 | $handler = new UserRoleHandler(); | ||
| 22 | |||
| 23 | $handler->addRolesToUser($user, ['author', 'user']); | ||
| 24 | |||
| 25 | self::assertEquals(['author'], $user->roles); | ||
| 26 | } | ||
| 27 | |||
| 28 | public function testEqualUserRolesAreEasy() : void | ||
| 29 | { | ||
| 30 | $user = new WP_User(1); | ||
| 31 | $user->add_role('administrator'); | ||
| 32 | $user->add_role('author'); | ||
| 33 | |||
| 34 | $handler = new UserRoleHandler(); | ||
| 35 | |||
| 36 | $handler->addRolesToUser($user, ['administrator', 'author']); | ||
| 37 | |||
| 38 | self::assertEquals(['administrator', 'author'], $user->roles); | ||
| 39 | } | ||
| 40 | |||
| 41 | public function testUserRolesAreNotAssignedWhenUserAlreadyHasRole() : void | ||
| 42 | { | ||
| 43 | $user = new WP_User(1); | ||
| 44 | $user->add_role('administrator'); | ||
| 45 | $user->add_role('author'); | ||
| 46 | |||
| 47 | $handler = new UserRoleHandler(); | ||
| 48 | |||
| 49 | $handler->addRolesToUser($user, ['author', 'editor']); | ||
| 50 | |||
| 51 | self::assertEquals(['author', 'editor'], $user->roles); | ||
| 52 | } | ||
| 53 | |||
| 54 | public function testEmptyRolesAreIgnored() : void | ||
| 55 | { | ||
| 56 | $user = new WP_User(1); | ||
| 57 | $user->add_role('administrator'); | ||
| 58 | |||
| 59 | $handler = new UserRoleHandler(); | ||
| 60 | $handler->addRolesToUser($user, []); | ||
| 61 | |||
| 62 | self::assertEquals(['administrator'], $user->roles); | ||
| 63 | } | ||
| 64 | } |
wp-content/plugins/authLdap/view/admin.phtml
0 → 100644
This diff is collapsed.
Click to expand it.
| 1 | 1.4.20 | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | { | ||
| 2 | "name" : "lampo/wp-auth-ldap", | ||
| 3 | "type" : "wordpress-plugin", | ||
| 4 | "description": "Fork of http://github.com/heiglandreas/authLdap, moves settings to defined constants.", | ||
| 5 | "keywords": ["ldap","authenticate", "auth", "wordpress"], | ||
| 6 | "homepage": "http://github.com/lampo/wp-auth-ldap", | ||
| 7 | "license": "MIT", | ||
| 8 | "authors": [{ | ||
| 9 | "name": "Andreas Heigl", | ||
| 10 | "email": "andreas@heigl.org", | ||
| 11 | "homepage": "http://andreas.heigl.org", | ||
| 12 | "role": "Developer" | ||
| 13 | },{ | ||
| 14 | "name": "Micah Flatt", | ||
| 15 | "email": "mflatt@flattware.net", | ||
| 16 | "role": "Developer" | ||
| 17 | }], | ||
| 18 | "require" : { | ||
| 19 | "php": ">=5.4", | ||
| 20 | "composer/installers": "~1.0" | ||
| 21 | }, | ||
| 22 | "autoload" : { | ||
| 23 | "psr-4" : { | ||
| 24 | "Org_Heigl\\AuthLdap\\" : "./" | ||
| 25 | } | ||
| 26 | } | ||
| 27 | } |
| 1 | <?php | ||
| 2 | /** | ||
| 3 | * $Id: ldap.php 381646 2011-05-06 09:37:31Z heiglandreas $ | ||
| 4 | * | ||
| 5 | * authLdap - Authenticate Wordpress against an LDAP-Backend. | ||
| 6 | * Copyright (c) 2008 Andreas Heigl<andreas@heigl.org> | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or | ||
| 9 | * modify it under the terms of the GNU General Public License | ||
| 10 | * as published by the Free Software Foundation; either version 2 | ||
| 11 | * of the License, or (at your option) any later version. | ||
| 12 | * | ||
| 13 | * This program is distributed in the hope that it will be useful, | ||
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 16 | * GNU General Public License for more details. | ||
| 17 | * | ||
| 18 | * You should have received a copy of the GNU General Public License | ||
| 19 | * along with this program; if not, write to the Free Software | ||
| 20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
| 21 | * | ||
| 22 | * This file handles the basic LDAP-Tasks | ||
| 23 | * | ||
| 24 | * @author Andreas Heigl<andreas@heigl.org> | ||
| 25 | * @package authLdap | ||
| 26 | * @category authLdap | ||
| 27 | * @since 2008 | ||
| 28 | */ | ||
| 29 | namespace Org_Heigl\AuthLdap; | ||
| 30 | |||
| 31 | use Exception; | ||
| 32 | |||
| 33 | class LDAP | ||
| 34 | { | ||
| 35 | private $_server = ''; | ||
| 36 | |||
| 37 | private $_scheme = 'ldap'; | ||
| 38 | |||
| 39 | private $_port = 389; | ||
| 40 | |||
| 41 | private $_baseDn = ''; | ||
| 42 | |||
| 43 | private $_debug = false; | ||
| 44 | /** | ||
| 45 | * This property contains the connection handle to the ldap-server | ||
| 46 | * | ||
| 47 | * @var Ressource | ||
| 48 | */ | ||
| 49 | private $_ch = null; | ||
| 50 | |||
| 51 | private $_username = ''; | ||
| 52 | |||
| 53 | private $_password = ''; | ||
| 54 | |||
| 55 | private $_starttls = false; | ||
| 56 | |||
| 57 | public function __construct($URI, $debug = false, $starttls = false) | ||
| 58 | { | ||
| 59 | $this->_debug=$debug; | ||
| 60 | $array = parse_url($URI); | ||
| 61 | if (! is_array($array)) { | ||
| 62 | throw new Exception($URI . ' seems not to be a valid URI'); | ||
| 63 | } | ||
| 64 | $url = array_map(function ($item) { return urldecode($item); }, $array); | ||
| 65 | if (false === $url) { | ||
| 66 | throw new Exception($URI . ' is an invalid URL'); | ||
| 67 | } | ||
| 68 | if (! isset ( $url['scheme'] )) { | ||
| 69 | throw new Exception($URI . ' does not provide a scheme'); | ||
| 70 | } | ||
| 71 | if (0 !== strpos($url['scheme'], 'ldap')) { | ||
| 72 | throw new Exception($URI . ' is an invalid LDAP-URI'); | ||
| 73 | } | ||
| 74 | if (! isset ( $url['host'] )) { | ||
| 75 | throw new Exception($URI . ' does not provide a server'); | ||
| 76 | } | ||
| 77 | if (! isset ( $url['path'] )) { | ||
| 78 | throw new Exception($URI . ' does not provide a search-base'); | ||
| 79 | } | ||
| 80 | if (1 == strlen($url['path'])) { | ||
| 81 | throw new Exception($URI . ' does not provide a valid search-base'); | ||
| 82 | } | ||
| 83 | $this -> _server = $url['host']; | ||
| 84 | $this -> _scheme = $url['scheme']; | ||
| 85 | $this -> _baseDn = substr($url['path'], 1); | ||
| 86 | if (isset ( $url['user'] )) { | ||
| 87 | $this -> _username = $url['user']; | ||
| 88 | } | ||
| 89 | if ('' == trim($this -> _username)) { | ||
| 90 | $this -> _username = 'anonymous'; | ||
| 91 | } | ||
| 92 | if (isset ( $url['pass'] )) { | ||
| 93 | $this -> _password = $url['pass']; | ||
| 94 | } | ||
| 95 | if (isset ( $url['port'] )) { | ||
| 96 | $this -> _port = $url['port']; | ||
| 97 | } | ||
| 98 | $this->_starttls = $starttls; | ||
| 99 | } | ||
| 100 | |||
| 101 | /** | ||
| 102 | * Connect to the given LDAP-Server | ||
| 103 | * | ||
| 104 | * @return LDAP | ||
| 105 | * @throws AuthLdap_Exception | ||
| 106 | */ | ||
| 107 | public function connect() | ||
| 108 | { | ||
| 109 | $this -> disconnect(); | ||
| 110 | if ('ldaps' == $this->_scheme && 389 == $this->_port) { | ||
| 111 | $this->_port = 636; | ||
| 112 | } | ||
| 113 | |||
| 114 | $this->_ch = @ldap_connect($this->_scheme . '://' . $this->_server . ':' . $this -> _port); | ||
| 115 | if (! $this->_ch) { | ||
| 116 | throw new AuthLDAP_Exception('Could not connect to the server'); | ||
| 117 | } | ||
| 118 | ldap_set_option($this->_ch, LDAP_OPT_PROTOCOL_VERSION, 3); | ||
| 119 | ldap_set_option($this->_ch, LDAP_OPT_REFERRALS, 0); | ||
| 120 | //if configured try to upgrade encryption to tls for ldap connections | ||
| 121 | if ($this->_starttls) { | ||
| 122 | ldap_start_tls($this->_ch); | ||
| 123 | } | ||
| 124 | return $this; | ||
| 125 | } | ||
| 126 | |||
| 127 | /** | ||
| 128 | * Disconnect from a resource if one is available | ||
| 129 | * | ||
| 130 | * @return LDAP | ||
| 131 | */ | ||
| 132 | public function disconnect() | ||
| 133 | { | ||
| 134 | if (is_resource($this->_ch)) { | ||
| 135 | @ldap_unbind($this->_ch); | ||
| 136 | } | ||
| 137 | $this->_ch = null; | ||
| 138 | return $this; | ||
| 139 | } | ||
| 140 | |||
| 141 | /** | ||
| 142 | * Bind to an LDAP-Server with the given credentials | ||
| 143 | * | ||
| 144 | * @return LDAP | ||
| 145 | * @throw AuthLdap_Exception | ||
| 146 | */ | ||
| 147 | public function bind() | ||
| 148 | { | ||
| 149 | if (! $this->_ch) { | ||
| 150 | $this->connect(); | ||
| 151 | } | ||
| 152 | if (! is_resource($this->_ch)) { | ||
| 153 | throw new AuthLDAP_Exception('No Resource-handle given'); | ||
| 154 | } | ||
| 155 | $bind = false; | ||
| 156 | if (( ( $this->_username ) | ||
| 157 | && ( $this->_username != 'anonymous') ) | ||
| 158 | && ( $this->_password != '' ) ) { | ||
| 159 | $bind = @ldap_bind($this->_ch, $this->_username, $this->_password); | ||
| 160 | } else { | ||
| 161 | $bind = @ldap_bind($this->_ch); | ||
| 162 | } | ||
| 163 | if (! $bind) { | ||
| 164 | throw new AuthLDAP_Exception('bind was not successfull: ' . ldap_error($this->_ch)); | ||
| 165 | } | ||
| 166 | return $this; | ||
| 167 | } | ||
| 168 | |||
| 169 | public function getErrorNumber() | ||
| 170 | { | ||
| 171 | return @ldap_errno($this->_ch); | ||
| 172 | } | ||
| 173 | |||
| 174 | public function getErrorText() | ||
| 175 | { | ||
| 176 | return @ldap_error($this->_ch); | ||
| 177 | } | ||
| 178 | |||
| 179 | /** | ||
| 180 | * This method does the actual ldap-serch. | ||
| 181 | * | ||
| 182 | * This is using the filter <var>$filter</var> for retrieving the attributes | ||
| 183 | * <var>$attributes</var> | ||
| 184 | * | ||
| 185 | * | ||
| 186 | * @param string $filter | ||
| 187 | * @param array $attributes | ||
| 188 | * @return array | ||
| 189 | */ | ||
| 190 | public function search($filter, $attributes = array('uid')) | ||
| 191 | { | ||
| 192 | if (! is_Resource($this->_ch)) { | ||
| 193 | throw new AuthLDAP_Exception('No resource handle avbailable'); | ||
| 194 | } | ||
| 195 | $result = @ldap_search($this->_ch, $this->_baseDn, $filter, $attributes); | ||
| 196 | if ($result === false) { | ||
| 197 | throw new AuthLDAP_Exception('no result found'); | ||
| 198 | } | ||
| 199 | $this->_info = @ldap_get_entries($this->_ch, $result); | ||
| 200 | if ($this->_info === false) { | ||
| 201 | throw new AuthLDAP_Exception('invalid results found'); | ||
| 202 | } | ||
| 203 | return $this -> _info; | ||
| 204 | } | ||
| 205 | |||
| 206 | /** | ||
| 207 | * This method sets debugging to ON | ||
| 208 | */ | ||
| 209 | public function debugOn() | ||
| 210 | { | ||
| 211 | $this->_debug = true; | ||
| 212 | return $this; | ||
| 213 | } | ||
| 214 | |||
| 215 | /** | ||
| 216 | * This method sets debugging to OFF | ||
| 217 | */ | ||
| 218 | public function debugOff() | ||
| 219 | { | ||
| 220 | $this->_debug = false; | ||
| 221 | return $this; | ||
| 222 | } | ||
| 223 | |||
| 224 | /** | ||
| 225 | * This method authenticates the user <var>$username</var> using the | ||
| 226 | * password <var>$password</var> | ||
| 227 | * | ||
| 228 | * @param string $username | ||
| 229 | * @param string $password | ||
| 230 | * @param string $filter OPTIONAL This parameter defines the Filter to be used | ||
| 231 | * when searchin for the username. This MUST contain the string '%s' which | ||
| 232 | * will be replaced by the vaue given in <var>$username</var> | ||
| 233 | * @return boolean true or false depending on successfull authentication or not | ||
| 234 | */ | ||
| 235 | public function authenticate($username, $password, $filter = '(uid=%s)') | ||
| 236 | { | ||
| 237 | //return true; | ||
| 238 | $this->connect(); | ||
| 239 | $this->bind(); | ||
| 240 | $res = $this->search(sprintf($filter, $username)); | ||
| 241 | if (! $res || ! is_array($res) || ( $res ['count'] != 1 )) { | ||
| 242 | return false; | ||
| 243 | } | ||
| 244 | $dn = $res[0]['dn']; | ||
| 245 | if ($username && $password) { | ||
| 246 | if (@ldap_bind($this->_ch, $dn, $password)) { | ||
| 247 | return true; | ||
| 248 | } | ||
| 249 | } | ||
| 250 | return false; | ||
| 251 | } | ||
| 252 | /** | ||
| 253 | * $this method loggs errors if debugging is set to ON | ||
| 254 | */ | ||
| 255 | public function logError() | ||
| 256 | { | ||
| 257 | if ($this->_debug) { | ||
| 258 | $_v = debug_backtrace(); | ||
| 259 | throw new AuthLDAP_Exception('[LDAP_ERROR]' . ldap_errno($this->_ch) . ':' . ldap_error($this->_ch), $_v[0]['line']); | ||
| 260 | } | ||
| 261 | } | ||
| 262 | } | ||
| 263 | |||
| 264 | class AuthLDAP_Exception extends Exception | ||
| 265 | { | ||
| 266 | public function __construct($message, $line = null) | ||
| 267 | { | ||
| 268 | parent :: __construct($message); | ||
| 269 | if ($line) { | ||
| 270 | $this -> line = $line; | ||
| 271 | } | ||
| 272 | } | ||
| 273 | } |
This diff is collapsed.
Click to expand it.
-
Please register or sign in to post a comment