Skip to content

Commit

Permalink
Shifting metadata config into the site itself (#5)
Browse files Browse the repository at this point in the history
Remote SPs can now be configured internally without having to set environment variables or restart the service.
Custom users can be overridden by providing a volumed file in the right location (check the readme).
  • Loading branch information
codyfinegan authored Feb 28, 2023
1 parent 6130995 commit 69e63c8
Show file tree
Hide file tree
Showing 20 changed files with 611 additions and 302 deletions.
2 changes: 0 additions & 2 deletions .env.dist

This file was deleted.

1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ server.crt
simplesamlphp-*/
simplesamlphp-*.tar.gz
.env
custom_auth_sources.php
21 changes: 15 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ FROM php:8.0-apache-buster as dev
COPY --from=node_builder /app/samlphp/ /var/www/html/

ENV SIMPLESAMLPHP_CONFIG_DIR /var/www/config/
ENV SIMPLESAMLPHP_METADATA_DIR /var/www/metadata/
ENV SIMPLESAMLPHP_METADATA_STORAGE_DIR /var/www/metadata_storage/
ENV LISTEN_PORT 8089

# Default expose port
Expand All @@ -47,15 +49,19 @@ RUN cp "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini" && \
echo "log_errors = On\nerror_log = /dev/stderr" > "$PHP_INI_DIR/conf.d/error.ini"

# Override the core module so we can alter the theme
RUN sed -ri -e 's!core:show_metadata.tpl.php!show_metadata.tpl.php!g' /var/www/html/modules/core/www/show_metadata.php && \
sed -ri -e 's!core:frontpage_federation.tpl.php!frontpage_federation.tpl.php!g' /var/www/html/modules/core/www/frontpage_federation.php
#RUN #sed -ri -e 's!core:show_metadata.tpl.php!show_metadata.tpl.php!g' /var/www/html/modules/core/www/show_metadata.php && \
# sed -ri -e 's!core:frontpage_federation.tpl.php!frontpage_federation.tpl.php!g' /var/www/html/modules/core/www/frontpage_federation.php

RUN mkdir -p /var/www/metadata_storage && \
chown www-data /var/www/metadata_storage


RUN mkdir -p /var/www/html/modules/totara/locales/en/LC_MESSAGES && \
cp /var/www/html/modules/core/locales/en/LC_MESSAGES/core.po /var/www/html/modules/totara/locales/en/LC_MESSAGES/totara.po

FROM php:8.0-apache-buster as prod

ENV SIMPLESAMLPHP_CONFIG_DIR /var/www/config/
ENV SIMPLESAMLPHP_METADATA_DIR /var/www/metadata/
ENV SIMPLESAMLPHP_METADATA_STORAGE_DIR /var/www/metadata_storage/
ENV LISTEN_PORT 8089

# Default expose port
Expand All @@ -67,5 +73,8 @@ COPY --from=dev /var/www/html /var/www/html
COPY --from=dev /etc/apache2/ /etc/apache2/

COPY config/ /var/www/config/
COPY metadata/ /var/www/html/metadata/
COPY modules/totara/themes/ /var/www/html/modules/totara/themes/
COPY metadata/ /var/www/metadata/
COPY modules/totara/ /var/www/html/modules/totara/

RUN mkdir -p /var/www/metadata_storage && \
chown www-data /var/www/metadata_storage
50 changes: 34 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,8 @@ Currently embedded is SimpleSAMLphp version **1.19.7**.

## Configuration

There are two environmental variables that need to be set in the Docker image for this to work.

| Variable | Description |
|---------------|---------------------------------------------------------------------------------------------------------------------------------------------------------|
| `SP_URLS` | The URLs of the Service Provider instances to register. Eg: `http://my-instance.local/path/to/metadata.php,http://another-site/path/to/metadata.php`. Accept multiple if seperated by a comma. **Must be the full URL to the metadata**. |
| `LISTEN_PORT` | The port used to access the service. Defaults to `8089`. |
| `SITE_TITLE` | Override the default site title, used when running multiple to tell them apart. |

Expand All @@ -22,10 +19,15 @@ There are two environmental variables that need to be set in the Docker image fo
docker pull totara/simple-saml-test:latest

# Start the service
docker run --rm -p 8089:8089 -e LISTEN_PORT=8089 -e SP_URLS=http://{YOUR_SP_INSTANCE}/path/to/metadata.php -it totara/simple-saml-test:latest
docker run --rm -p 8089:8089 -e LISTEN_PORT=8089 -it totara/simple-saml-test:latest
```

Set `{YOUR_SP_INSTANCE}` to the domain of your service provider instance (typically a Totara instance but technically could work with any SAML site).
Once started, you can access the service via `http://localhost:{LISTEN_PORT}` (defaults to 8089).

Open the site, and then navigate to Federation -> Manage Metadata (you'll neeed to sign in with the admin account).
Add any SP instances on the page there, the URL must be the full URL to your metadata (it does not fully validate).

Eg: http://{YOUR_SP_INSTANCE}/path/to/metadata.php

If your domain isn't publicly resolvable (such as it's a test environment) you will need to teach the
Domain/IP to this docker image.
Expand All @@ -38,8 +40,6 @@ docker run --add-host={YOUR_SP_INSTANCE}:host-gateway ... -it totara/simple-saml
docker run --add-host={YOUR_SP_INSTANCE}:{IP_OF_SITE} ... -it totara/simple-saml-test:latest
```

Once started, you can access the service via `http://localhost:{LISTEN_PORT}` (defaults to 8089).

### Using Totara Docker Dev

If you're using Totara Docker Dev library, you can add this image to the service directly.
Expand All @@ -59,19 +59,10 @@ services:
ports:
- "8089:8089"
environment:
- SP_URLS=${SAML_TOTARA_URLS}
- LISTEN_PORT=8089
- SITE_TITLE="Testing"
```
Edit your `.env` file and add the following line.

```dotenv
SAML_TOTARA_URLS=http://totara74/path/to/sp/metadata.php
```

In it place the name of the Totara instance you're using to connect.

Make sure you add `saml2` to your local hosts file, so it resolves in your browser.

Start the docker service using `t up saml2`.
Expand All @@ -82,6 +73,33 @@ Try and access http://saml2:8089 and confirm you see the test environment.

The path to the metadata file depends on what SAML plugin you are using which is why it's not specified here.

## Custom Users
By default there's a hard-coded list of users and attributes. However you can provide your own PHP file via volumes and replace the user list with your own.

Create a new file called `custom_auth_sources.php` with the following structure:
```php
<?php
return [
// username:password => [array of attributes]
'my_user:password1' => [
'uid' => ['my_uid'],
'username' => ['my_username'],
],
'another:password' => [
'uid' => ['another'],
'username' => ['annie_example'],
'firstname' => ['annie']
],
```

The `username:password` section applies to the IdP, while the internal array is what will be posted back to the SP.
In the example above, the `my_user` user is known as `my_username` or `my_uid` to the service provider and will never see `my_user`.

Once created, include it as a volume, such as:
`docker run ... -v /path/to/custom_auth_sources.php:/var/www/custom_auth_sources.php ... -it totara/simple-saml-test:latest`


## Developing This Image

* Fork this repo, create a new branch and make the change.
Expand Down
171 changes: 88 additions & 83 deletions config/authsources.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,91 @@
<?php

$sources = [
'user1:password' => [
'uid' => ['denise_steeves'],
'eduPersonAffiliation' => ['member', 'student'],
'username' => ['denise_steeves'],
'firstname' => ['Denise'],
'lastname' => ['Steeves'],
'email' => ['denise.steeves@example.com'],
],
'user2:password' => [
'uid' => ['jennie_nichols'],
'eduPersonAffiliation' => ['member', 'student'],
'username' => ['jennie_nichols'],
'firstname' => ['Jennie'],
'lastname' => ['Nichols'],
'email' => ['jennie.nichols@example.com'],
],
'user3:password' => [
'uid' => ['noah_larson'],
'eduPersonAffiliation' => ['member', 'student'],
'username' => ['noah_larson'],
'firstname' => ['Noah'],
'lastname' => ['Larson'],
'email' => ['noah.larson@example.com'],
],
'user4:password' => [
'uid' => ['kenneth_castro'],
'eduPersonAffiliation' => ['member', 'student'],
'username' => ['kenneth_castro'],
'firstname' => ['Kenneth'],
'lastname' => ['Castro'],
'email' => ['kenneth.castro@example.com'],
],
'user5:password' => [
'uid' => ['phyllis_mcdonalid'],
'eduPersonAffiliation' => ['member', 'student'],
'username' => ['phyllis_mcdonalid'],
'firstname' => ['Phyllis'],
'lastname' => ['Mcdonalid'],
'email' => ['phyllis.mcdonalid@example.com'],
],
'user6:password' => [
'uid' => ['jar_hamilton'],
'eduPersonAffiliation' => ['member', 'student'],
'username' => ['jar_hamilton'],
'firstname' => ['Jar'],
'lastname' => ['Hamilton'],
'email' => ['jar.hamilton@example.com'],
],
'user7:password' => [
'uid' => ['femi_olu'],
'eduPersonAffiliation' => ['member', 'student'],
'username' => ['femi_olu'],
'firstname' => ['Femi'],
'lastname' => ['Olu'],
'email' => ['femi.olu@example.com'],
],
'user8:password' => [
'uid' => ['tommy_ramos'],
'eduPersonAffiliation' => ['member', 'student'],
'username' => ['tommy_ramos'],
'firstname' => ['Tommy'],
'lastname' => ['Ramos'],
'email' => ['tommy.ramos@example.com'],
],
'user9:password' => [
'uid' => ['naomi_green'],
'eduPersonAffiliation' => ['member', 'student'],
'username' => ['naomi_green'],
'firstname' => ['Naomi'],
'lastname' => ['Green'],
'email' => ['naomi.green@example.com'],
],
'user10:password' => [
'uid' => ['sarah_allison'],
'eduPersonAffiliation' => ['member', 'student'],
'username' => ['sarah_allison'],
'firstname' => ['Sarah'],
'lastname' => ['Allison'],
'email' => ['sarah.allison@example.com'],
],
];
if (file_exists('/var/www/custom_auth_sources.php')) {
$sources = include('/var/www/custom_auth_sources.php');
}

$config = [
/*
* When multiple authentication sources are defined, you can specify one to use by default
Expand Down Expand Up @@ -84,95 +170,14 @@



'example-userpass' => [
'example-userpass' => array_merge([
'exampleauth:UserPass',

// Give the user an option to save their username for future login attempts
// And when enabled, what should the default be, to save the username or not
'remember.username.enabled' => true,
//'remember.username.checked' => false,

'user1:password' => [
'uid' => ['denise_steeves'],
'eduPersonAffiliation' => ['member', 'student'],
'username' => ['denise_steeves'],
'firstname' => ['Denise'],
'lastname' => ['Steeves'],
'email' => ['denise.steeves@example.com'],
],
'user2:password' => [
'uid' => ['jennie_nichols'],
'eduPersonAffiliation' => ['member', 'student'],
'username' => ['jennie_nichols'],
'firstname' => ['Jennie'],
'lastname' => ['Nichols'],
'email' => ['jennie.nichols@example.com'],
],
'user3:password' => [
'uid' => ['noah_larson'],
'eduPersonAffiliation' => ['member', 'student'],
'username' => ['noah_larson'],
'firstname' => ['Noah'],
'lastname' => ['Larson'],
'email' => ['noah.larson@example.com'],
],
'user4:password' => [
'uid' => ['kenneth_castro'],
'eduPersonAffiliation' => ['member', 'student'],
'username' => ['kenneth_castro'],
'firstname' => ['Kenneth'],
'lastname' => ['Castro'],
'email' => ['kenneth.castro@example.com'],
],
'user5:password' => [
'uid' => ['phyllis_mcdonalid'],
'eduPersonAffiliation' => ['member', 'student'],
'username' => ['phyllis_mcdonalid'],
'firstname' => ['Phyllis'],
'lastname' => ['Mcdonalid'],
'email' => ['phyllis.mcdonalid@example.com'],
],
'user6:password' => [
'uid' => ['jar_hamilton'],
'eduPersonAffiliation' => ['member', 'student'],
'username' => ['jar_hamilton'],
'firstname' => ['Jar'],
'lastname' => ['Hamilton'],
'email' => ['jar.hamilton@example.com'],
],
'user7:password' => [
'uid' => ['femi_olu'],
'eduPersonAffiliation' => ['member', 'student'],
'username' => ['femi_olu'],
'firstname' => ['Femi'],
'lastname' => ['Olu'],
'email' => ['femi.olu@example.com'],
],
'user8:password' => [
'uid' => ['tommy_ramos'],
'eduPersonAffiliation' => ['member', 'student'],
'username' => ['tommy_ramos'],
'firstname' => ['Tommy'],
'lastname' => ['Ramos'],
'email' => ['tommy.ramos@example.com'],
],
'user9:password' => [
'uid' => ['naomi_green'],
'eduPersonAffiliation' => ['member', 'student'],
'username' => ['naomi_green'],
'firstname' => ['Naomi'],
'lastname' => ['Green'],
'email' => ['naomi.green@example.com'],
],
'user10:password' => [
'uid' => ['sarah_allison'],
'eduPersonAffiliation' => ['member', 'student'],
'username' => ['sarah_allison'],
'firstname' => ['Sarah'],
'lastname' => ['Allison'],
'email' => ['sarah.allison@example.com'],
],
],
], $sources),


/*
Expand Down
16 changes: 7 additions & 9 deletions config/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -980,14 +980,12 @@
* Both Shibboleth and SAML 2.0
*/
'authproc.idp' => [
/* Enable the authproc filter below to add URN prefixes to all attributes
10 => array[
/* Enable the authproc filter below to add URN prefixes to all attributes */
10 => [
'class' => 'core:AttributeMap', 'addurnprefix'
],
*/
/* Enable the authproc filter below to automatically generated eduPersonTargetedID.
20 => 'core:TargetedID',
*/
/* nable the authproc filter below to automatically generated eduPersonTargetedID. */
// 20 => 'core:TargetedID',

// Adopts language from attribute to use in UI
30 => 'core:LanguageAdaptor',
Expand All @@ -1006,15 +1004,15 @@
/*
* Search attribute "distinguishedName" for pattern and replaces if found
*/
/*

60 => [
'class' => 'core:AttributeAlter',
'pattern' => '/OU=studerende/',
'replacement' => 'Student',
'subject' => 'distinguishedName',
'%replace',
],
*/


/*
* Consent module is enabled (with no permanent storage, using cookies).
Expand Down Expand Up @@ -1071,7 +1069,7 @@
* This option allows you to specify a directory for your metadata outside of the standard metadata directory
* included in the standard distribution of the software.
*/
'metadatadir' => 'metadata',
'metadatadir' => getenv('SIMPLESAMLPHP_METADATA_DIR') ?? 'metadata',

/*
* This option configures the metadata sources. The metadata sources is given as an array with
Expand Down
Loading

0 comments on commit 69e63c8

Please sign in to comment.