Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEATURE] Add Further Tests #7

Draft
wants to merge 25 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/coding-standards.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,5 @@ jobs:
uses: "ramsey/composer-install@v1"

- name: "Run PHP_CodeSniffer"
run: "vendor/bin/phpcs -q --no-colors --report=checkstyle | cs2pr"
run: |
vendor/bin/phpcs -q --no-colors --report=checkstyle | cs2pr
39 changes: 34 additions & 5 deletions .github/workflows/continuous-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,18 +50,33 @@ jobs:

services:
ldap:
image: bitnami/openldap
image: bitnami/openldap:latest
ports:
- 3389:3389
- 1389:1389
- 1636:1636
env:
LDAP_ADMIN_USERNAME: admin
LDAP_ADMIN_PASSWORD: a_great_password
LDAP_ROOT: dc=local,dc=com
LDAP_PORT_NUMBER: 3389
LDAP_PORT_NUMBER: 1389
LDAP_USERS: a
LDAP_PASSWORDS: a
LDAP_ENABLE_TLS: yes
LDAP_LDAPS_PORT_NUMBER: 1636
LDAP_TLS_VERIFY_CLIENT: try
LDAP_TLS_CERT_FILE: /opt/bitnami/openldap/certs/openldap.crt
LDAP_TLS_KEY_FILE: /opt/bitnami/openldap/certs/openldap.key
LDAP_TLS_CA_FILE: /opt/bitnami/openldap/certs/openldapCA.crt
volumes:
- ${{ github.workspace }}/Tests/certs:/opt/bitnami/openldap/certs
options: --name=ldaprecord

steps:
# Required as ./Tests/certs is created during ldap service build.
- name: "Make current user owner of workspace"
run: |
sudo chown -R $USER:$USER ${{ github.workspace }}

- name: "Checkout"
uses: "actions/checkout@v2"

Expand All @@ -73,17 +88,30 @@ jobs:
php-version: "${{ matrix.php-version }}"
ini-values: "zend.assertions=1"

- name: "Generate certificates"
run: |
composer generate-certs

- name: "Restart Docker"
run: |
docker restart ldaprecord

- name: "Validate composer files"
run: "composer validate --strict"
run: |
composer validate --strict

- name: "Cache dependencies installed with composer"
uses: "actions/cache@v2"
with:
path: "~/.composer/cache"
key: php-${{ matrix.php-version }}-symfony-${{ matrix.symfony-require }}-composer-locked-${{ hashFiles('composer.lock') }}
restore-keys: |
php-${{ matrix.php-version }}-symfony-${{ matrix.symfony-require }}-composer-locked-${{ hashFiles('composer.lock') }}
php-${{ matrix.php-version }}-symfony-${{ matrix.symfony-require }}-composer-locked-
php-${{ matrix.php-version }}-symfony-${{ matrix.symfony-require }}
php-${{ matrix.php-version }}-symfony-
php-${{ matrix.php-version }}-
php-

- name: "Install dependencies with composer"
env:
Expand All @@ -93,4 +121,5 @@ jobs:
composer update --no-interaction --no-progress ${{ matrix.composer-flags }}

- name: "Run PHPUnit"
run: "vendor/bin/phpunit"
run: |
composer phpunit
6 changes: 4 additions & 2 deletions .github/workflows/static-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ jobs:
uses: "ramsey/composer-install@v1"

- name: "Run a static analysis with phpstan/phpstan"
run: "vendor/bin/phpstan analyse"
run: |
vendor/bin/phpstan analyse

- name: "Run a static analysis with vimeo/psalm"
run: "vendor/bin/psalm --output-format=github"
run: |
vendor/bin/psalm --output-format=github
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,8 @@ package.tar
/.psalm/
/.idea/
/.phpcs-cache
#/Tests/certs/*.crt
/Tests/certs/*.csr
#/Tests/certs/*.key
/Tests/certs/*.srl

1 change: 1 addition & 0 deletions DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public function getConfigTreeBuilder(): TreeBuilder
->defaultFalse()
->end()
->arrayNode('options')
->useAttributeAsKey('name')
->arrayPrototype()
->children()
->scalarNode('name')->end()
Expand Down
130 changes: 108 additions & 22 deletions Tests/DependencyInjection/Iter8LdapRecordExtensionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,30 +29,39 @@ public function test_load_empty_configuration(): void
{
$this->expectException(InvalidConfigurationException::class);

$container = $this->createContainer();
$container->registerExtension(new Iter8LdapRecordExtension());
$container->loadFromExtension('iter8_ldap_record');
$container->compile();
$this->createContainerWithConfig([]);
}

public function test_load_valid_configuration(): void
{
$container = $this->createContainer();
$container->registerExtension(new Iter8LdapRecordExtension());
$container->loadFromExtension('iter8_ldap_record', $this->baseConfig());
$container->compile();
$ldapConfig = $this->getLdapConfig();

$config = \array_merge(
$this->baseConfig(),
[
'hosts' => [$ldapConfig['host']],
'port' => $ldapConfig['port'],
]
);

$container = $this->createContainerWithConfig($config);

self::assertTrue($container->getDefinition('iter8_ldap_record.connection')->isPublic());
}

public function test_is_connected_with_auto_connect_disabled(): void
{
$this->getLdapConfig();
$ldapConfig = $this->getLdapConfig();

$container = $this->createContainer();
$container->registerExtension(new Iter8LdapRecordExtension());
$container->loadFromExtension('iter8_ldap_record', $this->baseConfig());
$container->compile();
$config = \array_merge(
$this->baseConfig(),
[
'hosts' => [$ldapConfig['host']],
'port' => $ldapConfig['port'],
]
);

$container = $this->createContainerWithConfig($config);

/** @var Connection $connection */
$connection = $container->get('iter8_ldap_record.connection');
Expand All @@ -62,35 +71,112 @@ public function test_is_connected_with_auto_connect_disabled(): void

public function test_is_connected_with_auto_connect_enabled(): void
{
$this->getLdapConfig();
$ldapConfig = $this->getLdapConfig();

$config = array_merge(
$config = \array_merge(
$this->baseConfig(),
['auto_connect' => true]
[
'hosts' => [$ldapConfig['host']],
'port' => $ldapConfig['port'],
'auto_connect' => true,
]
);

$container = $this->createContainer();
$container->registerExtension(new Iter8LdapRecordExtension());
$container->loadFromExtension('iter8_ldap_record', $config);
$container->compile();
$container = $this->createContainerWithConfig($config);

/** @var Connection $connection */
$connection = $container->get('iter8_ldap_record.connection');

self::assertTrue($connection->isConnected());
}

public function test_manual_connect_with_unsecured_connection(): void
{
$ldapConfig = $this->getLdapConfig();

$config = \array_merge(
$this->baseConfig(),
[
'hosts' => [$ldapConfig['host']],
'port' => $ldapConfig['port'],
]
);

$container = $this->createContainerWithConfig($config);

/** @var Connection $connection */
$connection = $container->get('iter8_ldap_record.connection');

$connection->connect();

self::assertTrue($connection->isConnected());
}

public function test_manual_connect_with_tls_connection(): void
{
$ldapConfig = $this->getLdapsConfig();

$config = \array_merge(
$this->baseConfig(),
[
'hosts' => [$ldapConfig['host']],
'port' => $ldapConfig['port'],
'use_tls' => true,
]
);

$container = $this->createContainerWithConfig($config);

/** @var Connection $connection */
$connection = $container->get('iter8_ldap_record.connection');

$connection->connect();

self::assertTrue($connection->isConnected());
}

public function test_can_find_user(): void
{
$ldapConfig = $this->getLdapConfig();

$config = \array_merge(
$this->baseConfig(),
[
'hosts' => [$ldapConfig['host']],
'port' => $ldapConfig['port'],
]
);

$container = $this->createContainerWithConfig($config);

/** @var Connection $connection */
$connection = $container->get('iter8_ldap_record.connection');

$results = $connection->query()->where('cn', '=', 'a')->get();

dump($results);
self::assertNotEmpty($results);
}

private function baseConfig(): array
{
return [
'hosts' => ['localhost'],
'base_dn' => 'dc=local,dc=com',
'username' => 'cn=admin,dc=local,dc=com',
'password' => 'a_great_password',
'port' => 3389,
];
}

private function createContainerWithConfig(array $config): ContainerBuilder
{
$container = $this->createContainer();
$container->registerExtension(new Iter8LdapRecordExtension());
$container->loadFromExtension('iter8_ldap_record', $config);
$container->compile();

return $container;
}

private function createContainer(): ContainerBuilder
{
return new ContainerBuilder(new ParameterBag([
Expand Down
38 changes: 37 additions & 1 deletion Tests/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@

use PHPUnit\Framework\TestCase as PHPUnitTestCase;

/**
* @see https://github.com/symfony/symfony/blob/89fedfa/src/Symfony/Component/Ldap/Tests/LdapTestCase.php
*/
class TestCase extends PHPUnitTestCase
{
protected function getLdapConfig(): array
Expand All @@ -22,7 +25,40 @@ protected function getLdapConfig(): array

return [
'host' => getenv('LDAP_HOST'),
'port' => getenv('LDAP_PORT'),
'port' => (int) getenv('LDAP_PORT'),
];
}

protected function getLdapsConfig(): array
{
putenv('TLS_REQCERT=allow');

// @ldap_set_option(null, \LDAP_OPT_DEBUG_LEVEL, 7);
@ldap_set_option(null, \LDAP_OPT_X_TLS_REQUIRE_CERT, \LDAP_OPT_X_TLS_ALLOW);
/** @var resource|null $h */
$h = @ldap_connect((string) getenv('LDAP_HOST'), (int) getenv('LDAPS_PORT'));
@ldap_set_option($h, \LDAP_OPT_PROTOCOL_VERSION, 3);
@ldap_set_option($h, \LDAP_OPT_REFERRALS, 0);
if (\is_resource($h)) {
@ldap_get_option($h, \LDAP_OPT_DIAGNOSTIC_MESSAGE, $extendedError);
@ldap_start_tls($h);
}

if (!\is_resource($h) || !@ldap_bind($h)) {
// dump(@ldap_error($h));
// dump($extendedError);
self::markTestSkipped(\sprintf(
'No server is listening on LDAP_HOST:LDAPS_PORT (%s:%s)',
getenv('LDAP_HOST'),
getenv('LDAPS_PORT')
));
}

ldap_unbind($h);

return [
'host' => getenv('LDAP_HOST'),
'port' => (int) getenv('LDAPS_PORT'),
];
}
}
25 changes: 25 additions & 0 deletions Tests/certs/generate.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/usr/bin/env bash

set -e

SCRIPT_PATH=$(dirname "$(realpath "$0")")

# Create a root CA signing key.
openssl genrsa -out "${SCRIPT_PATH}/openldapCA.key" 4096

# Now create and self-sign the root CA certificate.
openssl req -x509 -new -nodes -key "${SCRIPT_PATH}/openldapCA.key" -sha256 -days 3650 -subj "/CN=localhostCA" -out "${SCRIPT_PATH}/openldapCA.crt"

# Generate the LDAP server key.
openssl genrsa -out "${SCRIPT_PATH}/openldap.key" 2048

# Now create the CSR for the LDAP server certificate so we can sign it with our root CA.
openssl req -new -sha256 -key "${SCRIPT_PATH}/openldap.key" -subj "/CN=localhost" -out "${SCRIPT_PATH}/openldap.csr"

# Finally, sign the LDAP server CSR with our root CA so it's ready to use.
openssl x509 -req -in "${SCRIPT_PATH}/openldap.csr" -CA "${SCRIPT_PATH}/openldapCA.crt" -CAkey "${SCRIPT_PATH}/openldapCA.key" -CAcreateserial -out "${SCRIPT_PATH}/openldap.crt" -sha256 -days 3650

# Remove the CSR as it's no longer needed.
rm "${SCRIPT_PATH}/openldap.csr"

exit 0
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
"phpstan": "phpstan analyze",
"phpstan-max": "@phpstan --level=max",
"phpunit": "phpunit",
"psalm": "psalm --show-info=true"
"psalm": "psalm --show-info=true",
"generate-certs": "./Tests/certs/generate.sh"
}
}
Loading