Skip to content

Commit

Permalink
SSP-2060-Use_processing_chain (#43)
Browse files Browse the repository at this point in the history
* Added Processing Chain factory.
* Moved TicketFactory to Factories directory.
* Get state from authsource and pass it to extract user attributes
* Add processing chain query parameter handling.
* Fix ProcessingChaing redirect request handling.
* Fixed unit tests and phpcs
* Add testing steps with docker image to README
* Fix markdown errors
* Fix scrutinizer reported issues

---------

Co-authored-by: Patrick Radtke <[email protected]>
Co-authored-by: Tim van Dijen <[email protected]>
  • Loading branch information
3 people authored Nov 18, 2024
1 parent f872b6e commit 81b6b53
Show file tree
Hide file tree
Showing 24 changed files with 1,989 additions and 199 deletions.
25 changes: 24 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,30 @@ chance it will just mess up your code.
phpcbf --ignore=somefile.php --standard=PSR12 lib/ tests/ www/ templates/
```

### Local testing with docker

To explore the module using docker run the below command. This will run an SSP image, with the current git checkout
of the `casserver` module mounted in the container, along with some configuration files. Any code changes you make to your git checkout are
"live" in the container, allowing you to test and iterate different things.

```bash
# Note: this currently errors on this module requiring a newer version of `simplesamlphp/xml-common` than what is in the base image
docker run --name ssp-casserver-dev \
--mount type=bind,source="$(pwd)",target=/var/simplesamlphp/staging-modules/casserver,readonly \
-e STAGINGCOMPOSERREPOS=casserver \
-e COMPOSER_REQUIRE="simplesamlphp/simplesamlphp-module-casserver:@dev simplesamlphp/simplesamlphp-module-preprodwarning"
-e SSP_ADMIN_PASSWORD=secret1 \
--mount type=bind,source="$(pwd)/docker/ssp/module_casserver.php",target=/var/simplesamlphp/config/module_casserver.php,readonly \
--mount type=bind,source="$(pwd)/docker/ssp/authsources.php",target=/var/simplesamlphp/config/authsources.php,readonly \
--mount type=bind,source="$(pwd)/docker/ssp/config-override.php",target=/var/simplesamlphp/config/config-override.php,readonly \
--mount type=bind,source="$(pwd)/docker/apache-override.cf",target=/etc/apache2/sites-enabled/ssp-override.cf,readonly \
-p 443:443 cirrusid/simplesamlphp:v2.3.2
```

Visit [https://localhost/simplesaml/](https://localhost/simplesaml/) and confirm you get the default page.
Then navigate to [casserver debug](https://localhost/cas/login?service=http://host1.domain:1234/path1&debugMode=true), authenticate and confirm
use see what a ticket would look like. To see what a CAS v1 saml response looks like set [debugMode=samlValidate](https://localhost/cas/login?service=http://host1.domain:1234/path1&debugMode=samlValidate)

## History

CAS 1.0 and 2.0 compliant CAS server module for simpleSAMLphp
Expand All @@ -101,4 +125,3 @@ See Google Groups discussion in [this thread][1].

This work is licensed under a Creative Commons GNU Lesser General Public
License License.

21 changes: 16 additions & 5 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,22 +35,33 @@
"ext-filter": "*",
"ext-libxml": "*",
"ext-SimpleXML": "*",

"simplesamlphp/assert": "^1.1",
"simplesamlphp/composer-module-installer": "^1.3",
"simplesamlphp/simplesamlphp": "^2.2",
"simplesamlphp/xml-cas": "^1.2",
"simplesamlphp/xml-common": "^1.16",
"simplesamlphp/xml-soap": "^1.4"
"simplesamlphp/xml-cas": "^v1.3",
"simplesamlphp/xml-common": "^v1.17",
"simplesamlphp/xml-soap": "^v1.5"
},
"require-dev": {
"simplesamlphp/simplesamlphp-test-framework": "^1.7"
"simplesamlphp/simplesamlphp-test-framework": "^1.7",
"phpunit/phpunit": "^10",
"psalm/plugin-phpunit": "^0.19.0",
"squizlabs/php_codesniffer": "^3.7"
},
"support": {
"issues": "https://github.com/simplesamlphp/simplesamlphp-module-casserver/issues",
"source": "https://github.com/simplesamlphp/simplesamlphp-module-casserver"
},
"suggest": {
"ext-pdo": "*"
},
"scripts": {
"validate": [
"vendor/bin/phpunit --no-coverage --testdox",
"vendor/bin/phpcs -p"
],
"tests": [
"vendor/bin/phpunit --no-coverage"
]
}
}
14 changes: 14 additions & 0 deletions docker/apache-override.cf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
RewriteEngine On
RewriteRule ^/.well-known/openid-configuration(.*) /${SSP_APACHE_ALIAS}module.php/oidc/.well-known/openid-configuration$1 [PT]
RewriteRule ^/.well-known/openid-federation(.*) /${SSP_APACHE_ALIAS}module.php/oidc/.well-known/openid-federation$1 [PT]

# Some CAS clients expect you to run under /cas/ so you use some rewrite rules

RewriteRule ^/cas/login(.*) /${SSP_APACHE_ALIAS}module.php/casserver/login.php$1 [PT]
RewriteRule ^/cas/serviceValidate(.*) /${SSP_APACHE_ALIAS}module.php/casserver/serviceValidate.php$1 [PT]
RewriteRule ^/cas/p3/serviceValidate(.*) /${SSP_APACHE_ALIAS}module.php/casserver/serviceValidate.php$1 [PT]
RewriteRule ^/cas/proxyValidate(.*) /${SSP_APACHE_ALIAS}module.php/casserver/serviceValidate.php$1 [PT]
RewriteRule ^/cas/p3/proxyValidate(.*) /${SSP_APACHE_ALIAS}module.php/casserver/serviceValidate.php$1 [PT]
RewriteRule ^/cas/validate(.*) /${SSP_APACHE_ALIAS}module.php/casserver/validate.php$1 [PT]
RewriteRule ^/cas/logout(.*) /${SSP_APACHE_ALIAS}module.php/casserver/logout.php$1 [PT]
RewriteRule ^/cas/samlValidate(.*) /${SSP_APACHE_ALIAS}module.php/casserver/samlValidate.php$1 [PT]
62 changes: 62 additions & 0 deletions docker/ssp/authsources.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php

declare(strict_types=1);

$config = array(

// This is an authentication source which handles admin authentication.
'admin' => array(
'core:AdminPassword',
),

'example-userpass' => [
'exampleauth:UserPass',
'users' => [
'student:studentpass' => [
'uid' => ['student'],
'eduPersonAffiliation' => ['member', 'student'],
'eduPersonNickname' => 'Sir_Nickname',
'displayName' => 'Some User',
'givenName' => 'Firsty',
'middle_name' => 'Mid',
'sn' => 'Lasty',
'labeledURI' => 'https://example.com/student',
'jpegURL' => 'https://example.com/student.jpg',
'mail' => '[email protected]',
'email_verified' => 'yes',
'zoneinfo' => 'Europe/Paris',
'updated_at' => '1621374126',
'preferredLanguage' => 'fr-CA',
'website' => 'https://example.com/student-blog',
'gender' => 'female',
'birthdate' => '1945-03-21',
'eduPersonUniqueId' => '13579',
'phone_number_verified' => 'yes',
'mobile' => '+1 (604) 555-1234;ext=5678',
'postalAddress' => ["Place Charles de Gaulle, Paris"],
'street_address' => ['Place Charles de Gaulle'],
'locality' => ['Paris'],
'region' => ['Île-de-France'],
'postal_code' => ['75008'],
'country' => ['France'],
// Confirm that an attribute containing xml stuff is handled
'attributeContainingXml' => ['<confirmNothingBreaks test="true"/>', 'test < "']
],
'employee:employeepass' => [
'uid' => ['employee'],
'eduPersonAffiliation' => ['member', 'employee'],
'eduPersonEntitlement' => ['urn:example:oidc:manage:client']
],
'member:memberpass' => [
'uid' => ['member'],
'eduPersonAffiliation' => ['member'],
'eduPersonEntitlement' => ['urn:example:oidc:manage:client']
],
'minimal:minimalpass' => [
'uid' => ['minimal'],
],
],
],


);
12 changes: 12 additions & 0 deletions docker/ssp/config-override.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

declare(strict_types=1);

$config['module.enable']['exampleauth'] = true;
$config['module.enable']['casserver'] = true;
// Have preprod warning enabled (though it may not be installed) to ease authproc redirect testing
$config['module.enable']['preprodwarning'] = true;
$config = [
'secretsalt' => 'testsalt',
'logging.level' => 7,
] + $config;
126 changes: 126 additions & 0 deletions docker/ssp/module_casserver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
<?php

/*
* Configuration for the module casserver.
*
*/

$config = [
'authsource' => 'example-userpass',

/* Scopes are named sets of entityIDs to be used for scoping. If a named scope is provided during login, then the
IdPs listed by the disco service will be restricted to entityIDs in the specified set. */
'scopes' => [
'mobile' => [
'https://idp1.domain:1234/saml2/idp/metadata.php',
'https://idp2.domain:5678/saml2/idp/metadata.php'
],
'desktop' => [
'https://idp3.domain:1234/saml2/idp/metadata.php',
'https://idp4.domain:5678/saml2/idp/metadata.php'
]
],
'legal_service_urls' => [
//Any service url string matching any of the following prefixes is accepted
'http://host1.domain:1234/path1',
'http://host1.domain:1234/noattributes' => [
'attributes' => false,
],
'https://host2.domain:5678/path2/path3',
// So is regex
'|^https://.*\.domain.com/|',
// Some configuration options can be overridden
'https://override.example.com' => [
'attrname' => 'uid',
'attributes_to_transfer' => ['cn'],
],
],

'legal_target_service_urls' => [
//Any target service url string matching any of the following prefixes is accepted
'http://host3.domain:4321/path4',
'https://host4.domain:8765/path5/path6',
],

'ticketstore' => [
//defaults to filesystem ticket store using the directory 'ticketcache'
'class' => 'casserver:FileSystemTicketStore', //Not intended for production
'directory' => 'ticketcache',

//'class' => 'casserver:MemCacheTicketStore',
//'prefix' => 'some_prefix',

//'class' => 'casserver:SQLTicketStore',
//'dsn' => 'pgsql:host=localhost;port=5432;dbname=casserver',
//'username' => 'username',
//'password' => 'password',
//'prefix' => 'some_prefix',
//'options' => [
// \PDO::ATTR_TIMEOUT => 4,
// ]

//'class' => 'casserver:RedisTicketStore',
//'prefix' => 'some_prefix',

// Store tickets in multiple ticket stores for redundancy or to allow
// transitions between data stores without downtime.
/*
'class' => 'casserver:DelegatingTicketStore',
'delegateTo' => 'all',
'ticketStores' => [
'oldStore' => [
'class' => 'casserver:RedisTicketStore',
'prefix' => 'cas',
],
'newStore' => [
'class' => 'casserver:FileSystemTicketStore',
'prefix' => 'cas'
]
]*/
],

'attrname' => 'uid', // 'eduPersonPrincipalName',
'attributes' => true, // enable transfer of attributes, defaults to true
'attributes_to_transfer' => ['cn', 'eduPersonAffiliation', 'attributeContainingXml'], // set of attributes to transfer, defaults to all

/**
* Optional authproc filter. Only authproc filters that solely rely on attributes
* (such as core:AttributeMap and AttributeAlter)
* may be used. If your authsource supports authproc filters you are better off doing it there.
*/
'authproc' => [
[
'class' => 'core:AttributeMap',
'oid2name',
'urn:example' => 'example',
],
[
'class' => 'preprodwarning:Warning',
],
// Additional authproc filter
],

'base64attributes' => false, // base64 encode transferred attributes, defaults to false

/**
* add an attribute with the value of the base64attributes
* configuration parameter to the set of transferred attributes.
* Defaults to not adding an indicator attribute.
*/
'base64_attributes_indicator_attribute' => 'base64Attributes',

'enable_logout' => true, // enable CAS logout, defaults to false
'skip_logout_page' => true, /*perform a redirect instead of showing a logout page with a link to the location
given in the url parameter, defaults to false. Skipping the logout page makes the
url query parameter to CAS logout mandatory for obvious reasons.*/

// how many seconds service tickets are valid for, defaults to 5
'service_ticket_expire_time' => 5,
// how many seconds proxy granting tickets are valid for at most, defaults to 3600
'proxy_granting_ticket_expire_time' => 600,
//how many seconds proxy tickets are valid for, defaults to 5
'proxy_ticket_expire_time' => 5,

// If query param debugMode=true is sent to the login endpoint then print cas ticket xml. Default false
'debugMode' => true,
];
3 changes: 3 additions & 0 deletions phpcs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
<exclude-pattern>tests/www/UtilsTest.php</exclude-pattern>
</rule>

<!-- Use this to exclude paths. You can have multiple patterns -->
<exclude-pattern>tests/config/*</exclude-pattern>

<!-- This is the rule we inherit from. If you want to exclude some specific rules, see the docs on how to do that -->
<rule ref="PSR12"/>
<rule ref="vendor/simplesamlphp/simplesamlphp-test-framework/phpcs-simplesamlphp.xml"/>
Expand Down
7 changes: 6 additions & 1 deletion phpunit.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" bootstrap="tests/bootstrap.php" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd" cacheDirectory=".phpunit.cache">
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
colors="true"
bootstrap="tests/bootstrap.php"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd"
backupGlobals="false"
cacheDirectory=".phpunit.cache">
<coverage>
<report>
<clover outputFile="build/logs/clover.xml"/>
Expand Down
Loading

0 comments on commit 81b6b53

Please sign in to comment.