diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..5d8d77f6 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,15 @@ +root = true + +[*] +end_of_line = lf +insert_final_newline = true +indent_style = space +trim_trailing_whitespace = true + +[*.php] +charset = utf-8 +indent_size = 4 + +[*.twig] +charset = utf-8 +indent_size = 2 diff --git a/.github/workflows/test-and-publish.yml b/.github/workflows/test-and-publish.yml index 3a75adfb..ceb06f46 100644 --- a/.github/workflows/test-and-publish.yml +++ b/.github/workflows/test-and-publish.yml @@ -10,14 +10,16 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v4 + - name: Create env files + run: cp local.env.dist local.env && cp local.broker.env.dist local.broker.env - name: test - run: docker compose -f actions-services.yml run test ./run-tests.sh + run: docker compose run test ./run-tests.sh - name: check hub metadata for tests - run: docker compose -f actions-services.yml run ssp-hub.local ./run-metadata-tests.sh + run: docker compose run ssp-hub.local ./run-metadata-tests.sh - name: check idp metadata for tests - run: docker compose -f actions-services.yml run ssp-idp1.local ./run-metadata-tests.sh + run: docker compose run ssp-idp1.local ./run-metadata-tests.sh - name: check sp metadata for tests - run: docker compose -f actions-services.yml run ssp-sp1.local ./run-metadata-tests.sh + run: docker compose run ssp-sp1.local ./run-metadata-tests.sh build-and-publish: name: Build and Publish diff --git a/Dockerfile b/Dockerfile index 08d8c8ef..99ff8c10 100644 --- a/Dockerfile +++ b/Dockerfile @@ -45,28 +45,31 @@ ENV SSP_PATH /data/vendor/simplesamlphp/simplesamlphp COPY modules/ $SSP_PATH/modules # Copy material theme templates to other modules, just in case the "default" theme is selected +COPY modules/material/themes/material/default/* $SSP_PATH/modules/default/templates/ COPY modules/material/themes/material/expirychecker/* $SSP_PATH/modules/expirychecker/templates/ COPY modules/material/themes/material/mfa/* $SSP_PATH/modules/mfa/templates/ COPY modules/material/themes/material/profilereview/* $SSP_PATH/modules/profilereview/templates/ +COPY modules/material/themes/material/silauth/* $SSP_PATH/modules/silauth/templates/ # Copy in SSP override files -RUN mv $SSP_PATH/www/index.php $SSP_PATH/www/ssp-index.php -COPY dockerbuild/ssp-overrides/index.php $SSP_PATH/www/index.php -RUN mv $SSP_PATH/www/saml2/idp/SingleLogoutService.php $SSP_PATH/www/saml2/idp/ssp-SingleLogoutService.php -COPY dockerbuild/ssp-overrides/SingleLogoutService.php $SSP_PATH/www/saml2/idp/SingleLogoutService.php +RUN mv $SSP_PATH/public/index.php $SSP_PATH/public/ssp-index.php +COPY dockerbuild/ssp-overrides/index.php $SSP_PATH/public/index.php COPY dockerbuild/ssp-overrides/saml20-idp-remote.php $SSP_PATH/metadata/saml20-idp-remote.php COPY dockerbuild/ssp-overrides/saml20-sp-remote.php $SSP_PATH/metadata/saml20-sp-remote.php COPY dockerbuild/config/* $SSP_PATH/config/ -COPY dockerbuild/ssp-overrides/id.php $SSP_PATH/www/id.php +COPY dockerbuild/ssp-overrides/id.php $SSP_PATH/public/id.php COPY dockerbuild/ssp-overrides/announcement.php $SSP_PATH/announcement/announcement.php COPY tests /data/tests -RUN cp $SSP_PATH/modules/sildisco/lib/SSOService.php $SSP_PATH/www/saml2/idp/ RUN chmod a+x /data/run.sh /data/run-tests.sh ADD https://github.com/silinternational/config-shim/releases/latest/download/config-shim.gz config-shim.gz RUN gzip -d config-shim.gz && chmod 755 config-shim && mv config-shim /usr/local/bin +# Set permissions for cache directory. Corresponds to the `cachedir` setting in config.php. +RUN mkdir /data/cache +RUN chown -R www-data:www-data /data/cache + EXPOSE 80 ENTRYPOINT ["/usr/local/bin/s3-expand"] CMD ["/data/run.sh"] diff --git a/Makefile b/Makefile index 76024d52..50292e2b 100644 --- a/Makefile +++ b/Makefile @@ -18,8 +18,8 @@ test-integration: docker compose run --rm test ./run-integration-tests.sh copyJsLib: - cp ./node_modules/@simplewebauthn/browser/dist/bundle/index.umd.min.js ./modules/mfa/www/simplewebauthn/browser.js - cp ./node_modules/@simplewebauthn/browser/LICENSE.md ./modules/mfa/www/simplewebauthn/LICENSE.md + cp ./node_modules/@simplewebauthn/browser/dist/bundle/index.umd.min.js ./modules/mfa/public/simplewebauthn/browser.js + cp ./node_modules/@simplewebauthn/browser/LICENSE.md ./modules/mfa/public/simplewebauthn/LICENSE.md deps: docker compose run --rm node npm install --ignore-scripts diff --git a/README.md b/README.md index a32fc312..8e768d15 100644 --- a/README.md +++ b/README.md @@ -229,14 +229,14 @@ Update `/simplesamlphp/config/config.php`: 'theme.color-scheme' => ['indigo-purple'|'blue_grey-teal'|'red-teal'|'orange-light_blue'|'brown-orange'|'teal-blue'] ``` -The login page looks for `/simplesamlphp/www/logo.png` which is **NOT** provided by default. +The login page looks for `/simplesamlphp/public/logo.png` which is **NOT** provided by default. ##### Analytics Update `/simplesamlphp/config/config.php`: ``` -'analytics.trackingId' => 'G-some-unique-id-for-your-site' +'analytics.trackingId' => 'UA-some-unique-id-for-your-site' ``` This project provides a convenience by loading this config with whatever is in the environment variable `ANALYTICS_ID`._ diff --git a/Vagrantfile b/Vagrantfile deleted file mode 100644 index 512d79b6..00000000 --- a/Vagrantfile +++ /dev/null @@ -1,84 +0,0 @@ -# -*- mode: ruby -*- -# vi: set ft=ruby : - -# All Vagrant configuration is done below. The "2" in Vagrant.configure -# configures the configuration version (we support older styles for -# backwards compatibility). Please don't change it unless you know what -# you're doing. -Vagrant.configure(2) do |config| - # The most common configuration options are documented and commented below. - # For a complete reference, please see the online documentation at - # https://docs.vagrantup.com. - - # Every Vagrant development environment requires a box. You can search for - # boxes at https://atlas.hashicorp.com/search. - config.vm.box = "ubuntu/trusty64" - - # Create a private network, which allows host-only access to the machine - # using a specific IP. - config.vm.network "private_network", ip: "192.168.62.10" - - # Provider-specific configuration so you can fine-tune various - # backing providers for Vagrant. These expose provider-specific options. - # Example for VirtualBox: - # - config.vm.provider "virtualbox" do |vb| - # Customize the amount of memory on the VM: - vb.memory = "2048" - - # A fix for speed issues with DNS resolution: - # http://serverfault.com/questions/453185/vagrant-virtualbox-dns-10-0-2-3-not-working?rq=1 - vb.customize ["modifyvm", :id, "--natdnshostresolver1", "on"] - - # Set the timesync threshold to 59 seconds, instead of the default 20 minutes. - # 59 seconds chosen to ensure SimpleSAML never gets too far out of date. - vb.customize ["guestproperty", "set", :id, "/VirtualBox/GuestAdd/VBoxService/--timesync-set-threshold", 59000] - end - # - # View the documentation for the provider you are using for more - # information on available options. - - # This provisioner runs on the first `vagrant up`. - config.vm.provision "install", type: "shell", inline: <<-SHELL - # Add Docker apt repository - sudo apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D - sudo sh -c 'echo deb https://apt.dockerproject.org/repo ubuntu-trusty main > /etc/apt/sources.list.d/docker.list' - sudo apt-get update -y - # Add NTP so that the LDAP queries don't unexpectedly fail. - sudo apt-get install ntp -y - # Uninstall old lxc-docker - apt-get purge lxc-docker - apt-cache policy docker-engine - # Install docker and dependencies - sudo apt-get install -y linux-image-extra-$(uname -r) - sudo apt-get install -y docker-engine - # Add user vagrant to docker group - sudo groupadd docker - sudo usermod -aG docker vagrant - # Install Docker Compose - curl -L https://github.com/docker/compose/releases/download/1.17.0/docker compose-`uname -s`-`uname -m` > /usr/local/bin/docker compose - chmod +x /usr/local/bin/docker compose - SHELL - - # This provisioner runs on every `vagrant reload' (as well as the first - # `vagrant up`), reinstalling from local directories - config.vm.provision "recompose", type: "shell", - run: "always", inline: <<-SHELL - - # Run docker compose (which will update preloaded images, and - # pulls any images not preloaded) - cd /vagrant - - # Set necessary environment variables for shell access. - export COMPOSER_CACHE_DIR=/tmp - export DOCKER_UIDGID="$(id -u):$(id -g)" - - # Set up necessary env. vars to automatically be present each time. - cat << 'EOF' >> /home/vagrant/.bashrc -export COMPOSER_CACHE_DIR=/tmp -export DOCKER_UIDGID="$(id -u):$(id -g)" -EOF - - SHELL - -end diff --git a/actions-services.yml b/actions-services.yml index 1f06cfdf..bb62a63f 100644 --- a/actions-services.yml +++ b/actions-services.yml @@ -57,10 +57,7 @@ services: - ./development/announcement.php:/data/vendor/simplesamlphp/simplesamlphp/announcement/announcement.php # Utilize custom metadata - - ./development/hub/metadata/idp-remote.php:/data/vendor/simplesamlphp/simplesamlphp/metadata/idp-remote.php - - ./development/hub/metadata/saml20-idp-hosted.php:/data/vendor/simplesamlphp/simplesamlphp/metadata/saml20-idp-hosted.php - - ./development/hub/metadata/saml20-sp-hosted.php:/data/vendor/simplesamlphp/simplesamlphp/metadata/saml20-sp-hosted.php - - ./development/hub/metadata/sp-remote.php:/data/vendor/simplesamlphp/simplesamlphp/metadata/sp-remote.php + - ./development/hub/metadata/:/data/vendor/simplesamlphp/simplesamlphp/metadata/ # Enable checking our test metadata - ./dockerbuild/run-metadata-tests.sh:/data/run-metadata-tests.sh @@ -69,7 +66,6 @@ services: SECRET_SALT: "not-secret-h57fjemb&dn^nsJFGNjweJ" IDP_NAME: "Hub" SECURE_COOKIE: "false" - ADMIN_PROTECT_INDEX_PAGE: "false" SHOW_SAML_ERRORS: "true" THEME_COLOR_SCHEME: "orange-light_blue" HUB_MODE: "true" @@ -84,15 +80,15 @@ services: # Utilize custom configs - ./development/idp-local/config/authsources.php:/data/vendor/simplesamlphp/simplesamlphp/config/authsources.php - - ./development/idp-local/config/config.php:/data/vendor/simplesamlphp/simplesamlphp/config/config.php - ./development/announcement.php:/data/vendor/simplesamlphp/simplesamlphp/announcement/announcement.php + - ./development/enable-exampleauth.sh:/data/enable-exampleauth.sh # Utilize custom metadata - ./development/idp-local/metadata/saml20-idp-hosted.php:/data/vendor/simplesamlphp/simplesamlphp/metadata/saml20-idp-hosted.php - ./development/idp-local/metadata/saml20-sp-remote.php:/data/vendor/simplesamlphp/simplesamlphp/metadata/saml20-sp-remote.php # Customized SSP code -- TODO: make a better solution that doesn't require hacking SSP code - - ./development/UserPass.php:/data/vendor/simplesamlphp/simplesamlphp/modules/exampleauth/lib/Auth/Source/UserPass.php + - ./development/UserPass.php:/data/vendor/simplesamlphp/simplesamlphp/modules/exampleauth/src/Auth/Source/UserPass.php # Enable checking our test metadata - ./dockerbuild/run-metadata-tests.sh:/data/run-metadata-tests.sh @@ -100,7 +96,8 @@ services: # Include the features folder (for the FakeIdBrokerClient class) - ./features:/data/features command: > - bash -c "whenavail db 3306 60 /data/vendor/simplesamlphp/simplesamlphp/modules/silauth/lib/Auth/Source/yii migrate --interactive=0 && + bash -c "whenavail db 3306 60 /data/vendor/simplesamlphp/simplesamlphp/modules/silauth/src/Auth/Source/yii migrate --interactive=0 && + /data/enable-exampleauth.sh && /data/run.sh" environment: ADMIN_PASS: "a" @@ -125,25 +122,38 @@ services: ssp-idp2.local: build: . + depends_on: + - db + - broker volumes: # Utilize custom certs - - ./development/idp2-local/cert:/data/vendor/simplesamlphp/simplesamlphp/cert + - ./development/idp2-local/cert:/data/vendor/simplesamlphp/simplesamlphp/cert # Utilize custom configs - ./development/idp2-local/config/authsources.php:/data/vendor/simplesamlphp/simplesamlphp/config/authsources.php - - ./development/idp2-local/config/config.php:/data/vendor/simplesamlphp/simplesamlphp/config/config.php + - ./development/enable-exampleauth.sh:/data/enable-exampleauth.sh # Utilize custom metadata - ./development/idp2-local/metadata/saml20-idp-hosted.php:/data/vendor/simplesamlphp/simplesamlphp/metadata/saml20-idp-hosted.php - ./development/idp2-local/metadata/saml20-sp-remote.php:/data/vendor/simplesamlphp/simplesamlphp/metadata/saml20-sp-remote.php # Customized SSP code -- TODO: make a better solution that doesn't require hacking SSP code - - ./development/UserPass.php:/data/vendor/simplesamlphp/simplesamlphp/modules/exampleauth/lib/Auth/Source/UserPass.php + - ./development/UserPass.php:/data/vendor/simplesamlphp/simplesamlphp/modules/exampleauth/src/Auth/Source/UserPass.php + command: bash -c "/data/enable-exampleauth.sh && /data/run.sh" environment: ADMIN_PASS: "b" SECRET_SALT: "h57fjemb&dn^nsJFGNjweJ" IDP_NAME: "IDP 2" + IDP_DOMAIN_NAME: "ssp-idp1.local" + ID_BROKER_ACCESS_TOKEN: "test-cli-abc123" + ID_BROKER_ASSERT_VALID_IP: "true" + ID_BROKER_BASE_URI: "http://broker" + ID_BROKER_TRUSTED_IP_RANGES: "10.20.38.0/24" + MYSQL_HOST: "db" + MYSQL_DATABASE: "silauth" + MYSQL_USER: "silauth" + MYSQL_PASSWORD: "silauth" SECURE_COOKIE: "false" SHOW_SAML_ERRORS: "true" @@ -155,7 +165,6 @@ services: # Utilize custom configs - ./development/idp3-local/config/authsources.php:/data/vendor/simplesamlphp/simplesamlphp/config/authsources.php - - ./development/idp3-local/config/config.php:/data/vendor/simplesamlphp/simplesamlphp/config/config.php # Utilize custom metadata - ./development/idp3-local/metadata/saml20-idp-hosted.php:/data/vendor/simplesamlphp/simplesamlphp/metadata/saml20-idp-hosted.php @@ -169,13 +178,12 @@ services: IDP_NAME: "IdP3" ssp-sp1.local: - build: . + image: silintl/ssp-base:9.3.0 volumes: # Utilize custom certs - ./development/sp-local/cert:/data/vendor/simplesamlphp/simplesamlphp/cert # Utilize custom configs - - ./development/sp-local/config/config.php:/data/vendor/simplesamlphp/simplesamlphp/config/config.php - ./development/sp-local/config/authsources.php:/data/vendor/simplesamlphp/simplesamlphp/config/authsources.php # Utilize custom metadata @@ -184,7 +192,9 @@ services: # Enable checking our test metadata - ./dockerbuild/run-metadata-tests.sh:/data/run-metadata-tests.sh environment: + ADMIN_EMAIL: "john_doe@there.com" ADMIN_PASS: "sp1" + IDP_NAME: "NA" SECRET_SALT: "not-secret-h57fjemb&dn^nsJFGNjweJz1" SECURE_COOKIE: "false" SHOW_SAML_ERRORS: "true" @@ -192,20 +202,21 @@ services: ADMIN_PROTECT_INDEX_PAGE: "false" ssp-sp2.local: - build: . + image: silintl/ssp-base:9.3.0 volumes: # Utilize custom certs - ./development/sp2-local/cert:/data/vendor/simplesamlphp/simplesamlphp/cert # Utilize custom configs - - ./development/sp2-local/config/config.php:/data/vendor/simplesamlphp/simplesamlphp/config/config.php - ./development/sp2-local/config/authsources.php:/data/vendor/simplesamlphp/simplesamlphp/config/authsources.php # Utilize custom metadata - ./development/sp2-local/metadata/saml20-idp-remote.php:/data/vendor/simplesamlphp/simplesamlphp/metadata/saml20-idp-remote.php environment: + ADMIN_EMAIL: "john_doe@there.com" ADMIN_PASS: sp2 + IDP_NAME: "NA" SECRET_SALT: h57fjemb&dn^nsJFGNjweJz2 SECURE_COOKIE: "false" SHOW_SAML_ERRORS: "true" @@ -213,20 +224,21 @@ services: ADMIN_PROTECT_INDEX_PAGE: "false" ssp-sp3.local: - build: . + image: silintl/ssp-base:9.3.0 volumes: # Utilize custom certs - ./development/sp3-local/cert:/data/vendor/simplesamlphp/simplesamlphp/cert # Utilize custom configs - - ./development/sp3-local/config/config.php:/data/vendor/simplesamlphp/simplesamlphp/config/config.php - ./development/sp3-local/config/authsources.php:/data/vendor/simplesamlphp/simplesamlphp/config/authsources.php # Utilize custom metadata - ./development/sp3-local/metadata/saml20-idp-remote.php:/data/vendor/simplesamlphp/simplesamlphp/metadata/saml20-idp-remote.php environment: + ADMIN_EMAIL: "john_doe@there.com" ADMIN_PASS: sp3 + IDP_NAME: "NA" SECRET_SALT: h57fjemb&dn^nsJFGNjweJz3 SECURE_COOKIE: "false" SHOW_SAML_ERRORS: "true" @@ -235,7 +247,7 @@ services: pwmanager.local: - image: silintl/ssp-base:develop + image: silintl/ssp-base:9.3.0 volumes: # Utilize custom certs - ./development/sp-local/cert:/data/vendor/simplesamlphp/simplesamlphp/cert @@ -246,6 +258,7 @@ services: # Utilize custom metadata - ./development/sp-local/metadata/saml20-idp-remote.php:/data/vendor/simplesamlphp/simplesamlphp/metadata/saml20-idp-remote.php environment: + ADMIN_EMAIL: "john_doe@there.com" ADMIN_PASS: sp1 IDP_NAME: THIS VARIABLE IS REQUIRED BUT PROBABLY NOT USED SECRET_SALT: NOT-a-secret-k49fjfkw73hjf9t87wjiw @@ -276,12 +289,19 @@ services: EMAIL_SIGNATURE: "one red pill, please" API_ACCESS_KEYS: "test-cli-abc123" APP_ENV: "prod" - MFA_TOTP_apiBaseUrl: not_needed_here - MFA_TOTP_apiKey: not_needed_here - MFA_TOTP_apiSecret: not_needed_here - MFA_WEBAUTHN_apiBaseUrl: not_needed_here - MFA_WEBAUTHN_apiKey: not_needed_here - MFA_WEBAUTHN_apiSecret: not_needed_here + RP_ORIGINS: "https://ssp-idp1.local,https://ssp-idp3.local,https://ssp-idp3.local" + HIBP_CHECK_ON_LOGIN: "false" + MFA_TOTP_apiBaseUrl: dummy + MFA_TOTP_apiKey: 10345678-1234-1234-1234-123456789012 + MFA_TOTP_apiSecret: 11345678-1234-1234-1234-12345678 + MFA_WEBAUTHN_apiBaseUrl: dummy + MFA_WEBAUTHN_apiKey: 10345678-1234-1234-1234-123456789012 + MFA_WEBAUTHN_apiSecret: 11345678-1234-1234-1234-12345678 + MFA_WEBAUTHN_appId: ourApp99 + MFA_WEBAUTHN_rpDisplayName: Our App + MFA_WEBAUTHN_rpId: http://app99 + volumes: + - ./development/m991231_235959_insert_test_users.php:/data/console/migrations/m991231_235959_insert_test_users.php command: "bash -c 'whenavail brokerDb 3306 60 ./yii migrate --interactive=0 && ./run.sh'" brokerDb: diff --git a/behat.yml b/behat.yml index 6306126b..4ef546fd 100644 --- a/behat.yml +++ b/behat.yml @@ -18,16 +18,16 @@ default: profilereview_features: paths: [ '%paths.base%//features//profilereview.feature' ] contexts: [ 'ProfileReviewContext' ] - sildisco_features: - contexts: ['SilDiscoContext'] - paths: - - '%paths.base%//features//Sp1Idp1Sp2Idp2Sp3.feature' - - '%paths.base%//features//Sp1Idp2Sp2Sp3Idp1.feature' - - '%paths.base%//features//Sp2Idp2Sp1Idp1Sp3.feature' - - '%paths.base%//features//Sp2Idp2Sp1Idp2Sp3.feature' - - '%paths.base%//features//Sp3Idp1Sp1Idp1Sp2Idp2.feature' - - '%paths.base%//features//WwwMetadataCept.feature' - - '%paths.base%//features//ZSp1Idp1BetaSp1Idp3.feature' +# sildisco_features: +# contexts: ['SilDiscoContext'] +# paths: +# - '%paths.base%//features//Sp1Idp1Sp2Idp2Sp3.feature' +# - '%paths.base%//features//Sp1Idp2Sp2Sp3Idp1.feature' +# - '%paths.base%//features//Sp2Idp2Sp1Idp1Sp3.feature' +# - '%paths.base%//features//Sp2Idp2Sp1Idp2Sp3.feature' +# - '%paths.base%//features//Sp3Idp1Sp1Idp1Sp2Idp2.feature' +# - '%paths.base%//features//WwwMetadataCept.feature' +# - '%paths.base%//features//ZSp1Idp1BetaSp1Idp3.feature' status_features: paths: [ '%paths.base%//features//status.feature' ] contexts: [ 'StatusContext' ] diff --git a/composer.json b/composer.json index d40e19e6..e9b88a13 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "silinternational/ssp-base", "description": "Base image for SimpleSAMLphp", - "type": "library", + "type": "project", "license": "MIT", "authors": [ { @@ -14,30 +14,29 @@ "ext-gmp": "*", "ext-json": "*", "codemix/yii2-streamlog": "^1.3", - "simplesamlphp/simplesamlphp": "^1.19.6", - "simplesamlphp/composer-module-installer": "1.1.8", + "simplesamlphp/simplesamlphp": "^2.0", + "simplesamlphp/composer-module-installer": "^1.0", "rlanvin/php-ip": "^1.0", - "silinternational/ssp-utilities": "^1.1.0", + "silinternational/ssp-utilities": "v2.0.0", "silinternational/php-env": "^3.1.0", - "silinternational/psr3-adapters": "^3.1", + "silinternational/psr3-adapters": "v4.0.0", "silinternational/yii2-json-log-targets": "^2.0", - "gettext/gettext": "^4.8@dev", "silinternational/idp-id-broker-php-client": "^4.3", "sinergi/browser-detector": "^6.1", "yiisoft/yii2": "~2.0.12", "yiisoft/yii2-gii": "^2.0", - "fillup/fake-bower-assets": "^2.0", "google/recaptcha": "^1.1", - "psr/log": "^1.0", - "monolog/monolog": "^1.22", - "aws/aws-sdk-php": "^3.313" + "psr/log": "^3.0", + "monolog/monolog": "^3.0", + "aws/aws-sdk-php": "^3.313", + "yidas/yii2-composer-bower-skip": "^2.0" }, "require-dev": { "behat/behat": "^3.8", - "behat/mink-extension": "^2.3", "dmore/chrome-mink-driver": "^2.8", "phpunit/phpunit": "^7.5.19 || ^8.0", - "roave/security-advisories": "dev-master" + "roave/security-advisories": "dev-master", + "friends-of-behat/mink-extension": "^2.7" }, "autoload": { "files": [ diff --git a/composer.lock b/composer.lock index 41b9cdaf..0029c94e 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "03d85826c06d84fb2d637696e16bc4b8", + "content-hash": "a4096531caaadf1c30b8c7600e11a4e1", "packages": [ { "name": "aws/aws-crt-php", @@ -62,16 +62,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.313.0", + "version": "3.314.1", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "2f5f173300888d6f630ce24751a6ee0f1e6d72e8" + "reference": "85207a1f342443f40711ac8fe246120821370f11" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/2f5f173300888d6f630ce24751a6ee0f1e6d72e8", - "reference": "2f5f173300888d6f630ce24751a6ee0f1e6d72e8", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/85207a1f342443f40711ac8fe246120821370f11", + "reference": "85207a1f342443f40711ac8fe246120821370f11", "shasum": "" }, "require": { @@ -151,9 +151,9 @@ "support": { "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80", "issues": "https://github.com/aws/aws-sdk-php/issues", - "source": "https://github.com/aws/aws-sdk-php/tree/3.313.0" + "source": "https://github.com/aws/aws-sdk-php/tree/3.314.1" }, - "time": "2024-06-11T18:20:58+00:00" + "time": "2024-06-13T18:07:00+00:00" }, { "name": "cebe/markdown", @@ -323,79 +323,30 @@ }, "time": "2023-11-17T15:01:25+00:00" }, - { - "name": "fillup/fake-bower-assets", - "version": "2.0.13", - "source": { - "type": "git", - "url": "https://github.com/fillup/fake-bower-assets.git", - "reference": "05ca2ac45757cee3906d6056c9623585c1eea68b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/fillup/fake-bower-assets/zipball/05ca2ac45757cee3906d6056c9623585c1eea68b", - "reference": "05ca2ac45757cee3906d6056c9623585c1eea68b", - "shasum": "" - }, - "replace": { - "bower-asset/bootstrap": "3.3.6", - "bower-asset/inputmask": "3.2.2", - "bower-asset/jquery": "2.2.2", - "bower-asset/jquery.inputmask": "3.2.2", - "bower-asset/punycode": "1.3.1", - "bower-asset/typeahead.js": "0.11.1", - "bower-asset/yii2-pjax": "2.0.1", - "yiisoft/yii2-bootstrap": "2.0.6" - }, - "type": "metapackage", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Phillip Shipley", - "email": "phillip.shipley@gmail.com" - } - ], - "description": "Use Composer \"replace\" to fake out installing bower-asset dependencies that aren't really needed", - "support": { - "issues": "https://github.com/fillup/fake-bower-assets/issues", - "source": "https://github.com/fillup/fake-bower-assets/tree/master" - }, - "time": "2018-05-08T17:44:00+00:00" - }, { "name": "gettext/gettext", - "version": "4.x-dev", + "version": "v5.7.0", "source": { "type": "git", "url": "https://github.com/php-gettext/Gettext.git", - "reference": "ed5535a5ae3314adee88fe603e5e730bb373adce" + "reference": "8657e580747bb3baacccdcebe69cac094661e404" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-gettext/Gettext/zipball/ed5535a5ae3314adee88fe603e5e730bb373adce", - "reference": "ed5535a5ae3314adee88fe603e5e730bb373adce", + "url": "https://api.github.com/repos/php-gettext/Gettext/zipball/8657e580747bb3baacccdcebe69cac094661e404", + "reference": "8657e580747bb3baacccdcebe69cac094661e404", "shasum": "" }, "require": { "gettext/languages": "^2.3", - "php": ">=5.4.0" + "php": "^7.2|^8.0" }, "require-dev": { - "illuminate/view": "^5.0.x-dev", - "phpunit/phpunit": "^4.8|^5.7|^6.5", - "squizlabs/php_codesniffer": "^3.0", - "symfony/yaml": "~2", - "twig/extensions": "*", - "twig/twig": "^1.31|^2.0" - }, - "suggest": { - "illuminate/view": "Is necessary if you want to use the Blade extractor", - "symfony/yaml": "Is necessary if you want to use the Yaml extractor/generator", - "twig/extensions": "Is necessary if you want to use the Twig extractor", - "twig/twig": "Is necessary if you want to use the Twig extractor" + "brick/varexporter": "^0.3.5", + "friendsofphp/php-cs-fixer": "^3.2", + "oscarotero/php-cs-fixer-config": "^2.0", + "phpunit/phpunit": "^8.0|^9.0", + "squizlabs/php_codesniffer": "^3.0" }, "type": "library", "autoload": { @@ -416,7 +367,7 @@ } ], "description": "PHP gettext manager", - "homepage": "https://github.com/oscarotero/Gettext", + "homepage": "https://github.com/php-gettext/Gettext", "keywords": [ "JS", "gettext", @@ -427,8 +378,8 @@ ], "support": { "email": "oom@oscarotero.com", - "issues": "https://github.com/oscarotero/Gettext/issues", - "source": "https://github.com/php-gettext/Gettext/tree/4.x" + "issues": "https://github.com/php-gettext/Gettext/issues", + "source": "https://github.com/php-gettext/Gettext/tree/v5.7.0" }, "funding": [ { @@ -444,7 +395,7 @@ "type": "patreon" } ], - "time": "2022-12-11T19:37:51+00:00" + "time": "2022-07-27T19:54:55+00:00" }, { "name": "gettext/languages", @@ -520,6 +471,80 @@ ], "time": "2022-10-18T15:00:10+00:00" }, + { + "name": "gettext/translator", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/php-gettext/Translator.git", + "reference": "a4fa5ed740f304a0ed7b3e169b2b554a195c7570" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-gettext/Translator/zipball/a4fa5ed740f304a0ed7b3e169b2b554a195c7570", + "reference": "a4fa5ed740f304a0ed7b3e169b2b554a195c7570", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.15", + "gettext/gettext": "^5.0.0", + "oscarotero/php-cs-fixer-config": "^1.0", + "phpunit/phpunit": "^8.0", + "squizlabs/php_codesniffer": "^3.0" + }, + "suggest": { + "gettext/gettext": "Is necessary to load and generate array files used by the translator" + }, + "type": "library", + "autoload": { + "psr-4": { + "Gettext\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Oscar Otero", + "email": "oom@oscarotero.com", + "homepage": "http://oscarotero.com", + "role": "Developer" + } + ], + "description": "Gettext translator functions", + "homepage": "https://github.com/php-gettext/Translator", + "keywords": [ + "gettext", + "i18n", + "php", + "translator" + ], + "support": { + "email": "oom@oscarotero.com", + "issues": "https://github.com/php-gettext/Translator/issues", + "source": "https://github.com/php-gettext/Translator/tree/v1.2.0" + }, + "funding": [ + { + "url": "https://paypal.me/oscarotero", + "type": "custom" + }, + { + "url": "https://github.com/oscarotero", + "type": "github" + }, + { + "url": "https://www.patreon.com/misteroom", + "type": "patreon" + } + ], + "time": "2023-11-06T15:42:03+00:00" + }, { "name": "google/recaptcha", "version": "1.3.0", @@ -574,26 +599,26 @@ }, { "name": "guzzlehttp/command", - "version": "1.3.0", + "version": "1.3.1", "source": { "type": "git", "url": "https://github.com/guzzle/command.git", - "reference": "3372bcfd79d4b357b6871665bf06155515e8d844" + "reference": "0eebc653784f4902b3272e826fe8e88743d14e77" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/command/zipball/3372bcfd79d4b357b6871665bf06155515e8d844", - "reference": "3372bcfd79d4b357b6871665bf06155515e8d844", + "url": "https://api.github.com/repos/guzzle/command/zipball/0eebc653784f4902b3272e826fe8e88743d14e77", + "reference": "0eebc653784f4902b3272e826fe8e88743d14e77", "shasum": "" }, "require": { - "guzzlehttp/guzzle": "^7.5.1", - "guzzlehttp/promises": "^1.5.3 || ^2.0", - "guzzlehttp/psr7": "^1.9.1 || ^2.4.5", + "guzzlehttp/guzzle": "^7.8", + "guzzlehttp/promises": "^1.5.3 || ^2.0.1", + "guzzlehttp/psr7": "^1.9.1 || ^2.5.1", "php": "^7.2.5 || ^8.0" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.8.1", + "bamarni/composer-bin-plugin": "^1.8.2", "phpunit/phpunit": "^8.5.19 || ^9.5.8" }, "type": "library", @@ -637,7 +662,7 @@ "description": "Provides the foundation for building command-based web service clients", "support": { "issues": "https://github.com/guzzle/command/issues", - "source": "https://github.com/guzzle/command/tree/1.3.0" + "source": "https://github.com/guzzle/command/tree/1.3.1" }, "funding": [ { @@ -653,26 +678,26 @@ "type": "tidelift" } ], - "time": "2023-05-21T14:15:09+00:00" + "time": "2023-12-03T20:46:20+00:00" }, { "name": "guzzlehttp/guzzle", - "version": "7.7.0", + "version": "7.8.1", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "fb7566caccf22d74d1ab270de3551f72a58399f5" + "reference": "41042bc7ab002487b876a0683fc8dce04ddce104" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/fb7566caccf22d74d1ab270de3551f72a58399f5", - "reference": "fb7566caccf22d74d1ab270de3551f72a58399f5", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/41042bc7ab002487b876a0683fc8dce04ddce104", + "reference": "41042bc7ab002487b876a0683fc8dce04ddce104", "shasum": "" }, "require": { "ext-json": "*", - "guzzlehttp/promises": "^1.5.3 || ^2.0", - "guzzlehttp/psr7": "^1.9.1 || ^2.4.5", + "guzzlehttp/promises": "^1.5.3 || ^2.0.1", + "guzzlehttp/psr7": "^1.9.1 || ^2.5.1", "php": "^7.2.5 || ^8.0", "psr/http-client": "^1.0", "symfony/deprecation-contracts": "^2.2 || ^3.0" @@ -681,11 +706,11 @@ "psr/http-client-implementation": "1.0" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.8.1", + "bamarni/composer-bin-plugin": "^1.8.2", "ext-curl": "*", "php-http/client-integration-tests": "dev-master#2c025848417c1135031fdf9c728ee53d0a7ceaee as 3.0.999", "php-http/message-factory": "^1.1", - "phpunit/phpunit": "^8.5.29 || ^9.5.23", + "phpunit/phpunit": "^8.5.36 || ^9.6.15", "psr/log": "^1.1 || ^2.0 || ^3.0" }, "suggest": { @@ -763,7 +788,7 @@ ], "support": { "issues": "https://github.com/guzzle/guzzle/issues", - "source": "https://github.com/guzzle/guzzle/tree/7.7.0" + "source": "https://github.com/guzzle/guzzle/tree/7.8.1" }, "funding": [ { @@ -779,31 +804,31 @@ "type": "tidelift" } ], - "time": "2023-05-21T14:04:53+00:00" + "time": "2023-12-03T20:35:24+00:00" }, { "name": "guzzlehttp/guzzle-services", - "version": "1.4.0", + "version": "1.4.1", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle-services.git", - "reference": "f4bb1c205152a56741624b88753732e01a60565c" + "reference": "bcab7c0d61672b606510a6fe5af3039d04968c0f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle-services/zipball/f4bb1c205152a56741624b88753732e01a60565c", - "reference": "f4bb1c205152a56741624b88753732e01a60565c", + "url": "https://api.github.com/repos/guzzle/guzzle-services/zipball/bcab7c0d61672b606510a6fe5af3039d04968c0f", + "reference": "bcab7c0d61672b606510a6fe5af3039d04968c0f", "shasum": "" }, "require": { - "guzzlehttp/command": "^1.3", - "guzzlehttp/guzzle": "^7.7", - "guzzlehttp/psr7": "^1.9.1 || ^2.4.5", + "guzzlehttp/command": "^1.3.1", + "guzzlehttp/guzzle": "^7.8", + "guzzlehttp/psr7": "^1.9.1 || ^2.5.1", "guzzlehttp/uri-template": "^1.0.1", "php": "^7.2.5 || ^8.0" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.8.1", + "bamarni/composer-bin-plugin": "^1.8.2", "phpunit/phpunit": "^8.5.19 || ^9.5.8" }, "suggest": { @@ -850,7 +875,7 @@ "description": "Provides an implementation of the Guzzle Command library that uses Guzzle service descriptions to describe web services, serialize requests, and parse responses into easy to use model structures.", "support": { "issues": "https://github.com/guzzle/guzzle-services/issues", - "source": "https://github.com/guzzle/guzzle-services/tree/1.4.0" + "source": "https://github.com/guzzle/guzzle-services/tree/1.4.1" }, "funding": [ { @@ -866,33 +891,37 @@ "type": "tidelift" } ], - "time": "2023-05-21T14:21:30+00:00" + "time": "2023-12-03T20:48:14+00:00" }, { "name": "guzzlehttp/promises", - "version": "1.5.3", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "67ab6e18aaa14d753cc148911d273f6e6cb6721e" + "reference": "bbff78d96034045e58e13dedd6ad91b5d1253223" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/67ab6e18aaa14d753cc148911d273f6e6cb6721e", - "reference": "67ab6e18aaa14d753cc148911d273f6e6cb6721e", + "url": "https://api.github.com/repos/guzzle/promises/zipball/bbff78d96034045e58e13dedd6ad91b5d1253223", + "reference": "bbff78d96034045e58e13dedd6ad91b5d1253223", "shasum": "" }, "require": { - "php": ">=5.5" + "php": "^7.2.5 || ^8.0" }, "require-dev": { - "symfony/phpunit-bridge": "^4.4 || ^5.1" + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.36 || ^9.6.15" }, "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, "autoload": { - "files": [ - "src/functions_include.php" - ], "psr-4": { "GuzzleHttp\\Promise\\": "src/" } @@ -929,7 +958,7 @@ ], "support": { "issues": "https://github.com/guzzle/promises/issues", - "source": "https://github.com/guzzle/promises/tree/1.5.3" + "source": "https://github.com/guzzle/promises/tree/2.0.2" }, "funding": [ { @@ -945,20 +974,20 @@ "type": "tidelift" } ], - "time": "2023-05-21T12:31:43+00:00" + "time": "2023-12-03T20:19:20+00:00" }, { "name": "guzzlehttp/psr7", - "version": "2.5.0", + "version": "2.6.2", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "b635f279edd83fc275f822a1188157ffea568ff6" + "reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/b635f279edd83fc275f822a1188157ffea568ff6", - "reference": "b635f279edd83fc275f822a1188157ffea568ff6", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/45b30f99ac27b5ca93cb4831afe16285f57b8221", + "reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221", "shasum": "" }, "require": { @@ -972,9 +1001,9 @@ "psr/http-message-implementation": "1.0" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.8.1", + "bamarni/composer-bin-plugin": "^1.8.2", "http-interop/http-factory-tests": "^0.9", - "phpunit/phpunit": "^8.5.29 || ^9.5.23" + "phpunit/phpunit": "^8.5.36 || ^9.6.15" }, "suggest": { "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" @@ -1045,7 +1074,7 @@ ], "support": { "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/2.5.0" + "source": "https://github.com/guzzle/psr7/tree/2.6.2" }, "funding": [ { @@ -1061,34 +1090,36 @@ "type": "tidelift" } ], - "time": "2023-04-17T16:11:26+00:00" + "time": "2023-12-03T20:05:35+00:00" }, { "name": "guzzlehttp/uri-template", - "version": "v1.0.1", + "version": "v1.0.3", "source": { "type": "git", "url": "https://github.com/guzzle/uri-template.git", - "reference": "b945d74a55a25a949158444f09ec0d3c120d69e2" + "reference": "ecea8feef63bd4fef1f037ecb288386999ecc11c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/uri-template/zipball/b945d74a55a25a949158444f09ec0d3c120d69e2", - "reference": "b945d74a55a25a949158444f09ec0d3c120d69e2", + "url": "https://api.github.com/repos/guzzle/uri-template/zipball/ecea8feef63bd4fef1f037ecb288386999ecc11c", + "reference": "ecea8feef63bd4fef1f037ecb288386999ecc11c", "shasum": "" }, "require": { "php": "^7.2.5 || ^8.0", - "symfony/polyfill-php80": "^1.17" + "symfony/polyfill-php80": "^1.24" }, "require-dev": { - "phpunit/phpunit": "^8.5.19 || ^9.5.8", + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.36 || ^9.6.15", "uri-template/tests": "1.0.0" }, "type": "library", "extra": { - "branch-alias": { - "dev-master": "1.0-dev" + "bamarni-bin": { + "bin-links": true, + "forward-command": false } }, "autoload": { @@ -1129,7 +1160,7 @@ ], "support": { "issues": "https://github.com/guzzle/uri-template/issues", - "source": "https://github.com/guzzle/uri-template/tree/v1.0.1" + "source": "https://github.com/guzzle/uri-template/tree/v1.0.3" }, "funding": [ { @@ -1145,7 +1176,7 @@ "type": "tidelift" } ], - "time": "2021-10-07T12:57:01+00:00" + "time": "2023-12-03T19:50:20+00:00" }, { "name": "mlocati/ip-lib", @@ -1220,51 +1251,66 @@ }, { "name": "monolog/monolog", - "version": "1.27.1", + "version": "3.6.0", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "904713c5929655dc9b97288b69cfeedad610c9a1" + "reference": "4b18b21a5527a3d5ffdac2fd35d3ab25a9597654" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/904713c5929655dc9b97288b69cfeedad610c9a1", - "reference": "904713c5929655dc9b97288b69cfeedad610c9a1", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/4b18b21a5527a3d5ffdac2fd35d3ab25a9597654", + "reference": "4b18b21a5527a3d5ffdac2fd35d3ab25a9597654", "shasum": "" }, "require": { - "php": ">=5.3.0", - "psr/log": "~1.0" + "php": ">=8.1", + "psr/log": "^2.0 || ^3.0" }, "provide": { - "psr/log-implementation": "1.0.0" + "psr/log-implementation": "3.0.0" }, "require-dev": { - "aws/aws-sdk-php": "^2.4.9 || ^3.0", + "aws/aws-sdk-php": "^3.0", "doctrine/couchdb": "~1.0@dev", - "graylog2/gelf-php": "~1.0", - "php-amqplib/php-amqplib": "~2.4", - "php-console/php-console": "^3.1.3", - "phpstan/phpstan": "^0.12.59", - "phpunit/phpunit": "~4.5", - "ruflin/elastica": ">=0.90 <3.0", - "sentry/sentry": "^0.13", - "swiftmailer/swiftmailer": "^5.3|^6.0" + "elasticsearch/elasticsearch": "^7 || ^8", + "ext-json": "*", + "graylog2/gelf-php": "^1.4.2 || ^2.0", + "guzzlehttp/guzzle": "^7.4.5", + "guzzlehttp/psr7": "^2.2", + "mongodb/mongodb": "^1.8", + "php-amqplib/php-amqplib": "~2.4 || ^3", + "phpstan/phpstan": "^1.9", + "phpstan/phpstan-deprecation-rules": "^1.0", + "phpstan/phpstan-strict-rules": "^1.4", + "phpunit/phpunit": "^10.5.17", + "predis/predis": "^1.1 || ^2", + "ruflin/elastica": "^7", + "symfony/mailer": "^5.4 || ^6", + "symfony/mime": "^5.4 || ^6" }, "suggest": { "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", "doctrine/couchdb": "Allow sending log messages to a CouchDB server", + "elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client", "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", - "ext-mongo": "Allow sending log messages to a MongoDB server", + "ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler", + "ext-mbstring": "Allow to work properly with unicode symbols", + "ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)", + "ext-openssl": "Required to send log messages using SSL", + "ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)", "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", - "mongodb/mongodb": "Allow sending log messages to a MongoDB server via PHP Driver", + "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)", "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", - "php-console/php-console": "Allow sending log messages to Google Chrome", "rollbar/rollbar": "Allow sending log messages to Rollbar", - "ruflin/elastica": "Allow sending log messages to an Elastic Search server", - "sentry/sentry": "Allow sending log messages to a Sentry server" + "ruflin/elastica": "Allow sending log messages to an Elastic Search server" }, "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, "autoload": { "psr-4": { "Monolog\\": "src/Monolog" @@ -1278,11 +1324,11 @@ { "name": "Jordi Boggiano", "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" + "homepage": "https://seld.be" } ], "description": "Sends your logs to files, sockets, inboxes, databases and various web services", - "homepage": "http://github.com/Seldaek/monolog", + "homepage": "https://github.com/Seldaek/monolog", "keywords": [ "log", "logging", @@ -1290,7 +1336,7 @@ ], "support": { "issues": "https://github.com/Seldaek/monolog/issues", - "source": "https://github.com/Seldaek/monolog/tree/1.27.1" + "source": "https://github.com/Seldaek/monolog/tree/3.6.0" }, "funding": [ { @@ -1302,7 +1348,7 @@ "type": "tidelift" } ], - "time": "2022-06-09T08:53:42+00:00" + "time": "2024-04-12T21:02:21+00:00" }, { "name": "mtdowling/jmespath.php", @@ -1420,94 +1466,18 @@ }, "time": "2020-10-15T08:29:30+00:00" }, - { - "name": "phpfastcache/riak-client", - "version": "3.4.3", - "source": { - "type": "git", - "url": "https://github.com/PHPSocialNetwork/riak-php-client.git", - "reference": "d771f75d16196006604a30bb15adc1c6a9b0fcc9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHPSocialNetwork/riak-php-client/zipball/d771f75d16196006604a30bb15adc1c6a9b0fcc9", - "reference": "d771f75d16196006604a30bb15adc1c6a9b0fcc9", - "shasum": "" - }, - "require": { - "ext-curl": "*", - "ext-json": "*", - "php": ">=5.4" - }, - "conflict": { - "basho/riak": "*" - }, - "require-dev": { - "apigen/apigen": "4.1.*", - "phpunit/phpunit": "4.8.*" - }, - "type": "library", - "autoload": { - "psr-4": { - "Basho\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache-2.0" - ], - "authors": [ - { - "name": "Georges.L", - "email": "contact@geolim4.com", - "homepage": "https://github.com/Geolim4", - "role": "Maintainer" - }, - { - "name": "Christopher Mancini", - "email": "cmancini@basho.com", - "homepage": "https://github.com/christophermancini", - "role": "Former Lead Developer" - }, - { - "name": "Alex Moore", - "email": "amoore@basho.com", - "homepage": "https://github.com/alexmoore", - "role": "Former Developer" - } - ], - "description": "Riak client for PHP (Fork of the official basho/riak due to maintainer significant inactivity)", - "homepage": "https://github.com/PHPSocialNetwork/riak-php-client", - "keywords": [ - "basho", - "client", - "crdt", - "data", - "database", - "datatype", - "driver", - "kv", - "nosql", - "riak" - ], - "support": { - "issues": "https://github.com/PHPSocialNetwork/riak-php-client/issues", - "source": "https://github.com/PHPSocialNetwork/riak-php-client/tree/develop" - }, - "time": "2017-11-23T21:33:15+00:00" - }, { "name": "phpmailer/phpmailer", - "version": "v6.8.0", + "version": "v6.9.1", "source": { "type": "git", "url": "https://github.com/PHPMailer/PHPMailer.git", - "reference": "df16b615e371d81fb79e506277faea67a1be18f1" + "reference": "039de174cd9c17a8389754d3b877a2ed22743e18" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/df16b615e371d81fb79e506277faea67a1be18f1", - "reference": "df16b615e371d81fb79e506277faea67a1be18f1", + "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/039de174cd9c17a8389754d3b877a2ed22743e18", + "reference": "039de174cd9c17a8389754d3b877a2ed22743e18", "shasum": "" }, "require": { @@ -1517,16 +1487,17 @@ "php": ">=5.5.0" }, "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.7.2", + "dealerdirect/phpcodesniffer-composer-installer": "^1.0", "doctrine/annotations": "^1.2.6 || ^1.13.3", "php-parallel-lint/php-console-highlighter": "^1.0.0", "php-parallel-lint/php-parallel-lint": "^1.3.2", "phpcompatibility/php-compatibility": "^9.3.5", "roave/security-advisories": "dev-latest", - "squizlabs/php_codesniffer": "^3.7.1", + "squizlabs/php_codesniffer": "^3.7.2", "yoast/phpunit-polyfills": "^1.0.4" }, "suggest": { + "decomplexity/SendOauth2": "Adapter for using XOAUTH2 authentication", "ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses", "ext-openssl": "Needed for secure SMTP sending and DKIM signing", "greew/oauth2-azure-provider": "Needed for Microsoft Azure XOAUTH2 authentication", @@ -1566,7 +1537,7 @@ "description": "PHPMailer is a full-featured email creation and transfer class for PHP", "support": { "issues": "https://github.com/PHPMailer/PHPMailer/issues", - "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.8.0" + "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.9.1" }, "funding": [ { @@ -1574,7 +1545,7 @@ "type": "github" } ], - "time": "2023-03-06T14:43:22+00:00" + "time": "2023-11-25T22:23:28+00:00" }, { "name": "phpspec/php-diff", @@ -1619,16 +1590,16 @@ }, { "name": "psr/cache", - "version": "2.0.0", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/php-fig/cache.git", - "reference": "213f9dbc5b9bfbc4f8db86d2838dc968752ce13b" + "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/cache/zipball/213f9dbc5b9bfbc4f8db86d2838dc968752ce13b", - "reference": "213f9dbc5b9bfbc4f8db86d2838dc968752ce13b", + "url": "https://api.github.com/repos/php-fig/cache/zipball/aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", + "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", "shasum": "" }, "require": { @@ -1662,28 +1633,33 @@ "psr-6" ], "support": { - "source": "https://github.com/php-fig/cache/tree/2.0.0" + "source": "https://github.com/php-fig/cache/tree/3.0.0" }, - "time": "2021-02-03T23:23:37+00:00" + "time": "2021-02-03T23:26:27+00:00" }, { "name": "psr/container", - "version": "1.1.2", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/php-fig/container.git", - "reference": "513e0666f7216c7459170d56df27dfcefe1689ea" + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea", - "reference": "513e0666f7216c7459170d56df27dfcefe1689ea", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", "shasum": "" }, "require": { "php": ">=7.4.0" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, "autoload": { "psr-4": { "Psr\\Container\\": "src/" @@ -1710,22 +1686,72 @@ ], "support": { "issues": "https://github.com/php-fig/container/issues", - "source": "https://github.com/php-fig/container/tree/1.1.2" + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+00:00" + }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" }, - "time": "2021-11-05T16:50:12+00:00" + "time": "2019-01-08T18:20:26+00:00" }, { "name": "psr/http-client", - "version": "1.0.2", + "version": "1.0.3", "source": { "type": "git", "url": "https://github.com/php-fig/http-client.git", - "reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31" + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-client/zipball/0955afe48220520692d2d09f7ab7e0f93ffd6a31", - "reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", "shasum": "" }, "require": { @@ -1762,26 +1788,26 @@ "psr-18" ], "support": { - "source": "https://github.com/php-fig/http-client/tree/1.0.2" + "source": "https://github.com/php-fig/http-client" }, - "time": "2023-04-10T20:12:12+00:00" + "time": "2023-09-23T14:17:50+00:00" }, { "name": "psr/http-factory", - "version": "1.0.2", + "version": "1.1.0", "source": { "type": "git", "url": "https://github.com/php-fig/http-factory.git", - "reference": "e616d01114759c4c489f93b099585439f795fe35" + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35", - "reference": "e616d01114759c4c489f93b099585439f795fe35", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a", "shasum": "" }, "require": { - "php": ">=7.0.0", + "php": ">=7.1", "psr/http-message": "^1.0 || ^2.0" }, "type": "library", @@ -1805,7 +1831,7 @@ "homepage": "https://www.php-fig.org/" } ], - "description": "Common interfaces for PSR-7 HTTP message factories", + "description": "PSR-17: Common interfaces for PSR-7 HTTP message factories", "keywords": [ "factory", "http", @@ -1817,9 +1843,9 @@ "response" ], "support": { - "source": "https://github.com/php-fig/http-factory/tree/1.0.2" + "source": "https://github.com/php-fig/http-factory" }, - "time": "2023-04-10T20:10:41+00:00" + "time": "2024-04-15T12:06:14+00:00" }, { "name": "psr/http-message", @@ -1876,30 +1902,30 @@ }, { "name": "psr/log", - "version": "1.1.4", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11" + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11", + "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=8.0.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1.x-dev" + "dev-master": "3.x-dev" } }, "autoload": { "psr-4": { - "Psr\\Log\\": "Psr/Log/" + "Psr\\Log\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -1920,9 +1946,9 @@ "psr-3" ], "support": { - "source": "https://github.com/php-fig/log/tree/1.1.4" + "source": "https://github.com/php-fig/log/tree/3.0.0" }, - "time": "2021-05-03T11:20:27+00:00" + "time": "2021-07-14T16:46:02+00:00" }, { "name": "ralouphie/getallheaders", @@ -2015,61 +2041,74 @@ "source": { "type": "git", "url": "https://github.com/Roave/SecurityAdvisories.git", - "reference": "69dafab8a5dffa4d6a4d6dab1ebadf48aca449c7" + "reference": "2e530fa2b00d046ceb5660f3139af583170ea7f9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/69dafab8a5dffa4d6a4d6dab1ebadf48aca449c7", - "reference": "69dafab8a5dffa4d6a4d6dab1ebadf48aca449c7", + "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/2e530fa2b00d046ceb5660f3139af583170ea7f9", + "reference": "2e530fa2b00d046ceb5660f3139af583170ea7f9", "shasum": "" }, "conflict": { "3f/pygmentize": "<1.2", - "admidio/admidio": "<4.2.10", + "admidio/admidio": "<4.2.13", "adodb/adodb-php": "<=5.20.20|>=5.21,<=5.21.3", "aheinze/cockpit": "<2.2", + "aimeos/ai-client-html": ">=2020.04.1,<2020.10.27|>=2021.04.1,<2021.10.21|>=2022.04.1,<2022.10.12|>=2023.04.1,<2023.10.14|>=2024.04.1,<2024.04.4", + "aimeos/aimeos-core": "<2024.04.7", "aimeos/aimeos-typo3": "<19.10.12|>=20,<20.10.5", + "airesvsg/acf-to-rest-api": "<=3.1", "akaunting/akaunting": "<2.1.13", "akeneo/pim-community-dev": "<5.0.119|>=6,<6.0.53", "alextselegidis/easyappointments": "<1.5", "alterphp/easyadmin-extension-bundle": ">=1.2,<1.2.11|>=1.3,<1.3.1", "amazing/media2click": ">=1,<1.3.3", "amphp/artax": "<1.0.6|>=2,<2.0.6", - "amphp/http": "<1.0.1", + "amphp/http": "<=1.7.2|>=2,<=2.1", "amphp/http-client": ">=4,<4.4", "anchorcms/anchor-cms": "<=0.12.7", "andreapollastri/cipi": "<=3.1.15", "andrewhaine/silverstripe-form-capture": ">=0.2,<=0.2.3|>=1,<1.0.2|>=2,<2.2.5", + "apache-solr-for-typo3/solr": "<2.8.3", "apereo/phpcas": "<1.6", "api-platform/core": ">=2.2,<2.2.10|>=2.3,<2.3.6|>=2.6,<2.7.10|>=3,<3.0.12|>=3.1,<3.1.3", "appwrite/server-ce": "<=1.2.1", "arc/web": "<3", "area17/twill": "<1.2.5|>=2,<2.5.3", "artesaos/seotools": "<0.17.2", - "asymmetricrypt/asymmetricrypt": ">=0,<9.9.99", + "asymmetricrypt/asymmetricrypt": "<9.9.99", "athlon1600/php-proxy": "<=5.1", "athlon1600/php-proxy-app": "<=3", - "automad/automad": "<1.8", + "austintoddj/canvas": "<=3.4.2", + "automad/automad": "<=1.10.9", + "automattic/jetpack": "<9.8", "awesome-support/awesome-support": "<=6.0.7", - "aws/aws-sdk-php": ">=3,<3.2.1", + "aws/aws-sdk-php": "<3.288.1", "azuracast/azuracast": "<0.18.3", "backdrop/backdrop": "<1.24.2", "backpack/crud": "<3.4.9", + "bacula-web/bacula-web": "<8.0.0.0-RC2-dev", "badaso/core": "<2.7", - "bagisto/bagisto": "<0.1.5", + "bagisto/bagisto": "<2.1", "barrelstrength/sprout-base-email": "<1.2.7", "barrelstrength/sprout-forms": "<3.9", "barryvdh/laravel-translation-manager": "<0.6.2", "barzahlen/barzahlen-php": "<2.0.1", - "baserproject/basercms": "<4.7.5", + "baserproject/basercms": "<5.0.9", "bassjobsen/bootstrap-3-typeahead": ">4.0.2", + "bbpress/bbpress": "<2.6.5", + "bcosca/fatfree": "<3.7.2", + "bedita/bedita": "<4", "bigfork/silverstripe-form-capture": ">=3,<3.1.1", - "billz/raspap-webgui": "<2.8.9", + "billz/raspap-webgui": "<2.9.5", "bk2k/bootstrap-package": ">=7.1,<7.1.2|>=8,<8.0.8|>=9,<9.0.4|>=9.1,<9.1.3|>=10,<10.0.10|>=11,<11.0.3", + "blueimp/jquery-file-upload": "==6.4.4", "bmarshall511/wordpress_zero_spam": "<5.2.13", "bolt/bolt": "<3.7.2", "bolt/core": "<=4.2", + "born05/craft-twofactorauthentication": "<3.3.4", "bottelet/flarepoint": "<2.2.1", + "bref/bref": "<2.1.17", "brightlocal/phpwhois": "<=4.2.5", "brotkrueml/codehighlight": "<2.7", "brotkrueml/schema": "<1.13.1|>=2,<2.5.1", @@ -2078,136 +2117,168 @@ "bugsnag/bugsnag-laravel": ">=2,<2.0.2", "bytefury/crater": "<6.0.2", "cachethq/cachet": "<2.5.1", - "cakephp/cakephp": "<3.10.3|>=4,<4.0.10|>=4.2,<4.2.12|>=4.3,<4.3.11|>=4.4,<4.4.10|= 1.3.7|>=4.1,<4.1.4", + "cakephp/cakephp": "<3.10.3|>=4,<4.0.10|>=4.1,<4.1.4|>=4.2,<4.2.12|>=4.3,<4.3.11|>=4.4,<4.4.10", "cakephp/database": ">=4.2,<4.2.12|>=4.3,<4.3.11|>=4.4,<4.4.10", "cardgate/magento2": "<2.0.33", "cardgate/woocommerce": "<=3.1.15", "cart2quote/module-quotation": ">=4.1.6,<=4.4.5|>=5,<5.4.4", + "cart2quote/module-quotation-encoded": ">=4.1.6,<=4.4.5|>=5,<5.4.4", "cartalyst/sentry": "<=2.1.6", "catfan/medoo": "<1.7.5", - "centreon/centreon": "<22.10-beta.1", + "causal/oidc": "<2.1", + "cecil/cecil": "<7.47.1", + "centreon/centreon": "<22.10.15", "cesnet/simplesamlphp-module-proxystatistics": "<3.1", - "cockpit-hq/cockpit": "<2.6", + "chriskacerguis/codeigniter-restserver": "<=2.7.1", + "civicrm/civicrm-core": ">=4.2,<4.2.9|>=4.3,<4.3.3", + "ckeditor/ckeditor": "<4.24", + "cockpit-hq/cockpit": "<2.7|==2.7", "codeception/codeception": "<3.1.3|>=4,<4.1.22", - "codeigniter/framework": "<=3.0.6", - "codeigniter4/framework": "<4.3.5", - "codeigniter4/shield": "<1-beta.4|= 1.0.0-beta", + "codeigniter/framework": "<3.1.9", + "codeigniter4/framework": "<4.4.7", + "codeigniter4/shield": "<1.0.0.0-beta8", "codiad/codiad": "<=2.8.4", - "composer/composer": "<1.10.26|>=2-alpha.1,<2.2.12|>=2.3,<2.3.5", - "concrete5/concrete5": "<9.2|>= 9.0.0RC1, < 9.1.3", + "composer/composer": "<1.10.27|>=2,<2.2.24|>=2.3,<2.7.7", + "concrete5/concrete5": "<9.2.8", "concrete5/core": "<8.5.8|>=9,<9.1", "contao-components/mediaelement": ">=2.14.2,<2.21.1", - "contao/contao": ">=4,<4.4.56|>=4.5,<4.9.40|>=4.10,<4.11.7|>=4.13,<4.13.21|>=5.1,<5.1.4", - "contao/core": ">=2,<3.5.39", - "contao/core-bundle": "<4.9.42|>=4.10,<4.13.28|>=5,<5.1.10|= 4.10.0", - "contao/listing-bundle": ">=4,<4.4.8", + "contao/comments-bundle": ">=2,<4.13.40|>=5.0.0.0-RC1-dev,<5.3.4", + "contao/contao": ">=3,<3.5.37|>=4,<4.4.56|>=4.5,<4.9.40|>=4.10,<4.11.7|>=4.13,<4.13.21|>=5.1,<5.1.4", + "contao/core": "<3.5.39", + "contao/core-bundle": "<4.13.40|>=5,<5.3.4", + "contao/listing-bundle": ">=3,<=3.5.30|>=4,<4.4.8", "contao/managed-edition": "<=1.5", + "corveda/phpsandbox": "<1.3.5", "cosenary/instagram": "<=2.3", - "craftcms/cms": "<=4.4.9|>= 4.0.0-RC1, < 4.4.12|>= 4.0.0-RC1, <= 4.4.5|>= 4.0.0-RC1, <= 4.4.6|>= 4.0.0-RC1, < 4.4.6|>= 4.0.0-RC1, < 4.3.7|>= 4.0.0-RC1, < 4.2.1", - "croogo/croogo": "<3.0.7", + "craftcms/cms": "<4.6.2", + "croogo/croogo": "<4", "cuyz/valinor": "<0.12", "czproject/git-php": "<4.0.3", + "dapphp/securimage": "<3.6.6", "darylldoyle/safe-svg": "<1.9.10", "datadog/dd-trace": ">=0.30,<0.30.2", + "datatables/datatables": "<1.10.10", "david-garcia/phpwhois": "<=4.3.1", "dbrisinajumi/d2files": "<1", - "dcat/laravel-admin": "<=2.1.3-beta", + "dcat/laravel-admin": "<=2.1.3.0-beta", "derhansen/fe_change_pwd": "<2.0.5|>=3,<3.0.3", - "derhansen/sf_event_mgt": "<4.3.1|>=5,<5.1.1", + "derhansen/sf_event_mgt": "<4.3.1|>=5,<5.1.1|>=7,<7.4", "desperado/xml-bundle": "<=0.1.7", - "directmailteam/direct-mail": "<5.2.4", - "doctrine/annotations": ">=1,<1.2.7", + "devgroup/dotplant": "<2020.09.14-dev", + "directmailteam/direct-mail": "<6.0.3|>=7,<7.0.3|>=8,<9.5.2", + "doctrine/annotations": "<1.2.7", "doctrine/cache": ">=1,<1.3.2|>=1.4,<1.4.2", - "doctrine/common": ">=2,<2.4.3|>=2.5,<2.5.1", + "doctrine/common": "<2.4.3|>=2.5,<2.5.1", "doctrine/dbal": ">=2,<2.0.8|>=2.1,<2.1.2|>=3,<3.1.4", "doctrine/doctrine-bundle": "<1.5.2", - "doctrine/doctrine-module": "<=0.7.1", - "doctrine/mongodb-odm": ">=1,<1.0.2", - "doctrine/mongodb-odm-bundle": ">=2,<3.0.1", - "doctrine/orm": ">=2,<2.4.8|>=2.5,<2.5.1|>=2.8.3,<2.8.4", - "dolibarr/dolibarr": "<17.0.1|= 12.0.5|>= 3.3.beta1, < 13.0.2", - "dompdf/dompdf": "<2.0.2|= 2.0.2", - "drupal/core": ">=7,<7.96|>=8,<9.4.14|>=9.5,<9.5.8|>=10,<10.0.8", - "drupal/drupal": ">=7,<7.80|>=8,<8.9.16|>=9,<9.1.12|>=9.2,<9.2.4", + "doctrine/doctrine-module": "<0.7.2", + "doctrine/mongodb-odm": "<1.0.2", + "doctrine/mongodb-odm-bundle": "<3.0.1", + "doctrine/orm": ">=1,<1.2.4|>=2,<2.4.8|>=2.5,<2.5.1|>=2.8.3,<2.8.4", + "dolibarr/dolibarr": "<19.0.2", + "dompdf/dompdf": "<2.0.4", + "doublethreedigital/guest-entries": "<3.1.2", + "drupal/core": ">=6,<6.38|>=7,<7.96|>=8,<10.1.8|>=10.2,<10.2.2", + "drupal/drupal": ">=5,<5.11|>=6,<6.38|>=7,<7.80|>=8,<8.9.16|>=9,<9.1.12|>=9.2,<9.2.4", + "duncanmcclean/guest-entries": "<3.1.2", "dweeves/magmi": "<=0.7.24", + "ec-cube/ec-cube": "<2.4.4|>=2.11,<=2.17.1|>=3,<=3.0.18.0-patch4|>=4,<=4.1.2", "ecodev/newsletter": "<=4", "ectouch/ectouch": "<=2.7.2", - "elefant/cms": "<1.3.13", + "egroupware/egroupware": "<16.1.20170922", + "elefant/cms": "<2.0.7", "elgg/elgg": "<3.3.24|>=4,<4.0.5", + "elijaa/phpmemcacheadmin": "<=1.3", "encore/laravel-admin": "<=1.8.19", "endroid/qr-code-bundle": "<3.4.2", + "enhavo/enhavo-app": "<=0.13.1", "enshrined/svg-sanitize": "<0.15", "erusev/parsedown": "<1.7.2", "ether/logs": "<3.0.4", + "evolutioncms/evolution": "<=3.2.3", "exceedone/exment": "<4.4.3|>=5,<5.0.3", - "exceedone/laravel-admin": "= 3.0.0|<2.2.3", - "ezsystems/demobundle": ">=5.4,<5.4.6.1", + "exceedone/laravel-admin": "<2.2.3|==3", + "ezsystems/demobundle": ">=5.4,<5.4.6.1-dev", "ezsystems/ez-support-tools": ">=2.2,<2.2.3", - "ezsystems/ezdemo-ls-extension": ">=5.4,<5.4.2.1", - "ezsystems/ezfind-ls": ">=5.3,<5.3.6.1|>=5.4,<5.4.11.1|>=2017.12,<2017.12.0.1", + "ezsystems/ezdemo-ls-extension": ">=5.4,<5.4.2.1-dev", + "ezsystems/ezfind-ls": ">=5.3,<5.3.6.1-dev|>=5.4,<5.4.11.1-dev|>=2017.12,<2017.12.0.1-dev", "ezsystems/ezplatform": "<=1.13.6|>=2,<=2.5.24", "ezsystems/ezplatform-admin-ui": ">=1.3,<1.3.5|>=1.4,<1.4.6|>=1.5,<1.5.29|>=2.3,<2.3.26", "ezsystems/ezplatform-admin-ui-assets": ">=4,<4.2.1|>=5,<5.0.1|>=5.1,<5.1.1", - "ezsystems/ezplatform-graphql": ">=1-rc.1,<1.0.13|>=2-beta.1,<2.3.12", - "ezsystems/ezplatform-kernel": "<1.2.5.1|>=1.3,<1.3.26", + "ezsystems/ezplatform-graphql": ">=1.0.0.0-RC1-dev,<1.0.13|>=2.0.0.0-beta1,<2.3.12", + "ezsystems/ezplatform-kernel": "<1.2.5.1-dev|>=1.3,<1.3.35", "ezsystems/ezplatform-rest": ">=1.2,<=1.2.2|>=1.3,<1.3.8", - "ezsystems/ezplatform-richtext": ">=2.3,<2.3.7.1", + "ezsystems/ezplatform-richtext": ">=2.3,<2.3.7.1-dev", + "ezsystems/ezplatform-solr-search-engine": ">=1.7,<1.7.12|>=2,<2.0.2|>=3.3,<3.3.15", "ezsystems/ezplatform-user": ">=1,<1.0.1", - "ezsystems/ezpublish-kernel": "<6.13.8.2|>=7,<7.5.30", - "ezsystems/ezpublish-legacy": "<=2017.12.7.3|>=2018.6,<=2019.3.5.1", + "ezsystems/ezpublish-kernel": "<6.13.8.2-dev|>=7,<7.5.31", + "ezsystems/ezpublish-legacy": "<=2017.12.7.3|>=2018.6,<=2019.03.5.1", "ezsystems/platform-ui-assets-bundle": ">=4.2,<4.2.3", - "ezsystems/repository-forms": ">=2.3,<2.3.2.1|>=2.5,<2.5.15", + "ezsystems/repository-forms": ">=2.3,<2.3.2.1-dev|>=2.5,<2.5.15", "ezyang/htmlpurifier": "<4.1.1", "facade/ignition": "<1.16.15|>=2,<2.4.2|>=2.5,<2.5.2", - "facturascripts/facturascripts": "<=2022.8", + "facturascripts/facturascripts": "<=2022.08", + "fastly/magento2": "<1.2.26", "feehi/cms": "<=2.1.1", "feehi/feehicms": "<=2.1.1", "fenom/fenom": "<=2.12.1", "filegator/filegator": "<7.8", + "filp/whoops": "<2.1.13", + "fineuploader/php-traditional-server": "<=1.2.2", "firebase/php-jwt": "<6", "fixpunkt/fp-masterquiz": "<2.2.1|>=3,<3.5.2", "fixpunkt/fp-newsletter": "<1.1.1|>=2,<2.1.2|>=2.2,<3.2.6", - "flarum/core": "<1.7", - "flarum/framework": "<=0.1-beta.7.1", + "flarum/core": "<1.8.5", + "flarum/flarum": "<0.1.0.0-beta8", + "flarum/framework": "<1.8.5", "flarum/mentions": "<1.6.3", - "flarum/sticky": ">=0.1-beta.14,<=0.1-beta.15", - "flarum/tags": "<=0.1-beta.13", + "flarum/sticky": ">=0.1.0.0-beta14,<=0.1.0.0-beta15", + "flarum/tags": "<=0.1.0.0-beta13", + "floriangaerber/magnesium": "<0.3.1", "fluidtypo3/vhs": "<5.1.1", - "fof/byobu": ">=0.3-beta.2,<1.1.7", + "fof/byobu": ">=0.3.0.0-beta2,<1.1.7", "fof/upload": "<1.2.3", + "foodcoopshop/foodcoopshop": ">=3.2,<3.6.1", "fooman/tcpdf": "<6.2.22", "forkcms/forkcms": "<5.11.1", "fossar/tcpdf-parser": "<6.2.22", - "francoisjacquet/rosariosis": "<11", + "francoisjacquet/rosariosis": "<=11.5.1", "frappant/frp-form-answers": "<3.1.2|>=4,<4.0.2", "friendsofsymfony/oauth2-php": "<1.3", "friendsofsymfony/rest-bundle": ">=1.2,<1.2.2", - "friendsofsymfony/user-bundle": ">=1.2,<1.3.5", + "friendsofsymfony/user-bundle": ">=1,<1.3.5", + "friendsofsymfony1/swiftmailer": ">=4,<5.4.13|>=6,<6.2.5", + "friendsofsymfony1/symfony1": ">=1.1,<1.15.19", "friendsoftypo3/mediace": ">=7.6.2,<7.6.5", - "froala/wysiwyg-editor": "<3.2.7", - "froxlor/froxlor": "<2.1", + "friendsoftypo3/openid": ">=4.5,<4.5.31|>=4.7,<4.7.16|>=6,<6.0.11|>=6.1,<6.1.6", + "froala/wysiwyg-editor": "<3.2.7|>=4.0.1,<=4.1.3", + "froxlor/froxlor": "<2.1.9", + "frozennode/administrator": "<=5.0.12", "fuel/core": "<1.8.1", "funadmin/funadmin": "<=3.2|>=3.3.2,<=3.3.3", "gaoming13/wechat-php-sdk": "<=1.10.2", "genix/cms": "<=1.1.11", - "getgrav/grav": "<=1.7.42.1", - "getkirby/cms": "= 3.8.0|<3.5.8.2|>=3.6,<3.6.6.2|>=3.7,<3.7.5.1", + "getformwork/formwork": "<1.13.1|==2.0.0.0-beta1", + "getgrav/grav": "<1.7.46", + "getkirby/cms": "<4.1.1", "getkirby/kirby": "<=2.5.12", "getkirby/panel": "<2.5.14", "getkirby/starterkit": "<=3.7.0.2", - "gilacms/gila": "<=1.11.4", + "gilacms/gila": "<=1.15.4", + "gleez/cms": "<=1.3|==2", "globalpayments/php-sdk": "<2", "gogentooss/samlbase": "<1.2.7", "google/protobuf": "<3.15", "gos/web-socket-bundle": "<1.10.4|>=2,<2.6.1|>=3,<3.3", "gree/jose": "<2.2.1", "gregwar/rst": "<1.0.3", - "grumpydictator/firefly-iii": "<6", + "grumpydictator/firefly-iii": "<6.1.7", + "gugoan/economizzer": "<=0.9.0.0-beta1", "guzzlehttp/guzzle": "<6.5.8|>=7,<7.4.5", "guzzlehttp/psr7": "<1.9.1|>=2,<2.4.5", "haffner/jh_captcha": "<=2.1.3|>=3,<=3.0.2", "harvesthq/chosen": "<1.8.7", - "helloxz/imgurl": "= 2.31|<=2.31", + "helloxz/imgurl": "<=2.31", "hhxsv5/laravel-s": "<3.7.36", "hillelcoren/invoice-ninja": "<5.3.35", "himiklab/yii2-jqgrid-widget": "<1.0.8", @@ -2216,268 +2287,340 @@ "httpsoft/http-message": "<1.0.12", "hyn/multi-tenant": ">=5.6,<5.7.2", "ibexa/admin-ui": ">=4.2,<4.2.3", - "ibexa/core": ">=4,<4.0.7|>=4.1,<4.1.4|>=4.2,<4.2.3", + "ibexa/core": ">=4,<4.0.7|>=4.1,<4.1.4|>=4.2,<4.2.3|>=4.5,<4.5.6|>=4.6,<4.6.2", "ibexa/graphql": ">=2.5,<2.5.31|>=3.3,<3.3.28|>=4.2,<4.2.3", "ibexa/post-install": "<=1.0.4", + "ibexa/solr": ">=4.5,<4.5.4", "ibexa/user": ">=4,<4.4.3", "icecoder/icecoder": "<=8.1", "idno/known": "<=1.3.1", - "illuminate/auth": ">=4,<4.0.99|>=4.1,<=4.1.31|>=4.2,<=4.2.22|>=5,<=5.0.35|>=5.1,<=5.1.46|>=5.2,<=5.2.45|>=5.3,<=5.3.31|>=5.4,<=5.4.36|>=5.5,<5.5.10", - "illuminate/cookie": ">=4,<=4.0.11|>=4.1,<=4.1.99999|>=4.2,<=4.2.99999|>=5,<=5.0.99999|>=5.1,<=5.1.99999|>=5.2,<=5.2.99999|>=5.3,<=5.3.99999|>=5.4,<=5.4.99999|>=5.5,<=5.5.49|>=5.6,<=5.6.99999|>=5.7,<=5.7.99999|>=5.8,<=5.8.99999|>=6,<6.18.31|>=7,<7.22.4", + "ilicmiljan/secure-props": ">=1.2,<1.2.2", + "illuminate/auth": "<5.5.10", + "illuminate/cookie": ">=4,<=4.0.11|>=4.1,<6.18.31|>=7,<7.22.4", "illuminate/database": "<6.20.26|>=7,<7.30.5|>=8,<8.40", "illuminate/encryption": ">=4,<=4.0.11|>=4.1,<=4.1.31|>=4.2,<=4.2.22|>=5,<=5.0.35|>=5.1,<=5.1.46|>=5.2,<=5.2.45|>=5.3,<=5.3.31|>=5.4,<=5.4.36|>=5.5,<5.5.40|>=5.6,<5.6.15", "illuminate/view": "<6.20.42|>=7,<7.30.6|>=8,<8.75", + "imdbphp/imdbphp": "<=5.1.1", "impresscms/impresscms": "<=1.4.5", - "in2code/femanager": "<5.5.3|>=6,<6.3.4|>=7,<7.1", + "impresspages/impresspages": "<=1.0.12", + "in2code/femanager": "<5.5.3|>=6,<6.3.4|>=7,<7.2.3", "in2code/ipandlanguageredirect": "<5.1.2", "in2code/lux": "<17.6.1|>=18,<24.0.2", "innologi/typo3-appointments": "<2.0.6", - "intelliants/subrion": "<=4.2.1", + "intelliants/subrion": "<4.2.2", + "inter-mediator/inter-mediator": "==5.5", "islandora/islandora": ">=2,<2.4.1", "ivankristianto/phpwhois": "<=4.3", "jackalope/jackalope-doctrine-dbal": "<1.7.4", "james-heinrich/getid3": "<1.9.21", + "james-heinrich/phpthumb": "<1.7.12", "jasig/phpcas": "<1.3.3", + "jcbrand/converse.js": "<3.3.3", + "johnbillion/wp-crontrol": "<1.16.2", + "joomla/application": "<1.0.13", "joomla/archive": "<1.1.12|>=2,<2.0.1", "joomla/filesystem": "<1.6.2|>=2,<2.0.1", "joomla/filter": "<1.4.4|>=2,<2.0.1", - "joomla/framework": ">=2.5.4,<=3.8.12", + "joomla/framework": "<1.5.7|>=2.5.4,<=3.8.12", "joomla/input": ">=2,<2.0.2", - "joomla/joomla-cms": ">=3,<3.9.12", + "joomla/joomla-cms": ">=2.5,<3.9.12", "joomla/session": "<1.3.1", "joyqi/hyper-down": "<=2.4.27", "jsdecena/laracom": "<2.0.9", "jsmitty12/phpwhois": "<5.1", + "juzaweb/cms": "<=3.4", "kazist/phpwhois": "<=4.2.6", "kelvinmo/simplexrd": "<3.1.1", "kevinpapst/kimai2": "<1.16.7", "khodakhah/nodcms": "<=3", - "kimai/kimai": "<1.1", + "kimai/kimai": "<2.16", "kitodo/presentation": "<3.2.3|>=3.3,<3.3.4", "klaviyo/magento2-extension": ">=1,<3", - "knplabs/knp-snappy": "<1.4.2", + "knplabs/knp-snappy": "<=1.4.2", + "kohana/core": "<3.3.3", "krayin/laravel-crm": "<1.2.2", "kreait/firebase-php": ">=3.2,<3.8.1", + "kumbiaphp/kumbiapp": "<=1.1.1", "la-haute-societe/tcpdf": "<6.2.22", - "laminas/laminas-diactoros": "<2.18.1|>=2.24,<2.24.2|>=2.25,<2.25.2|= 2.23.0|= 2.22.0|= 2.21.0|= 2.20.0|= 2.19.0", + "laminas/laminas-diactoros": "<2.18.1|==2.19|==2.20|==2.21|==2.22|==2.23|>=2.24,<2.24.2|>=2.25,<2.25.2", "laminas/laminas-form": "<2.17.1|>=3,<3.0.2|>=3.1,<3.1.1", "laminas/laminas-http": "<2.14.2", "laravel/fortify": "<1.11.1", "laravel/framework": "<6.20.44|>=7,<7.30.6|>=8,<8.75", - "laravel/socialite": ">=1,<1.0.99|>=2,<2.0.10", + "laravel/laravel": ">=5.4,<5.4.22", + "laravel/socialite": ">=1,<2.0.10", "latte/latte": "<2.10.8", - "lavalite/cms": "= 9.0.0|<=9", + "lavalite/cms": "<=9|==10.1", "lcobucci/jwt": ">=3.4,<3.4.6|>=4,<4.0.4|>=4.1,<4.1.5", "league/commonmark": "<0.18.3", "league/flysystem": "<1.1.4|>=2,<2.1.1", - "league/oauth2-server": ">=8.3.2,<8.5.3", + "league/oauth2-server": ">=8.3.2,<8.4.2|>=8.5,<8.5.3", "lexik/jwt-authentication-bundle": "<2.10.7|>=2.11,<2.11.3", - "librenms/librenms": "<22.10", + "libreform/libreform": ">=2,<=2.0.8", + "librenms/librenms": "<2017.08.18", "liftkit/database": "<2.13.2", + "lightsaml/lightsaml": "<1.3.5", "limesurvey/limesurvey": "<3.27.19", "livehelperchat/livehelperchat": "<=3.91", - "livewire/livewire": ">2.2.4,<2.2.6", + "livewire/livewire": ">2.2.4,<2.2.6|>=3.3.5,<3.4.9", "lms/routes": "<2.1.1", "localizationteam/l10nmgr": "<7.4|>=8,<8.7|>=9,<9.2", "luyadev/yii-helpers": "<1.2.1", - "magento/community-edition": "= 2.4.0|<=2.4", - "magento/magento1ce": "<1.9.4.3", - "magento/magento1ee": ">=1,<1.14.4.3", - "magento/product-community-edition": ">=2,<2.2.10|>=2.3,<2.3.2-p.2", + "magento/community-edition": "<2.4.5|==2.4.5|>=2.4.5.0-patch1,<2.4.5.0-patch8|==2.4.6|>=2.4.6.0-patch1,<2.4.6.0-patch6|==2.4.7", + "magento/core": "<=1.9.4.5", + "magento/magento1ce": "<1.9.4.3-dev", + "magento/magento1ee": ">=1,<1.14.4.3-dev", + "magento/product-community-edition": ">=2,<2.2.10|>=2.3,<2.3.2.0-patch2", + "magneto/core": "<1.9.4.4-dev", "maikuolan/phpmussel": ">=1,<1.6", - "mantisbt/mantisbt": "<=2.25.5", + "mainwp/mainwp": "<=4.4.3.3", + "mantisbt/mantisbt": "<2.26.2", "marcwillmann/turn": "<0.3.3", "matyhtf/framework": "<3.0.6", - "mautic/core": "<4.3|= 2.13.1", - "mediawiki/core": ">=1.27,<1.27.6|>=1.29,<1.29.3|>=1.30,<1.30.2|>=1.31,<1.31.9|>=1.32,<1.32.6|>=1.32.99,<1.33.3|>=1.33.99,<1.34.3|>=1.34.99,<1.35", + "mautic/core": "<4.4.12|>=5.0.0.0-alpha,<5.0.4", + "mdanter/ecc": "<2", + "mediawiki/core": "<1.36.2", "mediawiki/matomo": "<2.4.3", + "mediawiki/semantic-media-wiki": "<4.0.2", "melisplatform/melis-asset-manager": "<5.0.1", "melisplatform/melis-cms": "<5.0.1", "melisplatform/melis-front": "<5.0.1", "mezzio/mezzio-swoole": "<3.7|>=4,<4.3", "mgallegos/laravel-jqgrid": "<=1.3", - "microweber/microweber": "<=1.3.4|= 1.1.18", + "microsoft/microsoft-graph": ">=1.16,<1.109.1|>=2,<2.0.1", + "microsoft/microsoft-graph-beta": "<2.0.1", + "microsoft/microsoft-graph-core": "<2.0.2", + "microweber/microweber": "<=2.0.4", + "mikehaertl/php-shellcommand": "<1.6.1", "miniorange/miniorange-saml": "<1.4.3", "mittwald/typo3_forum": "<1.2.1", "mobiledetect/mobiledetectlib": "<2.8.32", - "modx/revolution": "<2.8|<= 2.8.3-pl", + "modx/revolution": "<=2.8.3.0-patch", "mojo42/jirafeau": "<4.4", + "mongodb/mongodb": ">=1,<1.9.2", "monolog/monolog": ">=1.8,<1.12", - "moodle/moodle": "<4.2-rc.2|= 3.4.3|= 3.5|= 3.7|= 3.9|= 3.8|= 4.2.0|= 3.11", + "moodle/moodle": "<4.3.4", + "mos/cimage": "<0.7.19", "movim/moxl": ">=0.8,<=0.10", + "movingbytes/social-network": "<=1.2.1", "mpdf/mpdf": "<=7.1.7", + "munkireport/comment": "<4.1", + "munkireport/managedinstalls": "<2.6", + "munkireport/munki_facts": "<1.5", + "munkireport/munkireport": ">=2.5.3,<5.6.3", + "munkireport/reportdata": "<3.5", + "munkireport/softwareupdate": "<1.6", "mustache/mustache": ">=2,<2.14.1", "namshi/jose": "<2.2", "neoan3-apps/template": "<1.1.1", - "neorazorx/facturascripts": "<2022.4", + "neorazorx/facturascripts": "<2022.04", "neos/flow": ">=1,<1.0.4|>=1.1,<1.1.1|>=2,<2.0.1|>=2.3,<2.3.16|>=3,<3.0.12|>=3.1,<3.1.10|>=3.2,<3.2.13|>=3.3,<3.3.13|>=4,<4.0.6", "neos/form": ">=1.2,<4.3.3|>=5,<5.0.9|>=5.1,<5.1.3", - "neos/neos": ">=1.1,<1.1.3|>=1.2,<1.2.13|>=2,<2.0.4|>=2.3,<2.9.99|>=3,<3.0.20|>=3.1,<3.1.18|>=3.2,<3.2.14|>=3.3,<5.3.10|>=7,<7.0.9|>=7.1,<7.1.7|>=7.2,<7.2.6|>=7.3,<7.3.4|>=8,<8.0.2", - "neos/swiftmailer": ">=4.1,<4.1.99|>=5.4,<5.4.5", + "neos/media-browser": "<7.3.19|>=8,<8.0.16|>=8.1,<8.1.11|>=8.2,<8.2.11|>=8.3,<8.3.9", + "neos/neos": ">=1.1,<1.1.3|>=1.2,<1.2.13|>=2,<2.0.4|>=2.3,<3.0.20|>=3.1,<3.1.18|>=3.2,<3.2.14|>=3.3,<5.3.10|>=7,<7.0.9|>=7.1,<7.1.7|>=7.2,<7.2.6|>=7.3,<7.3.4|>=8,<8.0.2", + "neos/swiftmailer": "<5.4.5", "netgen/tagsbundle": ">=3.4,<3.4.11|>=4,<4.0.15", "nette/application": ">=2,<2.0.19|>=2.1,<2.1.13|>=2.2,<2.2.10|>=2.3,<2.3.14|>=2.4,<2.4.16|>=3,<3.0.6", "nette/nette": ">=2,<2.0.19|>=2.1,<2.1.13", "nilsteampassnet/teampass": "<3.0.10", + "nonfiction/nterchange": "<4.1.1", "notrinos/notrinos-erp": "<=0.7", "noumo/easyii": "<=0.9", - "nukeviet/nukeviet": "<4.5.2", + "novaksolutions/infusionsoft-php-sdk": "<1", + "nukeviet/nukeviet": "<4.5.02", "nyholm/psr7": "<1.6.1", "nystudio107/craft-seomatic": "<3.4.12", + "nzedb/nzedb": "<0.8", "nzo/url-encryptor-bundle": ">=4,<4.3.2|>=5,<5.0.1", "october/backend": "<1.1.2", - "october/cms": "= 1.1.1|= 1.0.471|= 1.0.469|>=1.0.319,<1.0.469", - "october/october": "<1.0.466|>=2.1,<2.1.12", + "october/cms": "<1.0.469|==1.0.469|==1.0.471|==1.1.1", + "october/october": "<=3.4.4", "october/rain": "<1.0.472|>=1.1,<1.1.2", - "october/system": "<1.0.476|>=1.1,<1.1.12|>=2,<2.2.34|>=3,<3.0.66", + "october/system": "<1.0.476|>=1.1,<1.1.12|>=2,<2.2.34|>=3,<3.5.2", + "omeka/omeka-s": "<4.0.3", "onelogin/php-saml": "<2.10.4", - "oneup/uploader-bundle": "<1.9.3|>=2,<2.1.5", + "oneup/uploader-bundle": ">=1,<1.9.3|>=2,<2.1.5", "open-web-analytics/open-web-analytics": "<1.7.4", - "opencart/opencart": "<=3.0.3.7", + "opencart/opencart": "<=3.0.3.7|>=4,<4.0.2.3-dev", "openid/php-openid": "<2.3", - "openmage/magento-lts": "<19.4.22|>=20,<20.0.19", + "openmage/magento-lts": "<20.5", + "opensolutions/vimbadmin": "<=3.0.15", "opensource-workshop/connect-cms": "<1.7.2|>=2,<2.3.2", - "orchid/platform": ">=9,<9.4.4|>=14-alpha.4,<14.5", - "oro/commerce": ">=4.1,<5.0.6", + "orchid/platform": ">=9,<9.4.4|>=14.0.0.0-alpha4,<14.5", + "oro/calendar-bundle": ">=4.2,<=4.2.6|>=5,<=5.0.6|>=5.1,<5.1.1", + "oro/commerce": ">=4.1,<5.0.11|>=5.1,<5.1.1", "oro/crm": ">=1.7,<1.7.4|>=3.1,<4.1.17|>=4.2,<4.2.7", - "oro/platform": ">=1.7,<1.7.4|>=3.1,<3.1.29|>=4.1,<4.1.17|>=4.2,<4.2.8", + "oro/crm-call-bundle": ">=4.2,<=4.2.5|>=5,<5.0.4|>=5.1,<5.1.1", + "oro/customer-portal": ">=4.1,<=4.1.13|>=4.2,<=4.2.10|>=5,<=5.0.11|>=5.1,<=5.1.3", + "oro/platform": ">=1.7,<1.7.4|>=3.1,<3.1.29|>=4.1,<4.1.17|>=4.2,<=4.2.10|>=5,<=5.0.12|>=5.1,<=5.1.3", + "oxid-esales/oxideshop-ce": "<4.5", + "oxid-esales/paymorrow-module": ">=1,<1.0.2|>=2,<2.0.1", "packbackbooks/lti-1-3-php-library": "<5", "padraic/humbug_get_contents": "<1.1.2", - "pagarme/pagarme-php": ">=0,<3", + "pagarme/pagarme-php": "<3", "pagekit/pagekit": "<=1.0.18", + "paragonie/ecc": "<2.0.1", "paragonie/random_compat": "<2", - "passbolt/passbolt_api": "<2.11", + "passbolt/passbolt_api": "<4.6.2", + "paypal/adaptivepayments-sdk-php": "<=3.9.2", + "paypal/invoice-sdk-php": "<=3.9", "paypal/merchant-sdk-php": "<3.12", + "paypal/permissions-sdk-php": "<=3.9.1", "pear/archive_tar": "<1.4.14", + "pear/auth": "<1.2.4", "pear/crypt_gpg": "<1.6.7", "pear/pear": "<=1.10.1", "pegasus/google-for-jobs": "<1.5.1|>=2,<2.1.1", "personnummer/personnummer": "<3.0.2", "phanan/koel": "<5.1.4", + "phenx/php-svg-lib": "<0.5.2", + "php-censor/php-censor": "<2.0.13|>=2.1,<2.1.5", "php-mod/curl": "<2.3.2", "phpbb/phpbb": "<3.2.10|>=3.3,<3.3.1", + "phpems/phpems": ">=6,<=6.1.3", "phpfastcache/phpfastcache": "<6.1.5|>=7,<7.1.2|>=8,<8.0.7", "phpmailer/phpmailer": "<6.5", "phpmussel/phpmussel": ">=1,<1.6", "phpmyadmin/phpmyadmin": "<5.2.1", - "phpmyfaq/phpmyfaq": "<=3.1.7", + "phpmyfaq/phpmyfaq": "<3.2.5|==3.2.5", + "phpoffice/common": "<0.2.9", "phpoffice/phpexcel": "<1.8", "phpoffice/phpspreadsheet": "<1.16", - "phpseclib/phpseclib": "<2.0.31|>=3,<3.0.19", + "phpseclib/phpseclib": "<2.0.47|>=3,<3.0.36", "phpservermon/phpservermon": "<3.6", - "phpsysinfo/phpsysinfo": "<3.2.5", - "phpunit/phpunit": ">=4.8.19,<4.8.28|>=5,<5.6.3", + "phpsysinfo/phpsysinfo": "<3.4.3", + "phpunit/phpunit": ">=4.8.19,<4.8.28|>=5.0.10,<5.6.3", "phpwhois/phpwhois": "<=4.2.5", "phpxmlrpc/extras": "<0.6.1", "phpxmlrpc/phpxmlrpc": "<4.9.2", "pi/pi": "<=2.5", - "pimcore/admin-ui-classic-bundle": "<1.0.3", - "pimcore/customer-management-framework-bundle": "<3.4.1", + "pimcore/admin-ui-classic-bundle": "<=1.4.2", + "pimcore/customer-management-framework-bundle": "<4.0.6", "pimcore/data-hub": "<1.2.4", + "pimcore/demo": "<10.3", + "pimcore/ecommerce-framework-bundle": "<1.0.10", "pimcore/perspective-editor": "<1.5.1", - "pimcore/pimcore": "<10.6.4", - "pixelfed/pixelfed": "<=0.11.4", + "pimcore/pimcore": "<11.2.4", + "pixelfed/pixelfed": "<0.11.11", + "plotly/plotly.js": "<2.25.2", "pocketmine/bedrock-protocol": "<8.0.2", - "pocketmine/pocketmine-mp": "<4.22.3|>=5,<5.2.1|< 4.18.0-ALPHA2|>= 4.0.0-BETA5, < 4.4.2", + "pocketmine/pocketmine-mp": "<5.11.2", + "pocketmine/raklib": ">=0.14,<0.14.6|>=0.15,<0.15.1", "pressbooks/pressbooks": "<5.18", "prestashop/autoupgrade": ">=4,<4.10.1", + "prestashop/blockreassurance": "<=5.1.3", "prestashop/blockwishlist": ">=2,<2.1.1", "prestashop/contactform": ">=1.0.1,<4.3", "prestashop/gamification": "<2.3.2", - "prestashop/prestashop": "<8.0.4", + "prestashop/prestashop": "<8.1.6", "prestashop/productcomments": "<5.0.2", "prestashop/ps_emailsubscription": "<2.6.1", "prestashop/ps_facetedsearch": "<3.4.1", "prestashop/ps_linklist": "<3.1", "privatebin/privatebin": "<1.4", - "processwire/processwire": "<=3.0.200", - "propel/propel": ">=2-alpha.1,<=2-alpha.7", + "processwire/processwire": "<=3.0.210", + "propel/propel": ">=2.0.0.0-alpha1,<=2.0.0.0-alpha7", "propel/propel1": ">=1,<=1.7.1", - "pterodactyl/panel": "<1.7", + "pterodactyl/panel": "<1.11.6", + "ptheofan/yii2-statemachine": ">=2.0.0.0-RC1-dev,<=2", "ptrofimov/beanstalk_console": "<1.7.14", + "pubnub/pubnub": "<6.1", "pusher/pusher-php-server": "<2.2.1", - "pwweb/laravel-core": "<=0.3.6-beta", + "pwweb/laravel-core": "<=0.3.6.0-beta", "pyrocms/pyrocms": "<=3.9.1", + "qcubed/qcubed": "<=3.1.1", + "quickapps/cms": "<=2.0.0.0-beta2", + "rainlab/blog-plugin": "<1.4.1", "rainlab/debugbar-plugin": "<3.1", + "rainlab/user-plugin": "<=1.4.5", "rankmath/seo-by-rank-math": "<=1.0.95", "rap2hpoutre/laravel-log-viewer": "<0.13", "react/http": ">=0.7,<1.9", "really-simple-plugins/complianz-gdpr": "<6.4.2", - "remdex/livehelperchat": "<3.99", + "redaxo/source": "<=5.15.1", + "remdex/livehelperchat": "<4.29", + "reportico-web/reportico": "<=8.1", + "rhukster/dom-sanitizer": "<1.0.7", "rmccue/requests": ">=1.6,<1.8", - "robrichards/xmlseclibs": "<3.0.4", + "robrichards/xmlseclibs": ">=1,<3.0.4", "roots/soil": "<4.1", "rudloff/alltube": "<3.0.3", "s-cart/core": "<6.9", "s-cart/s-cart": "<6.9", "sabberworm/php-css-parser": ">=1,<1.0.1|>=2,<2.0.1|>=3,<3.0.1|>=4,<4.0.1|>=5,<5.0.9|>=5.1,<5.1.3|>=5.2,<5.2.1|>=6,<6.0.2|>=7,<7.0.4|>=8,<8.0.1|>=8.1,<8.1.1|>=8.2,<8.2.1|>=8.3,<8.3.1", - "sabre/dav": "<1.7.11|>=1.8,<1.8.9", - "scheb/two-factor-bundle": ">=0,<3.26|>=4,<4.11", + "sabre/dav": ">=1.6,<1.7.11|>=1.8,<1.8.9", + "scheb/two-factor-bundle": "<3.26|>=4,<4.11", "sensiolabs/connect": "<4.2.3", "serluck/phpwhois": "<=4.2.6", "sfroemken/url_redirect": "<=1.2.1", "sheng/yiicms": "<=1.2", - "shopware/core": "<=6.4.20", - "shopware/platform": "<=6.4.20", + "shopware/core": "<6.5.8.8-dev|>=6.6.0.0-RC1-dev,<6.6.1", + "shopware/platform": "<6.5.8.8-dev|>=6.6.0.0-RC1-dev,<6.6.1", "shopware/production": "<=6.3.5.2", - "shopware/shopware": "<=5.7.17", - "shopware/storefront": "<=6.4.8.1", + "shopware/shopware": "<6.2.3", + "shopware/storefront": "<=6.4.8.1|>=6.5.8,<6.5.8.7-dev", "shopxo/shopxo": "<2.2.6", "showdoc/showdoc": "<2.10.4", "silverstripe-australia/advancedreports": ">=1,<=2", - "silverstripe/admin": "<1.12.7", + "silverstripe/admin": "<1.13.19|>=2,<2.1.8", "silverstripe/assets": ">=1,<1.11.1", "silverstripe/cms": "<4.11.3", - "silverstripe/comments": ">=1.3,<1.9.99|>=2,<2.9.99|>=3,<3.1.1", + "silverstripe/comments": ">=1.3,<3.1.1", "silverstripe/forum": "<=0.6.1|>=0.7,<=0.7.3", - "silverstripe/framework": "<4.12.5", - "silverstripe/graphql": "<3.5.2|>=4-alpha.1,<4-alpha.2|>=4.1.1,<4.1.2|>=4.2.2,<4.2.3|= 4.0.0-alpha1", + "silverstripe/framework": "<4.13.39|>=5,<5.1.11", + "silverstripe/graphql": ">=2,<2.0.5|>=3,<3.8.2|>=4,<4.3.7|>=5,<5.1.3", "silverstripe/hybridsessions": ">=1,<2.4.1|>=2.5,<2.5.1", "silverstripe/recipe-cms": ">=4.5,<4.5.3", "silverstripe/registry": ">=2.1,<2.1.2|>=2.2,<2.2.1", - "silverstripe/restfulserver": ">=1,<1.0.9|>=2,<2.0.4", + "silverstripe/restfulserver": ">=1,<1.0.9|>=2,<2.0.4|>=2.1,<2.1.2", "silverstripe/silverstripe-omnipay": "<2.5.2|>=3,<3.0.2|>=3.1,<3.1.4|>=3.2,<3.2.1", "silverstripe/subsites": ">=2,<2.6.1", "silverstripe/taxonomy": ">=1.3,<1.3.1|>=2,<2.0.1", - "silverstripe/userforms": "<3", + "silverstripe/userforms": "<3|>=5,<5.4.2", "silverstripe/versioned-admin": ">=1,<1.11.1", "simple-updates/phpwhois": "<=1", - "simplesamlphp/saml2": "<1.10.6|>=2,<2.3.8|>=3,<3.1.4", + "simplesamlphp/saml2": "<1.10.6|>=2,<2.3.8|>=3,<3.1.4|==5.0.0.0-alpha12", "simplesamlphp/simplesamlphp": "<1.18.6", "simplesamlphp/simplesamlphp-module-infocard": "<1.0.1", "simplesamlphp/simplesamlphp-module-openid": "<1", "simplesamlphp/simplesamlphp-module-openidprovider": "<0.9", + "simplesamlphp/xml-security": "==1.6.11", "simplito/elliptic-php": "<1.0.6", "sitegeist/fluid-components": "<3.5", - "sjbr/sr-freecap": "<=2.5.2", + "sjbr/sr-freecap": "<2.4.6|>=2.5,<2.5.3", "slim/psr7": "<1.4.1|>=1.5,<1.5.1|>=1.6,<1.6.1", "slim/slim": "<2.6", - "smarty/smarty": "<3.1.48|>=4,<4.3.1", - "snipe/snipe-it": "<=6.0.14|>= 6.0.0-RC-1, <= 6.0.0-RC-5", + "slub/slub-events": "<3.0.3", + "smarty/smarty": "<4.5.3|>=5,<5.1.1", + "snipe/snipe-it": "<=6.2.2", "socalnick/scn-social-auth": "<1.15.2", "socialiteproviders/steam": "<1.1", "spatie/browsershot": "<3.57.4", - "spipu/html2pdf": "<5.2.4", + "spatie/image-optimizer": "<1.7.3", + "spipu/html2pdf": "<5.2.8", "spoon/library": "<1.4.1", "spoonity/tcpdf": "<6.2.22", "squizlabs/php_codesniffer": ">=1,<2.8.1|>=3,<3.0.1", - "ssddanbrown/bookstack": "<22.2.3", - "statamic/cms": "<4.10", - "stormpath/sdk": ">=0,<9.9.99", + "ssddanbrown/bookstack": "<22.02.3", + "statamic/cms": "<4.46|>=5.3,<5.6.2", + "stormpath/sdk": "<9.9.99", "studio-42/elfinder": "<2.1.62", "subhh/libconnect": "<7.0.8|>=8,<8.1", - "subrion/cms": "<=4.2.1", "sukohi/surpass": "<1", - "sulu/sulu": "= 2.4.0-RC1|<1.6.44|>=2,<2.2.18|>=2.3,<2.3.8", + "sulu/form-bundle": ">=2,<2.5.3", + "sulu/sulu": "<1.6.44|>=2,<2.4.17|>=2.5,<2.5.13", "sumocoders/framework-user-bundle": "<1.4", + "superbig/craft-audit": "<3.0.2", "swag/paypal": "<5.4.4", - "swiftmailer/swiftmailer": ">=4,<5.4.5", + "swiftmailer/swiftmailer": "<6.2.5", + "swiftyedit/swiftyedit": "<1.2", "sylius/admin-bundle": ">=1,<1.0.17|>=1.1,<1.1.9|>=1.2,<1.2.2", "sylius/grid": ">=1,<1.1.19|>=1.2,<1.2.18|>=1.3,<1.3.13|>=1.4,<1.4.5|>=1.5,<1.5.1", "sylius/grid-bundle": "<1.10.1", "sylius/paypal-plugin": ">=1,<1.2.4|>=1.3,<1.3.1", - "sylius/resource-bundle": "<1.3.14|>=1.4,<1.4.7|>=1.5,<1.5.2|>=1.6,<1.6.4", - "sylius/sylius": "<1.9.10|>=1.10,<1.10.11|>=1.11,<1.11.2", - "symbiote/silverstripe-multivaluefield": ">=3,<3.0.99", + "sylius/resource-bundle": ">=1,<1.3.14|>=1.4,<1.4.7|>=1.5,<1.5.2|>=1.6,<1.6.4", + "sylius/sylius": "<1.9.10|>=1.10,<1.10.11|>=1.11,<1.11.2|>=1.12.0.0-alpha1,<1.12.16|>=1.13.0.0-alpha1,<1.13.1", + "symbiote/silverstripe-multivaluefield": ">=3,<3.1", "symbiote/silverstripe-queuedjobs": ">=3,<3.0.2|>=3.1,<3.1.4|>=4,<4.0.7|>=4.1,<4.1.2|>=4.2,<4.2.4|>=4.3,<4.3.3|>=4.4,<4.4.3|>=4.5,<4.5.1|>=4.6,<4.6.4", "symbiote/silverstripe-seed": "<6.0.3", "symbiote/silverstripe-versionedfiles": "<=2.0.3", @@ -2486,7 +2629,7 @@ "symfony/dependency-injection": ">=2,<2.0.17|>=2.7,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7", "symfony/error-handler": ">=4.4,<4.4.4|>=5,<5.0.4", "symfony/form": ">=2.3,<2.3.35|>=2.4,<2.6.12|>=2.7,<2.7.50|>=2.8,<2.8.49|>=3,<3.4.20|>=4,<4.0.15|>=4.1,<4.1.9|>=4.2,<4.2.1", - "symfony/framework-bundle": ">=2,<2.3.18|>=2.4,<2.4.8|>=2.5,<2.5.2|>=2.7,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7|>=5.3.14,<=5.3.14|>=5.4.3,<=5.4.3|>=6.0.3,<=6.0.3|= 6.0.3|= 5.4.3|= 5.3.14", + "symfony/framework-bundle": ">=2,<2.3.18|>=2.4,<2.4.8|>=2.5,<2.5.2|>=2.7,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7|>=5.3.14,<5.3.15|>=5.4.3,<5.4.4|>=6.0.3,<6.0.4", "symfony/http-foundation": ">=2,<2.8.52|>=3,<3.4.35|>=4,<4.2.12|>=4.3,<4.3.8|>=4.4,<4.4.7|>=5,<5.0.7", "symfony/http-kernel": ">=2,<4.4.50|>=5,<5.4.20|>=6,<6.0.20|>=6.1,<6.1.12|>=6.2,<6.2.6", "symfony/intl": ">=2.7,<2.7.38|>=2.8,<2.8.31|>=3,<3.2.14|>=3.3,<3.3.13", @@ -2502,60 +2645,83 @@ "symfony/security-core": ">=2.4,<2.6.13|>=2.7,<2.7.9|>=2.7.30,<2.7.32|>=2.8,<3.4.49|>=4,<4.4.24|>=5,<5.2.9", "symfony/security-csrf": ">=2.4,<2.7.48|>=2.8,<2.8.41|>=3,<3.3.17|>=3.4,<3.4.11|>=4,<4.0.11", "symfony/security-guard": ">=2.8,<3.4.48|>=4,<4.4.23|>=5,<5.2.8", - "symfony/security-http": ">=2.3,<2.3.41|>=2.4,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.2.12|>=4.3,<4.3.8|>=4.4,<4.4.7|>=5,<5.0.7|>=5.1,<5.2.8|>=5.3,<5.3.2", + "symfony/security-http": ">=2.3,<2.3.41|>=2.4,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.2.12|>=4.3,<4.3.8|>=4.4,<4.4.7|>=5,<5.0.7|>=5.1,<5.2.8|>=5.3,<5.3.2|>=5.4,<5.4.31|>=6,<6.3.8", "symfony/serializer": ">=2,<2.0.11|>=4.1,<4.4.35|>=5,<5.3.12", - "symfony/symfony": ">=2,<4.4.50|>=5,<5.4.20|>=6,<6.0.20|>=6.1,<6.1.12|>=6.2,<6.2.6", + "symfony/symfony": ">=2,<4.4.51|>=5,<5.4.31|>=6,<6.3.8", "symfony/translation": ">=2,<2.0.17", + "symfony/twig-bridge": ">=2,<4.4.51|>=5,<5.4.31|>=6,<6.3.8", + "symfony/ux-autocomplete": "<2.11.2", "symfony/validator": ">=2,<2.0.24|>=2.1,<2.1.12|>=2.2,<2.2.5|>=2.3,<2.3.3", "symfony/var-exporter": ">=4.2,<4.2.12|>=4.3,<4.3.8", "symfony/web-profiler-bundle": ">=2,<2.3.19|>=2.4,<2.4.9|>=2.5,<2.5.4", - "symfony/yaml": ">=2,<2.0.22|>=2.1,<2.1.7", - "t3/dce": ">=2.2,<2.6.2", + "symfony/webhook": ">=6.3,<6.3.8", + "symfony/yaml": ">=2,<2.0.22|>=2.1,<2.1.7|>=2.2.0.0-beta1,<2.2.0.0-beta2", + "symphonycms/symphony-2": "<2.6.4", + "t3/dce": "<0.11.5|>=2.2,<2.6.2", "t3g/svg-sanitizer": "<1.0.3", + "t3s/content-consent": "<1.0.3|>=2,<2.0.2", "tastyigniter/tastyigniter": "<3.3", "tcg/voyager": "<=1.4", - "tecnickcom/tcpdf": "<6.2.22", + "tecnickcom/tcpdf": "<=6.7.4", "terminal42/contao-tablelookupwizard": "<3.3.5", "thelia/backoffice-default-template": ">=2.1,<2.1.2", - "thelia/thelia": ">=2.1-beta.1,<2.1.3", + "thelia/thelia": ">=2.1,<2.1.3", "theonedemon/phpwhois": "<=4.2.5", - "thinkcmf/thinkcmf": "<=5.1.7", - "thorsten/phpmyfaq": "<3.2-beta.2", - "tinymce/tinymce": "<5.10.7|>=6,<6.3.1", + "thinkcmf/thinkcmf": "<6.0.8", + "thorsten/phpmyfaq": "<3.2.2", + "tikiwiki/tiki-manager": "<=17.1", + "timber/timber": ">=0.16.6,<1.23.1|>=1.24,<1.24.1|>=2,<2.1", + "tinymce/tinymce": "<7", "tinymighty/wiki-seo": "<1.2.2", - "titon/framework": ">=0,<9.9.99", - "tobiasbg/tablepress": "<= 2.0-RC1", - "topthink/framework": "<6.0.14", + "titon/framework": "<9.9.99", + "tobiasbg/tablepress": "<=2.0.0.0-RC1", + "topthink/framework": "<6.0.17|>=6.1,<6.1.5|>=8,<8.0.4", "topthink/think": "<=6.1.1", "topthink/thinkphp": "<=3.2.3", + "torrentpier/torrentpier": "<=2.4.1", "tpwd/ke_search": "<4.0.3|>=4.1,<4.6.6|>=5,<5.0.2", - "tribalsystems/zenario": "<=9.3.57595", + "tribalsystems/zenario": "<9.5.60602", "truckersmp/phpwhois": "<=4.3.1", "ttskch/pagination-service-provider": "<1", "twig/twig": "<1.44.7|>=2,<2.15.3|>=3,<3.4.3", - "typo3/cms": "<2.0.5|>=3,<3.0.3|>=6.2,<=6.2.38|>=7,<7.6.32|>=8,<8.7.38|>=9,<9.5.29|>=10,<10.4.35|>=11,<11.5.23|>=12,<12.2", - "typo3/cms-backend": ">=7,<=7.6.50|>=8,<=8.7.39|>=9,<=9.5.24|>=10,<=10.4.13|>=11,<=11.1", - "typo3/cms-core": "<8.7.51|>=9,<9.5.42|>=10,<10.4.39|>=11,<11.5.30|>=12,<12.4.4", + "typo3/cms": "<9.5.29|>=10,<10.4.35|>=11,<11.5.23|>=12,<12.2", + "typo3/cms-backend": "<4.1.14|>=4.2,<4.2.15|>=4.3,<4.3.7|>=4.4,<4.4.4|>=7,<=7.6.50|>=8,<=8.7.39|>=9,<=9.5.24|>=10,<=10.4.13|>=11,<=11.1", + "typo3/cms-core": "<=8.7.56|>=9,<=9.5.47|>=10,<=10.4.44|>=11,<=11.5.36|>=12,<=12.4.14|>=13,<=13.1", + "typo3/cms-extbase": "<6.2.24|>=7,<7.6.8|==8.1.1", + "typo3/cms-fluid": "<4.3.4|>=4.4,<4.4.1", "typo3/cms-form": ">=8,<=8.7.39|>=9,<=9.5.24|>=10,<=10.4.13|>=11,<=11.1", + "typo3/cms-frontend": "<4.3.9|>=4.4,<4.4.5", + "typo3/cms-install": "<4.1.14|>=4.2,<4.2.16|>=4.3,<4.3.9|>=4.4,<4.4.5|>=12.2,<12.4.8", + "typo3/cms-rte-ckeditor": ">=9.5,<9.5.42|>=10,<10.4.39|>=11,<11.5.30", "typo3/flow": ">=1,<1.0.4|>=1.1,<1.1.1|>=2,<2.0.1|>=2.3,<2.3.16|>=3,<3.0.12|>=3.1,<3.1.10|>=3.2,<3.2.13|>=3.3,<3.3.13|>=4,<4.0.6", - "typo3/html-sanitizer": ">=1,<1.5.1|>=2,<2.1.2", + "typo3/html-sanitizer": ">=1,<=1.5.2|>=2,<=2.1.3", "typo3/neos": ">=1.1,<1.1.3|>=1.2,<1.2.13|>=2,<2.0.4|>=2.3,<2.3.99|>=3,<3.0.20|>=3.1,<3.1.18|>=3.2,<3.2.14|>=3.3,<3.3.23|>=4,<4.0.17|>=4.1,<4.1.16|>=4.2,<4.2.12|>=4.3,<4.3.3", "typo3/phar-stream-wrapper": ">=1,<2.1.1|>=3,<3.1.1", "typo3/swiftmailer": ">=4.1,<4.1.99|>=5.4,<5.4.5", "typo3fluid/fluid": ">=2,<2.0.8|>=2.1,<2.1.7|>=2.2,<2.2.4|>=2.3,<2.3.7|>=2.4,<2.4.4|>=2.5,<2.5.11|>=2.6,<2.6.10", "ua-parser/uap-php": "<3.8", - "unisharp/laravel-filemanager": "<=2.5.1", + "uasoft-indonesia/badaso": "<=2.9.7", + "unisharp/laravel-filemanager": "<2.6.4", "userfrosting/userfrosting": ">=0.3.1,<4.6.3", "usmanhalalit/pixie": "<1.0.3|>=2,<2.0.2", "uvdesk/community-skeleton": "<=1.1.1", + "uvdesk/core-framework": "<=1.1.1", "vanilla/safecurl": "<0.9.2", - "verot/class.upload.php": "<=1.0.3|>=2,<=2.0.4", + "verbb/comments": "<1.5.5", + "verbb/formie": "<2.1.6", + "verbb/image-resizer": "<2.0.9", + "verbb/knock-knock": "<1.2.8", + "verot/class.upload.php": "<=2.1.6", + "villagedefrance/opencart-overclocked": "<=1.11.1", "vova07/yii2-fileapi-widget": "<0.1.9", "vrana/adminer": "<4.8.1", + "vufind/vufind": ">=2,<9.1.1", + "waldhacker/hcaptcha": "<2.1.2", "wallabag/tcpdf": "<6.2.22", - "wallabag/wallabag": "<=2.5.4", + "wallabag/wallabag": "<2.6.7", "wanglelecc/laracms": "<=1.0.3", "web-auth/webauthn-framework": ">=3.3,<3.3.4", + "web-feet/coastercms": "==5.5", "webbuilders-group/silverstripe-kapost-bridge": "<0.4", "webcoast/deferred-image-processing": "<1.0.2", "webklex/laravel-imap": "<5.3", @@ -2564,21 +2730,28 @@ "wikibase/wikibase": "<=1.39.3", "wikimedia/parsoid": "<0.12.2", "willdurand/js-translation-bundle": "<2.1.1", - "wintercms/winter": "<1.2.3", - "woocommerce/woocommerce": "<6.6", - "wp-cli/wp-cli": "<2.5", + "winter/wn-backend-module": "<1.2.4", + "winter/wn-dusk-plugin": "<2.1", + "winter/wn-system-module": "<1.2.4", + "wintercms/winter": "<=1.2.3", + "woocommerce/woocommerce": "<6.6|>=8.8,<8.8.5|>=8.9,<8.9.3", + "wp-cli/wp-cli": ">=0.12,<2.5", "wp-graphql/wp-graphql": "<=1.14.5", + "wp-premium/gravityforms": "<2.4.21", "wpanel/wpanel4-cms": "<=4.3.1", "wpcloud/wp-stateless": "<3.2", - "wwbn/avideo": "<=12.4", + "wpglobus/wpglobus": "<=1.9.6", + "wwbn/avideo": "<14.3", "xataface/xataface": "<3", "xpressengine/xpressengine": "<3.0.15", + "yab/quarx": "<2.4.5", "yeswiki/yeswiki": "<4.1", "yetiforce/yetiforce-crm": "<=6.4", "yidashi/yii2cmf": "<=2", "yii2mod/yii2-cms": "<1.9.2", - "yiisoft/yii": "<1.1.27", - "yiisoft/yii2": "<2.0.38", + "yiisoft/yii": "<1.1.29", + "yiisoft/yii2": "<2.0.50", + "yiisoft/yii2-authclient": "<2.2.15", "yiisoft/yii2-bootstrap": "<2.0.4", "yiisoft/yii2-dev": "<2.0.43", "yiisoft/yii2-elasticsearch": "<2.0.5", @@ -2588,12 +2761,13 @@ "yikesinc/yikes-inc-easy-mailchimp-extender": "<6.8.6", "yoast-seo-for-typo3/yoast_seo": "<7.2.3", "yourls/yourls": "<=1.8.2", - "zencart/zencart": "<1.5.8", + "yuan1994/tpadmin": "<=1.3.12", + "zencart/zencart": "<=1.5.7.0-beta", "zendesk/zendesk_api_client_php": "<2.2.11", "zendframework/zend-cache": ">=2.4,<2.4.8|>=2.5,<2.5.3", "zendframework/zend-captcha": ">=2,<2.4.9|>=2.5,<2.5.2", "zendframework/zend-crypt": ">=2,<2.4.9|>=2.5,<2.5.2", - "zendframework/zend-db": ">=2,<2.0.99|>=2.1,<2.1.99|>=2.2,<2.2.10|>=2.3,<2.3.5", + "zendframework/zend-db": "<2.2.10|>=2.3,<2.3.5", "zendframework/zend-developer-tools": ">=1.2.2,<1.2.3", "zendframework/zend-diactoros": "<1.8.4", "zendframework/zend-feed": "<2.10.3", @@ -2601,22 +2775,30 @@ "zendframework/zend-http": "<2.8.1", "zendframework/zend-json": ">=2.1,<2.1.6|>=2.2,<2.2.6", "zendframework/zend-ldap": ">=2,<2.0.99|>=2.1,<2.1.99|>=2.2,<2.2.8|>=2.3,<2.3.3", - "zendframework/zend-mail": ">=2,<2.4.11|>=2.5,<2.7.2", + "zendframework/zend-mail": "<2.4.11|>=2.5,<2.7.2", "zendframework/zend-navigation": ">=2,<2.2.7|>=2.3,<2.3.1", - "zendframework/zend-session": ">=2,<2.0.99|>=2.1,<2.1.99|>=2.2,<2.2.9|>=2.3,<2.3.4", + "zendframework/zend-session": ">=2,<2.2.9|>=2.3,<2.3.4", "zendframework/zend-validator": ">=2.3,<2.3.6", "zendframework/zend-view": ">=2,<2.2.7|>=2.3,<2.3.1", "zendframework/zend-xmlrpc": ">=2.1,<2.1.6|>=2.2,<2.2.6", "zendframework/zendframework": "<=3", "zendframework/zendframework1": "<1.12.20", - "zendframework/zendopenid": ">=2,<2.0.2", + "zendframework/zendopenid": "<2.0.2", + "zendframework/zendrest": "<2.0.2", + "zendframework/zendservice-amazon": "<2.0.3", + "zendframework/zendservice-api": "<1", + "zendframework/zendservice-audioscrobbler": "<2.0.2", + "zendframework/zendservice-nirvanix": "<2.0.2", + "zendframework/zendservice-slideshare": "<2.0.2", + "zendframework/zendservice-technorati": "<2.0.2", + "zendframework/zendservice-windowsazure": "<2.0.2", "zendframework/zendxml": ">=1,<1.0.1", "zenstruck/collection": "<0.2.1", "zetacomponents/mail": "<1.8.2", "zf-commons/zfc-user": "<1.2.2", "zfcampus/zf-apigility-doctrine": ">=1,<1.0.3", "zfr/zfr-oauth2-server-module": "<0.1.2", - "zoujingli/thinkadmin": "<6.0.22" + "zoujingli/thinkadmin": "<=6.1.53" }, "type": "metapackage", "notification-url": "https://packagist.org/downloads/", @@ -2653,7 +2835,7 @@ "type": "tidelift" } ], - "time": "2023-07-25T19:04:12+00:00" + "time": "2024-06-13T20:04:44+00:00" }, { "name": "robrichards/xmlseclibs", @@ -2795,32 +2977,32 @@ }, { "name": "silinternational/psr3-adapters", - "version": "3.1.0", + "version": "4.0.0", "source": { "type": "git", "url": "https://github.com/silinternational/psr3-adapters.git", - "reference": "3f281e39b2925026e8f4b42625c1122198a8a01d" + "reference": "80a364235da0ff114c151e3b35eadb117db463cd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/silinternational/psr3-adapters/zipball/3f281e39b2925026e8f4b42625c1122198a8a01d", - "reference": "3f281e39b2925026e8f4b42625c1122198a8a01d", + "url": "https://api.github.com/repos/silinternational/psr3-adapters/zipball/80a364235da0ff114c151e3b35eadb117db463cd", + "reference": "80a364235da0ff114c151e3b35eadb117db463cd", "shasum": "" }, "require": { - "php": "^7.4 || ^8.0", - "psr/log": "^1.0" + "php": "^8.1", + "psr/log": "^3.0" }, "require-dev": { - "monolog/monolog": "^1.22", + "monolog/monolog": "^2.0 | ^3.0", "phpunit/phpunit": "^9.0", "roave/security-advisories": "dev-master", - "simplesamlphp/simplesamlphp": "^1.15.2", + "simplesamlphp/simplesamlphp": "^2.0", "yiisoft/yii2": "^2.0" }, "suggest": { - "monolog/monolog": "^1.22", - "simplesamlphp/simplesamlphp": "^1.15.2", + "monolog/monolog": "^2.0 | ^3.0", + "simplesamlphp/simplesamlphp": "^2.0", "yiisoft/yii2": "^2.0" }, "type": "library", @@ -2843,32 +3025,31 @@ "description": "Various PSR3-compatible logging adapters.", "support": { "issues": "https://github.com/silinternational/psr3-adapters/issues", - "source": "https://github.com/silinternational/psr3-adapters/tree/3.1.0" + "source": "https://github.com/silinternational/psr3-adapters/tree/4.0.0" }, - "time": "2022-08-24T14:44:38+00:00" + "time": "2024-06-18T00:37:01+00:00" }, { "name": "silinternational/ssp-utilities", - "version": "1.1.0", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/silinternational/ssp-utilities.git", - "reference": "3e257e7bbbcb0f7ef0d95e5d7c292c97c89ce18a" + "reference": "816a506c5d44e820d9c71372b024c279907dd382" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/silinternational/ssp-utilities/zipball/3e257e7bbbcb0f7ef0d95e5d7c292c97c89ce18a", - "reference": "3e257e7bbbcb0f7ef0d95e5d7c292c97c89ce18a", + "url": "https://api.github.com/repos/silinternational/ssp-utilities/zipball/816a506c5d44e820d9c71372b024c279907dd382", + "reference": "816a506c5d44e820d9c71372b024c279907dd382", "shasum": "" }, "require": { - "php": "^7.0 || ^8.0", - "simplesamlphp/simplesamlphp": "~1.18.6 || ~1.19.0" + "php": "^8.1", + "simplesamlphp/simplesamlphp": "^2.2" }, "require-dev": { "phpunit/phpunit": ">=7.0", - "roave/security-advisories": "dev-master", - "satooshi/php-coveralls": "^1.0.1" + "roave/security-advisories": "dev-master" }, "type": "library", "autoload": { @@ -2880,18 +3061,12 @@ "license": [ "MIT" ], - "authors": [ - { - "name": "Phillip Shipley", - "email": "phillip.shipley@gmail.com" - } - ], "description": "SimpleSAMLphp related utility classes", "support": { "issues": "https://github.com/silinternational/ssp-utilities/issues", - "source": "https://github.com/silinternational/ssp-utilities/tree/1.1.0" + "source": "https://github.com/silinternational/ssp-utilities/tree/2.0.0" }, - "time": "2022-08-24T20:12:45+00:00" + "time": "2024-06-15T02:06:26+00:00" }, { "name": "silinternational/yii2-json-log-targets", @@ -2950,34 +3125,33 @@ }, { "name": "simplesamlphp/assert", - "version": "v0.0.13", + "version": "v1.1.8", "source": { "type": "git", "url": "https://github.com/simplesamlphp/assert.git", - "reference": "5429921b320ca4f9d1844225884ac52f649ea1e3" + "reference": "0a5ffa660849db748872bbf017569b4365a39fac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/simplesamlphp/assert/zipball/5429921b320ca4f9d1844225884ac52f649ea1e3", - "reference": "5429921b320ca4f9d1844225884ac52f649ea1e3", + "url": "https://api.github.com/repos/simplesamlphp/assert/zipball/0a5ffa660849db748872bbf017569b4365a39fac", + "reference": "0a5ffa660849db748872bbf017569b4365a39fac", "shasum": "" }, "require": { + "ext-date": "*", + "ext-filter": "*", + "ext-pcre": "*", "ext-spl": "*", - "php": "^7.1 || ^8.0", - "webmozart/assert": "^1.9" + "php": "^8.1", + "webmozart/assert": "^1.11" }, "require-dev": { - "phpunit/phpunit": "^8.5", - "sensiolabs/security-checker": "~6.0", - "simplesamlphp/simplesamlphp-test-framework": "^0.2.7", - "squizlabs/php_codesniffer": "~3.5", - "vimeo/psalm": "~3.13" + "simplesamlphp/simplesamlphp-test-framework": "^1.5.5" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "v0.0.x-dev" + "dev-master": "v1.1.x-dev" } }, "autoload": { @@ -3002,35 +3176,40 @@ "description": "A wrapper around webmozart/assert to make it useful beyond checking method arguments", "support": { "issues": "https://github.com/simplesamlphp/assert/issues", - "source": "https://github.com/simplesamlphp/assert/tree/master" + "source": "https://github.com/simplesamlphp/assert/tree/v1.1.8" }, - "time": "2020-08-17T20:40:49+00:00" + "time": "2024-05-21T10:35:09+00:00" }, { "name": "simplesamlphp/composer-module-installer", - "version": "v1.1.8", + "version": "v1.3.4", "source": { "type": "git", "url": "https://github.com/simplesamlphp/composer-module-installer.git", - "reference": "45161b5406f3e9c82459d0f9a5a1dba064953cfa" + "reference": "36508ed9580a30c4d5ab0bb3c25c00d0b5d42946" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/simplesamlphp/composer-module-installer/zipball/45161b5406f3e9c82459d0f9a5a1dba064953cfa", - "reference": "45161b5406f3e9c82459d0f9a5a1dba064953cfa", + "url": "https://api.github.com/repos/simplesamlphp/composer-module-installer/zipball/36508ed9580a30c4d5ab0bb3c25c00d0b5d42946", + "reference": "36508ed9580a30c4d5ab0bb3c25c00d0b5d42946", "shasum": "" }, "require": { - "composer-plugin-api": "^1.1|^2.0", - "simplesamlphp/simplesamlphp": "*" + "composer-plugin-api": "^1.1 || ^2.0", + "php": "^7.4 || ^8.0", + "simplesamlphp/assert": "^0.8.0 || ^1.0" + }, + "require-dev": { + "composer/composer": "^2.4", + "simplesamlphp/simplesamlphp-test-framework": "^1.2.1" }, "type": "composer-plugin", "extra": { - "class": "SimpleSamlPhp\\Composer\\ModuleInstallerPlugin" + "class": "SimpleSAML\\Composer\\ModuleInstallerPlugin" }, "autoload": { - "psr-0": { - "SimpleSamlPhp\\Composer": "src/" + "psr-4": { + "SimpleSAML\\Composer\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -3040,22 +3219,22 @@ "description": "A Composer plugin that allows installing SimpleSAMLphp modules through Composer.", "support": { "issues": "https://github.com/simplesamlphp/composer-module-installer/issues", - "source": "https://github.com/simplesamlphp/composer-module-installer/tree/v1.1.8" + "source": "https://github.com/simplesamlphp/composer-module-installer/tree/v1.3.4" }, - "time": "2020-08-25T19:04:33+00:00" + "time": "2023-03-08T20:58:22+00:00" }, { "name": "simplesamlphp/saml2", - "version": "v4.6.10", + "version": "v4.6.12", "source": { "type": "git", "url": "https://github.com/simplesamlphp/saml2.git", - "reference": "a6c46e8134df2686da9ad44bc9b8f85443c03440" + "reference": "9545abd0d9d48388f2fa00469c5c1e0294f0303e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/simplesamlphp/saml2/zipball/a6c46e8134df2686da9ad44bc9b8f85443c03440", - "reference": "a6c46e8134df2686da9ad44bc9b8f85443c03440", + "url": "https://api.github.com/repos/simplesamlphp/saml2/zipball/9545abd0d9d48388f2fa00469c5c1e0294f0303e", + "reference": "9545abd0d9d48388f2fa00469c5c1e0294f0303e", "shasum": "" }, "require": { @@ -3098,22 +3277,22 @@ "description": "SAML2 PHP library from SimpleSAMLphp", "support": { "issues": "https://github.com/simplesamlphp/saml2/issues", - "source": "https://github.com/simplesamlphp/saml2/tree/v4.6.10" + "source": "https://github.com/simplesamlphp/saml2/tree/v4.6.12" }, - "time": "2023-05-31T16:03:51+00:00" + "time": "2024-04-25T14:10:08+00:00" }, { "name": "simplesamlphp/simplesamlphp", - "version": "1.19.8", + "version": "v2.2.2", "source": { "type": "git", "url": "https://github.com/simplesamlphp/simplesamlphp.git", - "reference": "a69141a45ad41b3b48f55535bafc9cd538a35b74" + "reference": "2339859b9c05a59d930585baec9fdbe0a77e947d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp/zipball/a69141a45ad41b3b48f55535bafc9cd538a35b74", - "reference": "a69141a45ad41b3b48f55535bafc9cd538a35b74", + "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp/zipball/2339859b9c05a59d930585baec9fdbe0a77e947d", + "reference": "2339859b9c05a59d930585baec9fdbe0a77e947d", "shasum": "" }, "require": { @@ -3124,80 +3303,77 @@ "ext-mbstring": "*", "ext-openssl": "*", "ext-pcre": "*", + "ext-session": "*", + "ext-simplexml": "*", "ext-spl": "*", "ext-zlib": "*", - "gettext/gettext": "^4.8.7", - "php": ">=7.1|^8", - "phpmailer/phpmailer": "^6.1", - "robrichards/xmlseclibs": "^3.1", - "simplesamlphp/assert": "^0.0.13", - "simplesamlphp/saml2": "^4.5", - "simplesamlphp/simplesamlphp-module-adfs": "^1.0", - "simplesamlphp/simplesamlphp-module-authcrypt": "^0.9", - "simplesamlphp/simplesamlphp-module-authfacebook": "^0.9", - "simplesamlphp/simplesamlphp-module-authorize": "^0.9", - "simplesamlphp/simplesamlphp-module-authtwitter": "^0.9", - "simplesamlphp/simplesamlphp-module-authwindowslive": "^0.9", - "simplesamlphp/simplesamlphp-module-authx509": "^0.9", - "simplesamlphp/simplesamlphp-module-authyubikey": "^0.9", - "simplesamlphp/simplesamlphp-module-cas": "^0.9", - "simplesamlphp/simplesamlphp-module-cdc": "^0.9", - "simplesamlphp/simplesamlphp-module-consent": "^0.9", - "simplesamlphp/simplesamlphp-module-consentadmin": "^0.9", - "simplesamlphp/simplesamlphp-module-discopower": "^0.10", - "simplesamlphp/simplesamlphp-module-exampleattributeserver": "^1.0", - "simplesamlphp/simplesamlphp-module-expirycheck": "^0.9", - "simplesamlphp/simplesamlphp-module-ldap": "^0.9 | ^1.0", - "simplesamlphp/simplesamlphp-module-memcachemonitor": "^0.9", - "simplesamlphp/simplesamlphp-module-memcookie": "^1.2", - "simplesamlphp/simplesamlphp-module-metarefresh": "^0.10", - "simplesamlphp/simplesamlphp-module-negotiate": "^0.9", - "simplesamlphp/simplesamlphp-module-oauth": "^0.9.3", - "simplesamlphp/simplesamlphp-module-preprodwarning": "^0.9", - "simplesamlphp/simplesamlphp-module-radius": "^0.9", - "simplesamlphp/simplesamlphp-module-riak": "^0.9", - "simplesamlphp/simplesamlphp-module-sanitycheck": "^0.9", - "simplesamlphp/simplesamlphp-module-smartattributes": "^0.9", - "simplesamlphp/simplesamlphp-module-sqlauth": "^0.9", - "simplesamlphp/simplesamlphp-module-statistics": "^0.9", - "simplesamlphp/twig-configurable-i18n": "~2.3.3", - "symfony/cache": "^4.4 || ^5.0", - "symfony/config": "^4.4 || ^5.0", - "symfony/console": "^4.4 || ^5.0", - "symfony/dependency-injection": "^4.4 || ^5.0", - "symfony/finder": "^4.4 || ^5.0", - "symfony/framework-bundle": "^4.4 || ^5.0", - "symfony/http-foundation": "^4.4 || ^5.0", - "symfony/http-kernel": "^4.4 || ^5.0", - "symfony/routing": "^4.4 || ^5.0", - "symfony/var-exporter": "^4.4 || ^5.0", - "symfony/yaml": "^4.4 || ^5.0", - "twig/twig": "^2.15.3" + "gettext/gettext": "^5.7", + "gettext/translator": "^1.1", + "php": "^8.1", + "phpmailer/phpmailer": "^6.8", + "psr/log": "^3.0", + "simplesamlphp/assert": "^1.0.0", + "simplesamlphp/composer-module-installer": "^1.3", + "simplesamlphp/saml2": "^4.6", + "simplesamlphp/simplesamlphp-assets-base": "~2.2", + "symfony/cache": "^6.4", + "symfony/config": "^6.4", + "symfony/console": "^6.4", + "symfony/dependency-injection": "^6.4", + "symfony/filesystem": "^6.4", + "symfony/finder": "^6.4", + "symfony/framework-bundle": "^6.4", + "symfony/http-foundation": "^6.4", + "symfony/http-kernel": "^6.4", + "symfony/intl": "^6.4", + "symfony/polyfill-intl-icu": "^1.28", + "symfony/routing": "^6.4", + "symfony/translation-contracts": "^3.0", + "symfony/twig-bridge": "^6.4", + "symfony/var-exporter": "^6.4", + "symfony/yaml": "^6.4", + "twig/intl-extra": "^3.7", + "twig/twig": "^3.5" }, "require-dev": { "ext-curl": "*", + "ext-pdo_sqlite": "*", + "gettext/php-scanner": "1.3.1", "mikey179/vfsstream": "~1.6", - "phpunit/phpunit": "^7.5", - "simplesamlphp/simplesamlphp-test-framework": "^0.1.2", - "vimeo/psalm": "~3.14" + "predis/predis": "^2.2", + "simplesamlphp/simplesamlphp-module-adfs": "^2.1", + "simplesamlphp/simplesamlphp-test-framework": "^1.5.4", + "simplesamlphp/xml-security": "^1.6.0", + "symfony/translation": "^6.4" }, "suggest": { "ext-curl": "Needed in order to check for updates automatically", + "ext-intl": "Needed if translations for non-English languages are required.", "ext-ldap": "Needed if an LDAP backend is used", "ext-memcache": "Needed if a Memcache server is used to store session information", "ext-mysql": "Needed if a MySQL backend is used, either for authentication or to store session information", "ext-pdo": "Needed if a database backend is used, either for authentication or to store session information", "ext-pgsql": "Needed if a PostgreSQL backend is used, either for authentication or to store session information", - "ext-radius": "Needed if a Radius backend is used", "predis/predis": "Needed if a Redis server is used to store session information" }, "type": "project", + "extra": { + "branch-alias": { + "dev-master": "2.2.x-dev" + } + }, "autoload": { "files": [ - "lib/_autoload_modules.php" + "src/_autoload_modules.php" ], "psr-4": { - "SimpleSAML\\": "lib/SimpleSAML" + "SimpleSAML\\": "src/SimpleSAML", + "SimpleSAML\\Module\\core\\": "modules/core/src", + "SimpleSAML\\Module\\cron\\": "modules/cron/src", + "SimpleSAML\\Module\\saml\\": "modules/saml/src", + "SimpleSAML\\Module\\admin\\": "modules/admin/src", + "SimpleSAML\\Module\\multiauth\\": "modules/multiauth/src", + "SimpleSAML\\Module\\exampleauth\\": "modules/exampleauth/src" } }, "notification-url": "https://packagist.org/downloads/", @@ -3218,8 +3394,8 @@ "email": "jaime.perez@uninett.no" } ], - "description": "A PHP implementation of a SAML 2.0 service provider and identity provider, also compatible with Shibboleth 1.3 and 2.0.", - "homepage": "http://simplesamlphp.org", + "description": "A PHP implementation of a SAML 2.0 service provider and identity provider.", + "homepage": "https://simplesamlphp.org", "keywords": [ "SAML2", "idp", @@ -3232,37 +3408,27 @@ "issues": "https://github.com/simplesamlphp/simplesamlphp/issues", "source": "https://github.com/simplesamlphp/simplesamlphp" }, - "time": "2023-03-02T11:44:45+00:00" + "time": "2024-04-30T16:38:57+00:00" }, { - "name": "simplesamlphp/simplesamlphp-module-adfs", - "version": "v1.0.9", + "name": "simplesamlphp/simplesamlphp-assets-base", + "version": "v2.2.1", "source": { "type": "git", - "url": "https://github.com/simplesamlphp/simplesamlphp-module-adfs.git", - "reference": "c47daabc262b7e14a76879015fd9db85319752ec" + "url": "https://github.com/simplesamlphp/simplesamlphp-assets-base.git", + "reference": "405e13a9856f3c1f314fcdb032575c2cc16afac5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-adfs/zipball/c47daabc262b7e14a76879015fd9db85319752ec", - "reference": "c47daabc262b7e14a76879015fd9db85319752ec", + "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-assets-base/zipball/405e13a9856f3c1f314fcdb032575c2cc16afac5", + "reference": "405e13a9856f3c1f314fcdb032575c2cc16afac5", "shasum": "" }, "require": { - "php": ">=7.1", - "simplesamlphp/assert": "^0.0.13", - "simplesamlphp/composer-module-installer": "^1.1.7" - }, - "require-dev": { - "simplesamlphp/simplesamlphp": "^1.18", - "simplesamlphp/simplesamlphp-test-framework": "^0.1.2" + "php": "^8.1", + "simplesamlphp/composer-module-installer": "^1.3.4" }, "type": "simplesamlphp-module", - "autoload": { - "psr-4": { - "SimpleSAML\\Module\\adfs\\": "lib/" - } - }, "notification-url": "https://packagist.org/downloads/", "license": [ "LGPL-2.1-or-later" @@ -3273,1500 +3439,278 @@ "email": "tvdijen@gmail.com" } ], - "description": "A module that implements the WS-federation IDP", - "keywords": [ - "adfs", - "simplesamlphp" - ], + "description": "Assets for the SimpleSAMLphp main repository", "support": { - "issues": "https://github.com/simplesamlphp/simplesamlphp-module-adfs/issues", - "source": "https://github.com/simplesamlphp/simplesamlphp-module-adfs" + "issues": "https://github.com/simplesamlphp/simplesamlphp-assets-base/issues", + "source": "https://github.com/simplesamlphp/simplesamlphp-assets-base/tree/v2.2.1" }, - "time": "2022-04-11T10:24:25+00:00" + "time": "2024-06-12T21:08:27+00:00" }, { - "name": "simplesamlphp/simplesamlphp-module-authcrypt", - "version": "v0.9.4", + "name": "sinergi/browser-detector", + "version": "6.1.4", "source": { "type": "git", - "url": "https://github.com/simplesamlphp/simplesamlphp-module-authcrypt.git", - "reference": "62555123e61b11463be3cd7adb708562023cff28" + "url": "https://github.com/sinergi/php-browser-detector.git", + "reference": "4927f7c2bedc48b68f183bd420aa3549c59e133b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-authcrypt/zipball/62555123e61b11463be3cd7adb708562023cff28", - "reference": "62555123e61b11463be3cd7adb708562023cff28", + "url": "https://api.github.com/repos/sinergi/php-browser-detector/zipball/4927f7c2bedc48b68f183bd420aa3549c59e133b", + "reference": "4927f7c2bedc48b68f183bd420aa3549c59e133b", "shasum": "" }, "require": { - "php": ">=5.6", - "simplesamlphp/composer-module-installer": "~1.1", - "webmozart/assert": "~1.4", - "whitehat101/apr1-md5": "~1.0" + "php": ">=7.2" }, "require-dev": { - "phpunit/phpunit": "~5.7", - "simplesamlphp/simplesamlphp": "^1.17" + "phpunit/phpunit": "^8.0 || ^9.4" }, - "type": "simplesamlphp-module", + "type": "library", "autoload": { "psr-4": { - "SimpleSAML\\Module\\authcrypt\\": "lib/" + "Sinergi\\BrowserDetector\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "LGPL-2.1-or-later" + "MIT" ], "authors": [ { - "name": "Olav Morken", - "email": "olavmrk@gmail.com" + "name": "Gabriel Bull", + "email": "me@gabrielbull.com" + }, + { + "name": "Chris Schuld" } ], - "description": "This module provides authentication against password hashes or .htpasswd files", + "description": "Detecting the user's browser, operating system and language.", "keywords": [ - "authcrypt", - "simplesamlphp" - ], - "support": { - "issues": "https://github.com/tvdijen/simplesamlphp-module-authcrypt/issues", - "source": "https://github.com/tvdijen/simplesamlphp-module-authcrypt" - }, - "time": "2022-01-03T20:50:47+00:00" - }, - { - "name": "simplesamlphp/simplesamlphp-module-authfacebook", - "version": "v0.9.3", - "source": { - "type": "git", - "url": "https://github.com/simplesamlphp/simplesamlphp-module-authfacebook.git", - "reference": "9152731e939ad4a49e0f06da5f0009ebde0d2b5c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-authfacebook/zipball/9152731e939ad4a49e0f06da5f0009ebde0d2b5c", - "reference": "9152731e939ad4a49e0f06da5f0009ebde0d2b5c", - "shasum": "" - }, - "require": { - "php": ">=5.6", - "simplesamlphp/composer-module-installer": "~1.1" - }, - "require-dev": { - "simplesamlphp/simplesamlphp": "^1.17", - "simplesamlphp/simplesamlphp-test-framework": "^0.0.10" - }, - "type": "simplesamlphp-module", - "autoload": { - "psr-4": { - "SimpleSAML\\Module\\authfacebook\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-3.0-or-later" - ], - "authors": [ - { - "name": "Andjelko Horvat", - "email": "comel@vingd.com" - }, - { - "name": "Tim van Dijen", - "email": "tvdijen@gmail.com" - } - ], - "description": "A module that is able to authenticate against Facebook", - "keywords": [ - "facebook", - "simplesamlphp" - ], - "support": { - "issues": "https://github.com/simplesamlphp/simplesamlphp-module-authfacebook/issues", - "source": "https://github.com/simplesamlphp/simplesamlphp-module-authfacebook" - }, - "abandoned": true, - "time": "2020-03-13T11:29:21+00:00" - }, - { - "name": "simplesamlphp/simplesamlphp-module-authorize", - "version": "v0.9.4", - "source": { - "type": "git", - "url": "https://github.com/simplesamlphp/simplesamlphp-module-authorize.git", - "reference": "4c7ce4eaa54fc301f131c62e803fc843e4d88056" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-authorize/zipball/4c7ce4eaa54fc301f131c62e803fc843e4d88056", - "reference": "4c7ce4eaa54fc301f131c62e803fc843e4d88056", - "shasum": "" - }, - "require": { - "php": ">=5.6", - "simplesamlphp/composer-module-installer": "~1.1" - }, - "require-dev": { - "phpunit/phpunit": "~5.7", - "simplesamlphp/simplesamlphp": "^1.17" - }, - "type": "simplesamlphp-module", - "autoload": { - "psr-4": { - "SimpleSAML\\Module\\authorize\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-2.1-or-later" - ], - "authors": [ - { - "name": "Ernesto Revilla", - "email": "erny@yaco.es" - } - ], - "description": "This module provides a user authorization filter based on attribute matching", - "keywords": [ - "authorize", - "simplesamlphp" - ], - "support": { - "issues": "https://github.com/tvdijen/simplesamlphp-module-authorize/issues", - "source": "https://github.com/tvdijen/simplesamlphp-module-authorize" - }, - "time": "2022-01-03T20:56:53+00:00" - }, - { - "name": "simplesamlphp/simplesamlphp-module-authtwitter", - "version": "v0.9.3", - "source": { - "type": "git", - "url": "https://github.com/simplesamlphp/simplesamlphp-module-authtwitter.git", - "reference": "6e178e7aae7827a64dc462b5bb2f28d6eddc4381" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-authtwitter/zipball/6e178e7aae7827a64dc462b5bb2f28d6eddc4381", - "reference": "6e178e7aae7827a64dc462b5bb2f28d6eddc4381", - "shasum": "" - }, - "require": { - "php": ">=5.5", - "simplesamlphp/composer-module-installer": "~1.0", - "simplesamlphp/simplesamlphp-module-oauth": "^0.9" - }, - "require-dev": { - "phpunit/phpunit": "~4.8.35", - "simplesamlphp/simplesamlphp": "^1.17", - "webmozart/assert": "<1.7" - }, - "type": "simplesamlphp-module", - "autoload": { - "psr-4": { - "SimpleSAML\\Module\\authtwitter\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-2.1-or-later" - ], - "authors": [ - { - "name": "Olav Morken", - "email": "olavmrk@gmail.com" - }, - { - "name": "Tim van Dijen", - "email": "tvdijen@gmail.com" - } - ], - "description": "A module that is able to perform authentication against Twitter", - "keywords": [ - "simplesamlphp", - "twitter" - ], - "support": { - "issues": "https://github.com/tvdijen/simplesamlphp-module-authtwitter/issues", - "source": "https://github.com/tvdijen/simplesamlphp-module-authtwitter" - }, - "time": "2022-01-03T23:01:48+00:00" - }, - { - "name": "simplesamlphp/simplesamlphp-module-authwindowslive", - "version": "v0.9.1", - "source": { - "type": "git", - "url": "https://github.com/simplesamlphp/simplesamlphp-module-authwindowslive.git", - "reference": "f40aecec6c0adaedb6693309840c98cec783876e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-authwindowslive/zipball/f40aecec6c0adaedb6693309840c98cec783876e", - "reference": "f40aecec6c0adaedb6693309840c98cec783876e", - "shasum": "" - }, - "require": { - "php": ">=5.6", - "simplesamlphp/composer-module-installer": "~1.1" - }, - "require-dev": { - "phpunit/phpunit": "~5.7", - "simplesamlphp/simplesamlphp": "^1.17" - }, - "type": "simplesamlphp-module", - "autoload": { - "psr-4": { - "SimpleSAML\\Module\\authwindowslive\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-3.0-or-later" - ], - "authors": [ - { - "name": "Olav Morken", - "email": "olavmrk@gmail.com" - }, - { - "name": "Tim van Dijen", - "email": "tvdijen@gmail.com" - } - ], - "description": "A module that is able to perform authentication against Windows Live", - "keywords": [ - "live", - "simplesamlphp", - "windows", - "windowslive" - ], - "support": { - "issues": "https://github.com/tvdijen/simplesamlphp-module-authwindowslive/issues", - "source": "https://github.com/tvdijen/simplesamlphp-module-authwindowslive" - }, - "abandoned": true, - "time": "2019-12-03T09:01:13+00:00" - }, - { - "name": "simplesamlphp/simplesamlphp-module-authx509", - "version": "v0.9.9", - "source": { - "type": "git", - "url": "https://github.com/simplesamlphp/simplesamlphp-module-authX509.git", - "reference": "b138f41b2bc725371f42abb63b5a39ac11b5432a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-authX509/zipball/b138f41b2bc725371f42abb63b5a39ac11b5432a", - "reference": "b138f41b2bc725371f42abb63b5a39ac11b5432a", - "shasum": "" - }, - "require": { - "php": ">=5.5", - "simplesamlphp/composer-module-installer": "~1.1", - "simplesamlphp/simplesamlphp-module-ldap": "^0.9" - }, - "require-dev": { - "simplesamlphp/simplesamlphp": "^1.17", - "simplesamlphp/simplesamlphp-test-framework": "^0.0.15" - }, - "type": "simplesamlphp-module", - "extra": { - "ssp-mixedcase-module-name": "authX509" - }, - "autoload": { - "psr-4": { - "SimpleSAML\\Module\\authX509\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-2.1-or-later" - ], - "authors": [ - { - "name": "Joost van Dijk", - "email": "Joost.vanDijk@surfnet.nl" - }, - { - "name": "Tim van Dijen", - "email": "tvdijen@gmail.com" - } - ], - "description": "A module that is able to authenticate users based on X509 client certificates", - "keywords": [ - "simplesamlphp", - "x509" - ], - "support": { - "issues": "https://github.com/tvdijen/simplesamlphp-module-authx509/issues", - "source": "https://github.com/tvdijen/simplesamlphp-module-authx509" - }, - "time": "2022-01-06T19:02:38+00:00" - }, - { - "name": "simplesamlphp/simplesamlphp-module-authyubikey", - "version": "v0.9.3", - "source": { - "type": "git", - "url": "https://github.com/simplesamlphp/simplesamlphp-module-authyubikey.git", - "reference": "414e2a73da4adfee6d97ba66e852ec7c85369913" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-authyubikey/zipball/414e2a73da4adfee6d97ba66e852ec7c85369913", - "reference": "414e2a73da4adfee6d97ba66e852ec7c85369913", - "shasum": "" - }, - "require": { - "php": ">=5.6", - "simplesamlphp/composer-module-installer": "~1.1", - "webmozart/assert": "~1.4" - }, - "require-dev": { - "phpunit/phpunit": "~5.7", - "simplesamlphp/simplesamlphp": "^1.17" - }, - "type": "simplesamlphp-module", - "extra": { - "ssp-mixedcase-module-name": "authYubiKey" - }, - "autoload": { - "psr-4": { - "SimpleSAML\\modules\\yubikey\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-2.1-or-later" - ], - "authors": [ - { - "name": "Tim van Dijen", - "email": "tvdijen@gmail.com" - } - ], - "description": "A module that is able to authenticate against YubiKey", - "keywords": [ - "authyubikey", - "simplesamlphp" - ], - "support": { - "issues": "https://github.com/tvdijen/simplesamlphp-module-authyubikey/issues", - "source": "https://github.com/tvdijen/simplesamlphp-module-authyubikey" - }, - "time": "2022-01-06T19:07:32+00:00" - }, - { - "name": "simplesamlphp/simplesamlphp-module-cas", - "version": "v0.9.1", - "source": { - "type": "git", - "url": "https://github.com/simplesamlphp/simplesamlphp-module-cas.git", - "reference": "63b72e4600550c507cdfc32fdd208ad59a64321e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-cas/zipball/63b72e4600550c507cdfc32fdd208ad59a64321e", - "reference": "63b72e4600550c507cdfc32fdd208ad59a64321e", - "shasum": "" - }, - "require": { - "php": ">=5.6", - "simplesamlphp/composer-module-installer": "~1.1", - "simplesamlphp/simplesamlphp-module-ldap": "^0.9", - "webmozart/assert": "~1.4" - }, - "require-dev": { - "phpunit/phpunit": "~5.7", - "simplesamlphp/simplesamlphp": "^1.17" - }, - "type": "simplesamlphp-module", - "autoload": { - "psr-4": { - "SimpleSAML\\Module\\cas\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-3.0-or-later" - ], - "authors": [ - { - "name": "Olav Morken", - "email": "olavmrk@gmail.com" - } - ], - "description": "A module that provides CAS authentication", - "keywords": [ - "cas", - "simplesamlphp" - ], - "support": { - "issues": "https://github.com/tvdijen/simplesamlphp-module-cas/issues", - "source": "https://github.com/tvdijen/simplesamlphp-module-cas" - }, - "time": "2019-12-03T09:03:06+00:00" - }, - { - "name": "simplesamlphp/simplesamlphp-module-cdc", - "version": "v0.9.2", - "source": { - "type": "git", - "url": "https://github.com/simplesamlphp/simplesamlphp-module-cdc.git", - "reference": "92498fc3004c02849d96da29ca472d99ed23af73" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-cdc/zipball/92498fc3004c02849d96da29ca472d99ed23af73", - "reference": "92498fc3004c02849d96da29ca472d99ed23af73", - "shasum": "" - }, - "require": { - "simplesamlphp/composer-module-installer": ">=1.1.6" - }, - "require-dev": { - "phpunit/phpunit": "~5.7", - "simplesamlphp/simplesamlphp": "^1.17", - "webmozart/assert": "<1.7" - }, - "type": "simplesamlphp-module", - "autoload": { - "psr-4": { - "SimpleSAML\\Module\\cdc\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-2.1-or-later" - ], - "authors": [ - { - "name": "Olav Morken", - "email": "olav.morken@uninett.no" - }, - { - "name": "Jaime Perez Crespo", - "email": "jaime.perez@uninett.no" - } - ], - "description": "A SimpleSAMLphp module that allows integration with CDC", - "homepage": "https://simplesamlphp.org/", - "keywords": [ - "cdc", - "simplesamlphp" - ], - "support": { - "issues": "https://github.com/simplesamlphp/simplesamlphp-module-cdc/issues", - "source": "https://github.com/simplesamlphp/simplesamlphp-module-cdc/" - }, - "time": "2022-01-06T19:27:16+00:00" - }, - { - "name": "simplesamlphp/simplesamlphp-module-consent", - "version": "v0.9.8", - "source": { - "type": "git", - "url": "https://github.com/simplesamlphp/simplesamlphp-module-consent.git", - "reference": "8466b0b7c6207b15ca5e265f436299ff2dec85da" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-consent/zipball/8466b0b7c6207b15ca5e265f436299ff2dec85da", - "reference": "8466b0b7c6207b15ca5e265f436299ff2dec85da", - "shasum": "" - }, - "require": { - "php": ">=5.6", - "simplesamlphp/composer-module-installer": "~1.1" - }, - "require-dev": { - "phpunit/phpunit": "~5.7", - "simplesamlphp/simplesamlphp": "^1.17", - "webmozart/assert": "<1.6" - }, - "type": "simplesamlphp-module", - "autoload": { - "psr-4": { - "SimpleSAML\\Module\\consent\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-2.1-or-later" - ], - "authors": [ - { - "name": "Olav Morken", - "email": "lavmrk@gmail.com" - } - ], - "description": "A module that will ask for user consent before releasing attributes", - "keywords": [ - "consent", - "simplesamlphp" - ], - "support": { - "issues": "https://github.com/tvdijen/simplesamlphp-module-consent/issues", - "source": "https://github.com/tvdijen/simplesamlphp-module-consent" - }, - "time": "2022-01-06T19:17:22+00:00" - }, - { - "name": "simplesamlphp/simplesamlphp-module-consentadmin", - "version": "v0.9.2", - "source": { - "type": "git", - "url": "https://github.com/simplesamlphp/simplesamlphp-module-consentadmin.git", - "reference": "62dc5e9d5b1a12a73549c80140b7224d7f7d1c2e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-consentadmin/zipball/62dc5e9d5b1a12a73549c80140b7224d7f7d1c2e", - "reference": "62dc5e9d5b1a12a73549c80140b7224d7f7d1c2e", - "shasum": "" - }, - "require": { - "php": ">=5.6", - "simplesamlphp/composer-module-installer": "~1.1", - "simplesamlphp/simplesamlphp-module-consent": "^0.9", - "webmozart/assert": "~1.4" - }, - "require-dev": { - "phpunit/phpunit": "~5.7", - "simplesamlphp/simplesamlphp": "^1.17" - }, - "type": "simplesamlphp-module", - "extra": { - "ssp-mixedcase-module-name": "consentAdmin" - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-2.1-or-later" - ], - "authors": [ - { - "name": "Jacob Christiansen", - "email": "jach@wayf.dk" - }, - { - "name": "Olav Morken", - "email": "olav.morken@uninett.no" - } - ], - "description": "A module that allows users to manage their consent", - "keywords": [ - "consentadmin", - "simplesamlphp" - ], - "support": { - "issues": "https://github.com/simplesamlphp/simplesamlphp-module-consentadmin/issues", - "source": "https://github.com/simplesamlphp/simplesamlphp-module-consentadmin" - }, - "time": "2022-01-06T19:19:38+00:00" - }, - { - "name": "simplesamlphp/simplesamlphp-module-discopower", - "version": "v0.10.1", - "source": { - "type": "git", - "url": "https://github.com/simplesamlphp/simplesamlphp-module-discopower.git", - "reference": "4cb6b7c648b455586903b8932a171397375b50b0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-discopower/zipball/4cb6b7c648b455586903b8932a171397375b50b0", - "reference": "4cb6b7c648b455586903b8932a171397375b50b0", - "shasum": "" - }, - "require": { - "php": ">=7.1", - "simplesamlphp/composer-module-installer": "~1.1" - }, - "require-dev": { - "simplesamlphp/simplesamlphp": "^1.19", - "simplesamlphp/simplesamlphp-test-framework": "^0.1.2" - }, - "type": "simplesamlphp-module", - "autoload": { - "psr-4": { - "SimpleSAML\\modules\\discopower\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-2.1-or-later" - ], - "authors": [ - { - "name": "Andreas Åkre Solberg", - "email": "andreas.solberg@uninett.no" - } - ], - "description": "Fancy tabbed discovery service with filtering capabilities where SPs can have different sets of metadata listed", - "keywords": [ - "discopower", - "discovery", - "simplesamlphp" - ], - "support": { - "issues": "https://github.com/tvdijen/simplesamlphp-module-discopower/issues", - "source": "https://github.com/tvdijen/simplesamlphp-module-discopower" - }, - "time": "2021-08-17T14:29:22+00:00" - }, - { - "name": "simplesamlphp/simplesamlphp-module-exampleattributeserver", - "version": "v1.0.0", - "source": { - "type": "git", - "url": "https://github.com/simplesamlphp/simplesamlphp-module-exampleattributeserver.git", - "reference": "63e0323e81c32bc3c9eaa01ea45194bb10153708" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-exampleattributeserver/zipball/63e0323e81c32bc3c9eaa01ea45194bb10153708", - "reference": "63e0323e81c32bc3c9eaa01ea45194bb10153708", - "shasum": "" - }, - "require": { - "php": ">=5.6", - "simplesamlphp/composer-module-installer": "~1.1" - }, - "require-dev": { - "phpunit/phpunit": "~5.7", - "simplesamlphp/simplesamlphp": "^1.17" - }, - "type": "simplesamlphp-module", - "autoload": { - "psr-4": { - "SimpleSAML\\Module\\exampleattributeserver\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-3.0-or-later" - ], - "authors": [ - { - "name": "Olav Morken", - "email": "olavmrk@gmail.com" - } - ], - "description": "An example for SAML attributes queries", - "keywords": [ - "exampleattributeserver", - "simplesamlphp" - ], - "support": { - "issues": "https://github.com/tvdijen/simplesamlphp-module-exampleattributeserver/issues", - "source": "https://github.com/tvdijen/simplesamlphp-module-exampleattributeserver" - }, - "time": "2019-05-28T12:37:15+00:00" - }, - { - "name": "simplesamlphp/simplesamlphp-module-expirycheck", - "version": "v0.9.4", - "source": { - "type": "git", - "url": "https://github.com/simplesamlphp/simplesamlphp-module-expirycheck.git", - "reference": "02101497281031befba93c48c96ee9133f57241d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-expirycheck/zipball/02101497281031befba93c48c96ee9133f57241d", - "reference": "02101497281031befba93c48c96ee9133f57241d", - "shasum": "" - }, - "require": { - "php": ">=5.6", - "simplesamlphp/composer-module-installer": "~1.1" - }, - "require-dev": { - "phpunit/phpunit": "~5.7", - "simplesamlphp/simplesamlphp": "^1.17" - }, - "type": "simplesamlphp-module", - "autoload": { - "psr-4": { - "SimpleSAML\\Module\\expirycheck\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-2.1-or-later" - ], - "authors": [ - { - "name": "Alex Mihičinac", - "email": "alexm@arnes.si" - } - ], - "description": "The expirycheck module validates user's expiry date", - "keywords": [ - "expirycheck", - "simplesamlphp" - ], - "support": { - "issues": "https://github.com/tvdijen/simplesamlphp-module-expirycheck/issues", - "source": "https://github.com/tvdijen/simplesamlphp-module-expirycheck" - }, - "time": "2022-01-06T21:16:01+00:00" - }, - { - "name": "simplesamlphp/simplesamlphp-module-ldap", - "version": "v0.9.17", - "source": { - "type": "git", - "url": "https://github.com/simplesamlphp/simplesamlphp-module-ldap.git", - "reference": "40f1bfe0c4ac2f91cf8e52d22fa6ec2fe1c03066" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-ldap/zipball/40f1bfe0c4ac2f91cf8e52d22fa6ec2fe1c03066", - "reference": "40f1bfe0c4ac2f91cf8e52d22fa6ec2fe1c03066", - "shasum": "" - }, - "require": { - "php": ">=5.6", - "simplesamlphp/composer-module-installer": "~1.1" - }, - "require-dev": { - "phpunit/phpunit": "~5.7", - "simplesamlphp/simplesamlphp": "^1.17" - }, - "suggest": { - "ext-ldap": "Needed when using LDAP authentication in SimpleSAMLphp" - }, - "type": "simplesamlphp-module", - "autoload": { - "psr-4": { - "SimpleSAML\\Module\\ldap\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-2.1-or-later" - ], - "authors": [ - { - "name": "Olav Morken", - "email": "olavmrk@gmail.com" - }, - { - "name": "Tim van Dijen", - "email": "tvdijen@gmail.com" - } - ], - "description": "A module that provides authentication against LDAP stores", - "keywords": [ - "ldap", - "simplesamlphp" - ], - "support": { - "issues": "https://github.com/tvdijen/simplesamlphp-module-ldap/issues", - "source": "https://github.com/tvdijen/simplesamlphp-module-ldap" - }, - "time": "2022-01-11T12:50:47+00:00" - }, - { - "name": "simplesamlphp/simplesamlphp-module-memcachemonitor", - "version": "v0.9.3", - "source": { - "type": "git", - "url": "https://github.com/simplesamlphp/simplesamlphp-module-memcachemonitor.git", - "reference": "8d25463ac56b4e2294f59f622a6658e0c67086f4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-memcachemonitor/zipball/8d25463ac56b4e2294f59f622a6658e0c67086f4", - "reference": "8d25463ac56b4e2294f59f622a6658e0c67086f4", - "shasum": "" - }, - "require": { - "php": ">=5.6", - "simplesamlphp/composer-module-installer": "~1.1" - }, - "require-dev": { - "simplesamlphp/simplesamlphp": "^1.17", - "simplesamlphp/simplesamlphp-test-framework": "~0.0.6" - }, - "type": "simplesamlphp-module", - "extra": { - "ssp-mixedcase-module-name": "memcacheMonitor" - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-2.1-or-later" - ], - "authors": [ - { - "name": "Andreas Åkre Solberg", - "email": "andreas.solberg@uninett.no" - }, - { - "name": "Tim van Dijen", - "email": "tvdijen@gmail.com" - } - ], - "description": "A module that is able display usage statistics of a memcache(d) store", - "keywords": [ - "memcachemonitor", - "simplesamlphp" - ], - "support": { - "issues": "https://github.com/tvdijen/simplesamlphp-module-memcachemonitor/issues", - "source": "https://github.com/tvdijen/simplesamlphp-module-memcachemonitor" - }, - "time": "2022-01-06T22:37:15+00:00" - }, - { - "name": "simplesamlphp/simplesamlphp-module-memcookie", - "version": "v1.2.2", - "source": { - "type": "git", - "url": "https://github.com/simplesamlphp/simplesamlphp-module-memcookie.git", - "reference": "39535304e8d464b7baa1e82cb441fa432947ff57" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-memcookie/zipball/39535304e8d464b7baa1e82cb441fa432947ff57", - "reference": "39535304e8d464b7baa1e82cb441fa432947ff57", - "shasum": "" - }, - "require": { - "php": ">=5.6", - "simplesamlphp/composer-module-installer": ">=1.1.6" - }, - "require-dev": { - "phpunit/phpunit": "~5.7", - "simplesamlphp/simplesamlphp": "^1.17", - "simplesamlphp/simplesamlphp-test-framework": "^0.0.6" - }, - "type": "simplesamlphp-module", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-2.1" - ], - "authors": [ - { - "name": "Olav Morken", - "email": "olav.morken@uninett.no" - }, - { - "name": "Jaime Perez Crespo", - "email": "jaime.perez@uninett.no" - } - ], - "description": "A SimpleSAMLphp module that allows integration with Auth MemCookie, allowing web applications written in other languages than PHP to integrate with SimpleSAMLphp.", - "homepage": "https://simplesamlphp.org/", - "keywords": [ - "Auth MemCookie", - "apache", - "cookies", - "simplesamlphp" - ], - "support": { - "issues": "https://github.com/simplesamlphp/simplesamlphp-module-memcookie/issues", - "source": "https://github.com/simplesamlphp/simplesamlphp-module-memcookie/" - }, - "time": "2019-08-08T18:33:47+00:00" - }, - { - "name": "simplesamlphp/simplesamlphp-module-metarefresh", - "version": "v0.10.0", - "source": { - "type": "git", - "url": "https://github.com/simplesamlphp/simplesamlphp-module-metarefresh.git", - "reference": "488d7809857c274befac89facfa03520a05bc1ba" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-metarefresh/zipball/488d7809857c274befac89facfa03520a05bc1ba", - "reference": "488d7809857c274befac89facfa03520a05bc1ba", - "shasum": "" - }, - "require": { - "php": ">=5.6", - "simplesamlphp/composer-module-installer": "~1.1" - }, - "require-dev": { - "phpunit/phpunit": "~5.7", - "simplesamlphp/simplesamlphp": "^1.18" - }, - "type": "simplesamlphp-module", - "autoload": { - "psr-4": { - "SimpleSAML\\Module\\metarefresh\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-2.1-or-later" - ], - "authors": [ - { - "name": "Andreas Åkre Solberg", - "email": "andreas.solberg@uninett.no" - } - ], - "description": "The metarefresh module will download and parse metadata documents and store them locally", - "keywords": [ - "metarefresh", - "simplesamlphp" - ], - "support": { - "issues": "https://github.com/tvdijen/simplesamlphp-module-metarefresh/issues", - "source": "https://github.com/tvdijen/simplesamlphp-module-metarefresh" - }, - "time": "2022-05-03T08:57:30+00:00" - }, - { - "name": "simplesamlphp/simplesamlphp-module-negotiate", - "version": "v0.9.12", - "source": { - "type": "git", - "url": "https://github.com/simplesamlphp/simplesamlphp-module-negotiate.git", - "reference": "48752cea80e81a60ebb522cc10789589ac16df50" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-negotiate/zipball/48752cea80e81a60ebb522cc10789589ac16df50", - "reference": "48752cea80e81a60ebb522cc10789589ac16df50", - "shasum": "" - }, - "require": { - "php": ">=5.6", - "simplesamlphp/composer-module-installer": "~1.1", - "simplesamlphp/simplesamlphp-module-ldap": "^0.9", - "webmozart/assert": "~1.4" - }, - "require-dev": { - "phpunit/phpunit": "~5.7", - "sensiolabs/security-checker": "^5.0.3", - "simplesamlphp/simplesamlphp": "dev-testing-1.18", - "simplesamlphp/simplesamlphp-test-framework": "^0.0.14", - "squizlabs/php_codesniffer": "^3.5" - }, - "suggest": { - "ext-krb5": "Needed in case the SimpleSAMLphp negotiate module is used" - }, - "type": "simplesamlphp-module", - "autoload": { - "psr-4": { - "SimpleSAML\\Module\\negotiate\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-2.1-or-later" - ], - "authors": [ - { - "name": "Olav Morken", - "email": "olavmrk@gmail.com" - } - ], - "description": "The Negotiate module implements Microsofts Kerberos SPNEGO mechanism", - "keywords": [ - "negotiate", - "simplesamlphp" - ], - "support": { - "issues": "https://github.com/simplesamlphp/simplesamlphp-module-negotiate/issues", - "source": "https://github.com/simplesamlphp/simplesamlphp-module-negotiate" - }, - "time": "2022-01-03T23:18:27+00:00" - }, - { - "name": "simplesamlphp/simplesamlphp-module-oauth", - "version": "v0.9.3", - "source": { - "type": "git", - "url": "https://github.com/simplesamlphp/simplesamlphp-module-oauth.git", - "reference": "2a2433144dca408315e4ee163f9ab73a6110b2b1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-oauth/zipball/2a2433144dca408315e4ee163f9ab73a6110b2b1", - "reference": "2a2433144dca408315e4ee163f9ab73a6110b2b1", - "shasum": "" - }, - "require": { - "simplesamlphp/composer-module-installer": ">=1.1.6" - }, - "require-dev": { - "phpunit/phpunit": "~4.8.36", - "simplesamlphp/simplesamlphp": "^1.17" - }, - "type": "simplesamlphp-module", - "autoload": { - "psr-4": { - "SimpleSAML\\Module\\oauth\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-2.1-or-later" - ], - "authors": [ - { - "name": "Olav Morken", - "email": "olav.morken@uninett.no" - }, - { - "name": "Jaime Perez Crespo", - "email": "jaime.perez@uninett.no" - } - ], - "description": "A SimpleSAMLphp module that allows integration with OAuth1,", - "homepage": "https://simplesamlphp.org/", - "keywords": [ - "oauth1", - "simplesamlphp" - ], - "support": { - "issues": "https://github.com/simplesamlphp/simplesamlphp-module-oauth/issues", - "source": "https://github.com/simplesamlphp/simplesamlphp-module-oauth/" - }, - "abandoned": true, - "time": "2021-08-31T18:55:00+00:00" - }, - { - "name": "simplesamlphp/simplesamlphp-module-preprodwarning", - "version": "v0.9.3", - "source": { - "type": "git", - "url": "https://github.com/simplesamlphp/simplesamlphp-module-preprodwarning.git", - "reference": "b3c6d9d41d009e340f4843ce5c24b4118a38e4c3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-preprodwarning/zipball/b3c6d9d41d009e340f4843ce5c24b4118a38e4c3", - "reference": "b3c6d9d41d009e340f4843ce5c24b4118a38e4c3", - "shasum": "" - }, - "require": { - "php": ">=7.0", - "simplesamlphp/composer-module-installer": "~1.1" - }, - "require-dev": { - "phpunit/phpunit": "~5.7", - "simplesamlphp/simplesamlphp": "dev-simplesamlphp-1.19", - "webmozart/assert": "^1.4" - }, - "type": "simplesamlphp-module", - "autoload": { - "psr-4": { - "SimpleSAML\\Module\\preprodwarning\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-2.1-or-later" - ], - "authors": [ - { - "name": "Andreas Åkre Solberg", - "email": "andreas.solberg@uninett.no" - } - ], - "description": "Display a warning when using a pre-production environment", - "keywords": [ - "preprodwarning", - "simplesamlphp" - ], - "support": { - "issues": "https://github.com/simplesamlphp/simplesamlphp-module-preprodwarning/issues", - "source": "https://github.com/simplesamlphp/simplesamlphp-module-preprodwarning" - }, - "time": "2022-01-06T23:21:17+00:00" - }, - { - "name": "simplesamlphp/simplesamlphp-module-radius", - "version": "v0.9.4", - "source": { - "type": "git", - "url": "https://github.com/simplesamlphp/simplesamlphp-module-radius.git", - "reference": "dbe2976ba27f5131faeca368a5665f8baeaae8b6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-radius/zipball/dbe2976ba27f5131faeca368a5665f8baeaae8b6", - "reference": "dbe2976ba27f5131faeca368a5665f8baeaae8b6", - "shasum": "" - }, - "require": { - "php": ">=5.6", - "simplesamlphp/composer-module-installer": "~1.1" - }, - "require-dev": { - "phpunit/phpunit": "~5.7", - "simplesamlphp/simplesamlphp": "^1.17", - "simplesamlphp/simplesamlphp-test-framework": "^0.0.7" - }, - "type": "simplesamlphp-module", - "autoload": { - "psr-4": { - "SimpleSAML\\Module\\radius\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-2.1-or-later" - ], - "authors": [ - { - "name": "Olav Morken", - "email": "olavmrk@gmail.com" - } - ], - "description": "A module that is able perform authentication against a RADIUS server", - "keywords": [ - "radius", - "simplesamlphp" - ], - "support": { - "issues": "https://github.com/tvdijen/simplesamlphp-module-radius/issues", - "source": "https://github.com/tvdijen/simplesamlphp-module-radius" - }, - "time": "2022-01-06T23:23:28+00:00" - }, - { - "name": "simplesamlphp/simplesamlphp-module-riak", - "version": "v0.9.1", - "source": { - "type": "git", - "url": "https://github.com/simplesamlphp/simplesamlphp-module-riak.git", - "reference": "c1a9d9545cb4e05b9205b34624850bb777aca991" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-riak/zipball/c1a9d9545cb4e05b9205b34624850bb777aca991", - "reference": "c1a9d9545cb4e05b9205b34624850bb777aca991", - "shasum": "" - }, - "require": { - "php": ">=5.6", - "phpfastcache/riak-client": "^3.4", - "simplesamlphp/composer-module-installer": "~1.1" - }, - "require-dev": { - "phpunit/phpunit": "~5.7", - "simplesamlphp/simplesamlphp": "^1.17" - }, - "type": "simplesamlphp-module", - "autoload": { - "psr-4": { - "SimpleSAML\\Module\\riak\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-3.0-or-later" - ], - "authors": [ - { - "name": "Tim van Dijen", - "email": "tvdijen@gmail.com" - } - ], - "description": "A module that is able to store key/value pairs in a Riak store", - "keywords": [ - "riak", - "simplesamlphp" - ], - "support": { - "issues": "https://github.com/tvdijen/simplesamlphp-module-riak/issues", - "source": "https://github.com/tvdijen/simplesamlphp-module-riak" - }, - "abandoned": true, - "time": "2019-12-03T08:28:45+00:00" - }, - { - "name": "simplesamlphp/simplesamlphp-module-sanitycheck", - "version": "v0.9.1", - "source": { - "type": "git", - "url": "https://github.com/simplesamlphp/simplesamlphp-module-sanitycheck.git", - "reference": "15d6664eae73a233c3c4c72fd8a5c2be72b6ed2a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-sanitycheck/zipball/15d6664eae73a233c3c4c72fd8a5c2be72b6ed2a", - "reference": "15d6664eae73a233c3c4c72fd8a5c2be72b6ed2a", - "shasum": "" - }, - "require": { - "php": ">=5.6", - "simplesamlphp/composer-module-installer": "~1.1", - "webmozart/assert": "~1.4" - }, - "require-dev": { - "phpunit/phpunit": "~5.7", - "simplesamlphp/simplesamlphp": "^1.17" - }, - "type": "simplesamlphp-module", - "autoload": { - "psr-4": { - "SimpleSAML\\Module\\sanitycheck\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-2.1-or-later" - ], - "authors": [ - { - "name": "Andreas Åkre Solberg", - "email": "andreas.solberg@uninett.no" - } - ], - "description": "Perform sanity checks on configuration", - "keywords": [ - "sanitycheck", - "simplesamlphp" - ], - "support": { - "issues": "https://github.com/tvdijen/simplesamlphp-module-sanitycheck/issues", - "source": "https://github.com/tvdijen/simplesamlphp-module-sanitycheck" - }, - "time": "2020-05-07T11:34:29+00:00" - }, - { - "name": "simplesamlphp/simplesamlphp-module-smartattributes", - "version": "v0.9.2", - "source": { - "type": "git", - "url": "https://github.com/simplesamlphp/simplesamlphp-module-smartattributes.git", - "reference": "ba6a32fa287db0f8d767104471176f70fad7f0e1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-smartattributes/zipball/ba6a32fa287db0f8d767104471176f70fad7f0e1", - "reference": "ba6a32fa287db0f8d767104471176f70fad7f0e1", - "shasum": "" - }, - "require": { - "php": ">=5.6", - "simplesamlphp/composer-module-installer": "~1.1" - }, - "require-dev": { - "phpunit/phpunit": "~5.7", - "simplesamlphp/simplesamlphp": "^1.17" - }, - "type": "simplesamlphp-module", - "autoload": { - "psr-4": { - "SimpleSAML\\Module\\smartattributes\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-2.1-or-later" - ], - "authors": [ - { - "name": "Andreas Åkre Solberg", - "email": "andreas.solberg@uninett.no" - } - ], - "description": "The SmartAttributes module provides additional authentication processing filters to manipulate attributes.", - "keywords": [ - "simplesamlphp", - "smartattributes" - ], - "support": { - "issues": "https://github.com/tvdijen/simplesamlphp-module-smartattributes/issues", - "source": "https://github.com/tvdijen/simplesamlphp-module-smartattributes" - }, - "time": "2022-01-06T23:42:07+00:00" - }, - { - "name": "simplesamlphp/simplesamlphp-module-sqlauth", - "version": "v0.9.4", - "source": { - "type": "git", - "url": "https://github.com/simplesamlphp/simplesamlphp-module-sqlauth.git", - "reference": "8a28f9a9726bab1dbc8fd3734daa08882dd0a25b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-sqlauth/zipball/8a28f9a9726bab1dbc8fd3734daa08882dd0a25b", - "reference": "8a28f9a9726bab1dbc8fd3734daa08882dd0a25b", - "shasum": "" - }, - "require": { - "php": ">=5.6", - "simplesamlphp/composer-module-installer": "~1.1" - }, - "require-dev": { - "phpunit/phpunit": "~5.7", - "simplesamlphp/simplesamlphp": "^1.17", - "webmozart/assert": "^1.4 <1.7" - }, - "type": "simplesamlphp-module", - "autoload": { - "psr-4": { - "SimpleSAML\\Module\\sqlauth\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-2.1-or-later" - ], - "authors": [ - { - "name": "Olav Morken", - "email": "olavmrk@gmail.com" - } - ], - "description": "This is a authentication module for authenticating a user against a SQL database", - "keywords": [ - "simplesamlphp", - "sqlauth" + "browser", + "detection", + "language", + "operating system", + "os" ], "support": { - "issues": "https://github.com/tvdijen/simplesamlphp-module-sqlauth/issues", - "source": "https://github.com/tvdijen/simplesamlphp-module-sqlauth" + "issues": "https://github.com/sinergi/php-browser-detector/issues", + "source": "https://github.com/sinergi/php-browser-detector/tree/6.1.4" }, - "time": "2022-01-06T23:50:52+00:00" + "abandoned": true, + "time": "2021-09-23T13:51:44+00:00" }, { - "name": "simplesamlphp/simplesamlphp-module-statistics", - "version": "v0.9.6", + "name": "symfony/cache", + "version": "v6.4.8", "source": { "type": "git", - "url": "https://github.com/simplesamlphp/simplesamlphp-module-statistics.git", - "reference": "03fb6bdbbf5ce0a0cb257208db79aacac227ac10" + "url": "https://github.com/symfony/cache.git", + "reference": "287142df5579ce223c485b3872df3efae8390984" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-statistics/zipball/03fb6bdbbf5ce0a0cb257208db79aacac227ac10", - "reference": "03fb6bdbbf5ce0a0cb257208db79aacac227ac10", + "url": "https://api.github.com/repos/symfony/cache/zipball/287142df5579ce223c485b3872df3efae8390984", + "reference": "287142df5579ce223c485b3872df3efae8390984", "shasum": "" }, "require": { - "php": ">=5.6", - "simplesamlphp/composer-module-installer": "~1.1", - "webmozart/assert": "^1.4" + "php": ">=8.1", + "psr/cache": "^2.0|^3.0", + "psr/log": "^1.1|^2|^3", + "symfony/cache-contracts": "^2.5|^3", + "symfony/service-contracts": "^2.5|^3", + "symfony/var-exporter": "^6.3.6|^7.0" + }, + "conflict": { + "doctrine/dbal": "<2.13.1", + "symfony/dependency-injection": "<5.4", + "symfony/http-kernel": "<5.4", + "symfony/var-dumper": "<5.4" + }, + "provide": { + "psr/cache-implementation": "2.0|3.0", + "psr/simple-cache-implementation": "1.0|2.0|3.0", + "symfony/cache-implementation": "1.1|2.0|3.0" }, "require-dev": { - "phpunit/phpunit": "~5.7", - "simplesamlphp/simplesamlphp": "^1.17", - "simplesamlphp/simplesamlphp-test-framework": "^0.0.12" + "cache/integration-tests": "dev-master", + "doctrine/dbal": "^2.13.1|^3|^4", + "predis/predis": "^1.1|^2.0", + "psr/simple-cache": "^1.0|^2.0|^3.0", + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/filesystem": "^5.4|^6.0|^7.0", + "symfony/http-kernel": "^5.4|^6.0|^7.0", + "symfony/messenger": "^5.4|^6.0|^7.0", + "symfony/var-dumper": "^5.4|^6.0|^7.0" }, - "type": "simplesamlphp-module", + "type": "library", "autoload": { "psr-4": { - "SimpleSAML\\Module\\statistics\\": "lib/" - } + "Symfony\\Component\\Cache\\": "" + }, + "classmap": [ + "Traits/ValueWrapper.php" + ], + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "LGPL-2.1-or-later" + "MIT" ], "authors": [ { - "name": "Andreas Åkre Solberg", - "email": "andreas.solberg@uninett.no" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "The SimpleSAMLphp statistics module", + "description": "Provides extended PSR-6, PSR-16 (and tags) implementations", + "homepage": "https://symfony.com", "keywords": [ - "simplesamlphp", - "statistics" + "caching", + "psr6" ], "support": { - "issues": "https://github.com/simplesamlphp/simplesamlphp-module-statistics/issues", - "source": "https://github.com/simplesamlphp/simplesamlphp-module-statistics" + "source": "https://github.com/symfony/cache/tree/v6.4.8" }, - "time": "2021-01-25T15:15:26+00:00" + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-05-31T14:49:08+00:00" }, { - "name": "simplesamlphp/twig-configurable-i18n", - "version": "v2.3.5", + "name": "symfony/cache-contracts", + "version": "v3.5.0", "source": { "type": "git", - "url": "https://github.com/simplesamlphp/twig-configurable-i18n.git", - "reference": "1dc0ff69ec1dfb4cab6a30c583b59faf0efc27d6" + "url": "https://github.com/symfony/cache-contracts.git", + "reference": "df6a1a44c890faded49a5fca33c2d5c5fd3c2197" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/simplesamlphp/twig-configurable-i18n/zipball/1dc0ff69ec1dfb4cab6a30c583b59faf0efc27d6", - "reference": "1dc0ff69ec1dfb4cab6a30c583b59faf0efc27d6", + "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/df6a1a44c890faded49a5fca33c2d5c5fd3c2197", + "reference": "df6a1a44c890faded49a5fca33c2d5c5fd3c2197", "shasum": "" }, "require": { - "php": ">=7.1", - "twig/extensions": "@dev" + "php": ">=8.1", + "psr/cache": "^3.0" }, - "require-dev": { - "phpunit/phpunit": "^7.5", - "sensiolabs/security-checker": "~6.0.3", - "simplesamlphp/simplesamlphp-test-framework": "~0.1.2", - "squizlabs/php_codesniffer": "^3.5", - "twig/twig": "^2.15.3" + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } }, - "type": "project", "autoload": { "psr-4": { - "SimpleSAML\\TwigConfigurableI18n\\": "src/" + "Symfony\\Contracts\\Cache\\": "" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "LGPL-2.1" + "MIT" ], "authors": [ { - "name": "Jaime Perez", - "email": "jaime.perez@uninett.no" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "This is an extension on top of Twig's i18n extension, allowing you to customize which functions to use for translations.", + "description": "Generic abstractions related to caching", + "homepage": "https://symfony.com", "keywords": [ - "extension", - "gettext", - "i18n", - "internationalization", - "translation", - "twig" + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" ], "support": { - "issues": "https://github.com/simplesamlphp/twig-configurable-i18n/issues", - "source": "https://github.com/simplesamlphp/twig-configurable-i18n" + "source": "https://github.com/symfony/cache-contracts/tree/v3.5.0" }, - "abandoned": true, - "time": "2022-11-28T16:34:29+00:00" + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-04-18T09:32:20+00:00" }, { - "name": "sinergi/browser-detector", - "version": "6.1.4", + "name": "symfony/config", + "version": "v6.4.8", "source": { "type": "git", - "url": "https://github.com/sinergi/php-browser-detector.git", - "reference": "4927f7c2bedc48b68f183bd420aa3549c59e133b" + "url": "https://github.com/symfony/config.git", + "reference": "12e7e52515ce37191b193cf3365903c4f3951e35" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sinergi/php-browser-detector/zipball/4927f7c2bedc48b68f183bd420aa3549c59e133b", - "reference": "4927f7c2bedc48b68f183bd420aa3549c59e133b", + "url": "https://api.github.com/repos/symfony/config/zipball/12e7e52515ce37191b193cf3365903c4f3951e35", + "reference": "12e7e52515ce37191b193cf3365903c4f3951e35", "shasum": "" }, "require": { - "php": ">=7.2" + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/filesystem": "^5.4|^6.0|^7.0", + "symfony/polyfill-ctype": "~1.8" + }, + "conflict": { + "symfony/finder": "<5.4", + "symfony/service-contracts": "<2.5" }, "require-dev": { - "phpunit/phpunit": "^8.0 || ^9.4" + "symfony/event-dispatcher": "^5.4|^6.0|^7.0", + "symfony/finder": "^5.4|^6.0|^7.0", + "symfony/messenger": "^5.4|^6.0|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/yaml": "^5.4|^6.0|^7.0" }, "type": "library", "autoload": { "psr-4": { - "Sinergi\\BrowserDetector\\": "src" - } + "Symfony\\Component\\Config\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -4774,81 +3718,83 @@ ], "authors": [ { - "name": "Gabriel Bull", - "email": "me@gabrielbull.com" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { - "name": "Chris Schuld" + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Detecting the user's browser, operating system and language.", - "keywords": [ - "browser", - "detection", - "language", - "operating system", - "os" - ], + "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", + "homepage": "https://symfony.com", "support": { - "issues": "https://github.com/sinergi/php-browser-detector/issues", - "source": "https://github.com/sinergi/php-browser-detector/tree/6.1.4" + "source": "https://github.com/symfony/config/tree/v6.4.8" }, - "abandoned": true, - "time": "2021-09-23T13:51:44+00:00" + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-05-31T14:49:08+00:00" }, { - "name": "symfony/cache", - "version": "v5.4.25", + "name": "symfony/console", + "version": "v6.4.8", "source": { "type": "git", - "url": "https://github.com/symfony/cache.git", - "reference": "e2013521c0f07473ae69a01fce0af78fc3ec0f23" + "url": "https://github.com/symfony/console.git", + "reference": "be5854cee0e8c7b110f00d695d11debdfa1a2a91" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/e2013521c0f07473ae69a01fce0af78fc3ec0f23", - "reference": "e2013521c0f07473ae69a01fce0af78fc3ec0f23", + "url": "https://api.github.com/repos/symfony/console/zipball/be5854cee0e8c7b110f00d695d11debdfa1a2a91", + "reference": "be5854cee0e8c7b110f00d695d11debdfa1a2a91", "shasum": "" }, "require": { - "php": ">=7.2.5", - "psr/cache": "^1.0|^2.0", - "psr/log": "^1.1|^2|^3", - "symfony/cache-contracts": "^1.1.7|^2", - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/polyfill-php73": "^1.9", - "symfony/polyfill-php80": "^1.16", - "symfony/service-contracts": "^1.1|^2|^3", - "symfony/var-exporter": "^4.4|^5.0|^6.0" + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/string": "^5.4|^6.0|^7.0" }, "conflict": { - "doctrine/dbal": "<2.13.1", - "symfony/dependency-injection": "<4.4", - "symfony/http-kernel": "<4.4", - "symfony/var-dumper": "<4.4" + "symfony/dependency-injection": "<5.4", + "symfony/dotenv": "<5.4", + "symfony/event-dispatcher": "<5.4", + "symfony/lock": "<5.4", + "symfony/process": "<5.4" }, "provide": { - "psr/cache-implementation": "1.0|2.0", - "psr/simple-cache-implementation": "1.0|2.0", - "symfony/cache-implementation": "1.0|2.0" + "psr/log-implementation": "1.0|2.0|3.0" }, "require-dev": { - "cache/integration-tests": "dev-master", - "doctrine/cache": "^1.6|^2.0", - "doctrine/dbal": "^2.13.1|^3.0", - "predis/predis": "^1.1", - "psr/simple-cache": "^1.0|^2.0", - "symfony/config": "^4.4|^5.0|^6.0", - "symfony/dependency-injection": "^4.4|^5.0|^6.0", - "symfony/filesystem": "^4.4|^5.0|^6.0", - "symfony/http-kernel": "^4.4|^5.0|^6.0", - "symfony/messenger": "^4.4|^5.0|^6.0", - "symfony/var-dumper": "^4.4|^5.0|^6.0" + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/event-dispatcher": "^5.4|^6.0|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/lock": "^5.4|^6.0|^7.0", + "symfony/messenger": "^5.4|^6.0|^7.0", + "symfony/process": "^5.4|^6.0|^7.0", + "symfony/stopwatch": "^5.4|^6.0|^7.0", + "symfony/var-dumper": "^5.4|^6.0|^7.0" }, "type": "library", "autoload": { "psr-4": { - "Symfony\\Component\\Cache\\": "" + "Symfony\\Component\\Console\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -4860,22 +3806,24 @@ ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Provides extended PSR-6, PSR-16 (and tags) implementations", + "description": "Eases the creation of beautiful and testable command line interfaces", "homepage": "https://symfony.com", "keywords": [ - "caching", - "psr6" + "cli", + "command-line", + "console", + "terminal" ], "support": { - "source": "https://github.com/symfony/cache/tree/v5.4.25" + "source": "https://github.com/symfony/console/tree/v6.4.8" }, "funding": [ { @@ -4891,43 +3839,53 @@ "type": "tidelift" } ], - "time": "2023-06-22T08:06:06+00:00" + "time": "2024-05-31T14:49:08+00:00" }, { - "name": "symfony/cache-contracts", - "version": "v2.5.2", + "name": "symfony/dependency-injection", + "version": "v6.4.8", "source": { "type": "git", - "url": "https://github.com/symfony/cache-contracts.git", - "reference": "64be4a7acb83b6f2bf6de9a02cee6dad41277ebc" + "url": "https://github.com/symfony/dependency-injection.git", + "reference": "d3b618176e8c3a9e5772151c51eba0c52a0c771c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/64be4a7acb83b6f2bf6de9a02cee6dad41277ebc", - "reference": "64be4a7acb83b6f2bf6de9a02cee6dad41277ebc", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/d3b618176e8c3a9e5772151c51eba0c52a0c771c", + "reference": "d3b618176e8c3a9e5772151c51eba0c52a0c771c", "shasum": "" }, "require": { - "php": ">=7.2.5", - "psr/cache": "^1.0|^2.0|^3.0" + "php": ">=8.1", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/service-contracts": "^2.5|^3.0", + "symfony/var-exporter": "^6.2.10|^7.0" }, - "suggest": { - "symfony/cache-implementation": "" + "conflict": { + "ext-psr": "<1.1|>=2", + "symfony/config": "<6.1", + "symfony/finder": "<5.4", + "symfony/proxy-manager-bridge": "<6.3", + "symfony/yaml": "<5.4" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } + "provide": { + "psr/container-implementation": "1.1|2.0", + "symfony/service-implementation": "1.1|2.0|3.0" + }, + "require-dev": { + "symfony/config": "^6.1|^7.0", + "symfony/expression-language": "^5.4|^6.0|^7.0", + "symfony/yaml": "^5.4|^6.0|^7.0" }, + "type": "library", "autoload": { "psr-4": { - "Symfony\\Contracts\\Cache\\": "" - } + "Symfony\\Component\\DependencyInjection\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -4935,26 +3893,18 @@ ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Generic abstractions related to caching", + "description": "Allows you to standardize and centralize the way objects are constructed in your application", "homepage": "https://symfony.com", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" - ], "support": { - "source": "https://github.com/symfony/cache-contracts/tree/v2.5.2" + "source": "https://github.com/symfony/dependency-injection/tree/v6.4.8" }, "funding": [ { @@ -4970,49 +3920,38 @@ "type": "tidelift" } ], - "time": "2022-01-02T09:53:40+00:00" + "time": "2024-05-31T14:49:08+00:00" }, { - "name": "symfony/config", - "version": "v4.4.44", + "name": "symfony/deprecation-contracts", + "version": "v3.5.0", "source": { "type": "git", - "url": "https://github.com/symfony/config.git", - "reference": "ed42f8f9da528d2c6cae36fe1f380b0c1d8f0658" + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/ed42f8f9da528d2c6cae36fe1f380b0c1d8f0658", - "reference": "ed42f8f9da528d2c6cae36fe1f380b0c1d8f0658", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", + "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", "shasum": "" }, "require": { - "php": ">=7.1.3", - "symfony/filesystem": "^3.4|^4.0|^5.0", - "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-php80": "^1.16", - "symfony/polyfill-php81": "^1.22" - }, - "conflict": { - "symfony/finder": "<3.4" - }, - "require-dev": { - "symfony/event-dispatcher": "^3.4|^4.0|^5.0", - "symfony/finder": "^3.4|^4.0|^5.0", - "symfony/messenger": "^4.1|^5.0", - "symfony/service-contracts": "^1.1|^2", - "symfony/yaml": "^3.4|^4.0|^5.0" - }, - "suggest": { - "symfony/yaml": "To use the yaml reference dumper" + "php": ">=8.1" }, "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Config\\": "" + "extra": { + "branch-alias": { + "dev-main": "3.5-dev" }, - "exclude-from-classmap": [ - "/Tests/" + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "files": [ + "function.php" ] }, "notification-url": "https://packagist.org/downloads/", @@ -5021,18 +3960,18 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", + "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/config/tree/v4.4.44" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.0" }, "funding": [ { @@ -5048,58 +3987,43 @@ "type": "tidelift" } ], - "time": "2022-07-20T09:59:04+00:00" + "time": "2024-04-18T09:32:20+00:00" }, { - "name": "symfony/console", - "version": "v4.4.49", + "name": "symfony/error-handler", + "version": "v6.4.8", "source": { "type": "git", - "url": "https://github.com/symfony/console.git", - "reference": "33fa45ffc81fdcc1ca368d4946da859c8cdb58d9" + "url": "https://github.com/symfony/error-handler.git", + "reference": "ef836152bf13472dc5fb5b08b0c0c4cfeddc0fcc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/33fa45ffc81fdcc1ca368d4946da859c8cdb58d9", - "reference": "33fa45ffc81fdcc1ca368d4946da859c8cdb58d9", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/ef836152bf13472dc5fb5b08b0c0c4cfeddc0fcc", + "reference": "ef836152bf13472dc5fb5b08b0c0c4cfeddc0fcc", "shasum": "" }, "require": { - "php": ">=7.1.3", - "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php73": "^1.8", - "symfony/polyfill-php80": "^1.16", - "symfony/service-contracts": "^1.1|^2" + "php": ">=8.1", + "psr/log": "^1|^2|^3", + "symfony/var-dumper": "^5.4|^6.0|^7.0" }, "conflict": { - "psr/log": ">=3", - "symfony/dependency-injection": "<3.4", - "symfony/event-dispatcher": "<4.3|>=5", - "symfony/lock": "<4.4", - "symfony/process": "<3.3" - }, - "provide": { - "psr/log-implementation": "1.0|2.0" + "symfony/deprecation-contracts": "<2.5", + "symfony/http-kernel": "<6.4" }, "require-dev": { - "psr/log": "^1|^2", - "symfony/config": "^3.4|^4.0|^5.0", - "symfony/dependency-injection": "^3.4|^4.0|^5.0", - "symfony/event-dispatcher": "^4.3", - "symfony/lock": "^4.4|^5.0", - "symfony/process": "^3.4|^4.0|^5.0", - "symfony/var-dumper": "^4.3|^5.0" - }, - "suggest": { - "psr/log": "For using the console logger", - "symfony/event-dispatcher": "", - "symfony/lock": "", - "symfony/process": "" + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/serializer": "^5.4|^6.0|^7.0" }, + "bin": [ + "Resources/bin/patch-type-declarations" + ], "type": "library", "autoload": { "psr-4": { - "Symfony\\Component\\Console\\": "" + "Symfony\\Component\\ErrorHandler\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -5119,10 +4043,10 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Eases the creation of beautiful and testable command line interfaces", + "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/console/tree/v4.4.49" + "source": "https://github.com/symfony/error-handler/tree/v6.4.8" }, "funding": [ { @@ -5138,36 +4062,48 @@ "type": "tidelift" } ], - "time": "2022-11-05T17:10:16+00:00" + "time": "2024-05-31T14:49:08+00:00" }, { - "name": "symfony/debug", - "version": "v4.4.44", + "name": "symfony/event-dispatcher", + "version": "v6.4.8", "source": { "type": "git", - "url": "https://github.com/symfony/debug.git", - "reference": "1a692492190773c5310bc7877cb590c04c2f05be" + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "8d7507f02b06e06815e56bb39aa0128e3806208b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/1a692492190773c5310bc7877cb590c04c2f05be", - "reference": "1a692492190773c5310bc7877cb590c04c2f05be", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/8d7507f02b06e06815e56bb39aa0128e3806208b", + "reference": "8d7507f02b06e06815e56bb39aa0128e3806208b", "shasum": "" }, "require": { - "php": ">=7.1.3", - "psr/log": "^1|^2|^3" + "php": ">=8.1", + "symfony/event-dispatcher-contracts": "^2.5|^3" }, "conflict": { - "symfony/http-kernel": "<3.4" + "symfony/dependency-injection": "<5.4", + "symfony/service-contracts": "<2.5" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "2.0|3.0" }, "require-dev": { - "symfony/http-kernel": "^3.4|^4.0|^5.0" + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/error-handler": "^5.4|^6.0|^7.0", + "symfony/expression-language": "^5.4|^6.0|^7.0", + "symfony/http-foundation": "^5.4|^6.0|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/stopwatch": "^5.4|^6.0|^7.0" }, "type": "library", "autoload": { "psr-4": { - "Symfony\\Component\\Debug\\": "" + "Symfony\\Component\\EventDispatcher\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -5187,10 +4123,10 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Provides tools to ease debugging PHP code", + "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/debug/tree/v4.4.44" + "source": "https://github.com/symfony/event-dispatcher/tree/v6.4.8" }, "funding": [ { @@ -5206,59 +4142,40 @@ "type": "tidelift" } ], - "abandoned": "symfony/error-handler", - "time": "2022-07-28T16:29:46+00:00" + "time": "2024-05-31T14:49:08+00:00" }, { - "name": "symfony/dependency-injection", - "version": "v4.4.49", + "name": "symfony/event-dispatcher-contracts", + "version": "v3.5.0", "source": { "type": "git", - "url": "https://github.com/symfony/dependency-injection.git", - "reference": "9065fe97dbd38a897e95ea254eb5ddfe1310f734" + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "8f93aec25d41b72493c6ddff14e916177c9efc50" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/9065fe97dbd38a897e95ea254eb5ddfe1310f734", - "reference": "9065fe97dbd38a897e95ea254eb5ddfe1310f734", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/8f93aec25d41b72493c6ddff14e916177c9efc50", + "reference": "8f93aec25d41b72493c6ddff14e916177c9efc50", "shasum": "" }, "require": { - "php": ">=7.1.3", - "psr/container": "^1.0", - "symfony/polyfill-php80": "^1.16", - "symfony/service-contracts": "^1.1.6|^2" - }, - "conflict": { - "symfony/config": "<4.3|>=5.0", - "symfony/finder": "<3.4", - "symfony/proxy-manager-bridge": "<3.4", - "symfony/yaml": "<4.4.26" - }, - "provide": { - "psr/container-implementation": "1.0", - "symfony/service-implementation": "1.0|2.0" - }, - "require-dev": { - "symfony/config": "^4.3", - "symfony/expression-language": "^3.4|^4.0|^5.0", - "symfony/yaml": "^4.4.26|^5.0" - }, - "suggest": { - "symfony/config": "", - "symfony/expression-language": "For using expressions in service container configuration", - "symfony/finder": "For using double-star glob patterns or when GLOB_BRACE portability is required", - "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them", - "symfony/yaml": "" + "php": ">=8.1", + "psr/event-dispatcher": "^1" }, "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, "autoload": { "psr-4": { - "Symfony\\Component\\DependencyInjection\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] + "Symfony\\Contracts\\EventDispatcher\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -5266,18 +4183,26 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Allows you to standardize and centralize the way objects are constructed in your application", + "description": "Generic abstractions related to dispatching event", "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], "support": { - "source": "https://github.com/symfony/dependency-injection/tree/v4.4.49" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.5.0" }, "funding": [ { @@ -5293,38 +4218,37 @@ "type": "tidelift" } ], - "time": "2022-11-16T16:18:09+00:00" + "time": "2024-04-18T09:32:20+00:00" }, { - "name": "symfony/deprecation-contracts", - "version": "v3.3.0", + "name": "symfony/filesystem", + "version": "v6.4.8", "source": { "type": "git", - "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf" + "url": "https://github.com/symfony/filesystem.git", + "reference": "4d37529150e7081c51b3c5d5718c55a04a9503f3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf", - "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/4d37529150e7081c51b3c5d5718c55a04a9503f3", + "reference": "4d37529150e7081c51b3c5d5718c55a04a9503f3", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.1", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.8" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.4-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } + "require-dev": { + "symfony/process": "^5.4|^6.4|^7.0" }, + "type": "library", "autoload": { - "files": [ - "function.php" + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -5333,18 +4257,18 @@ ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "A generic function and convention to trigger deprecation notices", + "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.3.0" + "source": "https://github.com/symfony/filesystem/tree/v6.4.8" }, "funding": [ { @@ -5360,36 +4284,32 @@ "type": "tidelift" } ], - "time": "2023-05-23T14:45:45+00:00" + "time": "2024-05-31T14:49:08+00:00" }, { - "name": "symfony/error-handler", - "version": "v4.4.44", + "name": "symfony/finder", + "version": "v6.4.8", "source": { "type": "git", - "url": "https://github.com/symfony/error-handler.git", - "reference": "be731658121ef2d8be88f3a1ec938148a9237291" + "url": "https://github.com/symfony/finder.git", + "reference": "3ef977a43883215d560a2cecb82ec8e62131471c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/be731658121ef2d8be88f3a1ec938148a9237291", - "reference": "be731658121ef2d8be88f3a1ec938148a9237291", + "url": "https://api.github.com/repos/symfony/finder/zipball/3ef977a43883215d560a2cecb82ec8e62131471c", + "reference": "3ef977a43883215d560a2cecb82ec8e62131471c", "shasum": "" }, "require": { - "php": ">=7.1.3", - "psr/log": "^1|^2|^3", - "symfony/debug": "^4.4.5", - "symfony/var-dumper": "^4.4|^5.0" + "php": ">=8.1" }, "require-dev": { - "symfony/http-kernel": "^4.4|^5.0", - "symfony/serializer": "^4.4|^5.0" + "symfony/filesystem": "^6.0|^7.0" }, "type": "library", "autoload": { "psr-4": { - "Symfony\\Component\\ErrorHandler\\": "" + "Symfony\\Component\\Finder\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -5409,10 +4329,10 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Provides tools to manage errors and ease debugging PHP code", + "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/error-handler/tree/v4.4.44" + "source": "https://github.com/symfony/finder/tree/v6.4.8" }, "funding": [ { @@ -5428,52 +4348,116 @@ "type": "tidelift" } ], - "time": "2022-07-28T16:29:46+00:00" + "time": "2024-05-31T14:49:08+00:00" }, { - "name": "symfony/event-dispatcher", - "version": "v4.4.44", + "name": "symfony/framework-bundle", + "version": "v6.4.8", "source": { "type": "git", - "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "1e866e9e5c1b22168e0ce5f0b467f19bba61266a" + "url": "https://github.com/symfony/framework-bundle.git", + "reference": "7c7739f87f1a8be1c2f5e7d28addfe763a917acb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/1e866e9e5c1b22168e0ce5f0b467f19bba61266a", - "reference": "1e866e9e5c1b22168e0ce5f0b467f19bba61266a", + "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/7c7739f87f1a8be1c2f5e7d28addfe763a917acb", + "reference": "7c7739f87f1a8be1c2f5e7d28addfe763a917acb", "shasum": "" }, "require": { - "php": ">=7.1.3", - "symfony/event-dispatcher-contracts": "^1.1", - "symfony/polyfill-php80": "^1.16" + "composer-runtime-api": ">=2.1", + "ext-xml": "*", + "php": ">=8.1", + "symfony/cache": "^5.4|^6.0|^7.0", + "symfony/config": "^6.1|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/error-handler": "^6.1|^7.0", + "symfony/event-dispatcher": "^5.4|^6.0|^7.0", + "symfony/filesystem": "^5.4|^6.0|^7.0", + "symfony/finder": "^5.4|^6.0|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4", + "symfony/polyfill-mbstring": "~1.0", + "symfony/routing": "^6.4|^7.0" }, "conflict": { - "symfony/dependency-injection": "<3.4" - }, - "provide": { - "psr/event-dispatcher-implementation": "1.0", - "symfony/event-dispatcher-implementation": "1.1" + "doctrine/annotations": "<1.13.1", + "doctrine/persistence": "<1.3", + "phpdocumentor/reflection-docblock": "<3.2.2", + "phpdocumentor/type-resolver": "<1.4.0", + "symfony/asset": "<5.4", + "symfony/asset-mapper": "<6.4", + "symfony/clock": "<6.3", + "symfony/console": "<5.4|>=7.0", + "symfony/dom-crawler": "<6.4", + "symfony/dotenv": "<5.4", + "symfony/form": "<5.4", + "symfony/http-client": "<6.3", + "symfony/lock": "<5.4", + "symfony/mailer": "<5.4", + "symfony/messenger": "<6.3", + "symfony/mime": "<6.4", + "symfony/property-access": "<5.4", + "symfony/property-info": "<5.4", + "symfony/scheduler": "<6.4.4|>=7.0.0,<7.0.4", + "symfony/security-core": "<5.4", + "symfony/security-csrf": "<5.4", + "symfony/serializer": "<6.4", + "symfony/stopwatch": "<5.4", + "symfony/translation": "<6.4", + "symfony/twig-bridge": "<5.4", + "symfony/twig-bundle": "<5.4", + "symfony/validator": "<6.4", + "symfony/web-profiler-bundle": "<6.4", + "symfony/workflow": "<6.4" }, "require-dev": { - "psr/log": "^1|^2|^3", - "symfony/config": "^3.4|^4.0|^5.0", - "symfony/dependency-injection": "^3.4|^4.0|^5.0", - "symfony/error-handler": "~3.4|~4.4", - "symfony/expression-language": "^3.4|^4.0|^5.0", - "symfony/http-foundation": "^3.4|^4.0|^5.0", - "symfony/service-contracts": "^1.1|^2", - "symfony/stopwatch": "^3.4|^4.0|^5.0" - }, - "suggest": { - "symfony/dependency-injection": "", - "symfony/http-kernel": "" + "doctrine/annotations": "^1.13.1|^2", + "doctrine/persistence": "^1.3|^2|^3", + "dragonmantank/cron-expression": "^3.1", + "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", + "seld/jsonlint": "^1.10", + "symfony/asset": "^5.4|^6.0|^7.0", + "symfony/asset-mapper": "^6.4|^7.0", + "symfony/browser-kit": "^5.4|^6.0|^7.0", + "symfony/clock": "^6.2|^7.0", + "symfony/console": "^5.4.9|^6.0.9|^7.0", + "symfony/css-selector": "^5.4|^6.0|^7.0", + "symfony/dom-crawler": "^6.4|^7.0", + "symfony/dotenv": "^5.4|^6.0|^7.0", + "symfony/expression-language": "^5.4|^6.0|^7.0", + "symfony/form": "^5.4|^6.0|^7.0", + "symfony/html-sanitizer": "^6.1|^7.0", + "symfony/http-client": "^6.3|^7.0", + "symfony/lock": "^5.4|^6.0|^7.0", + "symfony/mailer": "^5.4|^6.0|^7.0", + "symfony/messenger": "^6.3|^7.0", + "symfony/mime": "^6.4|^7.0", + "symfony/notifier": "^5.4|^6.0|^7.0", + "symfony/polyfill-intl-icu": "~1.0", + "symfony/process": "^5.4|^6.0|^7.0", + "symfony/property-info": "^5.4|^6.0|^7.0", + "symfony/rate-limiter": "^5.4|^6.0|^7.0", + "symfony/scheduler": "^6.4.4|^7.0.4", + "symfony/security-bundle": "^5.4|^6.0|^7.0", + "symfony/semaphore": "^5.4|^6.0|^7.0", + "symfony/serializer": "^6.4|^7.0", + "symfony/stopwatch": "^5.4|^6.0|^7.0", + "symfony/string": "^5.4|^6.0|^7.0", + "symfony/translation": "^6.4|^7.0", + "symfony/twig-bundle": "^5.4|^6.0|^7.0", + "symfony/uid": "^5.4|^6.0|^7.0", + "symfony/validator": "^6.4|^7.0", + "symfony/web-link": "^5.4|^6.0|^7.0", + "symfony/workflow": "^6.4|^7.0", + "symfony/yaml": "^5.4|^6.0|^7.0", + "twig/twig": "^2.10|^3.0.4" }, - "type": "library", + "type": "symfony-bundle", "autoload": { "psr-4": { - "Symfony\\Component\\EventDispatcher\\": "" + "Symfony\\Bundle\\FrameworkBundle\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -5493,10 +4477,10 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", + "description": "Provides a tight integration between Symfony components and the Symfony full-stack framework", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v4.4.44" + "source": "https://github.com/symfony/framework-bundle/tree/v6.4.8" }, "funding": [ { @@ -5512,43 +4496,49 @@ "type": "tidelift" } ], - "time": "2022-07-20T09:59:04+00:00" + "time": "2024-05-31T14:49:08+00:00" }, { - "name": "symfony/event-dispatcher-contracts", - "version": "v1.1.13", + "name": "symfony/http-foundation", + "version": "v6.4.8", "source": { "type": "git", - "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "1d5cd762abaa6b2a4169d3e77610193a7157129e" + "url": "https://github.com/symfony/http-foundation.git", + "reference": "27de8cc95e11db7a50b027e71caaab9024545947" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/1d5cd762abaa6b2a4169d3e77610193a7157129e", - "reference": "1d5cd762abaa6b2a4169d3e77610193a7157129e", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/27de8cc95e11db7a50b027e71caaab9024545947", + "reference": "27de8cc95e11db7a50b027e71caaab9024545947", "shasum": "" }, "require": { - "php": ">=7.1.3" + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.1", + "symfony/polyfill-php83": "^1.27" }, - "suggest": { - "psr/event-dispatcher": "", - "symfony/event-dispatcher-implementation": "" + "conflict": { + "symfony/cache": "<6.3" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.1-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } + "require-dev": { + "doctrine/dbal": "^2.13.1|^3|^4", + "predis/predis": "^1.1|^2.0", + "symfony/cache": "^6.3|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/expression-language": "^5.4|^6.0|^7.0", + "symfony/http-kernel": "^5.4.12|^6.0.12|^6.1.4|^7.0", + "symfony/mime": "^5.4|^6.0|^7.0", + "symfony/rate-limiter": "^5.4|^6.0|^7.0" }, + "type": "library", "autoload": { "psr-4": { - "Symfony\\Contracts\\EventDispatcher\\": "" - } + "Symfony\\Component\\HttpFoundation\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -5556,26 +4546,18 @@ ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Generic abstractions related to dispatching event", + "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" - ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v1.1.13" + "source": "https://github.com/symfony/http-foundation/tree/v6.4.8" }, "funding": [ { @@ -5591,32 +4573,82 @@ "type": "tidelift" } ], - "time": "2022-01-02T09:41:36+00:00" + "time": "2024-05-31T14:49:08+00:00" }, { - "name": "symfony/filesystem", - "version": "v5.4.25", + "name": "symfony/http-kernel", + "version": "v6.4.8", "source": { "type": "git", - "url": "https://github.com/symfony/filesystem.git", - "reference": "0ce3a62c9579a53358d3a7eb6b3dfb79789a6364" + "url": "https://github.com/symfony/http-kernel.git", + "reference": "6c519aa3f32adcfd1d1f18d923f6b227d9acf3c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/0ce3a62c9579a53358d3a7eb6b3dfb79789a6364", - "reference": "0ce3a62c9579a53358d3a7eb6b3dfb79789a6364", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/6c519aa3f32adcfd1d1f18d923f6b227d9acf3c1", + "reference": "6c519aa3f32adcfd1d1f18d923f6b227d9acf3c1", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-mbstring": "~1.8", - "symfony/polyfill-php80": "^1.16" + "php": ">=8.1", + "psr/log": "^1|^2|^3", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/error-handler": "^6.4|^7.0", + "symfony/event-dispatcher": "^5.4|^6.0|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "symfony/browser-kit": "<5.4", + "symfony/cache": "<5.4", + "symfony/config": "<6.1", + "symfony/console": "<5.4", + "symfony/dependency-injection": "<6.4", + "symfony/doctrine-bridge": "<5.4", + "symfony/form": "<5.4", + "symfony/http-client": "<5.4", + "symfony/http-client-contracts": "<2.5", + "symfony/mailer": "<5.4", + "symfony/messenger": "<5.4", + "symfony/translation": "<5.4", + "symfony/translation-contracts": "<2.5", + "symfony/twig-bridge": "<5.4", + "symfony/validator": "<6.4", + "symfony/var-dumper": "<6.3", + "twig/twig": "<2.13" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/cache": "^1.0|^2.0|^3.0", + "symfony/browser-kit": "^5.4|^6.0|^7.0", + "symfony/clock": "^6.2|^7.0", + "symfony/config": "^6.1|^7.0", + "symfony/console": "^5.4|^6.0|^7.0", + "symfony/css-selector": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/dom-crawler": "^5.4|^6.0|^7.0", + "symfony/expression-language": "^5.4|^6.0|^7.0", + "symfony/finder": "^5.4|^6.0|^7.0", + "symfony/http-client-contracts": "^2.5|^3", + "symfony/process": "^5.4|^6.0|^7.0", + "symfony/property-access": "^5.4.5|^6.0.5|^7.0", + "symfony/routing": "^5.4|^6.0|^7.0", + "symfony/serializer": "^6.4.4|^7.0.4", + "symfony/stopwatch": "^5.4|^6.0|^7.0", + "symfony/translation": "^5.4|^6.0|^7.0", + "symfony/translation-contracts": "^2.5|^3", + "symfony/uid": "^5.4|^6.0|^7.0", + "symfony/validator": "^6.4|^7.0", + "symfony/var-dumper": "^5.4|^6.4|^7.0", + "symfony/var-exporter": "^6.2|^7.0", + "twig/twig": "^2.13|^3.0.4" }, "type": "library", "autoload": { "psr-4": { - "Symfony\\Component\\Filesystem\\": "" + "Symfony\\Component\\HttpKernel\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -5636,10 +4668,10 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Provides basic utilities for the filesystem", + "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v5.4.25" + "source": "https://github.com/symfony/http-kernel/tree/v6.4.8" }, "funding": [ { @@ -5655,34 +4687,38 @@ "type": "tidelift" } ], - "time": "2023-05-31T13:04:02+00:00" + "time": "2024-06-02T16:06:25+00:00" }, { - "name": "symfony/finder", - "version": "v5.4.27", + "name": "symfony/intl", + "version": "v6.4.8", "source": { "type": "git", - "url": "https://github.com/symfony/finder.git", - "reference": "ff4bce3c33451e7ec778070e45bd23f74214cd5d" + "url": "https://github.com/symfony/intl.git", + "reference": "50265cdcf5a44bec3fcf487b5d0015aece91d1eb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/ff4bce3c33451e7ec778070e45bd23f74214cd5d", - "reference": "ff4bce3c33451e7ec778070e45bd23f74214cd5d", + "url": "https://api.github.com/repos/symfony/intl/zipball/50265cdcf5a44bec3fcf487b5d0015aece91d1eb", + "reference": "50265cdcf5a44bec3fcf487b5d0015aece91d1eb", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/polyfill-php80": "^1.16" + "php": ">=8.1" + }, + "require-dev": { + "symfony/filesystem": "^5.4|^6.0|^7.0", + "symfony/finder": "^5.4|^6.0|^7.0", + "symfony/var-exporter": "^5.4|^6.0|^7.0" }, "type": "library", "autoload": { "psr-4": { - "Symfony\\Component\\Finder\\": "" + "Symfony\\Component\\Intl\\": "" }, "exclude-from-classmap": [ - "/Tests/" + "/Tests/", + "/Resources/data/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -5691,18 +4727,34 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + }, + { + "name": "Eriksen Costa", + "email": "eriksen.costa@infranology.com.br" + }, + { + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Finds files and directories via an intuitive fluent interface", + "description": "Provides access to the localization data of the ICU library", "homepage": "https://symfony.com", + "keywords": [ + "i18n", + "icu", + "internationalization", + "intl", + "l10n", + "localization" + ], "support": { - "source": "https://github.com/symfony/finder/tree/v5.4.27" + "source": "https://github.com/symfony/intl/tree/v6.4.8" }, "funding": [ { @@ -5718,118 +4770,45 @@ "type": "tidelift" } ], - "time": "2023-07-31T08:02:31+00:00" + "time": "2024-05-31T14:49:08+00:00" }, { - "name": "symfony/framework-bundle", - "version": "v4.4.49", + "name": "symfony/polyfill-ctype", + "version": "v1.29.0", "source": { "type": "git", - "url": "https://github.com/symfony/framework-bundle.git", - "reference": "d8cf2558249004a29b8e27b1f6eae52337ff471b" + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/d8cf2558249004a29b8e27b1f6eae52337ff471b", - "reference": "d8cf2558249004a29b8e27b1f6eae52337ff471b", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ef4d7e442ca910c4764bce785146269b30cb5fc4", + "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4", "shasum": "" }, "require": { - "ext-xml": "*", - "php": ">=7.1.3", - "symfony/cache": "^4.4|^5.0", - "symfony/config": "^4.4.11|~5.0.11|^5.1.3", - "symfony/dependency-injection": "^4.4.38|^5.0.1", - "symfony/error-handler": "^4.4.1|^5.0.1", - "symfony/filesystem": "^3.4|^4.0|^5.0", - "symfony/finder": "^3.4|^4.0|^5.0", - "symfony/http-foundation": "^4.4|^5.0", - "symfony/http-kernel": "^4.4", - "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php80": "^1.16", - "symfony/routing": "^4.4.12|^5.1.4" - }, - "conflict": { - "doctrine/persistence": "<1.3", - "phpdocumentor/reflection-docblock": "<3.0|>=3.2.0,<3.2.2", - "phpdocumentor/type-resolver": "<0.3.0|1.3.*", - "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0", - "symfony/asset": "<3.4", - "symfony/browser-kit": "<4.3", - "symfony/console": "<4.4.21", - "symfony/dom-crawler": "<4.3", - "symfony/dotenv": "<4.3.6", - "symfony/form": "<4.3.5", - "symfony/http-client": "<4.4", - "symfony/lock": "<4.4", - "symfony/mailer": "<4.4", - "symfony/messenger": "<4.4", - "symfony/mime": "<4.4", - "symfony/property-info": "<3.4", - "symfony/security-bundle": "<4.4", - "symfony/serializer": "<4.4", - "symfony/stopwatch": "<3.4", - "symfony/translation": "<4.4", - "symfony/twig-bridge": "<4.1.1", - "symfony/twig-bundle": "<4.4", - "symfony/validator": "<4.4", - "symfony/web-profiler-bundle": "<4.4", - "symfony/workflow": "<4.3.6" + "php": ">=7.1" }, - "require-dev": { - "doctrine/annotations": "^1.10.4", - "doctrine/cache": "^1.0|^2.0", - "doctrine/persistence": "^1.3|^2|^3", - "paragonie/sodium_compat": "^1.8", - "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", - "symfony/asset": "^3.4|^4.0|^5.0", - "symfony/browser-kit": "^4.3|^5.0", - "symfony/console": "^4.4.42|^5.4.9", - "symfony/css-selector": "^3.4|^4.0|^5.0", - "symfony/dom-crawler": "^4.4.30|^5.3.7", - "symfony/dotenv": "^4.3.6|^5.0", - "symfony/expression-language": "^3.4|^4.0|^5.0", - "symfony/form": "^4.3.5|^5.0", - "symfony/http-client": "^4.4|^5.0", - "symfony/lock": "^4.4|^5.0", - "symfony/mailer": "^4.4|^5.0", - "symfony/messenger": "^4.4|^5.0", - "symfony/mime": "^4.4|^5.0", - "symfony/polyfill-intl-icu": "~1.0", - "symfony/process": "^3.4|^4.0|^5.0", - "symfony/property-info": "^3.4|^4.0|^5.0", - "symfony/security-core": "^3.4|^4.4|^5.2", - "symfony/security-csrf": "^3.4|^4.0|^5.0", - "symfony/security-http": "^3.4|^4.0|^5.0", - "symfony/serializer": "^4.4|^5.0", - "symfony/stopwatch": "^3.4|^4.0|^5.0", - "symfony/templating": "^3.4|^4.0|^5.0", - "symfony/translation": "^4.4|^5.0", - "symfony/twig-bundle": "^4.4|^5.0", - "symfony/validator": "^4.4|^5.0", - "symfony/web-link": "^4.4|^5.0", - "symfony/workflow": "^4.3.6|^5.0", - "symfony/yaml": "^3.4|^4.0|^5.0", - "twig/twig": "^1.43|^2.13|^3.0.4" + "provide": { + "ext-ctype": "*" }, "suggest": { - "ext-apcu": "For best performance of the system caches", - "symfony/console": "For using the console commands", - "symfony/form": "For using forms", - "symfony/property-info": "For using the property_info service", - "symfony/serializer": "For using the serializer service", - "symfony/validator": "For using validation", - "symfony/web-link": "For using web links, features such as preloading, prefetching or prerendering", - "symfony/yaml": "For using the debug:config and lint:yaml commands" + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } }, - "type": "symfony-bundle", "autoload": { + "files": [ + "bootstrap.php" + ], "psr-4": { - "Symfony\\Bundle\\FrameworkBundle\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] + "Symfony\\Polyfill\\Ctype\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -5837,18 +4816,24 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Provides a tight integration between Symfony components and the Symfony full-stack framework", + "description": "Symfony polyfill for ctype functions", "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], "support": { - "source": "https://github.com/symfony/framework-bundle/tree/v4.4.49" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.29.0" }, "funding": [ { @@ -5864,41 +4849,41 @@ "type": "tidelift" } ], - "time": "2022-11-05T15:42:31+00:00" + "time": "2024-01-29T20:11:03+00:00" }, { - "name": "symfony/http-client-contracts", - "version": "v2.5.2", + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.29.0", "source": { "type": "git", - "url": "https://github.com/symfony/http-client-contracts.git", - "reference": "ba6a9f0e8f3edd190520ee3b9a958596b6ca2e70" + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/ba6a9f0e8f3edd190520ee3b9a958596b6ca2e70", - "reference": "ba6a9f0e8f3edd190520ee3b9a958596b6ca2e70", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/32a9da87d7b3245e09ac426c83d334ae9f06f80f", + "reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f", "shasum": "" }, "require": { - "php": ">=7.2.5" + "php": ">=7.1" }, "suggest": { - "symfony/http-client-implementation": "" + "ext-intl": "For best performance" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "2.5-dev" - }, "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" } }, "autoload": { + "files": [ + "bootstrap.php" + ], "psr-4": { - "Symfony\\Contracts\\HttpClient\\": "" + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" } }, "notification-url": "https://packagist.org/downloads/", @@ -5915,18 +4900,18 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Generic abstractions related to HTTP clients", + "description": "Symfony polyfill for intl's grapheme_* functions", "homepage": "https://symfony.com", "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" ], "support": { - "source": "https://github.com/symfony/http-client-contracts/tree/v2.5.2" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.29.0" }, "funding": [ { @@ -5942,45 +4927,45 @@ "type": "tidelift" } ], - "time": "2022-04-12T15:48:08+00:00" + "time": "2024-01-29T20:11:03+00:00" }, { - "name": "symfony/http-foundation", - "version": "v5.4.26", + "name": "symfony/polyfill-intl-icu", + "version": "v1.29.0", "source": { "type": "git", - "url": "https://github.com/symfony/http-foundation.git", - "reference": "e7793151e99dc2ac1352ff3735d100fb3b3bfc08" + "url": "https://github.com/symfony/polyfill-intl-icu.git", + "reference": "07094a28851a49107f3ab4f9120ca2975a64b6e1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/e7793151e99dc2ac1352ff3735d100fb3b3bfc08", - "reference": "e7793151e99dc2ac1352ff3735d100fb3b3bfc08", + "url": "https://api.github.com/repos/symfony/polyfill-intl-icu/zipball/07094a28851a49107f3ab4f9120ca2975a64b6e1", + "reference": "07094a28851a49107f3ab4f9120ca2975a64b6e1", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/polyfill-mbstring": "~1.1", - "symfony/polyfill-php80": "^1.16" - }, - "require-dev": { - "predis/predis": "~1.0", - "symfony/cache": "^4.4|^5.0|^6.0", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/expression-language": "^4.4|^5.0|^6.0", - "symfony/http-kernel": "^5.4.12|^6.0.12|^6.1.4", - "symfony/mime": "^4.4|^5.0|^6.0", - "symfony/rate-limiter": "^5.2|^6.0" + "php": ">=7.1" }, "suggest": { - "symfony/mime": "To use the file extension guesser" + "ext-intl": "For best performance and support of other locales than \"en\"" }, "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, "autoload": { + "files": [ + "bootstrap.php" + ], "psr-4": { - "Symfony\\Component\\HttpFoundation\\": "" + "Symfony\\Polyfill\\Intl\\Icu\\": "" }, + "classmap": [ + "Resources/stubs" + ], "exclude-from-classmap": [ "/Tests/" ] @@ -5991,18 +4976,26 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Defines an object-oriented layer for the HTTP specification", + "description": "Symfony polyfill for intl's ICU-related data and classes", "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "icu", + "intl", + "polyfill", + "portable", + "shim" + ], "support": { - "source": "https://github.com/symfony/http-foundation/tree/v5.4.26" + "source": "https://github.com/symfony/polyfill-intl-icu/tree/v1.29.0" }, "funding": [ { @@ -6018,75 +5011,44 @@ "type": "tidelift" } ], - "time": "2023-07-21T11:30:15+00:00" + "time": "2024-01-29T20:12:16+00:00" }, { - "name": "symfony/http-kernel", - "version": "v4.4.50", + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.29.0", "source": { "type": "git", - "url": "https://github.com/symfony/http-kernel.git", - "reference": "aa6df6c045f034aa13ac752fc234bb300b9488ef" + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "bc45c394692b948b4d383a08d7753968bed9a83d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/aa6df6c045f034aa13ac752fc234bb300b9488ef", - "reference": "aa6df6c045f034aa13ac752fc234bb300b9488ef", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/bc45c394692b948b4d383a08d7753968bed9a83d", + "reference": "bc45c394692b948b4d383a08d7753968bed9a83d", "shasum": "" }, "require": { - "php": ">=7.1.3", - "psr/log": "^1|^2", - "symfony/error-handler": "^4.4", - "symfony/event-dispatcher": "^4.4", - "symfony/http-client-contracts": "^1.1|^2", - "symfony/http-foundation": "^4.4.30|^5.3.7", - "symfony/polyfill-ctype": "^1.8", - "symfony/polyfill-php73": "^1.9", - "symfony/polyfill-php80": "^1.16" - }, - "conflict": { - "symfony/browser-kit": "<4.3", - "symfony/config": "<3.4", - "symfony/console": ">=5", - "symfony/dependency-injection": "<4.3", - "symfony/translation": "<4.2", - "twig/twig": "<1.43|<2.13,>=2" - }, - "provide": { - "psr/log-implementation": "1.0|2.0" - }, - "require-dev": { - "psr/cache": "^1.0|^2.0|^3.0", - "symfony/browser-kit": "^4.3|^5.0", - "symfony/config": "^3.4|^4.0|^5.0", - "symfony/console": "^3.4|^4.0", - "symfony/css-selector": "^3.4|^4.0|^5.0", - "symfony/dependency-injection": "^4.3|^5.0", - "symfony/dom-crawler": "^3.4|^4.0|^5.0", - "symfony/expression-language": "^3.4|^4.0|^5.0", - "symfony/finder": "^3.4|^4.0|^5.0", - "symfony/process": "^3.4|^4.0|^5.0", - "symfony/routing": "^3.4|^4.0|^5.0", - "symfony/stopwatch": "^3.4|^4.0|^5.0", - "symfony/templating": "^3.4|^4.0|^5.0", - "symfony/translation": "^4.2|^5.0", - "symfony/translation-contracts": "^1.1|^2", - "twig/twig": "^1.43|^2.13|^3.0.4" + "php": ">=7.1" }, "suggest": { - "symfony/browser-kit": "", - "symfony/config": "", - "symfony/console": "", - "symfony/dependency-injection": "" + "ext-intl": "For best performance" }, "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, "autoload": { + "files": [ + "bootstrap.php" + ], "psr-4": { - "Symfony\\Component\\HttpKernel\\": "" + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" }, - "exclude-from-classmap": [ - "/Tests/" + "classmap": [ + "Resources/stubs" ] }, "notification-url": "https://packagist.org/downloads/", @@ -6095,18 +5057,26 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Provides a structured process for converting a Request into a Response", + "description": "Symfony polyfill for intl's Normalizer class and related functions", "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], "support": { - "source": "https://github.com/symfony/http-kernel/tree/v4.4.50" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.29.0" }, "funding": [ { @@ -6122,36 +5092,33 @@ "type": "tidelift" } ], - "time": "2023-02-01T08:01:31+00:00" + "time": "2024-01-29T20:11:03+00:00" }, { - "name": "symfony/polyfill-ctype", - "version": "v1.27.0", + "name": "symfony/polyfill-mbstring", + "version": "v1.29.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "5bbc823adecdae860bb64756d639ecfec17b050a" + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a", - "reference": "5bbc823adecdae860bb64756d639ecfec17b050a", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec", + "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec", "shasum": "" }, "require": { "php": ">=7.1" }, "provide": { - "ext-ctype": "*" + "ext-mbstring": "*" }, "suggest": { - "ext-ctype": "For best performance" + "ext-mbstring": "For best performance" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" @@ -6162,7 +5129,7 @@ "bootstrap.php" ], "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" + "Symfony\\Polyfill\\Mbstring\\": "" } }, "notification-url": "https://packagist.org/downloads/", @@ -6171,24 +5138,25 @@ ], "authors": [ { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill for ctype functions", + "description": "Symfony polyfill for the Mbstring extension", "homepage": "https://symfony.com", "keywords": [ "compatibility", - "ctype", + "mbstring", "polyfill", - "portable" + "portable", + "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.29.0" }, "funding": [ { @@ -6204,36 +5172,27 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2024-01-29T20:11:03+00:00" }, { - "name": "symfony/polyfill-mbstring", - "version": "v1.27.0", + "name": "symfony/polyfill-php80", + "version": "v1.29.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534", - "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", + "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", "shasum": "" }, "require": { "php": ">=7.1" }, - "provide": { - "ext-mbstring": "*" - }, - "suggest": { - "ext-mbstring": "For best performance" - }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" @@ -6244,14 +5203,21 @@ "bootstrap.php" ], "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - } + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, { "name": "Nicolas Grekas", "email": "p@tchwork.com" @@ -6261,17 +5227,16 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill for the Mbstring extension", + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", "homepage": "https://symfony.com", "keywords": [ "compatibility", - "mbstring", "polyfill", "portable", "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.29.0" }, "funding": [ { @@ -6287,30 +5252,28 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2024-01-29T20:11:03+00:00" }, { - "name": "symfony/polyfill-php72", - "version": "v1.27.0", + "name": "symfony/polyfill-php83", + "version": "v1.29.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "869329b1e9894268a8a61dabb69153029b7a8c97" + "url": "https://github.com/symfony/polyfill-php83.git", + "reference": "86fcae159633351e5fd145d1c47de6c528f8caff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/869329b1e9894268a8a61dabb69153029b7a8c97", - "reference": "869329b1e9894268a8a61dabb69153029b7a8c97", + "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/86fcae159633351e5fd145d1c47de6c528f8caff", + "reference": "86fcae159633351e5fd145d1c47de6c528f8caff", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.1", + "symfony/polyfill-php80": "^1.14" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" @@ -6321,8 +5284,11 @@ "bootstrap.php" ], "psr-4": { - "Symfony\\Polyfill\\Php72\\": "" - } + "Symfony\\Polyfill\\Php83\\": "" + }, + "classmap": [ + "Resources/stubs" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -6338,7 +5304,7 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", + "description": "Symfony polyfill backporting some PHP 8.3+ features to lower PHP versions", "homepage": "https://symfony.com", "keywords": [ "compatibility", @@ -6347,7 +5313,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php72/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-php83/tree/v1.29.0" }, "funding": [ { @@ -6363,44 +5329,48 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2024-01-29T20:11:03+00:00" }, { - "name": "symfony/polyfill-php73", - "version": "v1.27.0", + "name": "symfony/routing", + "version": "v6.4.8", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "9e8ecb5f92152187c4799efd3c96b78ccab18ff9" + "url": "https://github.com/symfony/routing.git", + "reference": "8a40d0f9b01f0fbb80885d3ce0ad6714fb603a58" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/9e8ecb5f92152187c4799efd3c96b78ccab18ff9", - "reference": "9e8ecb5f92152187c4799efd3c96b78ccab18ff9", + "url": "https://api.github.com/repos/symfony/routing/zipball/8a40d0f9b01f0fbb80885d3ce0ad6714fb603a58", + "reference": "8a40d0f9b01f0fbb80885d3ce0ad6714fb603a58", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } + "conflict": { + "doctrine/annotations": "<1.12", + "symfony/config": "<6.2", + "symfony/dependency-injection": "<5.4", + "symfony/yaml": "<5.4" + }, + "require-dev": { + "doctrine/annotations": "^1.12|^2", + "psr/log": "^1|^2|^3", + "symfony/config": "^6.2|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/expression-language": "^5.4|^6.0|^7.0", + "symfony/http-foundation": "^5.4|^6.0|^7.0", + "symfony/yaml": "^5.4|^6.0|^7.0" }, + "type": "library", "autoload": { - "files": [ - "bootstrap.php" - ], "psr-4": { - "Symfony\\Polyfill\\Php73\\": "" + "Symfony\\Component\\Routing\\": "" }, - "classmap": [ - "Resources/stubs" + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -6409,24 +5379,24 @@ ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", + "description": "Maps an HTTP request to a set of configuration variables", "homepage": "https://symfony.com", "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" + "router", + "routing", + "uri", + "url" ], "support": { - "source": "https://github.com/symfony/polyfill-php73/tree/v1.27.0" + "source": "https://github.com/symfony/routing/tree/v6.4.8" }, "funding": [ { @@ -6442,41 +5412,46 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2024-05-31T14:49:08+00:00" }, { - "name": "symfony/polyfill-php80", - "version": "v1.29.0", + "name": "symfony/service-contracts", + "version": "v3.5.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b" + "url": "https://github.com/symfony/service-contracts.git", + "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", - "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/bd1d9e59a81d8fa4acdcea3f617c581f7475a80f", + "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=8.1", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "conflict": { + "ext-psr": "<1.1|>=2" }, "type": "library", "extra": { + "branch-alias": { + "dev-main": "3.5-dev" + }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" } }, "autoload": { - "files": [ - "bootstrap.php" - ], "psr-4": { - "Symfony\\Polyfill\\Php80\\": "" + "Symfony\\Contracts\\Service\\": "" }, - "classmap": [ - "Resources/stubs" + "exclude-from-classmap": [ + "/Test/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -6484,10 +5459,6 @@ "MIT" ], "authors": [ - { - "name": "Ion Bazan", - "email": "ion.bazan@gmail.com" - }, { "name": "Nicolas Grekas", "email": "p@tchwork.com" @@ -6497,16 +5468,18 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "description": "Generic abstractions related to writing services", "homepage": "https://symfony.com", "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.29.0" + "source": "https://github.com/symfony/service-contracts/tree/v3.5.0" }, "funding": [ { @@ -6522,44 +5495,49 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-04-18T09:32:20+00:00" }, { - "name": "symfony/polyfill-php81", - "version": "v1.27.0", + "name": "symfony/string", + "version": "v6.4.8", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-php81.git", - "reference": "707403074c8ea6e2edaf8794b0157a0bfa52157a" + "url": "https://github.com/symfony/string.git", + "reference": "a147c0f826c4a1f3afb763ab8e009e37c877a44d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/707403074c8ea6e2edaf8794b0157a0bfa52157a", - "reference": "707403074c8ea6e2edaf8794b0157a0bfa52157a", + "url": "https://api.github.com/repos/symfony/string/zipball/a147c0f826c4a1f3afb763ab8e009e37c877a44d", + "reference": "a147c0f826c4a1f3afb763ab8e009e37c877a44d", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=8.1", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-grapheme": "~1.0", + "symfony/polyfill-intl-normalizer": "~1.0", + "symfony/polyfill-mbstring": "~1.0" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } + "conflict": { + "symfony/translation-contracts": "<2.5" + }, + "require-dev": { + "symfony/error-handler": "^5.4|^6.0|^7.0", + "symfony/http-client": "^5.4|^6.0|^7.0", + "symfony/intl": "^6.2|^7.0", + "symfony/translation-contracts": "^2.5|^3.0", + "symfony/var-exporter": "^5.4|^6.0|^7.0" }, + "type": "library", "autoload": { "files": [ - "bootstrap.php" + "Resources/functions.php" ], "psr-4": { - "Symfony\\Polyfill\\Php81\\": "" + "Symfony\\Component\\String\\": "" }, - "classmap": [ - "Resources/stubs" + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -6576,16 +5554,18 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions", + "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", "homepage": "https://symfony.com", "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" ], "support": { - "source": "https://github.com/symfony/polyfill-php81/tree/v1.27.0" + "source": "https://github.com/symfony/string/tree/v6.4.8" }, "funding": [ { @@ -6601,54 +5581,41 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2024-05-31T14:49:08+00:00" }, { - "name": "symfony/routing", - "version": "v4.4.44", + "name": "symfony/translation-contracts", + "version": "v3.5.0", "source": { "type": "git", - "url": "https://github.com/symfony/routing.git", - "reference": "f7751fd8b60a07f3f349947a309b5bdfce22d6ae" + "url": "https://github.com/symfony/translation-contracts.git", + "reference": "b9d2189887bb6b2e0367a9fc7136c5239ab9b05a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/f7751fd8b60a07f3f349947a309b5bdfce22d6ae", - "reference": "f7751fd8b60a07f3f349947a309b5bdfce22d6ae", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/b9d2189887bb6b2e0367a9fc7136c5239ab9b05a", + "reference": "b9d2189887bb6b2e0367a9fc7136c5239ab9b05a", "shasum": "" }, "require": { - "php": ">=7.1.3", - "symfony/polyfill-php80": "^1.16" - }, - "conflict": { - "symfony/config": "<4.2", - "symfony/dependency-injection": "<3.4", - "symfony/yaml": "<3.4" - }, - "require-dev": { - "doctrine/annotations": "^1.10.4", - "psr/log": "^1|^2|^3", - "symfony/config": "^4.2|^5.0", - "symfony/dependency-injection": "^3.4|^4.0|^5.0", - "symfony/expression-language": "^3.4|^4.0|^5.0", - "symfony/http-foundation": "^3.4|^4.0|^5.0", - "symfony/yaml": "^3.4|^4.0|^5.0" - }, - "suggest": { - "doctrine/annotations": "For using the annotation loader", - "symfony/config": "For using the all-in-one router or any loader", - "symfony/expression-language": "For using expression matching", - "symfony/http-foundation": "For using a Symfony Request object", - "symfony/yaml": "For using the YAML loader" + "php": ">=8.1" }, "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, "autoload": { "psr-4": { - "Symfony\\Component\\Routing\\": "" + "Symfony\\Contracts\\Translation\\": "" }, "exclude-from-classmap": [ - "/Tests/" + "/Test/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -6657,24 +5624,26 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Maps an HTTP request to a set of configuration variables", + "description": "Generic abstractions related to translation", "homepage": "https://symfony.com", "keywords": [ - "router", - "routing", - "uri", - "url" + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" ], "support": { - "source": "https://github.com/symfony/routing/tree/v4.4.44" + "source": "https://github.com/symfony/translation-contracts/tree/v3.5.0" }, "funding": [ { @@ -6690,47 +5659,81 @@ "type": "tidelift" } ], - "time": "2022-07-20T09:59:04+00:00" + "time": "2024-04-18T09:32:20+00:00" }, { - "name": "symfony/service-contracts", - "version": "v2.5.2", + "name": "symfony/twig-bridge", + "version": "v6.4.8", "source": { "type": "git", - "url": "https://github.com/symfony/service-contracts.git", - "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c" + "url": "https://github.com/symfony/twig-bridge.git", + "reference": "57de1b7d7499053a2c5beb9344751e8bfd332649" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/4b426aac47d6427cc1a1d0f7e2ac724627f5966c", - "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c", + "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/57de1b7d7499053a2c5beb9344751e8bfd332649", + "reference": "57de1b7d7499053a2c5beb9344751e8bfd332649", "shasum": "" }, "require": { - "php": ">=7.2.5", - "psr/container": "^1.1", - "symfony/deprecation-contracts": "^2.1|^3" + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/translation-contracts": "^2.5|^3", + "twig/twig": "^2.13|^3.0.4" }, "conflict": { - "ext-psr": "<1.1|>=2" - }, - "suggest": { - "symfony/service-implementation": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } + "phpdocumentor/reflection-docblock": "<3.2.2", + "phpdocumentor/type-resolver": "<1.4.0", + "symfony/console": "<5.4", + "symfony/form": "<6.3", + "symfony/http-foundation": "<5.4", + "symfony/http-kernel": "<6.4", + "symfony/mime": "<6.2", + "symfony/serializer": "<6.4", + "symfony/translation": "<5.4", + "symfony/workflow": "<5.4" }, + "require-dev": { + "egulias/email-validator": "^2.1.10|^3|^4", + "league/html-to-markdown": "^5.0", + "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", + "symfony/asset": "^5.4|^6.0|^7.0", + "symfony/asset-mapper": "^6.3|^7.0", + "symfony/console": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/expression-language": "^5.4|^6.0|^7.0", + "symfony/finder": "^5.4|^6.0|^7.0", + "symfony/form": "^6.4|^7.0", + "symfony/html-sanitizer": "^6.1|^7.0", + "symfony/http-foundation": "^5.4|^6.0|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/intl": "^5.4|^6.0|^7.0", + "symfony/mime": "^6.2|^7.0", + "symfony/polyfill-intl-icu": "~1.0", + "symfony/property-info": "^5.4|^6.0|^7.0", + "symfony/routing": "^5.4|^6.0|^7.0", + "symfony/security-acl": "^2.8|^3.0", + "symfony/security-core": "^5.4|^6.0|^7.0", + "symfony/security-csrf": "^5.4|^6.0|^7.0", + "symfony/security-http": "^5.4|^6.0|^7.0", + "symfony/serializer": "^6.4.3|^7.0.3", + "symfony/stopwatch": "^5.4|^6.0|^7.0", + "symfony/translation": "^6.1|^7.0", + "symfony/web-link": "^5.4|^6.0|^7.0", + "symfony/workflow": "^5.4|^6.0|^7.0", + "symfony/yaml": "^5.4|^6.0|^7.0", + "twig/cssinliner-extra": "^2.12|^3", + "twig/inky-extra": "^2.12|^3", + "twig/markdown-extra": "^2.12|^3" + }, + "type": "symfony-bridge", "autoload": { "psr-4": { - "Symfony\\Contracts\\Service\\": "" - } + "Symfony\\Bridge\\Twig\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -6738,26 +5741,18 @@ ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Generic abstractions related to writing services", + "description": "Provides integration for Twig with various Symfony components", "homepage": "https://symfony.com", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" - ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v2.5.2" + "source": "https://github.com/symfony/twig-bridge/tree/v6.4.8" }, "funding": [ { @@ -6773,43 +5768,39 @@ "type": "tidelift" } ], - "time": "2022-05-30T19:17:29+00:00" + "time": "2024-05-31T14:49:08+00:00" }, { "name": "symfony/var-dumper", - "version": "v5.4.26", + "version": "v6.4.8", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "e706c99b4a6f4d9383b52b80dd8c74880501e314" + "reference": "ad23ca4312395f0a8a8633c831ef4c4ee542ed25" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/e706c99b4a6f4d9383b52b80dd8c74880501e314", - "reference": "e706c99b4a6f4d9383b52b80dd8c74880501e314", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/ad23ca4312395f0a8a8633c831ef4c4ee542ed25", + "reference": "ad23ca4312395f0a8a8633c831ef4c4ee542ed25", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php80": "^1.16" + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.0" }, "conflict": { - "symfony/console": "<4.4" + "symfony/console": "<5.4" }, "require-dev": { "ext-iconv": "*", - "symfony/console": "^4.4|^5.0|^6.0", - "symfony/http-kernel": "^4.4|^5.0|^6.0", - "symfony/process": "^4.4|^5.0|^6.0", - "symfony/uid": "^5.1|^6.0", + "symfony/console": "^5.4|^6.0|^7.0", + "symfony/error-handler": "^6.3|^7.0", + "symfony/http-kernel": "^5.4|^6.0|^7.0", + "symfony/process": "^5.4|^6.0|^7.0", + "symfony/uid": "^5.4|^6.0|^7.0", "twig/twig": "^2.13|^3.0.4" }, - "suggest": { - "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).", - "ext-intl": "To show region name in time zone dump", - "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script" - }, "bin": [ "Resources/bin/var-dump-server" ], @@ -6846,7 +5837,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v5.4.26" + "source": "https://github.com/symfony/var-dumper/tree/v6.4.8" }, "funding": [ { @@ -6862,28 +5853,30 @@ "type": "tidelift" } ], - "time": "2023-07-13T07:32:46+00:00" + "time": "2024-05-31T14:49:08+00:00" }, { "name": "symfony/var-exporter", - "version": "v5.4.26", + "version": "v6.4.8", "source": { "type": "git", "url": "https://github.com/symfony/var-exporter.git", - "reference": "11401fe94f960249b3c63a488c63ba73091c1e4a" + "reference": "792ca836f99b340f2e9ca9497c7953948c49a504" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-exporter/zipball/11401fe94f960249b3c63a488c63ba73091c1e4a", - "reference": "11401fe94f960249b3c63a488c63ba73091c1e4a", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/792ca836f99b340f2e9ca9497c7953948c49a504", + "reference": "792ca836f99b340f2e9ca9497c7953948c49a504", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/polyfill-php80": "^1.16" + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3" }, "require-dev": { - "symfony/var-dumper": "^4.4.9|^5.0.9|^6.0" + "symfony/property-access": "^6.4|^7.0", + "symfony/serializer": "^6.4|^7.0", + "symfony/var-dumper": "^5.4|^6.0|^7.0" }, "type": "library", "autoload": { @@ -6916,10 +5909,12 @@ "export", "hydrate", "instantiate", + "lazy-loading", + "proxy", "serialize" ], "support": { - "source": "https://github.com/symfony/var-exporter/tree/v5.4.26" + "source": "https://github.com/symfony/var-exporter/tree/v6.4.8" }, "funding": [ { @@ -6935,41 +5930,37 @@ "type": "tidelift" } ], - "time": "2023-07-20T07:21:16+00:00" + "time": "2024-05-31T14:49:08+00:00" }, { "name": "symfony/yaml", - "version": "v5.0.11", + "version": "v6.4.8", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "29b60e88ff11a45b708115004fdeacab1ee3dd5d" + "reference": "52903de178d542850f6f341ba92995d3d63e60c9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/29b60e88ff11a45b708115004fdeacab1ee3dd5d", - "reference": "29b60e88ff11a45b708115004fdeacab1ee3dd5d", + "url": "https://api.github.com/repos/symfony/yaml/zipball/52903de178d542850f6f341ba92995d3d63e60c9", + "reference": "52903de178d542850f6f341ba92995d3d63e60c9", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/polyfill-ctype": "~1.8" + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-ctype": "^1.8" }, "conflict": { - "symfony/console": "<4.4" + "symfony/console": "<5.4" }, "require-dev": { - "symfony/console": "^4.4|^5.0" - }, - "suggest": { - "symfony/console": "For validating YAML files using the lint command" + "symfony/console": "^5.4|^6.0|^7.0" }, + "bin": [ + "Resources/bin/yaml-lint" + ], "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\Yaml\\": "" @@ -6992,10 +5983,10 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Yaml Component", + "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/5.0" + "source": "https://github.com/symfony/yaml/tree/v6.4.8" }, "funding": [ { @@ -7011,45 +6002,38 @@ "type": "tidelift" } ], - "time": "2020-05-20T17:38:26+00:00" + "time": "2024-05-31T14:49:08+00:00" }, { - "name": "twig/extensions", - "version": "v1.5.4", + "name": "twig/intl-extra", + "version": "v3.10.0", "source": { "type": "git", - "url": "https://github.com/twigphp/Twig-extensions.git", - "reference": "57873c8b0c1be51caa47df2cdb824490beb16202" + "url": "https://github.com/twigphp/intl-extra.git", + "reference": "693f6beb8ca91fc6323e01b3addf983812f65c93" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig-extensions/zipball/57873c8b0c1be51caa47df2cdb824490beb16202", - "reference": "57873c8b0c1be51caa47df2cdb824490beb16202", + "url": "https://api.github.com/repos/twigphp/intl-extra/zipball/693f6beb8ca91fc6323e01b3addf983812f65c93", + "reference": "693f6beb8ca91fc6323e01b3addf983812f65c93", "shasum": "" }, "require": { - "twig/twig": "^1.27|^2.0" + "php": ">=7.2.5", + "symfony/intl": "^5.4|^6.4|^7.0", + "twig/twig": "^3.10" }, "require-dev": { - "symfony/phpunit-bridge": "^3.4", - "symfony/translation": "^2.7|^3.4" - }, - "suggest": { - "symfony/translation": "Allow the time_diff output to be translated" + "symfony/phpunit-bridge": "^6.4|^7.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.5-dev" - } - }, "autoload": { - "psr-0": { - "Twig_Extensions_": "lib/" - }, "psr-4": { - "Twig\\Extensions\\": "src/" - } + "Twig\\Extra\\Intl\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -7058,55 +6042,65 @@ "authors": [ { "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" } ], - "description": "Common additional features for Twig that do not directly belong in core", + "description": "A Twig extension for Intl", + "homepage": "https://twig.symfony.com", "keywords": [ - "i18n", - "text" + "intl", + "twig" ], "support": { - "issues": "https://github.com/twigphp/Twig-extensions/issues", - "source": "https://github.com/twigphp/Twig-extensions/tree/master" + "source": "https://github.com/twigphp/intl-extra/tree/v3.10.0" }, - "abandoned": true, - "time": "2018-12-05T18:34:18+00:00" + "funding": [ + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/twig/twig", + "type": "tidelift" + } + ], + "time": "2024-05-11T07:35:57+00:00" }, { "name": "twig/twig", - "version": "v2.15.5", + "version": "v3.10.3", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "fc02a6af3eeb97c4bf5650debc76c2eda85ac22e" + "reference": "67f29781ffafa520b0bbfbd8384674b42db04572" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/fc02a6af3eeb97c4bf5650debc76c2eda85ac22e", - "reference": "fc02a6af3eeb97c4bf5650debc76c2eda85ac22e", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/67f29781ffafa520b0bbfbd8384674b42db04572", + "reference": "67f29781ffafa520b0bbfbd8384674b42db04572", "shasum": "" }, "require": { - "php": ">=7.1.3", + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-ctype": "^1.8", "symfony/polyfill-mbstring": "^1.3", - "symfony/polyfill-php72": "^1.8" + "symfony/polyfill-php80": "^1.22" }, "require-dev": { - "psr/container": "^1.0", - "symfony/phpunit-bridge": "^4.4.9|^5.0.9|^6.0" + "psr/container": "^1.0|^2.0", + "symfony/phpunit-bridge": "^5.4.9|^6.4|^7.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.15-dev" - } - }, "autoload": { - "psr-0": { - "Twig_": "lib/" - }, + "files": [ + "src/Resources/core.php", + "src/Resources/debug.php", + "src/Resources/escaper.php", + "src/Resources/string_loader.php" + ], "psr-4": { "Twig\\": "src/" } @@ -7139,7 +6133,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v2.15.5" + "source": "https://github.com/twigphp/Twig/tree/v3.10.3" }, "funding": [ { @@ -7151,7 +6145,7 @@ "type": "tidelift" } ], - "time": "2023-05-03T17:49:41+00:00" + "time": "2024-05-16T10:04:27+00:00" }, { "name": "webmozart/assert", @@ -7212,79 +6206,71 @@ "time": "2022-06-03T18:03:27+00:00" }, { - "name": "whitehat101/apr1-md5", - "version": "v1.0.0", + "name": "yidas/yii2-composer-bower-skip", + "version": "2.0.13", "source": { "type": "git", - "url": "https://github.com/whitehat101/apr1-md5.git", - "reference": "8b261c9fc0481b4e9fa9d01c6ca70867b5d5e819" + "url": "https://github.com/yidas/yii2-composer-bower-skip.git", + "reference": "1156ed4dc2ddca811bd2582d09e8885585fbd0cb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/whitehat101/apr1-md5/zipball/8b261c9fc0481b4e9fa9d01c6ca70867b5d5e819", - "reference": "8b261c9fc0481b4e9fa9d01c6ca70867b5d5e819", + "url": "https://api.github.com/repos/yidas/yii2-composer-bower-skip/zipball/1156ed4dc2ddca811bd2582d09e8885585fbd0cb", + "reference": "1156ed4dc2ddca811bd2582d09e8885585fbd0cb", "shasum": "" }, - "require": { - "php": ">=5.3.0" - }, - "require-dev": { - "phpunit/phpunit": "4.0.*" - }, - "type": "library", - "autoload": { - "psr-4": { - "WhiteHat101\\Crypt\\": "src" - } + "provide": { + "bower-asset/bootstrap": "*", + "bower-asset/inputmask": "*", + "bower-asset/jquery": "*", + "bower-asset/punycode": "*", + "bower-asset/typeahead.js": "*", + "bower-asset/yii2-pjax": "*" }, + "type": "yii2-extension", "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "authors": [ - { - "name": "Jeremy Ebler", - "email": "jebler@gmail.com" - } - ], - "description": "Apache's APR1-MD5 algorithm in pure PHP", - "homepage": "https://github.com/whitehat101/apr1-md5", + "description": "A Composer package that allows you to install or update Yii2 without Bower-Asset", "keywords": [ - "MD5", - "apr1" + "bower", + "bower asset", + "framework", + "yii2" ], "support": { - "issues": "https://github.com/whitehat101/apr1-md5/issues", - "source": "https://github.com/whitehat101/apr1-md5/tree/master" + "issues": "https://github.com/yidas/yii2-composer-bower-skip/issues?state=open", + "source": "https://github.com/yidas/yii2-composer-bower-skip" }, - "time": "2015-02-11T11:06:42+00:00" + "time": "2017-11-03T06:28:14+00:00" }, { "name": "yiisoft/yii2", - "version": "2.0.49.3", + "version": "2.0.50", "source": { "type": "git", "url": "https://github.com/yiisoft/yii2-framework.git", - "reference": "783f65c9a743dfd7484b6026f1aa6f25e37159d9" + "reference": "a90b6638cce84e78ed8f681a5cad4a14c76464b4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/yiisoft/yii2-framework/zipball/783f65c9a743dfd7484b6026f1aa6f25e37159d9", - "reference": "783f65c9a743dfd7484b6026f1aa6f25e37159d9", + "url": "https://api.github.com/repos/yiisoft/yii2-framework/zipball/a90b6638cce84e78ed8f681a5cad4a14c76464b4", + "reference": "a90b6638cce84e78ed8f681a5cad4a14c76464b4", "shasum": "" }, "require": { - "bower-asset/inputmask": "~3.2.2 | ~3.3.5", + "bower-asset/inputmask": "^5.0.8 ", "bower-asset/jquery": "3.7.*@stable | 3.6.*@stable | 3.5.*@stable | 3.4.*@stable | 3.3.*@stable | 3.2.*@stable | 3.1.*@stable | 2.2.*@stable | 2.1.*@stable | 1.11.*@stable | 1.12.*@stable", - "bower-asset/punycode": "1.3.*", + "bower-asset/punycode": "^2.2", "bower-asset/yii2-pjax": "~2.0.1", "cebe/markdown": "~1.0.0 | ~1.1.0 | ~1.2.0", "ext-ctype": "*", "ext-mbstring": "*", - "ezyang/htmlpurifier": "^4.6", + "ezyang/htmlpurifier": "^4.17", "lib-pcre": "*", "paragonie/random_compat": ">=1", - "php": ">=5.4.0", + "php": ">=7.3.0", "yiisoft/yii2-composer": "~2.0.4" }, "bin": [ @@ -7379,7 +6365,7 @@ "type": "tidelift" } ], - "time": "2023-10-31T15:39:08+00:00" + "time": "2024-05-30T17:23:31+00:00" }, { "name": "yiisoft/yii2-composer", @@ -7762,69 +6748,6 @@ }, "time": "2023-12-09T11:23:23+00:00" }, - { - "name": "behat/mink-extension", - "version": "2.3.1", - "source": { - "type": "git", - "url": "https://github.com/Behat/MinkExtension.git", - "reference": "80f7849ba53867181b7e412df9210e12fba50177" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Behat/MinkExtension/zipball/80f7849ba53867181b7e412df9210e12fba50177", - "reference": "80f7849ba53867181b7e412df9210e12fba50177", - "shasum": "" - }, - "require": { - "behat/behat": "^3.0.5", - "behat/mink": "^1.5", - "php": ">=5.3.2", - "symfony/config": "^2.7|^3.0|^4.0" - }, - "require-dev": { - "behat/mink-goutte-driver": "^1.1", - "phpspec/phpspec": "^2.0" - }, - "type": "behat-extension", - "extra": { - "branch-alias": { - "dev-master": "2.1.x-dev" - } - }, - "autoload": { - "psr-0": { - "Behat\\MinkExtension": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Christophe Coevoet", - "email": "stof@notk.org" - }, - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com" - } - ], - "description": "Mink extension for Behat", - "homepage": "http://extensions.behat.org/mink", - "keywords": [ - "browser", - "gui", - "test", - "web" - ], - "support": { - "issues": "https://github.com/Behat/MinkExtension/issues", - "source": "https://github.com/Behat/MinkExtension/tree/master" - }, - "time": "2018-02-06T15:36:30+00:00" - }, { "name": "behat/transliterator", "version": "v1.5.0", @@ -7876,16 +6799,16 @@ }, { "name": "dmore/chrome-mink-driver", - "version": "2.9.2", + "version": "2.9.3", "source": { "type": "git", - "url": "git@gitlab.com:behat-chrome/chrome-mink-driver.git", - "reference": "a91b61c809c2e834c5f94f6df3af4d4117735e70" + "url": "https://gitlab.com/behat-chrome/chrome-mink-driver.git", + "reference": "4dc18d3b4668e749ab7bef5a6796c13711c93e61" }, "dist": { "type": "zip", - "url": "https://gitlab.com/api/v4/projects/behat-chrome%2Fchrome-mink-driver/repository/archive.zip?sha=a91b61c809c2e834c5f94f6df3af4d4117735e70", - "reference": "a91b61c809c2e834c5f94f6df3af4d4117735e70", + "url": "https://gitlab.com/api/v4/projects/behat-chrome%2Fchrome-mink-driver/repository/archive.zip?sha=4dc18d3b4668e749ab7bef5a6796c13711c93e61", + "reference": "4dc18d3b4668e749ab7bef5a6796c13711c93e61", "shasum": "" }, "require": { @@ -7893,7 +6816,7 @@ "ext-curl": "*", "ext-json": "*", "ext-mbstring": "*", - "textalk/websocket": "^1.2.0" + "phrity/websocket": "^1.7.0" }, "require-dev": { "mink/driver-testsuite": "dev-master", @@ -7919,9 +6842,10 @@ "description": "Mink driver for controlling chrome without selenium", "homepage": "https://gitlab.com/behat-chrome/chrome-mink-driver", "support": { - "issues": "https://gitlab.com/behat-chrome/chrome-mink-driver/-/issues" + "issues": "https://gitlab.com/behat-chrome/chrome-mink-driver/-/issues", + "source": "https://gitlab.com/behat-chrome/chrome-mink-driver/-/tree/2.9.3" }, - "time": "2023-04-03T10:37:34+00:00" + "time": "2024-05-17T12:26:55+00:00" }, { "name": "doctrine/instantiator", @@ -7987,24 +6911,90 @@ "type": "patreon" }, { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", - "type": "tidelift" + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", + "type": "tidelift" + } + ], + "time": "2022-12-30T00:15:36+00:00" + }, + { + "name": "friends-of-behat/mink-extension", + "version": "v2.7.5", + "source": { + "type": "git", + "url": "https://github.com/FriendsOfBehat/MinkExtension.git", + "reference": "854336030e11983f580f49faad1b49a1238f9846" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/FriendsOfBehat/MinkExtension/zipball/854336030e11983f580f49faad1b49a1238f9846", + "reference": "854336030e11983f580f49faad1b49a1238f9846", + "shasum": "" + }, + "require": { + "behat/behat": "^3.0.5", + "behat/mink": "^1.5", + "php": ">=7.4", + "symfony/config": "^4.4 || ^5.0 || ^6.0 || ^7.0" + }, + "replace": { + "behat/mink-extension": "self.version" + }, + "require-dev": { + "behat/mink-goutte-driver": "^1.1 || ^2.0", + "phpspec/phpspec": "^6.0 || ^7.0 || 7.1.x-dev" + }, + "type": "behat-extension", + "extra": { + "branch-alias": { + "dev-master": "2.1.x-dev" + } + }, + "autoload": { + "psr-0": { + "Behat\\MinkExtension": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com" + }, + { + "name": "Christophe Coevoet", + "email": "stof@notk.org" } ], - "time": "2022-12-30T00:15:36+00:00" + "description": "Mink extension for Behat", + "homepage": "http://extensions.behat.org/mink", + "keywords": [ + "browser", + "gui", + "test", + "web" + ], + "support": { + "issues": "https://github.com/FriendsOfBehat/MinkExtension/issues", + "source": "https://github.com/FriendsOfBehat/MinkExtension/tree/v2.7.5" + }, + "time": "2024-01-11T09:12:02+00:00" }, { "name": "myclabs/deep-copy", - "version": "1.11.1", + "version": "1.12.0", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c" + "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", - "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", + "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", "shasum": "" }, "require": { @@ -8012,11 +7002,12 @@ }, "conflict": { "doctrine/collections": "<1.6.8", - "doctrine/common": "<2.13.3 || >=3,<3.2.2" + "doctrine/common": "<2.13.3 || >=3 <3.2.2" }, "require-dev": { "doctrine/collections": "^1.6.8", "doctrine/common": "^2.13.3 || ^3.2.2", + "phpspec/prophecy": "^1.10", "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" }, "type": "library", @@ -8042,7 +7033,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1" + "source": "https://github.com/myclabs/DeepCopy/tree/1.12.0" }, "funding": [ { @@ -8050,24 +7041,25 @@ "type": "tidelift" } ], - "time": "2023-03-08T13:26:56+00:00" + "time": "2024-06-12T14:39:25+00:00" }, { "name": "phar-io/manifest", - "version": "2.0.3", + "version": "2.0.4", "source": { "type": "git", "url": "https://github.com/phar-io/manifest.git", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53" + "reference": "54750ef60c58e43759730615a392c31c80e23176" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", + "reference": "54750ef60c58e43759730615a392c31c80e23176", "shasum": "" }, "require": { "ext-dom": "*", + "ext-libxml": "*", "ext-phar": "*", "ext-xmlwriter": "*", "phar-io/version": "^3.0.1", @@ -8108,9 +7100,15 @@ "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", "support": { "issues": "https://github.com/phar-io/manifest/issues", - "source": "https://github.com/phar-io/manifest/tree/2.0.3" + "source": "https://github.com/phar-io/manifest/tree/2.0.4" }, - "time": "2021-07-20T11:28:43+00:00" + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:33:53+00:00" }, { "name": "phar-io/version", @@ -8165,16 +7163,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "7.0.15", + "version": "7.0.17", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "819f92bba8b001d4363065928088de22f25a3a48" + "reference": "40a4ed114a4aea5afd6df8d0f0c9cd3033097f66" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/819f92bba8b001d4363065928088de22f25a3a48", - "reference": "819f92bba8b001d4363065928088de22f25a3a48", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/40a4ed114a4aea5afd6df8d0f0c9cd3033097f66", + "reference": "40a4ed114a4aea5afd6df8d0f0c9cd3033097f66", "shasum": "" }, "require": { @@ -8226,7 +7224,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/7.0.15" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/7.0.17" }, "funding": [ { @@ -8234,20 +7232,20 @@ "type": "github" } ], - "time": "2021-07-26T12:20:09+00:00" + "time": "2024-03-02T06:09:37+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "2.0.5", + "version": "2.0.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "42c5ba5220e6904cbfe8b1a1bda7c0cfdc8c12f5" + "reference": "69deeb8664f611f156a924154985fbd4911eb36b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/42c5ba5220e6904cbfe8b1a1bda7c0cfdc8c12f5", - "reference": "42c5ba5220e6904cbfe8b1a1bda7c0cfdc8c12f5", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/69deeb8664f611f156a924154985fbd4911eb36b", + "reference": "69deeb8664f611f156a924154985fbd4911eb36b", "shasum": "" }, "require": { @@ -8286,7 +7284,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/2.0.5" + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/2.0.6" }, "funding": [ { @@ -8294,7 +7292,7 @@ "type": "github" } ], - "time": "2021-12-02T12:42:26+00:00" + "time": "2024-03-01T13:39:50+00:00" }, { "name": "phpunit/php-text-template", @@ -8343,16 +7341,16 @@ }, { "name": "phpunit/php-timer", - "version": "2.1.3", + "version": "2.1.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662" + "reference": "a691211e94ff39a34811abd521c31bd5b305b0bb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/2454ae1765516d20c4ffe103d85a58a9a3bd5662", - "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/a691211e94ff39a34811abd521c31bd5b305b0bb", + "reference": "a691211e94ff39a34811abd521c31bd5b305b0bb", "shasum": "" }, "require": { @@ -8368,207 +7366,435 @@ } }, "autoload": { - "classmap": [ - "src/" - ] + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/2.1.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-01T13:42:41+00:00" + }, + { + "name": "phpunit/php-token-stream", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "a853a0e183b9db7eed023d7933a858fa1c8d25a3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/a853a0e183b9db7eed023d7933a858fa1c8d25a3", + "reference": "a853a0e183b9db7eed023d7933a858fa1c8d25a3", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": "^7.3 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-token-stream/issues", + "source": "https://github.com/sebastianbergmann/php-token-stream/tree/master" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "abandoned": true, + "time": "2020-08-04T08:28:15+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "8.5.38", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "1ecad678646c817a29e55a32c930f3601c3f5a8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/1ecad678646c817a29e55a32c930f3601c3f5a8c", + "reference": "1ecad678646c817a29e55a32c930f3601c3f5a8c", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.3.1", + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.10.0", + "phar-io/manifest": "^2.0.3", + "phar-io/version": "^3.0.2", + "php": ">=7.2", + "phpunit/php-code-coverage": "^7.0.12", + "phpunit/php-file-iterator": "^2.0.4", + "phpunit/php-text-template": "^1.2.1", + "phpunit/php-timer": "^2.1.2", + "sebastian/comparator": "^3.0.5", + "sebastian/diff": "^3.0.2", + "sebastian/environment": "^4.2.3", + "sebastian/exporter": "^3.1.5", + "sebastian/global-state": "^3.0.0", + "sebastian/object-enumerator": "^3.0.3", + "sebastian/resource-operations": "^2.0.1", + "sebastian/type": "^1.1.3", + "sebastian/version": "^2.0.1" + }, + "suggest": { + "ext-soap": "To be able to generate mocks based on WSDL files", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage", + "phpunit/php-invoker": "To allow enforcing time limits" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "8.5-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/8.5.38" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" + } + ], + "time": "2024-04-05T04:31:23+00:00" + }, + { + "name": "phrity/net-stream", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/sirn-se/phrity-net-stream.git", + "reference": "9105931b65ad90c75f4885a40b268b0f65802e3e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sirn-se/phrity-net-stream/zipball/9105931b65ad90c75f4885a40b268b0f65802e3e", + "reference": "9105931b65ad90c75f4885a40b268b0f65802e3e", + "shasum": "" + }, + "require": { + "php": "^7.4 | ^8.0", + "phrity/util-errorhandler": "^1.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.0 | ^2.0" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.0", + "phpunit/phpunit": "^9.0 | ^10.0", + "phrity/net-uri": "^1.1", + "squizlabs/php_codesniffer": "^3.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Phrity\\Net\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Sören Jensen", + "email": "sirn@sirn.se", + "homepage": "https://phrity.sirn.se" + } + ], + "description": "Socket stream classes implementing PSR-7 Stream and PSR-17 StreamFactory", + "homepage": "https://phrity.sirn.se/net-stream", + "keywords": [ + "Socket", + "client", + "psr-17", + "psr-7", + "server", + "stream", + "stream factory" + ], + "support": { + "issues": "https://github.com/sirn-se/phrity-net-stream/issues", + "source": "https://github.com/sirn-se/phrity-net-stream/tree/1.3.0" + }, + "time": "2023-10-22T10:47:03+00:00" + }, + { + "name": "phrity/net-uri", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/sirn-se/phrity-net-uri.git", + "reference": "3f458e0c4d1ddc0e218d7a5b9420127c63925f43" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sirn-se/phrity-net-uri/zipball/3f458e0c4d1ddc0e218d7a5b9420127c63925f43", + "reference": "3f458e0c4d1ddc0e218d7a5b9420127c63925f43", + "shasum": "" + }, + "require": { + "php": "^7.4 | ^8.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.0 | ^2.0" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.0", + "phpunit/phpunit": "^9.0 | ^10.0", + "squizlabs/php_codesniffer": "^3.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Phrity\\Net\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Sören Jensen", + "email": "sirn@sirn.se", + "homepage": "https://phrity.sirn.se" } ], - "description": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", + "description": "PSR-7 Uri and PSR-17 UriFactory implementation", + "homepage": "https://phrity.sirn.se/net-uri", "keywords": [ - "timer" + "psr-17", + "psr-7", + "uri", + "uri factory" ], "support": { - "issues": "https://github.com/sebastianbergmann/php-timer/issues", - "source": "https://github.com/sebastianbergmann/php-timer/tree/2.1.3" + "issues": "https://github.com/sirn-se/phrity-net-uri/issues", + "source": "https://github.com/sirn-se/phrity-net-uri/tree/1.3.0" }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-11-30T08:20:02+00:00" + "time": "2023-08-21T10:33:06+00:00" }, { - "name": "phpunit/php-token-stream", - "version": "4.0.4", + "name": "phrity/util-errorhandler", + "version": "1.1.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "a853a0e183b9db7eed023d7933a858fa1c8d25a3" + "url": "https://github.com/sirn-se/phrity-util-errorhandler.git", + "reference": "4016d9f9615a4c602f525b0542e4835e316a42e4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/a853a0e183b9db7eed023d7933a858fa1c8d25a3", - "reference": "a853a0e183b9db7eed023d7933a858fa1c8d25a3", + "url": "https://api.github.com/repos/sirn-se/phrity-util-errorhandler/zipball/4016d9f9615a4c602f525b0542e4835e316a42e4", + "reference": "4016d9f9615a4c602f525b0542e4835e316a42e4", "shasum": "" }, "require": { - "ext-tokenizer": "*", - "php": "^7.3 || ^8.0" + "php": "^7.4 | ^8.0" }, "require-dev": { - "phpunit/phpunit": "^9.0" + "php-coveralls/php-coveralls": "^2.0", + "phpunit/phpunit": "^9.0 | ^10.0 | ^11.0", + "squizlabs/php_codesniffer": "^3.5" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-dev" - } - }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Phrity\\Util\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "Sören Jensen", + "email": "sirn@sirn.se", + "homepage": "https://phrity.sirn.se" } ], - "description": "Wrapper around PHP's tokenizer extension.", - "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "description": "Inline error handler; catch and resolve errors for code block.", + "homepage": "https://phrity.sirn.se/util-errorhandler", "keywords": [ - "tokenizer" + "error", + "warning" ], "support": { - "issues": "https://github.com/sebastianbergmann/php-token-stream/issues", - "source": "https://github.com/sebastianbergmann/php-token-stream/tree/master" + "issues": "https://github.com/sirn-se/phrity-util-errorhandler/issues", + "source": "https://github.com/sirn-se/phrity-util-errorhandler/tree/1.1.0" }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "abandoned": true, - "time": "2020-08-04T08:28:15+00:00" + "time": "2024-03-05T19:32:14+00:00" }, { - "name": "phpunit/phpunit", - "version": "8.5.33", + "name": "phrity/websocket", + "version": "1.7.3", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "7d1ff0e8c6b35db78ff13e3e05517d7cbf7aa32e" + "url": "https://github.com/sirn-se/websocket-php.git", + "reference": "8a525da4457b599ab1960f24183f25626c96ce3c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/7d1ff0e8c6b35db78ff13e3e05517d7cbf7aa32e", - "reference": "7d1ff0e8c6b35db78ff13e3e05517d7cbf7aa32e", + "url": "https://api.github.com/repos/sirn-se/websocket-php/zipball/8a525da4457b599ab1960f24183f25626c96ce3c", + "reference": "8a525da4457b599ab1960f24183f25626c96ce3c", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.3.1", - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "ext-mbstring": "*", - "ext-xml": "*", - "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.10.0", - "phar-io/manifest": "^2.0.3", - "phar-io/version": "^3.0.2", - "php": ">=7.2", - "phpunit/php-code-coverage": "^7.0.12", - "phpunit/php-file-iterator": "^2.0.4", - "phpunit/php-text-template": "^1.2.1", - "phpunit/php-timer": "^2.1.2", - "sebastian/comparator": "^3.0.5", - "sebastian/diff": "^3.0.2", - "sebastian/environment": "^4.2.3", - "sebastian/exporter": "^3.1.5", - "sebastian/global-state": "^3.0.0", - "sebastian/object-enumerator": "^3.0.3", - "sebastian/resource-operations": "^2.0.1", - "sebastian/type": "^1.1.3", - "sebastian/version": "^2.0.1" + "php": "^7.4 | ^8.0", + "phrity/net-stream": "^1.2", + "phrity/net-uri": "^1.2", + "phrity/util-errorhandler": "^1.0", + "psr/http-message": "^1.1 | ^2.0", + "psr/log": "^1.0 | ^2.0 | ^3.0" }, - "suggest": { - "ext-soap": "*", - "ext-xdebug": "*", - "phpunit/php-invoker": "^2.0.0" + "require-dev": { + "php-coveralls/php-coveralls": "^2.0", + "phpunit/phpunit": "^9.0 | ^10.0", + "phrity/net-mock": "^1.3", + "squizlabs/php_codesniffer": "^3.5" }, - "bin": [ - "phpunit" - ], "type": "library", - "extra": { - "branch-alias": { - "dev-master": "8.5-dev" - } - }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "WebSocket\\": "lib/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "ISC" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Fredrik Liljegren" + }, + { + "name": "Sören Jensen", + "email": "sirn@sirn.se", + "homepage": "https://phrity.sirn.se" } ], - "description": "The PHP Unit Testing framework.", - "homepage": "https://phpunit.de/", + "description": "WebSocket client and server", + "homepage": "https://phrity.sirn.se/websocket", "keywords": [ - "phpunit", - "testing", - "xunit" + "client", + "server", + "websocket" ], "support": { - "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/8.5.33" + "issues": "https://github.com/sirn-se/websocket-php/issues", + "source": "https://github.com/sirn-se/websocket-php/tree/1.7.3" }, - "funding": [ - { - "url": "https://phpunit.de/sponsors.html", - "type": "custom" - }, - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", - "type": "tidelift" - } - ], - "time": "2023-02-27T13:04:50+00:00" + "time": "2024-05-31T13:43:32+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", - "version": "1.0.2", + "version": "1.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619" + "reference": "92a1a52e86d34cde6caa54f1b5ffa9fda18e5d54" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/1de8cd5c010cb153fcd68b8d0f64606f523f7619", - "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/92a1a52e86d34cde6caa54f1b5ffa9fda18e5d54", + "reference": "92a1a52e86d34cde6caa54f1b5ffa9fda18e5d54", "shasum": "" }, "require": { @@ -8602,7 +7828,7 @@ "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", "support": { "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", - "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/1.0.2" + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/1.0.3" }, "funding": [ { @@ -8610,7 +7836,7 @@ "type": "github" } ], - "time": "2020-11-30T08:15:22+00:00" + "time": "2024-03-01T13:45:45+00:00" }, { "name": "sebastian/comparator", @@ -8688,16 +7914,16 @@ }, { "name": "sebastian/diff", - "version": "3.0.4", + "version": "3.0.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "6296a0c086dd0117c1b78b059374d7fcbe7545ae" + "reference": "98ff311ca519c3aa73ccd3de053bdb377171d7b6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/6296a0c086dd0117c1b78b059374d7fcbe7545ae", - "reference": "6296a0c086dd0117c1b78b059374d7fcbe7545ae", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/98ff311ca519c3aa73ccd3de053bdb377171d7b6", + "reference": "98ff311ca519c3aa73ccd3de053bdb377171d7b6", "shasum": "" }, "require": { @@ -8742,7 +7968,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", - "source": "https://github.com/sebastianbergmann/diff/tree/3.0.4" + "source": "https://github.com/sebastianbergmann/diff/tree/3.0.6" }, "funding": [ { @@ -8750,20 +7976,20 @@ "type": "github" } ], - "time": "2023-05-07T05:30:20+00:00" + "time": "2024-03-02T06:16:36+00:00" }, { "name": "sebastian/environment", - "version": "4.2.4", + "version": "4.2.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0" + "reference": "56932f6049a0482853056ffd617c91ffcc754205" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/d47bbbad83711771f167c72d4e3f25f7fcc1f8b0", - "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/56932f6049a0482853056ffd617c91ffcc754205", + "reference": "56932f6049a0482853056ffd617c91ffcc754205", "shasum": "" }, "require": { @@ -8805,7 +8031,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/4.2.4" + "source": "https://github.com/sebastianbergmann/environment/tree/4.2.5" }, "funding": [ { @@ -8813,24 +8039,24 @@ "type": "github" } ], - "time": "2020-11-30T07:53:42+00:00" + "time": "2024-03-01T13:49:59+00:00" }, { "name": "sebastian/exporter", - "version": "3.1.5", + "version": "3.1.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "73a9676f2833b9a7c36968f9d882589cd75511e6" + "reference": "1939bc8fd1d39adcfa88c5b35335910869214c56" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/73a9676f2833b9a7c36968f9d882589cd75511e6", - "reference": "73a9676f2833b9a7c36968f9d882589cd75511e6", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/1939bc8fd1d39adcfa88c5b35335910869214c56", + "reference": "1939bc8fd1d39adcfa88c5b35335910869214c56", "shasum": "" }, "require": { - "php": ">=7.0", + "php": ">=7.2", "sebastian/recursion-context": "^3.0" }, "require-dev": { @@ -8882,7 +8108,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/3.1.5" + "source": "https://github.com/sebastianbergmann/exporter/tree/3.1.6" }, "funding": [ { @@ -8890,20 +8116,20 @@ "type": "github" } ], - "time": "2022-09-14T06:00:17+00:00" + "time": "2024-03-02T06:21:38+00:00" }, { "name": "sebastian/global-state", - "version": "3.0.2", + "version": "3.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "de036ec91d55d2a9e0db2ba975b512cdb1c23921" + "reference": "91c7c47047a971f02de57ed6f040087ef110c5d9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/de036ec91d55d2a9e0db2ba975b512cdb1c23921", - "reference": "de036ec91d55d2a9e0db2ba975b512cdb1c23921", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/91c7c47047a971f02de57ed6f040087ef110c5d9", + "reference": "91c7c47047a971f02de57ed6f040087ef110c5d9", "shasum": "" }, "require": { @@ -8946,7 +8172,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/3.0.2" + "source": "https://github.com/sebastianbergmann/global-state/tree/3.0.5" }, "funding": [ { @@ -8954,20 +8180,20 @@ "type": "github" } ], - "time": "2022-02-10T06:55:38+00:00" + "time": "2024-03-02T06:13:16+00:00" }, { "name": "sebastian/object-enumerator", - "version": "3.0.4", + "version": "3.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2" + "reference": "ac5b293dba925751b808e02923399fb44ff0d541" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2", - "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/ac5b293dba925751b808e02923399fb44ff0d541", + "reference": "ac5b293dba925751b808e02923399fb44ff0d541", "shasum": "" }, "require": { @@ -9003,7 +8229,7 @@ "homepage": "https://github.com/sebastianbergmann/object-enumerator/", "support": { "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/3.0.4" + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/3.0.5" }, "funding": [ { @@ -9011,20 +8237,20 @@ "type": "github" } ], - "time": "2020-11-30T07:40:27+00:00" + "time": "2024-03-01T13:54:02+00:00" }, { "name": "sebastian/object-reflector", - "version": "1.1.2", + "version": "1.1.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d" + "reference": "1d439c229e61f244ff1f211e5c99737f90c67def" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/9b8772b9cbd456ab45d4a598d2dd1a1bced6363d", - "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/1d439c229e61f244ff1f211e5c99737f90c67def", + "reference": "1d439c229e61f244ff1f211e5c99737f90c67def", "shasum": "" }, "require": { @@ -9058,7 +8284,7 @@ "homepage": "https://github.com/sebastianbergmann/object-reflector/", "support": { "issues": "https://github.com/sebastianbergmann/object-reflector/issues", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/1.1.2" + "source": "https://github.com/sebastianbergmann/object-reflector/tree/1.1.3" }, "funding": [ { @@ -9066,20 +8292,20 @@ "type": "github" } ], - "time": "2020-11-30T07:37:18+00:00" + "time": "2024-03-01T13:56:04+00:00" }, { "name": "sebastian/recursion-context", - "version": "3.0.1", + "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb" + "reference": "9bfd3c6f1f08c026f542032dfb42813544f7d64c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/367dcba38d6e1977be014dc4b22f47a484dac7fb", - "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/9bfd3c6f1f08c026f542032dfb42813544f7d64c", + "reference": "9bfd3c6f1f08c026f542032dfb42813544f7d64c", "shasum": "" }, "require": { @@ -9121,7 +8347,7 @@ "homepage": "http://www.github.com/sebastianbergmann/recursion-context", "support": { "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/3.0.1" + "source": "https://github.com/sebastianbergmann/recursion-context/tree/3.0.2" }, "funding": [ { @@ -9129,20 +8355,20 @@ "type": "github" } ], - "time": "2020-11-30T07:34:24+00:00" + "time": "2024-03-01T14:07:30+00:00" }, { "name": "sebastian/resource-operations", - "version": "2.0.2", + "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3" + "reference": "72a7f7674d053d548003b16ff5a106e7e0e06eee" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/31d35ca87926450c44eae7e2611d45a7a65ea8b3", - "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/72a7f7674d053d548003b16ff5a106e7e0e06eee", + "reference": "72a7f7674d053d548003b16ff5a106e7e0e06eee", "shasum": "" }, "require": { @@ -9172,8 +8398,7 @@ "description": "Provides a list of PHP built-in functions that operate on resources", "homepage": "https://www.github.com/sebastianbergmann/resource-operations", "support": { - "issues": "https://github.com/sebastianbergmann/resource-operations/issues", - "source": "https://github.com/sebastianbergmann/resource-operations/tree/2.0.2" + "source": "https://github.com/sebastianbergmann/resource-operations/tree/2.0.3" }, "funding": [ { @@ -9181,20 +8406,20 @@ "type": "github" } ], - "time": "2020-11-30T07:30:19+00:00" + "time": "2024-03-01T13:59:09+00:00" }, { "name": "sebastian/type", - "version": "1.1.4", + "version": "1.1.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "0150cfbc4495ed2df3872fb31b26781e4e077eb4" + "reference": "18f071c3a29892b037d35e6b20ddf3ea39b42874" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/0150cfbc4495ed2df3872fb31b26781e4e077eb4", - "reference": "0150cfbc4495ed2df3872fb31b26781e4e077eb4", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/18f071c3a29892b037d35e6b20ddf3ea39b42874", + "reference": "18f071c3a29892b037d35e6b20ddf3ea39b42874", "shasum": "" }, "require": { @@ -9229,7 +8454,7 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/1.1.4" + "source": "https://github.com/sebastianbergmann/type/tree/1.1.5" }, "funding": [ { @@ -9237,7 +8462,7 @@ "type": "github" } ], - "time": "2020-11-30T07:25:11+00:00" + "time": "2024-03-01T14:04:07+00:00" }, { "name": "sebastian/version", @@ -9288,16 +8513,16 @@ }, { "name": "symfony/css-selector", - "version": "v6.4.7", + "version": "v6.4.8", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "1c5d5c2103c3762aff27a27e1e2409e30a79083b" + "reference": "4b61b02fe15db48e3687ce1c45ea385d1780fe08" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/1c5d5c2103c3762aff27a27e1e2409e30a79083b", - "reference": "1c5d5c2103c3762aff27a27e1e2409e30a79083b", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/4b61b02fe15db48e3687ce1c45ea385d1780fe08", + "reference": "4b61b02fe15db48e3687ce1c45ea385d1780fe08", "shasum": "" }, "require": { @@ -9333,7 +8558,7 @@ "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/css-selector/tree/v6.4.7" + "source": "https://github.com/symfony/css-selector/tree/v6.4.8" }, "funding": [ { @@ -9349,55 +8574,61 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:22:46+00:00" + "time": "2024-05-31T14:49:08+00:00" }, { "name": "symfony/translation", - "version": "v4.4.47", + "version": "v6.4.8", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "45036b1d53accc48fe9bab71ccd86d57eba0dd94" + "reference": "a002933b13989fc4bd0b58e04bf7eec5210e438a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/45036b1d53accc48fe9bab71ccd86d57eba0dd94", - "reference": "45036b1d53accc48fe9bab71ccd86d57eba0dd94", + "url": "https://api.github.com/repos/symfony/translation/zipball/a002933b13989fc4bd0b58e04bf7eec5210e438a", + "reference": "a002933b13989fc4bd0b58e04bf7eec5210e438a", "shasum": "" }, "require": { - "php": ">=7.1.3", + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php80": "^1.16", - "symfony/translation-contracts": "^1.1.6|^2" + "symfony/translation-contracts": "^2.5|^3.0" }, "conflict": { - "symfony/config": "<3.4", - "symfony/dependency-injection": "<3.4", - "symfony/http-kernel": "<4.4", - "symfony/yaml": "<3.4" + "symfony/config": "<5.4", + "symfony/console": "<5.4", + "symfony/dependency-injection": "<5.4", + "symfony/http-client-contracts": "<2.5", + "symfony/http-kernel": "<5.4", + "symfony/service-contracts": "<2.5", + "symfony/twig-bundle": "<5.4", + "symfony/yaml": "<5.4" }, "provide": { - "symfony/translation-implementation": "1.0|2.0" + "symfony/translation-implementation": "2.3|3.0" }, "require-dev": { + "nikic/php-parser": "^4.18|^5.0", "psr/log": "^1|^2|^3", - "symfony/config": "^3.4|^4.0|^5.0", - "symfony/console": "^3.4|^4.0|^5.0", - "symfony/dependency-injection": "^3.4|^4.0|^5.0", - "symfony/finder": "~2.8|~3.0|~4.0|^5.0", - "symfony/http-kernel": "^4.4", - "symfony/intl": "^3.4|^4.0|^5.0", - "symfony/service-contracts": "^1.1.2|^2", - "symfony/yaml": "^3.4|^4.0|^5.0" - }, - "suggest": { - "psr/log-implementation": "To use logging capability in translator", - "symfony/config": "", - "symfony/yaml": "" + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/console": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/finder": "^5.4|^6.0|^7.0", + "symfony/http-client-contracts": "^2.5|^3.0", + "symfony/http-kernel": "^5.4|^6.0|^7.0", + "symfony/intl": "^5.4|^6.0|^7.0", + "symfony/polyfill-intl-icu": "^1.21", + "symfony/routing": "^5.4|^6.0|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/yaml": "^5.4|^6.0|^7.0" }, "type": "library", "autoload": { + "files": [ + "Resources/functions.php" + ], "psr-4": { "Symfony\\Component\\Translation\\": "" }, @@ -9422,85 +8653,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v4.4.47" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2022-10-03T15:15:11+00:00" - }, - { - "name": "symfony/translation-contracts", - "version": "v2.5.2", - "source": { - "type": "git", - "url": "https://github.com/symfony/translation-contracts.git", - "reference": "136b19dd05cdf0709db6537d058bcab6dd6e2dbe" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/136b19dd05cdf0709db6537d058bcab6dd6e2dbe", - "reference": "136b19dd05cdf0709db6537d058bcab6dd6e2dbe", - "shasum": "" - }, - "require": { - "php": ">=7.2.5" - }, - "suggest": { - "symfony/translation-implementation": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Contracts\\Translation\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Generic abstractions related to translation", - "homepage": "https://symfony.com", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" - ], - "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v2.5.2" + "source": "https://github.com/symfony/translation/tree/v6.4.8" }, "funding": [ { @@ -9516,69 +8669,20 @@ "type": "tidelift" } ], - "time": "2022-06-27T16:58:25+00:00" - }, - { - "name": "textalk/websocket", - "version": "1.5.8", - "source": { - "type": "git", - "url": "https://github.com/Textalk/websocket-php.git", - "reference": "d05dbaa97500176447ffb1f1800573f23085ab13" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Textalk/websocket-php/zipball/d05dbaa97500176447ffb1f1800573f23085ab13", - "reference": "d05dbaa97500176447ffb1f1800573f23085ab13", - "shasum": "" - }, - "require": { - "php": "^7.2 | ^8.0", - "psr/log": "^1 | ^2 | ^3" - }, - "require-dev": { - "php-coveralls/php-coveralls": "^2.0", - "phpunit/phpunit": "^8.0|^9.0", - "squizlabs/php_codesniffer": "^3.5" - }, - "type": "library", - "autoload": { - "psr-4": { - "WebSocket\\": "lib" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "ISC" - ], - "authors": [ - { - "name": "Fredrik Liljegren" - }, - { - "name": "Sören Jensen", - "email": "soren@abicart.se" - } - ], - "description": "WebSocket client and server", - "support": { - "issues": "https://github.com/Textalk/websocket-php/issues", - "source": "https://github.com/Textalk/websocket-php/tree/1.5.8" - }, - "time": "2022-04-26T06:28:24+00:00" + "time": "2024-05-31T14:49:08+00:00" }, { "name": "theseer/tokenizer", - "version": "1.2.1", + "version": "1.2.3", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", "shasum": "" }, "require": { @@ -9607,7 +8711,7 @@ "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", "support": { "issues": "https://github.com/theseer/tokenizer/issues", - "source": "https://github.com/theseer/tokenizer/tree/1.2.1" + "source": "https://github.com/theseer/tokenizer/tree/1.2.3" }, "funding": [ { @@ -9615,13 +8719,12 @@ "type": "github" } ], - "time": "2021-07-28T10:34:58+00:00" + "time": "2024-03-03T12:36:25+00:00" } ], "aliases": [], "minimum-stability": "stable", "stability-flags": { - "gettext/gettext": 20, "roave/security-advisories": 20 }, "prefer-stable": false, diff --git a/development/UserPass.php b/development/UserPass.php index ebb331d0..8c3b6b3e 100644 --- a/development/UserPass.php +++ b/development/UserPass.php @@ -1,89 +1,113 @@ :", * while the value of each element is a new array with the attributes for each user. + * + * @var array */ - private $users; + private array $users; + /** * Constructor for this authentication source. * - * @param array $info Information about this authentication source. - * @param array $config Configuration. + * @param array $info Information about this authentication source. + * @param array $config Configuration. */ - public function __construct($info, $config) + public function __construct(array $info, array $config) { - assert(is_array($info)); - assert(is_array($config)); - // Call the parent constructor first, as required by the interface parent::__construct($info, $config); $this->users = []; + // Old version of SimpleSAMLphp had the username:password just be a list in the top level + // configuration. We now have them under the "users" key, so that exampleauth can be used + // for testing things like core:loginpage_links, etc. that require top level configuration. + if (array_key_exists('users', $config)) { + $config_users = $config['users']; + } else { + Logger::warning("Module exampleauth:UserPass configured in legacy mode. Please put your " . + "username:password entries under the \"users\" key in your authsource."); + $config_users = $config; + } + // Validate and parse our configuration - foreach ($config as $userpass => $attributes) { + foreach ($config_users as $userpass => $attributes) { if (!is_string($userpass)) { - throw new \Exception( - 'Invalid : for authentication source '.$this->authId.': '.$userpass + throw new Exception( + 'Invalid : for authentication source ' . $this->authId . ': ' . $userpass ); } $userpass = explode(':', $userpass, 2); if (count($userpass) !== 2) { - throw new \Exception( - 'Invalid : for authentication source '.$this->authId.': '.$userpass[0] + throw new Exception( + 'Invalid : for authentication source ' . $this->authId . ': ' . $userpass[0] ); } $username = $userpass[0]; $password = $userpass[1]; + // GTIS begin +// $attrUtils = new Utils\Attributes(); +// // try { -// $attributes = \SimpleSAML\Utils\Attributes::normalizeAttributesArray($attributes); -// } catch (\Exception $e) { -// throw new \Exception('Invalid attributes for user '.$username. +// $attributes = $attrUtils->normalizeAttributesArray($attributes); +// } catch (Exception $e) { +// throw new Exception('Invalid attributes for user '.$username. // ' in authentication source '.$this->authId.': '.$e->getMessage()); // } - $this->users[$username.':'.$password] = $attributes; + // GTIS end + $this->users[$username . ':' . $password] = $attributes; } } + /** * Attempt to log in using the given username and password. * * On a successful login, this function should return the users attributes. On failure, * it should throw an exception. If the error was caused by the user entering the wrong - * username or password, a \SimpleSAML\Error\Error('WRONGUSERPASS') should be thrown. + * username or password, a \SimpleSAML\Error\Error(\SimpleSAML\Error\ErrorCodes::WRONGUSERPASS) should be thrown. * * Note that both the username and the password are UTF-8 encoded. * - * @param string $username The username the user wrote. - * @param string $password The password the user wrote. + * @param string $username The username the user wrote. + * @param string $password The password the user wrote. * @return array Associative array with the users attributes. */ - protected function login($username, $password) + protected function login(string $username, string $password): array { - assert(is_string($username)); - assert(is_string($password)); - - $userpass = $username.':'.$password; + $userpass = $username . ':' . $password; if (!array_key_exists($userpass, $this->users)) { - throw new \SimpleSAML\Error\Error('WRONGUSERPASS'); + throw new Error\Error(Error\ErrorCodes::WRONGUSERPASS); } return $this->users[$userpass]; diff --git a/development/enable-exampleauth.sh b/development/enable-exampleauth.sh new file mode 100755 index 00000000..a14ba725 --- /dev/null +++ b/development/enable-exampleauth.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env sh + +sed -i 's@^\( *'\''module\.enable'\'' => \[\)@\1\n '\''exampleauth'\'' => true,@' /data/vendor/simplesamlphp/simplesamlphp/config/config.php diff --git a/development/hub/config/authsources.php b/development/hub/config/authsources.php index b7ae2cb1..b348f3bf 100644 --- a/development/hub/config/authsources.php +++ b/development/hub/config/authsources.php @@ -3,7 +3,7 @@ $config = [ 'hub-discovery' => [ - 'sildisco:SP', + 'saml:SP', // The entity ID of this SP. // Can be NULL/unset, in which case an entity ID is generated based on the metadata URL. @@ -12,7 +12,7 @@ // The URL to the discovery service. // Can be NULL/unset, in which case a builtin discovery service will be used. - 'discoURL' => 'http://ssp-hub.local/module.php/sildisco/disco.php', +// 'discoURL' => 'http://ssp-hub.local/module.php/sildisco/disco.php', ], diff --git a/development/hub/metadata/idp-remote.php b/development/hub/metadata/idp-remote.php deleted file mode 100644 index 81c89b2a..00000000 --- a/development/hub/metadata/idp-remote.php +++ /dev/null @@ -1,143 +0,0 @@ - [ - 'metadata-set' => 'saml20-idp-remote', - 'entityid' => 'http://ssp-idp1.local:8085', - 'name' => [ - 'en' => 'IDP 1:8085', - ], - 'IDPNamespace' => 'IDP-1-custom-port', - 'logoCaption' => 'IDP-1:8085 staff', - 'enabled' => true, - 'logoURL' => 'https://dummyimage.com/125x125/0f4fbd/ffffff.png&text=IDP+1+8085', - - 'description' => 'Local IDP for testing SSP Hub (custom port)', - - 'SingleSignOnService' => 'http://ssp-idp1.local:8085/saml2/idp/SSOService.php', - 'SingleLogoutService' => 'http://ssp-idp1.local:8085/saml2/idp/SingleLogoutService.php', - 'certData' => 'MIIDzzCCAregAwIBAgIJAPlZYTAQSIbHMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE3MTIzMTQ1WhcNMjYxMDE3MTIzMTQ1WjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArssOaeKbdOQFpN6bBolwSJ/6QFBXA73Sotg60anx9v6aYdUTmi+b7SVtvOmHDgsD5X8pN/6Z11QCZfTYg2nW3ZevGZsj8W/R6C8lRLHzWUr7e7DXKfj8GKZptHlUs68kn0ndNVt9r/+irJe9KBdZ+4kAihykomNdeZg06bvkklxVcvpkOfLTQzEqJAmISPPIeOXes6hXORdqLuRNTuIKarcZ9rstLnpgAs2TE4XDOrSuUg3XFnM05eDpFQpUb0RXWcD16mLCPWw+CPrGoCfoftD5ZGfll+W2wZ7d0kQ4TbCpNyxQH35q65RPVyVNPgSNSsFFkmdcqP9DsFqjJ8YC6wIDAQABo1AwTjAdBgNVHQ4EFgQUD6oyJKOPPhvLQpDCC3027QcuQwUwHwYDVR0jBBgwFoAUD6oyJKOPPhvLQpDCC3027QcuQwUwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAA6tCLHJQGfXGdFerQ3J0wUu8YDSLb0WJqPtGdIuyeiywR5ooJf8G/jjYMPgZArepLQSSi6t8/cjEdkYWejGnjMG323drQ9M1sKMUhOJF4po9R3t7IyvGAL3fSqjXA8JXH5MuGuGtChWxaqhduA0dBJhFAtAXQ61IuIQF7vSFxhTwCvJnaWdWD49sG5OqjCfgIQdY/mw70e45rLnR/bpfoigL67sTJxy+Kx2ogbvMR6lITByOEQFMt7BYpMtXrwvKUM7k9NOo1jREmJacC8PTx//jRhCWwzUj1RsfIri24BuITrawwqMsYl8DZiiwMpjUf9m4NPaf4E7+QRpzo+MCcg==', - - // NOTE: This breaks being able to test the hub's authentication sources - // since the hub doesn't create an SP entry in the session - 'SPList' => ['http://ssp-sp1.local:8081', 'http://ssp-sp2.local:8082', 'http://ssp-sp3.local:8083'], - ], - 'http://ssp-idp1.local' => [ - 'metadata-set' => 'saml20-idp-remote', - 'entityid' => 'http://ssp-idp1.local', - 'name' => [ - 'en' => 'IDP 1', - ], - 'IDPNamespace' => 'IDP-1', - 'logoCaption' => 'IDP-1 staff', - 'enabled' => true, - 'logoURL' => 'https://dummyimage.com/125x125/0f4fbd/ffffff.png&text=IDP+1', - - 'description' => 'Local IDP for testing SSP Hub (default port)', - - 'SingleSignOnService' => 'http://ssp-idp1.local/saml2/idp/SSOService.php', - 'SingleLogoutService' => 'http://ssp-idp1.local/saml2/idp/SingleLogoutService.php', - // 'certFingerprint' => 'c9ed4dfb07caf13fc21e0fec1572047eb8a7a4cb' - 'certData' => 'MIIDzzCCAregAwIBAgIJAPlZYTAQSIbHMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE3MTIzMTQ1WhcNMjYxMDE3MTIzMTQ1WjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArssOaeKbdOQFpN6bBolwSJ/6QFBXA73Sotg60anx9v6aYdUTmi+b7SVtvOmHDgsD5X8pN/6Z11QCZfTYg2nW3ZevGZsj8W/R6C8lRLHzWUr7e7DXKfj8GKZptHlUs68kn0ndNVt9r/+irJe9KBdZ+4kAihykomNdeZg06bvkklxVcvpkOfLTQzEqJAmISPPIeOXes6hXORdqLuRNTuIKarcZ9rstLnpgAs2TE4XDOrSuUg3XFnM05eDpFQpUb0RXWcD16mLCPWw+CPrGoCfoftD5ZGfll+W2wZ7d0kQ4TbCpNyxQH35q65RPVyVNPgSNSsFFkmdcqP9DsFqjJ8YC6wIDAQABo1AwTjAdBgNVHQ4EFgQUD6oyJKOPPhvLQpDCC3027QcuQwUwHwYDVR0jBBgwFoAUD6oyJKOPPhvLQpDCC3027QcuQwUwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAA6tCLHJQGfXGdFerQ3J0wUu8YDSLb0WJqPtGdIuyeiywR5ooJf8G/jjYMPgZArepLQSSi6t8/cjEdkYWejGnjMG323drQ9M1sKMUhOJF4po9R3t7IyvGAL3fSqjXA8JXH5MuGuGtChWxaqhduA0dBJhFAtAXQ61IuIQF7vSFxhTwCvJnaWdWD49sG5OqjCfgIQdY/mw70e45rLnR/bpfoigL67sTJxy+Kx2ogbvMR6lITByOEQFMt7BYpMtXrwvKUM7k9NOo1jREmJacC8PTx//jRhCWwzUj1RsfIri24BuITrawwqMsYl8DZiiwMpjUf9m4NPaf4E7+QRpzo+MCcg==', - - // NOTE: This breaks being able to test the hub's authentication sources - // since the hub doesn't create an SP entry in the session - 'SPList' => ['http://ssp-sp1.local', 'http://ssp-sp2.local', 'http://ssp-sp3.local'], - ], - - /* - * IdP 2 - */ - 'http://ssp-idp2.local:8086' => [ - 'metadata-set' => 'saml20-idp-remote', - 'entityid' => 'http://ssp-idp2.local:8086', - 'name' => [ - 'en' => 'IDP 2:8086', - ], - 'IDPNamespace' => 'IDP-2-custom-port', - 'logoCaption' => 'IDP-2:8086 staff', - 'enabled' => true, - 'betaEnabled' => true, - 'logoURL' => 'https://dummyimage.com/125x125/0f4fbd/ffffff.png&text=IDP+2+8086', - - 'description' => 'Local IDP2 for testing SSP Hub (custom port)', - - 'SingleSignOnService' => 'http://ssp-idp2.local:8086/saml2/idp/SSOService.php', - 'SingleLogoutService' => 'http://ssp-idp2.local:8086/saml2/idp/SingleLogoutService.php', - 'certData' => 'MIIDzzCCAregAwIBAgIJALBaUrvz1X5DMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE4MTQwMDUxWhcNMjYxMDE4MTQwMDUxWjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx5mZNwjEnakJho+5etuFyx+2g9rs96iLX/LDC24aBAsdNxTNuIc1jJ7pxBxGrepEND4LkietLNBlOr1q50nq2+ddTrCfmoJB+9BqBOxcm9qWeqWbp8/arUjaxPzK3DfZrxJxIVFjzqFF7gI91y9yvEW/fqLRMhvnH1ns+N1ne59zr1y6h9mmHfBffGr1YXAfyEAuV1ich4AfTfjqhdwFwxhFLLCVnxA0bDbNw/0eGCSiA13N7a013xTurLeJu0AQaZYssMqvc/17UphH4gWDMEZAwy0EfRSBOsDOYCxeNxVajnWX1834VDpBDfpnZj996Gh8tzRQxQgT9/plHKhGiwIDAQABo1AwTjAdBgNVHQ4EFgQUApxlUQg26GrG3eH8lEG3SkqbH/swHwYDVR0jBBgwFoAUApxlUQg26GrG3eH8lEG3SkqbH/swDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEANhbm8WgIqBDlF7DIRVUbq04TEA9nOJG8wdjJYdoKrPX9f/E9slkFuD2StcK99RTcowa8Z2OmW7tksa+onyH611Lq21QXh4aHzQUAm2HbsmPQRZnkByeYoCJ/1tuEho+x+VGanaUICSBVWYiebAQVKHR6miFypRElibNBizm2nqp6Q9B87V8COzyDVngR1DlWDduxYaNOBgvht3Rk9Y2pVHqym42dIfN+pprcsB1PGBkY/BngIuS/aqTENbmoC737vcb06e8uzBsbCpHtqUBjPpL2psQZVJ2Y84JmHafC3B7nFQrjdZBbc9eMHfPo240Rh+pDLwxdxPqRAZdeLaUkCQ==', - - // limit which Sps can use this IdP - 'SPList' => ['http://ssp-sp1.local:8081', 'http://ssp-sp2.local:8082'], - ], - 'http://ssp-idp2.local' => [ - 'metadata-set' => 'saml20-idp-remote', - 'entityid' => 'http://ssp-idp2.local', - 'name' => [ - 'en' => 'IDP 2', - ], - 'IDPNamespace' => 'IDP-2', - 'logoCaption' => 'IDP-2 staff', - 'enabled' => true, - 'betaEnabled' => true, - 'logoURL' => 'https://dummyimage.com/125x125/0f4fbd/ffffff.png&text=IDP+2', - - 'description' => 'Local IDP2 for testing SSP Hub (normal port)', - - 'SingleSignOnService' => 'http://ssp-idp2.local/saml2/idp/SSOService.php', - 'SingleLogoutService' => 'http://ssp-idp2.local/saml2/idp/SingleLogoutService.php', - 'certData' => 'MIIDzzCCAregAwIBAgIJALBaUrvz1X5DMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE4MTQwMDUxWhcNMjYxMDE4MTQwMDUxWjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx5mZNwjEnakJho+5etuFyx+2g9rs96iLX/LDC24aBAsdNxTNuIc1jJ7pxBxGrepEND4LkietLNBlOr1q50nq2+ddTrCfmoJB+9BqBOxcm9qWeqWbp8/arUjaxPzK3DfZrxJxIVFjzqFF7gI91y9yvEW/fqLRMhvnH1ns+N1ne59zr1y6h9mmHfBffGr1YXAfyEAuV1ich4AfTfjqhdwFwxhFLLCVnxA0bDbNw/0eGCSiA13N7a013xTurLeJu0AQaZYssMqvc/17UphH4gWDMEZAwy0EfRSBOsDOYCxeNxVajnWX1834VDpBDfpnZj996Gh8tzRQxQgT9/plHKhGiwIDAQABo1AwTjAdBgNVHQ4EFgQUApxlUQg26GrG3eH8lEG3SkqbH/swHwYDVR0jBBgwFoAUApxlUQg26GrG3eH8lEG3SkqbH/swDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEANhbm8WgIqBDlF7DIRVUbq04TEA9nOJG8wdjJYdoKrPX9f/E9slkFuD2StcK99RTcowa8Z2OmW7tksa+onyH611Lq21QXh4aHzQUAm2HbsmPQRZnkByeYoCJ/1tuEho+x+VGanaUICSBVWYiebAQVKHR6miFypRElibNBizm2nqp6Q9B87V8COzyDVngR1DlWDduxYaNOBgvht3Rk9Y2pVHqym42dIfN+pprcsB1PGBkY/BngIuS/aqTENbmoC737vcb06e8uzBsbCpHtqUBjPpL2psQZVJ2Y84JmHafC3B7nFQrjdZBbc9eMHfPo240Rh+pDLwxdxPqRAZdeLaUkCQ==', - - // limit which Sps can use this IdP - 'SPList' => ['http://ssp-sp1.local', 'http://ssp-sp2.local'], - ], - - /* - * IdP 3 - */ - 'http://ssp-idp3.local:8087' => [ - 'metadata-set' => 'saml20-idp-remote', - 'entityid' => 'http://ssp-idp3.local:8087', - 'name' => [ - 'en' => 'IDP 3:8087', - ], - 'IDPNamespace' => 'IDP-3-custom-port', - 'logoCaption' => 'IDP-3:8087 staff', - 'enabled' => false, - 'betaEnabled' => true, - 'logoURL' => 'https://dummyimage.com/125x125/0f4fbd/ffffff.png&text=IDP+3+8087', - - 'description' => 'Local IDP3 for testing SSP Hub (custom port)', - - 'SingleSignOnService' => 'http://ssp-idp3.local:8087/saml2/idp/SSOService.php', - 'SingleLogoutService' => 'http://ssp-idp3.local:8087/saml2/idp/SingleLogoutService.php', - 'certData' => 'MIIDzzCCAregAwIBAgIJALBaUrvz1X5DMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE4MTQwMDUxWhcNMjYxMDE4MTQwMDUxWjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx5mZNwjEnakJho+5etuFyx+2g9rs96iLX/LDC24aBAsdNxTNuIc1jJ7pxBxGrepEND4LkietLNBlOr1q50nq2+ddTrCfmoJB+9BqBOxcm9qWeqWbp8/arUjaxPzK3DfZrxJxIVFjzqFF7gI91y9yvEW/fqLRMhvnH1ns+N1ne59zr1y6h9mmHfBffGr1YXAfyEAuV1ich4AfTfjqhdwFwxhFLLCVnxA0bDbNw/0eGCSiA13N7a013xTurLeJu0AQaZYssMqvc/17UphH4gWDMEZAwy0EfRSBOsDOYCxeNxVajnWX1834VDpBDfpnZj996Gh8tzRQxQgT9/plHKhGiwIDAQABo1AwTjAdBgNVHQ4EFgQUApxlUQg26GrG3eH8lEG3SkqbH/swHwYDVR0jBBgwFoAUApxlUQg26GrG3eH8lEG3SkqbH/swDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEANhbm8WgIqBDlF7DIRVUbq04TEA9nOJG8wdjJYdoKrPX9f/E9slkFuD2StcK99RTcowa8Z2OmW7tksa+onyH611Lq21QXh4aHzQUAm2HbsmPQRZnkByeYoCJ/1tuEho+x+VGanaUICSBVWYiebAQVKHR6miFypRElibNBizm2nqp6Q9B87V8COzyDVngR1DlWDduxYaNOBgvht3Rk9Y2pVHqym42dIfN+pprcsB1PGBkY/BngIuS/aqTENbmoC737vcb06e8uzBsbCpHtqUBjPpL2psQZVJ2Y84JmHafC3B7nFQrjdZBbc9eMHfPo240Rh+pDLwxdxPqRAZdeLaUkCQ==', - ], - 'http://ssp-idp3.local' => [ - 'metadata-set' => 'saml20-idp-remote', - 'entityid' => 'http://ssp-idp3.local', - 'name' => [ - 'en' => 'IDP 3', - ], - 'IDPNamespace' => 'IDP-3', - 'logoCaption' => 'IDP-3 staff', - 'enabled' => false, - 'betaEnabled' => true, - 'logoURL' => 'https://dummyimage.com/125x125/0f4fbd/ffffff.png&text=IDP+3', - - 'description' => 'Local IDP3 for testing SSP Hub', - - 'SingleSignOnService' => 'http://ssp-idp3.local/saml2/idp/SSOService.php', - 'SingleLogoutService' => 'http://ssp-idp3.local/saml2/idp/SingleLogoutService.php', - 'certData' => 'MIIDzzCCAregAwIBAgIJALBaUrvz1X5DMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE4MTQwMDUxWhcNMjYxMDE4MTQwMDUxWjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx5mZNwjEnakJho+5etuFyx+2g9rs96iLX/LDC24aBAsdNxTNuIc1jJ7pxBxGrepEND4LkietLNBlOr1q50nq2+ddTrCfmoJB+9BqBOxcm9qWeqWbp8/arUjaxPzK3DfZrxJxIVFjzqFF7gI91y9yvEW/fqLRMhvnH1ns+N1ne59zr1y6h9mmHfBffGr1YXAfyEAuV1ich4AfTfjqhdwFwxhFLLCVnxA0bDbNw/0eGCSiA13N7a013xTurLeJu0AQaZYssMqvc/17UphH4gWDMEZAwy0EfRSBOsDOYCxeNxVajnWX1834VDpBDfpnZj996Gh8tzRQxQgT9/plHKhGiwIDAQABo1AwTjAdBgNVHQ4EFgQUApxlUQg26GrG3eH8lEG3SkqbH/swHwYDVR0jBBgwFoAUApxlUQg26GrG3eH8lEG3SkqbH/swDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEANhbm8WgIqBDlF7DIRVUbq04TEA9nOJG8wdjJYdoKrPX9f/E9slkFuD2StcK99RTcowa8Z2OmW7tksa+onyH611Lq21QXh4aHzQUAm2HbsmPQRZnkByeYoCJ/1tuEho+x+VGanaUICSBVWYiebAQVKHR6miFypRElibNBizm2nqp6Q9B87V8COzyDVngR1DlWDduxYaNOBgvht3Rk9Y2pVHqym42dIfN+pprcsB1PGBkY/BngIuS/aqTENbmoC737vcb06e8uzBsbCpHtqUBjPpL2psQZVJ2Y84JmHafC3B7nFQrjdZBbc9eMHfPo240Rh+pDLwxdxPqRAZdeLaUkCQ==', - ], - -]; diff --git a/development/hub/metadata/saml20-idp-hosted.php b/development/hub/metadata/saml20-idp-hosted.php index c413373d..ba8cd8b8 100644 --- a/development/hub/metadata/saml20-idp-hosted.php +++ b/development/hub/metadata/saml20-idp-hosted.php @@ -6,29 +6,28 @@ */ $metadata['ssp-hub.local'] = [ - /* - * The hostname of the server (VHOST) that will use this SAML entity. - * - * Can be '__DEFAULT__', to use this entry by default. - */ - 'host' => 'ssp-hub.local', + /* + * The hostname of the server (VHOST) that will use this SAML entity. + * + * Can be '__DEFAULT__', to use this entry by default. + */ + 'host' => 'ssp-hub.local', - // X.509 key and certificate. Relative to the cert directory. - 'privatekey' => 'saml.pem', - 'certificate' => 'saml.crt', + // X.509 key and certificate. Relative to the cert directory. + 'privatekey' => 'saml.pem', + 'certificate' => 'saml.crt', - // User the SSOService.php file provided by the sildisco module 'SingleSignOnService' => 'http://ssp-hub.local/saml2/idp/SSOService.php', - /* - * Authentication source to use. Must be one that is configured in - * 'config/authsources.php'. - */ - 'auth' => 'hub-discovery', + /* + * Authentication source to use. Must be one that is configured in + * 'config/authsources.php'. + */ + 'auth' => 'hub-discovery', 'authproc' => [ 95 => [ - 'class' =>'sildisco:TrackIdps', - ] + 'class' => 'sildisco:TrackIdps', + ] ], 'attributes.NameFormat' => 'urn:oasis:names:tc:SAML:2.0:attrname-format:uri', ]; diff --git a/development/hub/metadata/saml20-idp-remote.php b/development/hub/metadata/saml20-idp-remote.php new file mode 100644 index 00000000..ce8c6a93 --- /dev/null +++ b/development/hub/metadata/saml20-idp-remote.php @@ -0,0 +1,140 @@ + 'saml20-idp-remote', + 'entityid' => 'http://ssp-idp1.local:8085', + 'name' => [ + 'en' => 'IDP 1:8085', + ], + 'IDPNamespace' => 'IDP-1-custom-port', + 'logoCaption' => 'IDP-1:8085 staff', + 'enabled' => true, + 'logoURL' => 'https://dummyimage.com/125x125/0f4fbd/ffffff.png&text=IDP+1+8085', + + 'description' => 'Local IDP for testing SSP Hub (custom port)', + + 'SingleSignOnService' => 'http://ssp-idp1.local:8085/saml2/idp/SSOService.php', + 'SingleLogoutService' => 'http://ssp-idp1.local:8085/saml2/idp/SingleLogoutService.php', + 'certData' => 'MIIDzzCCAregAwIBAgIJAPlZYTAQSIbHMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE3MTIzMTQ1WhcNMjYxMDE3MTIzMTQ1WjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArssOaeKbdOQFpN6bBolwSJ/6QFBXA73Sotg60anx9v6aYdUTmi+b7SVtvOmHDgsD5X8pN/6Z11QCZfTYg2nW3ZevGZsj8W/R6C8lRLHzWUr7e7DXKfj8GKZptHlUs68kn0ndNVt9r/+irJe9KBdZ+4kAihykomNdeZg06bvkklxVcvpkOfLTQzEqJAmISPPIeOXes6hXORdqLuRNTuIKarcZ9rstLnpgAs2TE4XDOrSuUg3XFnM05eDpFQpUb0RXWcD16mLCPWw+CPrGoCfoftD5ZGfll+W2wZ7d0kQ4TbCpNyxQH35q65RPVyVNPgSNSsFFkmdcqP9DsFqjJ8YC6wIDAQABo1AwTjAdBgNVHQ4EFgQUD6oyJKOPPhvLQpDCC3027QcuQwUwHwYDVR0jBBgwFoAUD6oyJKOPPhvLQpDCC3027QcuQwUwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAA6tCLHJQGfXGdFerQ3J0wUu8YDSLb0WJqPtGdIuyeiywR5ooJf8G/jjYMPgZArepLQSSi6t8/cjEdkYWejGnjMG323drQ9M1sKMUhOJF4po9R3t7IyvGAL3fSqjXA8JXH5MuGuGtChWxaqhduA0dBJhFAtAXQ61IuIQF7vSFxhTwCvJnaWdWD49sG5OqjCfgIQdY/mw70e45rLnR/bpfoigL67sTJxy+Kx2ogbvMR6lITByOEQFMt7BYpMtXrwvKUM7k9NOo1jREmJacC8PTx//jRhCWwzUj1RsfIri24BuITrawwqMsYl8DZiiwMpjUf9m4NPaf4E7+QRpzo+MCcg==', + + // NOTE: This breaks being able to test the hub's authentication sources + // since the hub doesn't create an SP entry in the session + 'SPList' => ['http://ssp-sp1.local:8081', 'http://ssp-sp2.local:8082', 'http://ssp-sp3.local:8083'], +]; +$metadata['http://ssp-idp1.local'] = [ + 'metadata-set' => 'saml20-idp-remote', + 'entityid' => 'http://ssp-idp1.local', + 'name' => [ + 'en' => 'IDP 1', + ], + 'IDPNamespace' => 'IDP-1', + 'logoCaption' => 'IDP-1 staff', + 'enabled' => true, + 'logoURL' => 'https://dummyimage.com/125x125/0f4fbd/ffffff.png&text=IDP+1', + + 'description' => 'Local IDP for testing SSP Hub (default port)', + + 'SingleSignOnService' => 'http://ssp-idp1.local/saml2/idp/SSOService.php', + 'SingleLogoutService' => 'http://ssp-idp1.local/saml2/idp/SingleLogoutService.php', + 'certData' => 'MIIDzzCCAregAwIBAgIJAPlZYTAQSIbHMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE3MTIzMTQ1WhcNMjYxMDE3MTIzMTQ1WjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArssOaeKbdOQFpN6bBolwSJ/6QFBXA73Sotg60anx9v6aYdUTmi+b7SVtvOmHDgsD5X8pN/6Z11QCZfTYg2nW3ZevGZsj8W/R6C8lRLHzWUr7e7DXKfj8GKZptHlUs68kn0ndNVt9r/+irJe9KBdZ+4kAihykomNdeZg06bvkklxVcvpkOfLTQzEqJAmISPPIeOXes6hXORdqLuRNTuIKarcZ9rstLnpgAs2TE4XDOrSuUg3XFnM05eDpFQpUb0RXWcD16mLCPWw+CPrGoCfoftD5ZGfll+W2wZ7d0kQ4TbCpNyxQH35q65RPVyVNPgSNSsFFkmdcqP9DsFqjJ8YC6wIDAQABo1AwTjAdBgNVHQ4EFgQUD6oyJKOPPhvLQpDCC3027QcuQwUwHwYDVR0jBBgwFoAUD6oyJKOPPhvLQpDCC3027QcuQwUwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAA6tCLHJQGfXGdFerQ3J0wUu8YDSLb0WJqPtGdIuyeiywR5ooJf8G/jjYMPgZArepLQSSi6t8/cjEdkYWejGnjMG323drQ9M1sKMUhOJF4po9R3t7IyvGAL3fSqjXA8JXH5MuGuGtChWxaqhduA0dBJhFAtAXQ61IuIQF7vSFxhTwCvJnaWdWD49sG5OqjCfgIQdY/mw70e45rLnR/bpfoigL67sTJxy+Kx2ogbvMR6lITByOEQFMt7BYpMtXrwvKUM7k9NOo1jREmJacC8PTx//jRhCWwzUj1RsfIri24BuITrawwqMsYl8DZiiwMpjUf9m4NPaf4E7+QRpzo+MCcg==', + + // NOTE: This breaks being able to test the hub's authentication sources + // since the hub doesn't create an SP entry in the session + 'SPList' => ['http://ssp-sp1.local', 'http://ssp-sp2.local', 'http://ssp-sp3.local'], +]; + +/* + * IdP 2 + */ +$metadata['http://ssp-idp2.local:8086'] = [ + 'metadata-set' => 'saml20-idp-remote', + 'entityid' => 'http://ssp-idp2.local:8086', + 'name' => [ + 'en' => 'IDP 2:8086', + ], + 'IDPNamespace' => 'IDP-2-custom-port', + 'logoCaption' => 'IDP-2:8086 staff', + 'enabled' => true, + 'betaEnabled' => true, + 'logoURL' => 'https://dummyimage.com/125x125/0f4fbd/ffffff.png&text=IDP+2+8086', + + 'description' => 'Local IDP2 for testing SSP Hub (custom port)', + + 'SingleSignOnService' => 'http://ssp-idp2.local:8086/saml2/idp/SSOService.php', + 'SingleLogoutService' => 'http://ssp-idp2.local:8086/saml2/idp/SingleLogoutService.php', + 'certData' => 'MIIDzzCCAregAwIBAgIJALBaUrvz1X5DMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE4MTQwMDUxWhcNMjYxMDE4MTQwMDUxWjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx5mZNwjEnakJho+5etuFyx+2g9rs96iLX/LDC24aBAsdNxTNuIc1jJ7pxBxGrepEND4LkietLNBlOr1q50nq2+ddTrCfmoJB+9BqBOxcm9qWeqWbp8/arUjaxPzK3DfZrxJxIVFjzqFF7gI91y9yvEW/fqLRMhvnH1ns+N1ne59zr1y6h9mmHfBffGr1YXAfyEAuV1ich4AfTfjqhdwFwxhFLLCVnxA0bDbNw/0eGCSiA13N7a013xTurLeJu0AQaZYssMqvc/17UphH4gWDMEZAwy0EfRSBOsDOYCxeNxVajnWX1834VDpBDfpnZj996Gh8tzRQxQgT9/plHKhGiwIDAQABo1AwTjAdBgNVHQ4EFgQUApxlUQg26GrG3eH8lEG3SkqbH/swHwYDVR0jBBgwFoAUApxlUQg26GrG3eH8lEG3SkqbH/swDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEANhbm8WgIqBDlF7DIRVUbq04TEA9nOJG8wdjJYdoKrPX9f/E9slkFuD2StcK99RTcowa8Z2OmW7tksa+onyH611Lq21QXh4aHzQUAm2HbsmPQRZnkByeYoCJ/1tuEho+x+VGanaUICSBVWYiebAQVKHR6miFypRElibNBizm2nqp6Q9B87V8COzyDVngR1DlWDduxYaNOBgvht3Rk9Y2pVHqym42dIfN+pprcsB1PGBkY/BngIuS/aqTENbmoC737vcb06e8uzBsbCpHtqUBjPpL2psQZVJ2Y84JmHafC3B7nFQrjdZBbc9eMHfPo240Rh+pDLwxdxPqRAZdeLaUkCQ==', + + // limit which Sps can use this IdP + 'SPList' => ['http://ssp-sp1.local:8081', 'http://ssp-sp2.local:8082'], +]; +$metadata['http://ssp-idp2.local'] = [ + 'metadata-set' => 'saml20-idp-remote', + 'entityid' => 'http://ssp-idp2.local', + 'name' => [ + 'en' => 'IDP 2', + ], + 'IDPNamespace' => 'IDP-2', + 'logoCaption' => 'IDP-2 staff', + 'enabled' => true, + 'betaEnabled' => true, + 'logoURL' => 'https://dummyimage.com/125x125/0f4fbd/ffffff.png&text=IDP+2', + + 'description' => 'Local IDP2 for testing SSP Hub (normal port)', + + 'SingleSignOnService' => 'http://ssp-idp2.local/saml2/idp/SSOService.php', + 'SingleLogoutService' => 'http://ssp-idp2.local/saml2/idp/SingleLogoutService.php', + 'certData' => 'MIIDzzCCAregAwIBAgIJALBaUrvz1X5DMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE4MTQwMDUxWhcNMjYxMDE4MTQwMDUxWjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx5mZNwjEnakJho+5etuFyx+2g9rs96iLX/LDC24aBAsdNxTNuIc1jJ7pxBxGrepEND4LkietLNBlOr1q50nq2+ddTrCfmoJB+9BqBOxcm9qWeqWbp8/arUjaxPzK3DfZrxJxIVFjzqFF7gI91y9yvEW/fqLRMhvnH1ns+N1ne59zr1y6h9mmHfBffGr1YXAfyEAuV1ich4AfTfjqhdwFwxhFLLCVnxA0bDbNw/0eGCSiA13N7a013xTurLeJu0AQaZYssMqvc/17UphH4gWDMEZAwy0EfRSBOsDOYCxeNxVajnWX1834VDpBDfpnZj996Gh8tzRQxQgT9/plHKhGiwIDAQABo1AwTjAdBgNVHQ4EFgQUApxlUQg26GrG3eH8lEG3SkqbH/swHwYDVR0jBBgwFoAUApxlUQg26GrG3eH8lEG3SkqbH/swDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEANhbm8WgIqBDlF7DIRVUbq04TEA9nOJG8wdjJYdoKrPX9f/E9slkFuD2StcK99RTcowa8Z2OmW7tksa+onyH611Lq21QXh4aHzQUAm2HbsmPQRZnkByeYoCJ/1tuEho+x+VGanaUICSBVWYiebAQVKHR6miFypRElibNBizm2nqp6Q9B87V8COzyDVngR1DlWDduxYaNOBgvht3Rk9Y2pVHqym42dIfN+pprcsB1PGBkY/BngIuS/aqTENbmoC737vcb06e8uzBsbCpHtqUBjPpL2psQZVJ2Y84JmHafC3B7nFQrjdZBbc9eMHfPo240Rh+pDLwxdxPqRAZdeLaUkCQ==', + + // limit which Sps can use this IdP + 'SPList' => ['http://ssp-sp1.local', 'http://ssp-sp2.local'], +]; + +/* + * IdP 3 + */ +$metadata['http://ssp-idp3.local:8087'] = [ + 'metadata-set' => 'saml20-idp-remote', + 'entityid' => 'http://ssp-idp3.local:8087', + 'name' => [ + 'en' => 'IDP 3:8087', + ], + 'IDPNamespace' => 'IDP-3-custom-port', + 'logoCaption' => 'IDP-3:8087 staff', + 'enabled' => false, + 'betaEnabled' => true, + 'logoURL' => 'https://dummyimage.com/125x125/0f4fbd/ffffff.png&text=IDP+3+8087', + + 'description' => 'Local IDP3 for testing SSP Hub (custom port)', + + 'SingleSignOnService' => 'http://ssp-idp3.local:8087/saml2/idp/SSOService.php', + 'SingleLogoutService' => 'http://ssp-idp3.local:8087/saml2/idp/SingleLogoutService.php', + 'certData' => 'MIIDzzCCAregAwIBAgIJALBaUrvz1X5DMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE4MTQwMDUxWhcNMjYxMDE4MTQwMDUxWjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx5mZNwjEnakJho+5etuFyx+2g9rs96iLX/LDC24aBAsdNxTNuIc1jJ7pxBxGrepEND4LkietLNBlOr1q50nq2+ddTrCfmoJB+9BqBOxcm9qWeqWbp8/arUjaxPzK3DfZrxJxIVFjzqFF7gI91y9yvEW/fqLRMhvnH1ns+N1ne59zr1y6h9mmHfBffGr1YXAfyEAuV1ich4AfTfjqhdwFwxhFLLCVnxA0bDbNw/0eGCSiA13N7a013xTurLeJu0AQaZYssMqvc/17UphH4gWDMEZAwy0EfRSBOsDOYCxeNxVajnWX1834VDpBDfpnZj996Gh8tzRQxQgT9/plHKhGiwIDAQABo1AwTjAdBgNVHQ4EFgQUApxlUQg26GrG3eH8lEG3SkqbH/swHwYDVR0jBBgwFoAUApxlUQg26GrG3eH8lEG3SkqbH/swDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEANhbm8WgIqBDlF7DIRVUbq04TEA9nOJG8wdjJYdoKrPX9f/E9slkFuD2StcK99RTcowa8Z2OmW7tksa+onyH611Lq21QXh4aHzQUAm2HbsmPQRZnkByeYoCJ/1tuEho+x+VGanaUICSBVWYiebAQVKHR6miFypRElibNBizm2nqp6Q9B87V8COzyDVngR1DlWDduxYaNOBgvht3Rk9Y2pVHqym42dIfN+pprcsB1PGBkY/BngIuS/aqTENbmoC737vcb06e8uzBsbCpHtqUBjPpL2psQZVJ2Y84JmHafC3B7nFQrjdZBbc9eMHfPo240Rh+pDLwxdxPqRAZdeLaUkCQ==', +]; +$metadata['http://ssp-idp3.local'] = [ + 'metadata-set' => 'saml20-idp-remote', + 'entityid' => 'http://ssp-idp3.local', + 'name' => [ + 'en' => 'IDP 3', + ], + 'IDPNamespace' => 'IDP-3', + 'logoCaption' => 'IDP-3 staff', + 'enabled' => false, + 'betaEnabled' => true, + 'logoURL' => 'https://dummyimage.com/125x125/0f4fbd/ffffff.png&text=IDP+3', + + 'description' => 'Local IDP3 for testing SSP Hub', + + 'SingleSignOnService' => 'http://ssp-idp3.local/saml2/idp/SSOService.php', + 'SingleLogoutService' => 'http://ssp-idp3.local/saml2/idp/SingleLogoutService.php', + 'certData' => 'MIIDzzCCAregAwIBAgIJALBaUrvz1X5DMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE4MTQwMDUxWhcNMjYxMDE4MTQwMDUxWjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx5mZNwjEnakJho+5etuFyx+2g9rs96iLX/LDC24aBAsdNxTNuIc1jJ7pxBxGrepEND4LkietLNBlOr1q50nq2+ddTrCfmoJB+9BqBOxcm9qWeqWbp8/arUjaxPzK3DfZrxJxIVFjzqFF7gI91y9yvEW/fqLRMhvnH1ns+N1ne59zr1y6h9mmHfBffGr1YXAfyEAuV1ich4AfTfjqhdwFwxhFLLCVnxA0bDbNw/0eGCSiA13N7a013xTurLeJu0AQaZYssMqvc/17UphH4gWDMEZAwy0EfRSBOsDOYCxeNxVajnWX1834VDpBDfpnZj996Gh8tzRQxQgT9/plHKhGiwIDAQABo1AwTjAdBgNVHQ4EFgQUApxlUQg26GrG3eH8lEG3SkqbH/swHwYDVR0jBBgwFoAUApxlUQg26GrG3eH8lEG3SkqbH/swDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEANhbm8WgIqBDlF7DIRVUbq04TEA9nOJG8wdjJYdoKrPX9f/E9slkFuD2StcK99RTcowa8Z2OmW7tksa+onyH611Lq21QXh4aHzQUAm2HbsmPQRZnkByeYoCJ/1tuEho+x+VGanaUICSBVWYiebAQVKHR6miFypRElibNBizm2nqp6Q9B87V8COzyDVngR1DlWDduxYaNOBgvht3Rk9Y2pVHqym42dIfN+pprcsB1PGBkY/BngIuS/aqTENbmoC737vcb06e8uzBsbCpHtqUBjPpL2psQZVJ2Y84JmHafC3B7nFQrjdZBbc9eMHfPo240Rh+pDLwxdxPqRAZdeLaUkCQ==', +]; diff --git a/development/hub/metadata/saml20-sp-remote.php b/development/hub/metadata/saml20-sp-remote.php new file mode 100644 index 00000000..95b29601 --- /dev/null +++ b/development/hub/metadata/saml20-sp-remote.php @@ -0,0 +1,85 @@ + "SP1 (custom port)", + 'AssertionConsumerService' => 'http://ssp-sp1.local:8081/module.php/saml/sp/saml2-acs.php/ssp-hub-custom-port', + 'SingleLogoutService' => 'http://ssp-sp1.local:8081/module.php/saml/sp/saml2-logout.php/ssp-hub-custom-port', + 'certData' => 'MIIDzzCCAregAwIBAgIJAPnOHgSgAeNrMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE3MTIyNzU2WhcNMjYxMDE3MTIyNzU2WjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0u+mXWS8vUkKjtJcK1hd0iGW2vbTvYosgyDdqClcSzwpbWJg1A1ChuiQIf7S+5bWL2AN4zMoem/JTn7cE9octqU34ZJAyP/cesppA9G53F9gH4XdoPgnWsb8vdWooDDUk+asc7ah/XwKixQNcELPDZkOba5+pqoKGjMxfL7JQ6+P6LB+xItzvLBXU4+onbGPIF6pmZ8S74mt0J62Y6ne40BHx8FdrtBgdk5TFcDedW09rRJrTFpi3hGSUkcjqj84B+oLAb08Z0SHoELMp5Yh7Tg5QZ2c+S8I47tQjV72rNhUYhIyFuImzSg27R7aRJ6Jj6sK4zEg0Ai4VhO4RmgyzwIDAQABo1AwTjAdBgNVHQ4EFgQUgkYcMbT0o8kmxAz2O3+p1lDVj1MwHwYDVR0jBBgwFoAUgkYcMbT0o8kmxAz2O3+p1lDVj1MwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEANgyTgMVRghgL8klqvZvQpfh80XDPTZotJCc8mZJZ98YkNC8jnR2RIUJpah+XrgotlKNDOK3HMNuyKGgYcqcno4PdDXKbqp4yXmywdNbbEHwPWDGqZXULw2az+UVwPUZJcJyJuwJjy3diCJT53N9G0LqXfeEsV0OPQPaB2PWgYNraBd59fckmBTc298HuvsHtxUcoXM53ms2Ck6GygGwH1vCg7qyIRRQFL4DiSlnoS8jxt3IIpZZs9FAl1ejtFBepSne9kEo7lLhAWY1TQqRrRXNHngG/L70ZkZonE9TNK/9xIHuaawqWkV6WLnkhT0DHCOw67GP97MWzceyFw+n9Vg==', + 'IDPList' => [ + 'http://ssp-idp1.local:8085', + 'http://ssp-idp2.local:8086', + 'http://ssp-idp3.local:8087', + ], + 'assertion.encryption' => true, +]; + +$metadata['http://ssp-sp1.local'] = [ + 'name' => "SP1", + 'AssertionConsumerService' => 'http://ssp-sp1.local/module.php/saml/sp/saml2-acs.php/ssp-hub', + 'SingleLogoutService' => 'http://ssp-sp1.local/module.php/saml/sp/saml2-logout.php/ssp-hub', + 'certData' => 'MIIDzzCCAregAwIBAgIJAPnOHgSgAeNrMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE3MTIyNzU2WhcNMjYxMDE3MTIyNzU2WjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0u+mXWS8vUkKjtJcK1hd0iGW2vbTvYosgyDdqClcSzwpbWJg1A1ChuiQIf7S+5bWL2AN4zMoem/JTn7cE9octqU34ZJAyP/cesppA9G53F9gH4XdoPgnWsb8vdWooDDUk+asc7ah/XwKixQNcELPDZkOba5+pqoKGjMxfL7JQ6+P6LB+xItzvLBXU4+onbGPIF6pmZ8S74mt0J62Y6ne40BHx8FdrtBgdk5TFcDedW09rRJrTFpi3hGSUkcjqj84B+oLAb08Z0SHoELMp5Yh7Tg5QZ2c+S8I47tQjV72rNhUYhIyFuImzSg27R7aRJ6Jj6sK4zEg0Ai4VhO4RmgyzwIDAQABo1AwTjAdBgNVHQ4EFgQUgkYcMbT0o8kmxAz2O3+p1lDVj1MwHwYDVR0jBBgwFoAUgkYcMbT0o8kmxAz2O3+p1lDVj1MwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEANgyTgMVRghgL8klqvZvQpfh80XDPTZotJCc8mZJZ98YkNC8jnR2RIUJpah+XrgotlKNDOK3HMNuyKGgYcqcno4PdDXKbqp4yXmywdNbbEHwPWDGqZXULw2az+UVwPUZJcJyJuwJjy3diCJT53N9G0LqXfeEsV0OPQPaB2PWgYNraBd59fckmBTc298HuvsHtxUcoXM53ms2Ck6GygGwH1vCg7qyIRRQFL4DiSlnoS8jxt3IIpZZs9FAl1ejtFBepSne9kEo7lLhAWY1TQqRrRXNHngG/L70ZkZonE9TNK/9xIHuaawqWkV6WLnkhT0DHCOw67GP97MWzceyFw+n9Vg==', + 'IDPList' => [ + 'http://ssp-idp1.local', + 'http://ssp-idp2.local', + 'http://ssp-idp3.local', + ], + 'assertion.encryption' => true, +]; + +$metadata['http://ssp-sp2.local:8082'] = [ + 'AssertionConsumerService' => 'http://ssp-sp2.local:8082/module.php/saml/sp/saml2-acs.php/ssp-hub-custom-port', + 'SingleLogoutService' => 'http://ssp-sp2.local:8082/module.php/saml/sp/saml2-logout.php/ssp-hub-custom-port', + 'IDPList' => [ + 'http://ssp-idp2.local:8086', + ], + 'name' => 'SP2 (custom port)', + 'certData' => 'MIIDzzCCAregAwIBAgIJAPnOHgSgAeNrMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE3MTIyNzU2WhcNMjYxMDE3MTIyNzU2WjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0u+mXWS8vUkKjtJcK1hd0iGW2vbTvYosgyDdqClcSzwpbWJg1A1ChuiQIf7S+5bWL2AN4zMoem/JTn7cE9octqU34ZJAyP/cesppA9G53F9gH4XdoPgnWsb8vdWooDDUk+asc7ah/XwKixQNcELPDZkOba5+pqoKGjMxfL7JQ6+P6LB+xItzvLBXU4+onbGPIF6pmZ8S74mt0J62Y6ne40BHx8FdrtBgdk5TFcDedW09rRJrTFpi3hGSUkcjqj84B+oLAb08Z0SHoELMp5Yh7Tg5QZ2c+S8I47tQjV72rNhUYhIyFuImzSg27R7aRJ6Jj6sK4zEg0Ai4VhO4RmgyzwIDAQABo1AwTjAdBgNVHQ4EFgQUgkYcMbT0o8kmxAz2O3+p1lDVj1MwHwYDVR0jBBgwFoAUgkYcMbT0o8kmxAz2O3+p1lDVj1MwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEANgyTgMVRghgL8klqvZvQpfh80XDPTZotJCc8mZJZ98YkNC8jnR2RIUJpah+XrgotlKNDOK3HMNuyKGgYcqcno4PdDXKbqp4yXmywdNbbEHwPWDGqZXULw2az+UVwPUZJcJyJuwJjy3diCJT53N9G0LqXfeEsV0OPQPaB2PWgYNraBd59fckmBTc298HuvsHtxUcoXM53ms2Ck6GygGwH1vCg7qyIRRQFL4DiSlnoS8jxt3IIpZZs9FAl1ejtFBepSne9kEo7lLhAWY1TQqRrRXNHngG/L70ZkZonE9TNK/9xIHuaawqWkV6WLnkhT0DHCOw67GP97MWzceyFw+n9Vg==', + 'assertion.encryption' => true, +]; + +$metadata['http://ssp-sp2.local'] = [ + 'AssertionConsumerService' => 'http://ssp-sp2.local/module.php/saml/sp/saml2-acs.php/ssp-hub', + 'SingleLogoutService' => 'http://ssp-sp2.local/module.php/saml/sp/saml2-logout.php/ssp-hub', + 'IDPList' => [ + 'http://ssp-idp2.local', + ], + 'name' => 'SP2', + 'certData' => 'MIIDzzCCAregAwIBAgIJAPnOHgSgAeNrMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE3MTIyNzU2WhcNMjYxMDE3MTIyNzU2WjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0u+mXWS8vUkKjtJcK1hd0iGW2vbTvYosgyDdqClcSzwpbWJg1A1ChuiQIf7S+5bWL2AN4zMoem/JTn7cE9octqU34ZJAyP/cesppA9G53F9gH4XdoPgnWsb8vdWooDDUk+asc7ah/XwKixQNcELPDZkOba5+pqoKGjMxfL7JQ6+P6LB+xItzvLBXU4+onbGPIF6pmZ8S74mt0J62Y6ne40BHx8FdrtBgdk5TFcDedW09rRJrTFpi3hGSUkcjqj84B+oLAb08Z0SHoELMp5Yh7Tg5QZ2c+S8I47tQjV72rNhUYhIyFuImzSg27R7aRJ6Jj6sK4zEg0Ai4VhO4RmgyzwIDAQABo1AwTjAdBgNVHQ4EFgQUgkYcMbT0o8kmxAz2O3+p1lDVj1MwHwYDVR0jBBgwFoAUgkYcMbT0o8kmxAz2O3+p1lDVj1MwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEANgyTgMVRghgL8klqvZvQpfh80XDPTZotJCc8mZJZ98YkNC8jnR2RIUJpah+XrgotlKNDOK3HMNuyKGgYcqcno4PdDXKbqp4yXmywdNbbEHwPWDGqZXULw2az+UVwPUZJcJyJuwJjy3diCJT53N9G0LqXfeEsV0OPQPaB2PWgYNraBd59fckmBTc298HuvsHtxUcoXM53ms2Ck6GygGwH1vCg7qyIRRQFL4DiSlnoS8jxt3IIpZZs9FAl1ejtFBepSne9kEo7lLhAWY1TQqRrRXNHngG/L70ZkZonE9TNK/9xIHuaawqWkV6WLnkhT0DHCOw67GP97MWzceyFw+n9Vg==', + 'assertion.encryption' => true, +]; + +// for test purposes, SP3 should be on the SPList entry of idp2 + +$metadata['http://ssp-sp3.local:8083'] = [ + 'AssertionConsumerService' => 'http://ssp-sp3.local:8083/module.php/saml/sp/saml2-acs.php/ssp-hub', + 'SingleLogoutService' => 'http://ssp-sp3.local:8083/module.php/saml/sp/saml2-logout.php/ssp-hub', + 'IDPList' => [ + 'http://ssp-idp1.local:8085', + 'http://ssp-idp2.local:8086', // overruled by Idp2 + 'http://ssp-idp3.local:8087' + ], + 'name' => 'SP3 (custom port)', + 'certData' => 'MIIDzzCCAregAwIBAgIJAPnOHgSgAeNrMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE3MTIyNzU2WhcNMjYxMDE3MTIyNzU2WjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0u+mXWS8vUkKjtJcK1hd0iGW2vbTvYosgyDdqClcSzwpbWJg1A1ChuiQIf7S+5bWL2AN4zMoem/JTn7cE9octqU34ZJAyP/cesppA9G53F9gH4XdoPgnWsb8vdWooDDUk+asc7ah/XwKixQNcELPDZkOba5+pqoKGjMxfL7JQ6+P6LB+xItzvLBXU4+onbGPIF6pmZ8S74mt0J62Y6ne40BHx8FdrtBgdk5TFcDedW09rRJrTFpi3hGSUkcjqj84B+oLAb08Z0SHoELMp5Yh7Tg5QZ2c+S8I47tQjV72rNhUYhIyFuImzSg27R7aRJ6Jj6sK4zEg0Ai4VhO4RmgyzwIDAQABo1AwTjAdBgNVHQ4EFgQUgkYcMbT0o8kmxAz2O3+p1lDVj1MwHwYDVR0jBBgwFoAUgkYcMbT0o8kmxAz2O3+p1lDVj1MwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEANgyTgMVRghgL8klqvZvQpfh80XDPTZotJCc8mZJZ98YkNC8jnR2RIUJpah+XrgotlKNDOK3HMNuyKGgYcqcno4PdDXKbqp4yXmywdNbbEHwPWDGqZXULw2az+UVwPUZJcJyJuwJjy3diCJT53N9G0LqXfeEsV0OPQPaB2PWgYNraBd59fckmBTc298HuvsHtxUcoXM53ms2Ck6GygGwH1vCg7qyIRRQFL4DiSlnoS8jxt3IIpZZs9FAl1ejtFBepSne9kEo7lLhAWY1TQqRrRXNHngG/L70ZkZonE9TNK/9xIHuaawqWkV6WLnkhT0DHCOw67GP97MWzceyFw+n9Vg==', + 'assertion.encryption' => true, +]; + +$metadata['http://ssp-sp3.local'] = [ + 'AssertionConsumerService' => 'http://ssp-sp3.local/module.php/saml/sp/saml2-acs.php/ssp-hub', + 'SingleLogoutService' => 'http://ssp-sp3.local/module.php/saml/sp/saml2-logout.php/ssp-hub', + 'IDPList' => [ + 'http://ssp-idp1.local', + 'http://ssp-idp2.local', // overruled by Idp2 + 'http://ssp-idp3.local' + ], + 'name' => 'SP3', + 'certData' => 'MIIDzzCCAregAwIBAgIJAPnOHgSgAeNrMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE3MTIyNzU2WhcNMjYxMDE3MTIyNzU2WjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0u+mXWS8vUkKjtJcK1hd0iGW2vbTvYosgyDdqClcSzwpbWJg1A1ChuiQIf7S+5bWL2AN4zMoem/JTn7cE9octqU34ZJAyP/cesppA9G53F9gH4XdoPgnWsb8vdWooDDUk+asc7ah/XwKixQNcELPDZkOba5+pqoKGjMxfL7JQ6+P6LB+xItzvLBXU4+onbGPIF6pmZ8S74mt0J62Y6ne40BHx8FdrtBgdk5TFcDedW09rRJrTFpi3hGSUkcjqj84B+oLAb08Z0SHoELMp5Yh7Tg5QZ2c+S8I47tQjV72rNhUYhIyFuImzSg27R7aRJ6Jj6sK4zEg0Ai4VhO4RmgyzwIDAQABo1AwTjAdBgNVHQ4EFgQUgkYcMbT0o8kmxAz2O3+p1lDVj1MwHwYDVR0jBBgwFoAUgkYcMbT0o8kmxAz2O3+p1lDVj1MwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEANgyTgMVRghgL8klqvZvQpfh80XDPTZotJCc8mZJZ98YkNC8jnR2RIUJpah+XrgotlKNDOK3HMNuyKGgYcqcno4PdDXKbqp4yXmywdNbbEHwPWDGqZXULw2az+UVwPUZJcJyJuwJjy3diCJT53N9G0LqXfeEsV0OPQPaB2PWgYNraBd59fckmBTc298HuvsHtxUcoXM53ms2Ck6GygGwH1vCg7qyIRRQFL4DiSlnoS8jxt3IIpZZs9FAl1ejtFBepSne9kEo7lLhAWY1TQqRrRXNHngG/L70ZkZonE9TNK/9xIHuaawqWkV6WLnkhT0DHCOw67GP97MWzceyFw+n9Vg==', + 'assertion.encryption' => true, +]; diff --git a/development/hub/metadata/sp-remote.php b/development/hub/metadata/sp-remote.php deleted file mode 100644 index 68f6974e..00000000 --- a/development/hub/metadata/sp-remote.php +++ /dev/null @@ -1,87 +0,0 @@ - [ - 'name' => "SP1 (custom port)", - 'AssertionConsumerService' => 'http://ssp-sp1.local:8081/module.php/saml/sp/saml2-acs.php/ssp-hub-custom-port', - 'SingleLogoutService' => 'http://ssp-sp1.local:8081/module.php/saml/sp/saml2-logout.php/ssp-hub-custom-port', - 'certData' => 'MIIDzzCCAregAwIBAgIJAPnOHgSgAeNrMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE3MTIyNzU2WhcNMjYxMDE3MTIyNzU2WjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0u+mXWS8vUkKjtJcK1hd0iGW2vbTvYosgyDdqClcSzwpbWJg1A1ChuiQIf7S+5bWL2AN4zMoem/JTn7cE9octqU34ZJAyP/cesppA9G53F9gH4XdoPgnWsb8vdWooDDUk+asc7ah/XwKixQNcELPDZkOba5+pqoKGjMxfL7JQ6+P6LB+xItzvLBXU4+onbGPIF6pmZ8S74mt0J62Y6ne40BHx8FdrtBgdk5TFcDedW09rRJrTFpi3hGSUkcjqj84B+oLAb08Z0SHoELMp5Yh7Tg5QZ2c+S8I47tQjV72rNhUYhIyFuImzSg27R7aRJ6Jj6sK4zEg0Ai4VhO4RmgyzwIDAQABo1AwTjAdBgNVHQ4EFgQUgkYcMbT0o8kmxAz2O3+p1lDVj1MwHwYDVR0jBBgwFoAUgkYcMbT0o8kmxAz2O3+p1lDVj1MwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEANgyTgMVRghgL8klqvZvQpfh80XDPTZotJCc8mZJZ98YkNC8jnR2RIUJpah+XrgotlKNDOK3HMNuyKGgYcqcno4PdDXKbqp4yXmywdNbbEHwPWDGqZXULw2az+UVwPUZJcJyJuwJjy3diCJT53N9G0LqXfeEsV0OPQPaB2PWgYNraBd59fckmBTc298HuvsHtxUcoXM53ms2Ck6GygGwH1vCg7qyIRRQFL4DiSlnoS8jxt3IIpZZs9FAl1ejtFBepSne9kEo7lLhAWY1TQqRrRXNHngG/L70ZkZonE9TNK/9xIHuaawqWkV6WLnkhT0DHCOw67GP97MWzceyFw+n9Vg==', - 'IDPList' => [ - 'http://ssp-idp1.local:8085', - 'http://ssp-idp2.local:8086', - 'http://ssp-idp3.local:8087', - ], - 'assertion.encryption' => true, - ], - - 'http://ssp-sp1.local' => [ - 'name' => "SP1", - 'AssertionConsumerService' => 'http://ssp-sp1.local/module.php/saml/sp/saml2-acs.php/ssp-hub', - 'SingleLogoutService' => 'http://ssp-sp1.local/module.php/saml/sp/saml2-logout.php/ssp-hub', - 'certData' => 'MIIDzzCCAregAwIBAgIJAPnOHgSgAeNrMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE3MTIyNzU2WhcNMjYxMDE3MTIyNzU2WjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0u+mXWS8vUkKjtJcK1hd0iGW2vbTvYosgyDdqClcSzwpbWJg1A1ChuiQIf7S+5bWL2AN4zMoem/JTn7cE9octqU34ZJAyP/cesppA9G53F9gH4XdoPgnWsb8vdWooDDUk+asc7ah/XwKixQNcELPDZkOba5+pqoKGjMxfL7JQ6+P6LB+xItzvLBXU4+onbGPIF6pmZ8S74mt0J62Y6ne40BHx8FdrtBgdk5TFcDedW09rRJrTFpi3hGSUkcjqj84B+oLAb08Z0SHoELMp5Yh7Tg5QZ2c+S8I47tQjV72rNhUYhIyFuImzSg27R7aRJ6Jj6sK4zEg0Ai4VhO4RmgyzwIDAQABo1AwTjAdBgNVHQ4EFgQUgkYcMbT0o8kmxAz2O3+p1lDVj1MwHwYDVR0jBBgwFoAUgkYcMbT0o8kmxAz2O3+p1lDVj1MwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEANgyTgMVRghgL8klqvZvQpfh80XDPTZotJCc8mZJZ98YkNC8jnR2RIUJpah+XrgotlKNDOK3HMNuyKGgYcqcno4PdDXKbqp4yXmywdNbbEHwPWDGqZXULw2az+UVwPUZJcJyJuwJjy3diCJT53N9G0LqXfeEsV0OPQPaB2PWgYNraBd59fckmBTc298HuvsHtxUcoXM53ms2Ck6GygGwH1vCg7qyIRRQFL4DiSlnoS8jxt3IIpZZs9FAl1ejtFBepSne9kEo7lLhAWY1TQqRrRXNHngG/L70ZkZonE9TNK/9xIHuaawqWkV6WLnkhT0DHCOw67GP97MWzceyFw+n9Vg==', - 'IDPList' => [ - 'http://ssp-idp1.local', - 'http://ssp-idp2.local', - 'http://ssp-idp3.local', - ], - 'assertion.encryption' => true, - ], - - 'http://ssp-sp2.local:8082' => [ - 'AssertionConsumerService' => 'http://ssp-sp2.local:8082/module.php/saml/sp/saml2-acs.php/ssp-hub-custom-port', - 'SingleLogoutService' => 'http://ssp-sp2.local:8082/module.php/saml/sp/saml2-logout.php/ssp-hub-custom-port', - 'IDPList' => [ - 'http://ssp-idp2.local:8086', - ], - 'name' => 'SP2 (custom port)', - 'certData' => 'MIIDzzCCAregAwIBAgIJAPnOHgSgAeNrMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE3MTIyNzU2WhcNMjYxMDE3MTIyNzU2WjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0u+mXWS8vUkKjtJcK1hd0iGW2vbTvYosgyDdqClcSzwpbWJg1A1ChuiQIf7S+5bWL2AN4zMoem/JTn7cE9octqU34ZJAyP/cesppA9G53F9gH4XdoPgnWsb8vdWooDDUk+asc7ah/XwKixQNcELPDZkOba5+pqoKGjMxfL7JQ6+P6LB+xItzvLBXU4+onbGPIF6pmZ8S74mt0J62Y6ne40BHx8FdrtBgdk5TFcDedW09rRJrTFpi3hGSUkcjqj84B+oLAb08Z0SHoELMp5Yh7Tg5QZ2c+S8I47tQjV72rNhUYhIyFuImzSg27R7aRJ6Jj6sK4zEg0Ai4VhO4RmgyzwIDAQABo1AwTjAdBgNVHQ4EFgQUgkYcMbT0o8kmxAz2O3+p1lDVj1MwHwYDVR0jBBgwFoAUgkYcMbT0o8kmxAz2O3+p1lDVj1MwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEANgyTgMVRghgL8klqvZvQpfh80XDPTZotJCc8mZJZ98YkNC8jnR2RIUJpah+XrgotlKNDOK3HMNuyKGgYcqcno4PdDXKbqp4yXmywdNbbEHwPWDGqZXULw2az+UVwPUZJcJyJuwJjy3diCJT53N9G0LqXfeEsV0OPQPaB2PWgYNraBd59fckmBTc298HuvsHtxUcoXM53ms2Ck6GygGwH1vCg7qyIRRQFL4DiSlnoS8jxt3IIpZZs9FAl1ejtFBepSne9kEo7lLhAWY1TQqRrRXNHngG/L70ZkZonE9TNK/9xIHuaawqWkV6WLnkhT0DHCOw67GP97MWzceyFw+n9Vg==', - 'assertion.encryption' => true, - ], - - 'http://ssp-sp2.local' => [ - 'AssertionConsumerService' => 'http://ssp-sp2.local/module.php/saml/sp/saml2-acs.php/ssp-hub', - 'SingleLogoutService' => 'http://ssp-sp2.local/module.php/saml/sp/saml2-logout.php/ssp-hub', - 'IDPList' => [ - 'http://ssp-idp2.local', - ], - 'name' => 'SP2', - 'certData' => 'MIIDzzCCAregAwIBAgIJAPnOHgSgAeNrMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE3MTIyNzU2WhcNMjYxMDE3MTIyNzU2WjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0u+mXWS8vUkKjtJcK1hd0iGW2vbTvYosgyDdqClcSzwpbWJg1A1ChuiQIf7S+5bWL2AN4zMoem/JTn7cE9octqU34ZJAyP/cesppA9G53F9gH4XdoPgnWsb8vdWooDDUk+asc7ah/XwKixQNcELPDZkOba5+pqoKGjMxfL7JQ6+P6LB+xItzvLBXU4+onbGPIF6pmZ8S74mt0J62Y6ne40BHx8FdrtBgdk5TFcDedW09rRJrTFpi3hGSUkcjqj84B+oLAb08Z0SHoELMp5Yh7Tg5QZ2c+S8I47tQjV72rNhUYhIyFuImzSg27R7aRJ6Jj6sK4zEg0Ai4VhO4RmgyzwIDAQABo1AwTjAdBgNVHQ4EFgQUgkYcMbT0o8kmxAz2O3+p1lDVj1MwHwYDVR0jBBgwFoAUgkYcMbT0o8kmxAz2O3+p1lDVj1MwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEANgyTgMVRghgL8klqvZvQpfh80XDPTZotJCc8mZJZ98YkNC8jnR2RIUJpah+XrgotlKNDOK3HMNuyKGgYcqcno4PdDXKbqp4yXmywdNbbEHwPWDGqZXULw2az+UVwPUZJcJyJuwJjy3diCJT53N9G0LqXfeEsV0OPQPaB2PWgYNraBd59fckmBTc298HuvsHtxUcoXM53ms2Ck6GygGwH1vCg7qyIRRQFL4DiSlnoS8jxt3IIpZZs9FAl1ejtFBepSne9kEo7lLhAWY1TQqRrRXNHngG/L70ZkZonE9TNK/9xIHuaawqWkV6WLnkhT0DHCOw67GP97MWzceyFw+n9Vg==', - 'assertion.encryption' => true, - ], - - // for test purposes, SP3 should be on the SPList entry of idp2 - - 'http://ssp-sp3.local:8083' => [ - 'AssertionConsumerService' => 'http://ssp-sp3.local:8083/module.php/saml/sp/saml2-acs.php/ssp-hub', - 'SingleLogoutService' => 'http://ssp-sp3.local:8083/module.php/saml/sp/saml2-logout.php/ssp-hub', - 'IDPList' => [ - 'http://ssp-idp1.local:8085', - 'http://ssp-idp2.local:8086', // overruled by Idp2 - 'http://ssp-idp3.local:8087' - ], - 'name' => 'SP3 (custom port)', - 'certData' => 'MIIDzzCCAregAwIBAgIJAPnOHgSgAeNrMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE3MTIyNzU2WhcNMjYxMDE3MTIyNzU2WjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0u+mXWS8vUkKjtJcK1hd0iGW2vbTvYosgyDdqClcSzwpbWJg1A1ChuiQIf7S+5bWL2AN4zMoem/JTn7cE9octqU34ZJAyP/cesppA9G53F9gH4XdoPgnWsb8vdWooDDUk+asc7ah/XwKixQNcELPDZkOba5+pqoKGjMxfL7JQ6+P6LB+xItzvLBXU4+onbGPIF6pmZ8S74mt0J62Y6ne40BHx8FdrtBgdk5TFcDedW09rRJrTFpi3hGSUkcjqj84B+oLAb08Z0SHoELMp5Yh7Tg5QZ2c+S8I47tQjV72rNhUYhIyFuImzSg27R7aRJ6Jj6sK4zEg0Ai4VhO4RmgyzwIDAQABo1AwTjAdBgNVHQ4EFgQUgkYcMbT0o8kmxAz2O3+p1lDVj1MwHwYDVR0jBBgwFoAUgkYcMbT0o8kmxAz2O3+p1lDVj1MwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEANgyTgMVRghgL8klqvZvQpfh80XDPTZotJCc8mZJZ98YkNC8jnR2RIUJpah+XrgotlKNDOK3HMNuyKGgYcqcno4PdDXKbqp4yXmywdNbbEHwPWDGqZXULw2az+UVwPUZJcJyJuwJjy3diCJT53N9G0LqXfeEsV0OPQPaB2PWgYNraBd59fckmBTc298HuvsHtxUcoXM53ms2Ck6GygGwH1vCg7qyIRRQFL4DiSlnoS8jxt3IIpZZs9FAl1ejtFBepSne9kEo7lLhAWY1TQqRrRXNHngG/L70ZkZonE9TNK/9xIHuaawqWkV6WLnkhT0DHCOw67GP97MWzceyFw+n9Vg==', - 'assertion.encryption' => true, - ], - - 'http://ssp-sp3.local' => [ - 'AssertionConsumerService' => 'http://ssp-sp3.local/module.php/saml/sp/saml2-acs.php/ssp-hub', - 'SingleLogoutService' => 'http://ssp-sp3.local/module.php/saml/sp/saml2-logout.php/ssp-hub', - 'IDPList' => [ - 'http://ssp-idp1.local', - 'http://ssp-idp2.local', // overruled by Idp2 - 'http://ssp-idp3.local' - ], - 'name' => 'SP3', - 'certData' => 'MIIDzzCCAregAwIBAgIJAPnOHgSgAeNrMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE3MTIyNzU2WhcNMjYxMDE3MTIyNzU2WjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0u+mXWS8vUkKjtJcK1hd0iGW2vbTvYosgyDdqClcSzwpbWJg1A1ChuiQIf7S+5bWL2AN4zMoem/JTn7cE9octqU34ZJAyP/cesppA9G53F9gH4XdoPgnWsb8vdWooDDUk+asc7ah/XwKixQNcELPDZkOba5+pqoKGjMxfL7JQ6+P6LB+xItzvLBXU4+onbGPIF6pmZ8S74mt0J62Y6ne40BHx8FdrtBgdk5TFcDedW09rRJrTFpi3hGSUkcjqj84B+oLAb08Z0SHoELMp5Yh7Tg5QZ2c+S8I47tQjV72rNhUYhIyFuImzSg27R7aRJ6Jj6sK4zEg0Ai4VhO4RmgyzwIDAQABo1AwTjAdBgNVHQ4EFgQUgkYcMbT0o8kmxAz2O3+p1lDVj1MwHwYDVR0jBBgwFoAUgkYcMbT0o8kmxAz2O3+p1lDVj1MwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEANgyTgMVRghgL8klqvZvQpfh80XDPTZotJCc8mZJZ98YkNC8jnR2RIUJpah+XrgotlKNDOK3HMNuyKGgYcqcno4PdDXKbqp4yXmywdNbbEHwPWDGqZXULw2az+UVwPUZJcJyJuwJjy3diCJT53N9G0LqXfeEsV0OPQPaB2PWgYNraBd59fckmBTc298HuvsHtxUcoXM53ms2Ck6GygGwH1vCg7qyIRRQFL4DiSlnoS8jxt3IIpZZs9FAl1ejtFBepSne9kEo7lLhAWY1TQqRrRXNHngG/L70ZkZonE9TNK/9xIHuaawqWkV6WLnkhT0DHCOw67GP97MWzceyFw+n9Vg==', - 'assertion.encryption' => true, - ], -]; diff --git a/development/idp-local/config/authsources.php b/development/idp-local/config/authsources.php index 2fb95e1b..dc785628 100644 --- a/development/idp-local/config/authsources.php +++ b/development/idp-local/config/authsources.php @@ -11,7 +11,7 @@ 'core:AdminPassword', ], - + // Set up example users for testing expirychecker module. 'example-userpass' => [ 'exampleauth:UserPass', @@ -448,6 +448,13 @@ 'last_used_utc' => null, 'data' => [ // Response from "POST /webauthn/login" MFA API call. + "id" => 88, + "label" => "My Webauthn Key", + "last_used_utc" => null, + "created_utc" => "2022-12-15 19:42:37", + "publicKey" => [ + "challenge" => "xxxxxxx", + ], ], ], ] diff --git a/development/idp-local/config/config.php b/development/idp-local/config/config.php deleted file mode 100644 index 1c87b7ee..00000000 --- a/development/idp-local/config/config.php +++ /dev/null @@ -1,1366 +0,0 @@ - SimpleSAML\Logger::ERR, // No statistics, only errors - 'WARNING' => SimpleSAML\Logger::WARNING, // No statistics, only warnings/errors - 'NOTICE' => SimpleSAML\Logger::NOTICE, // Statistics and errors - 'INFO' => SimpleSAML\Logger::INFO, // Verbose logs - 'DEBUG' => SimpleSAML\Logger::DEBUG, // Full debug logs - not recommended for production -]; - -try { - // Required to be defined in environment variables - $ADMIN_PASS = Env::requireEnv('ADMIN_PASS'); - $SECRET_SALT = Env::requireEnv('SECRET_SALT'); - $IDP_NAME = Env::requireEnv('IDP_NAME'); -} catch (EnvVarNotFoundException $e) { - - // Return error response code/message to HTTP request. - header('Content-Type: application/json'); - http_response_code(500); - $responseContent = json_encode([ - 'name' => 'Internal Server Error', - 'message' => $e->getMessage(), - 'status' => 500, - ]); - fwrite(fopen('php://stderr', 'w'), $responseContent . PHP_EOL); - exit($responseContent); -} - -// Defaults provided if not defined in environment -$IDP_DISPLAY_NAME = Env::get('IDP_DISPLAY_NAME', $IDP_NAME); -$BASE_URL_PATH = Env::get('BASE_URL_PATH', '/'); -$ADMIN_EMAIL = Env::get('ADMIN_EMAIL', 'na@example.org'); -$ADMIN_NAME = Env::get('ADMIN_NAME', 'SAML Admin'); -$ADMIN_PROTECT_INDEX_PAGE = Env::get('ADMIN_PROTECT_INDEX_PAGE', true); -$SHOW_SAML_ERRORS = Env::get('SHOW_SAML_ERRORS', false); -$ENABLE_DEBUG = Env::get('ENABLE_DEBUG', false); -$LOGGING_LEVEL = Env::get('LOGGING_LEVEL', 'NOTICE'); -$LOGGING_HANDLER = Env::get('LOGGING_HANDLER', 'stderr'); - -// Options: https://github.com/silinternational/simplesamlphp-module-material/blob/develop/README.md#branding -$THEME_COLOR_SCHEME = Env::get('THEME_COLOR_SCHEME', null); - -$SECURE_COOKIE = Env::get('SECURE_COOKIE', true); -$SESSION_DURATION = (int)(Env::get('SESSION_DURATION', (60 * 60 * 10))); // 10 hours. -$SESSION_STORE_TYPE = Env::get('SESSION_STORE_TYPE', 'phpsession'); -$MYSQL_HOST = Env::get('MYSQL_HOST', ''); -$MYSQL_DATABASE = Env::get('MYSQL_DATABASE', ''); -$MYSQL_USER = Env::get('MYSQL_USER', ''); -$MYSQL_PASSWORD = Env::get('MYSQL_PASSWORD', ''); - -$SAML20_IDP_ENABLE = Env::get('SAML20_IDP_ENABLE', true); -$HUB_MODE = Env::get('HUB_MODE', false); -$ANALYTICS_ID = Env::get('ANALYTICS_ID', null); -$PASSWORD_CHANGE_URL = Env::get('PASSWORD_CHANGE_URL'); -$PASSWORD_FORGOT_URL = Env::get('PASSWORD_FORGOT_URL'); -$HELP_CENTER_URL = Env::get('HELP_CENTER_URL'); - -$config = [ - - /* - * Whether this instance should act as a hub/proxy/bridge using sildisco - */ - 'hubmode' => $HUB_MODE, - - /* - * Name of this IdP - */ - 'idp_name' => $IDP_NAME, - - /* - * Name of this IdP to display to the user - */ - 'idp_display_name' => $IDP_DISPLAY_NAME, - - /* - * The tracking Id for Google Analytics or some other similar service - */ - 'analytics.trackingId' => $ANALYTICS_ID, - - 'passwordChangeUrl' => $PASSWORD_CHANGE_URL, - 'passwordForgotUrl' => $PASSWORD_FORGOT_URL, - 'helpCenterUrl' => $HELP_CENTER_URL, - - /******************************* - | BASIC CONFIGURATION OPTIONS | - *******************************/ - - /* - * Setup the following parameters to match your installation. - * See the user manual for more details. - */ - - /* - * baseurlpath is a *URL path* (not a filesystem path). - * A valid format for 'baseurlpath' is: - * [(http|https)://(hostname|fqdn)[:port]]/[path/to/simplesaml/] - * - * The full url format is useful if your SimpleSAMLphp setup is hosted behind - * a reverse proxy. In that case you can specify the external url here. - * - * Please note that SimpleSAMLphp will then redirect all queries to the - * external url, no matter where you come from (direct access or via the - * reverse proxy). - */ - 'baseurlpath' => $BASE_URL_PATH, - - /* - * The 'application' configuration array groups a set configuration options - * relative to an application protected by SimpleSAMLphp. - */ - //'application' => [ - /* - * The 'baseURL' configuration option allows you to specify a protocol, - * host and optionally a port that serves as the canonical base for all - * your application's URLs. This is useful when the environment - * observed in the server differs from the one observed by end users, - * for example, when using a load balancer to offload TLS. - * - * Note that this configuration option does not allow setting a path as - * part of the URL. If your setup involves URL rewriting or any other - * tricks that would result in SimpleSAMLphp observing a URL for your - * application's scripts different than the canonical one, you will - * need to compute the right URLs yourself and pass them dynamically - * to SimpleSAMLphp's API. - */ - //'baseURL' => 'https://example.com', - //], - - /* - * The following settings are *filesystem paths* which define where - * SimpleSAMLphp can find or write the following things: - * - 'certdir': The base directory for certificate and key material. - * - 'loggingdir': Where to write logs. - * - 'datadir': Storage of general data. - * - 'tempdir': Saving temporary files. SimpleSAMLphp will attempt to create - * this directory if it doesn't exist. - * When specified as a relative path, this is relative to the SimpleSAMLphp - * root directory. - */ - 'certdir' => 'cert/', - 'loggingdir' => 'log/', - 'datadir' => 'data/', - 'tempdir' => '/tmp/simplesaml', - - /* - * Some information about the technical persons running this installation. - * The email address will be used as the recipient address for error reports, and - * also as the technical contact in generated metadata. - */ - 'technicalcontact_name' => $ADMIN_NAME, - 'technicalcontact_email' => $ADMIN_EMAIL, - - /* - * (Optional) The method by which email is delivered. Defaults to mail which utilizes the - * PHP mail() function. - * - * Valid options are: mail, sendmail and smtp. - */ - //'mail.transport.method' => 'smtp', - - /* - * Set the transport options for the transport method specified. The valid settings are relative to the - * selected transport method. - */ - // // smtp mail transport options - // 'mail.transport.options' => [ - // 'host' => 'mail.example.org', // required - // 'port' => 25, // optional - // 'username' => 'user@example.org', // optional: if set, enables smtp authentication - // 'password' => 'password', // optional: if set, enables smtp authentication - // 'security' => 'tls', // optional: defaults to no smtp security - // ], - // // sendmail mail transport options - // 'mail.transport.options' => [ - // 'path' => '/usr/sbin/sendmail' // optional: defaults to php.ini path - // ], - - /* - * The envelope from address for outgoing emails. - * This should be in a domain that has your application's IP addresses in its SPF record - * to prevent it from being rejected by mail filters. - */ - //'sendmail_from' => 'no-reply@example.org', - - /* - * The timezone of the server. This option should be set to the timezone you want - * SimpleSAMLphp to report the time in. The default is to guess the timezone based - * on your system timezone. - * - * See this page for a list of valid timezones: http://php.net/manual/en/timezones.php - */ - 'timezone' => 'GMT', - - - - /********************************** - | SECURITY CONFIGURATION OPTIONS | - **********************************/ - - /* - * This is a secret salt used by SimpleSAMLphp when it needs to generate a secure hash - * of a value. It must be changed from its default value to a secret value. The value of - * 'secretsalt' can be any valid string of any length. - * - * A possible way to generate a random salt is by running the following command from a unix shell: - * LC_CTYPE=C tr -c -d '0123456789abcdefghijklmnopqrstuvwxyz' /dev/null;echo - */ - 'secretsalt' => $SECRET_SALT, - - /* - * This password must be kept secret, and modified from the default value 123. - * This password will give access to the installation page of SimpleSAMLphp with - * metadata listing and diagnostics pages. - * You can also put a hash here; run "bin/pwgen.php" to generate one. - */ - 'auth.adminpassword' => $ADMIN_PASS, - - /* - * Set this options to true if you want to require administrator password to access the web interface - * or the metadata pages, respectively. - */ - 'admin.protectindexpage' => $ADMIN_PROTECT_INDEX_PAGE, - 'admin.protectmetadata' => true, - - /* - * Set this option to false if you don't want SimpleSAMLphp to check for new stable releases when - * visiting the configuration tab in the web interface. - */ - 'admin.checkforupdates' => false, - - /* - * Array of domains that are allowed when generating links or redirects - * to URLs. SimpleSAMLphp will use this option to determine whether to - * to consider a given URL valid or not, but you should always validate - * URLs obtained from the input on your own (i.e. ReturnTo or RelayState - * parameters obtained from the $_REQUEST array). - * - * SimpleSAMLphp will automatically add your own domain (either by checking - * it dynamically, or by using the domain defined in the 'baseurlpath' - * directive, the latter having precedence) to the list of trusted domains, - * in case this option is NOT set to NULL. In that case, you are explicitly - * telling SimpleSAMLphp to verify URLs. - * - * Set to an empty array to disallow ALL redirects or links pointing to - * an external URL other than your own domain. This is the default behaviour. - * - * Set to NULL to disable checking of URLs. DO NOT DO THIS UNLESS YOU KNOW - * WHAT YOU ARE DOING! - * - * Example: - * 'trusted.url.domains' => ['sp.example.com', 'app.example.com'], - */ - 'trusted.url.domains' => null, - - /* - * Enable regular expression matching of trusted.url.domains. - * - * Set to true to treat the values in trusted.url.domains as regular - * expressions. Set to false to do exact string matching. - * - * If enabled, the start and end delimiters ('^' and '$') will be added to - * all regular expressions in trusted.url.domains. - */ - 'trusted.url.regex' => false, - - /* - * Enable secure POST from HTTPS to HTTP. - * - * If you have some SP's on HTTP and IdP is normally on HTTPS, this option - * enables secure POSTing to HTTP endpoint without warning from browser. - * - * For this to work, module.php/core/postredirect.php must be accessible - * also via HTTP on IdP, e.g. if your IdP is on - * https://idp.example.org/ssp/, then - * http://idp.example.org/ssp/module.php/core/postredirect.php must be accessible. - */ - 'enable.http_post' => false, - - /* - * Set the allowed clock skew between encrypting/decrypting assertions - * - * If you have an server that is constantly out of sync, this option - * allows you to adjust the allowed clock-skew. - * - * Allowed range: 180 - 300 - * Defaults to 180. - */ - 'assertion.allowed_clock_skew' => 180, - - - /************************ - | ERRORS AND DEBUGGING | - ************************/ - - /* - * The 'debug' option allows you to control how SimpleSAMLphp behaves in certain - * situations where further action may be taken - * - * It can be left unset, in which case, debugging is switched off for all actions. - * If set, it MUST be an array containing the actions that you want to enable, or - * alternatively a hashed array where the keys are the actions and their - * corresponding values are booleans enabling or disabling each particular action. - * - * SimpleSAMLphp provides some pre-defined actions, though modules could add new - * actions here. Refer to the documentation of every module to learn if they - * allow you to set any more debugging actions. - * - * The pre-defined actions are: - * - * - 'saml': this action controls the logging of SAML messages exchanged with other - * entities. When enabled ('saml' is present in this option, or set to true), all - * SAML messages will be logged, including plaintext versions of encrypted - * messages. - * - * - 'backtraces': this action controls the logging of error backtraces. If you - * want to log backtraces so that you can debug any possible errors happening in - * SimpleSAMLphp, enable this action (add it to the array or set it to true). - * - * - 'validatexml': this action allows you to validate SAML documents against all - * the relevant XML schemas. SAML 1.1 messages or SAML metadata parsed with - * the XML to SimpleSAMLphp metadata converter or the metaedit module will - * validate the SAML documents if this option is enabled. - * - * If you want to disable debugging completely, unset this option or set it to an - * empty array. - */ - 'debug' => [ - 'saml' => $ENABLE_DEBUG, - 'backtraces' => true, - 'validatexml' => $ENABLE_DEBUG, - ], - - /* - * When 'showerrors' is enabled, all error messages and stack traces will be output - * to the browser. - * - * When 'errorreporting' is enabled, a form will be presented for the user to report - * the error to 'technicalcontact_email'. - */ - 'showerrors' => $SHOW_SAML_ERRORS, - 'errorreporting' => false, - - /* - * Custom error show function called from SimpleSAML\Error\Error::show. - * See docs/simplesamlphp-errorhandling.txt for function code example. - * - * Example: - * 'errors.show_function' => ['SimpleSAML\Module\example\Error', 'show'], - */ - - - - /************************** - | LOGGING AND STATISTICS | - **************************/ - - /* - * Define the minimum log level to log. Available levels: - * - SimpleSAML\Logger::ERR No statistics, only errors - * - SimpleSAML\Logger::WARNING No statistics, only warnings/errors - * - SimpleSAML\Logger::NOTICE Statistics and errors - * - SimpleSAML\Logger::INFO Verbose logs - * - SimpleSAML\Logger::DEBUG Full debug logs - not recommended for production - * - * Choose logging handler. - * - * Options: [syslog,file,errorlog,stderr] - * - */ - 'logging.level' => $logLevels[$LOGGING_LEVEL], - 'logging.handler' => $LOGGING_HANDLER, - - /* - * Specify the format of the logs. Its use varies depending on the log handler used (for instance, you cannot - * control here how dates are displayed when using the syslog or errorlog handlers), but in general the options - * are: - * - * - %date{}: the date and time, with its format specified inside the brackets. See the PHP documentation - * of the strftime() function for more information on the format. If the brackets are omitted, the standard - * format is applied. This can be useful if you just want to control the placement of the date, but don't care - * about the format. - * - * - %process: the name of the SimpleSAMLphp process. Remember you can configure this in the 'logging.processname' - * option below. - * - * - %level: the log level (name or number depending on the handler used). - * - * - %stat: if the log entry is intended for statistical purposes, it will print the string 'STAT ' (bear in mind - * the trailing space). - * - * - %trackid: the track ID, an identifier that allows you to track a single session. - * - * - %srcip: the IP address of the client. If you are behind a proxy, make sure to modify the - * $_SERVER['REMOTE_ADDR'] variable on your code accordingly to the X-Forwarded-For header. - * - * - %msg: the message to be logged. - * - */ - //'logging.format' => '%date{%b %d %H:%M:%S} %process %level %stat[%trackid] %msg', - - /* - * Choose which facility should be used when logging with syslog. - * - * These can be used for filtering the syslog output from SimpleSAMLphp into its - * own file by configuring the syslog daemon. - * - * See the documentation for openlog (http://php.net/manual/en/function.openlog.php) for available - * facilities. Note that only LOG_USER is valid on windows. - * - * The default is to use LOG_LOCAL5 if available, and fall back to LOG_USER if not. - */ - 'logging.facility' => defined('LOG_LOCAL5') ? constant('LOG_LOCAL5') : LOG_USER, - - /* - * The process name that should be used when logging to syslog. - * The value is also written out by the other logging handlers. - */ - 'logging.processname' => 'simplesamlphp', - - /* - * Logging: file - Logfilename in the loggingdir from above. - */ - 'logging.logfile' => 'simplesamlphp.log', - - /* - * This is an array of outputs. Each output has at least a 'class' option, which - * selects the output. - */ - 'statistics.out' => [// Log statistics to the normal log. - /* - [ - 'class' => 'core:Log', - 'level' => 'notice', - ], - */ - // Log statistics to files in a directory. One file per day. - /* - [ - 'class' => 'core:File', - 'directory' => '/var/log/stats', - ], - */ - ], - - - - /*********************** - | PROXY CONFIGURATION | - ***********************/ - - /* - * Proxy to use for retrieving URLs. - * - * Example: - * 'proxy' => 'tcp://proxy.example.com:5100' - */ - 'proxy' => null, - - /* - * Username/password authentication to proxy (Proxy-Authorization: Basic) - * Example: - * 'proxy.auth' = 'myuser:password' - */ - //'proxy.auth' => 'myuser:password', - - - - /************************** - | DATABASE CONFIGURATION | - **************************/ - - /* - * This database configuration is optional. If you are not using - * core functionality or modules that require a database, you can - * skip this configuration. - */ - - /* - * Database connection string. - * Ensure that you have the required PDO database driver installed - * for your connection string. - */ - //'database.dsn' => 'mysql:host=localhost;dbname=saml', - - /* - * SQL database credentials - */ - //'database.username' => 'simplesamlphp', - //'database.password' => 'secret', - //'database.options' => [], - - /* - * (Optional) Table prefix - */ - //'database.prefix' => '', - - /* - * (Optional) Driver options - */ - //'database.driver_options' => [], - - /* - * True or false if you would like a persistent database connection - */ - //'database.persistent' => false, - - /* - * Database slave configuration is optional as well. If you are only - * running a single database server, leave this blank. If you have - * a master/slave configuration, you can define as many slave servers - * as you want here. Slaves will be picked at random to be queried from. - * - * Configuration options in the slave array are exactly the same as the - * options for the master (shown above) with the exception of the table - * prefix and driver options. - */ - //'database.slaves' => [ - // /* - // [ - // 'dsn' => 'mysql:host=myslave;dbname=saml', - // 'username' => 'simplesamlphp', - // 'password' => 'secret', - // 'persistent' => false, - // ], - // */ - //], - - - - /************* - | PROTOCOLS | - *************/ - - /* - * Which functionality in SimpleSAMLphp do you want to enable. Normally you would enable only - * one of the functionalities below, but in some cases you could run multiple functionalities. - * In example when you are setting up a federation bridge. - */ - 'enable.saml20-idp' => $SAML20_IDP_ENABLE, - 'enable.shib13-idp' => false, - 'enable.adfs-idp' => false, - - /* - * Whether SimpleSAMLphp should sign the response or the assertion in SAML 1.1 authentication - * responses. - * - * The default is to sign the assertion element, but that can be overridden by setting this - * option to TRUE. It can also be overridden on a pr. SP basis by adding an option with the - * same name to the metadata of the SP. - */ - 'shib13.signresponse' => true, - - - - /*********** - | MODULES | - ***********/ - - /* - * Configuration to override module enabling/disabling. - * - * Example: - * - * 'module.enable' => [ - * 'exampleauth' => true, // Setting to TRUE enables. - * 'consent' => false, // Setting to FALSE disables. - * 'core' => null, // Unset or NULL uses default. - * ], - * - */ - - 'module.enable' => [ - 'saml' => true, - 'core' => true, - 'admin' => true, - 'expirychecker' => true, - 'material' => true, - 'mfa' => true, - 'profilereview' => true, - 'silauth' => true, - 'sildisco' => true, - 'exampleauth' => true, - ], - - - - /************************* - | SESSION CONFIGURATION | - *************************/ - - /* - * This value is the duration of the session in seconds. Make sure that the time duration of - * cookies both at the SP and the IdP exceeds this duration. - */ - 'session.duration' => $SESSION_DURATION, - - /* - * Sets the duration, in seconds, data should be stored in the datastore. As the data store is used for - * login and logout requests, this option will control the maximum time these operations can take. - * The default is 4 hours (4*60*60) seconds, which should be more than enough for these operations. - */ - 'session.datastore.timeout' => $SESSION_DURATION, - - /* - * Sets the duration, in seconds, auth state should be stored. - */ - 'session.state.timeout' => $SESSION_DURATION, - - /* - * Option to override the default settings for the session cookie name - */ - 'session.cookie.name' => 'SSPSESSID', - - /* - * Expiration time for the session cookie, in seconds. - * - * Defaults to 0, which means that the cookie expires when the browser is closed. - * - * Example: - * 'session.cookie.lifetime' => 30*60, - */ - 'session.cookie.lifetime' => 0, - - /* - * Limit the path of the cookies. - * - * Can be used to limit the path of the cookies to a specific subdirectory. - * - * Example: - * 'session.cookie.path' => '/simplesaml/', - */ - 'session.cookie.path' => '/', - - /* - * Cookie domain. - * - * Can be used to make the session cookie available to several domains. - * - * Example: - * 'session.cookie.domain' => '.example.org', - */ - 'session.cookie.domain' => null, - - /* - * Set the secure flag in the cookie. - * - * Set this to TRUE if the user only accesses your service - * through https. If the user can access the service through - * both http and https, this must be set to FALSE. - */ - 'session.cookie.secure' => $SECURE_COOKIE, - - /* - * Set the SameSite attribute in the cookie. - * - * You can set this to the strings 'None', 'Lax', or 'Strict' to support - * the RFC6265bis SameSite cookie attribute. If set to null, no SameSite - * attribute will be sent. - * - * Example: - * 'session.cookie.samesite' => 'None', - */ - 'session.cookie.samesite' => null, - - /* - * Options to override the default settings for php sessions. - */ - 'session.phpsession.cookiename' => 'SimpleSAML', - 'session.phpsession.savepath' => null, - 'session.phpsession.httponly' => true, - - /* - * Option to override the default settings for the auth token cookie - */ - 'session.authtoken.cookiename' => 'SSPAUTHTOKEN', - - /* - * Options for remember me feature for IdP sessions. Remember me feature - * has to be also implemented in authentication source used. - * - * Option 'session.cookie.lifetime' should be set to zero (0), i.e. cookie - * expires on browser session if remember me is not checked. - * - * Session duration ('session.duration' option) should be set according to - * 'session.rememberme.lifetime' option. - * - * It's advised to use remember me feature with session checking function - * defined with 'session.check_function' option. - */ - 'session.rememberme.enable' => false, - 'session.rememberme.checked' => false, - 'session.rememberme.lifetime' => (14 * 86400), // 14 days - - /* - * Custom function for session checking called on session init and loading. - * See docs/simplesamlphp-advancedfeatures.txt for function code example. - * - * Example: - * 'session.check_function' => ['\SimpleSAML\Module\example\Util', 'checkSession'], - */ - - - - /************************** - | MEMCACHE CONFIGURATION | - **************************/ - - /* - * Configuration for the 'memcache' session store. This allows you to store - * multiple redundant copies of sessions on different memcache servers. - * - * 'memcache_store.servers' is an array of server groups. Every data - * item will be mirrored in every server group. - * - * Each server group is an array of servers. The data items will be - * load-balanced between all servers in each server group. - * - * Each server is an array of parameters for the server. The following - * options are available: - * - 'hostname': This is the hostname or ip address where the - * memcache server runs. This is the only required option. - * - 'port': This is the port number of the memcache server. If this - * option isn't set, then we will use the 'memcache.default_port' - * ini setting. This is 11211 by default. - * - * When using the "memcache" extension, the following options are also - * supported: - * - 'weight': This sets the weight of this server in this server - * group. http://php.net/manual/en/function.Memcache-addServer.php - * contains more information about the weight option. - * - 'timeout': The timeout for this server. By default, the timeout - * is 3 seconds. - * - * Example of redundant configuration with load balancing: - * This configuration makes it possible to lose both servers in the - * a-group or both servers in the b-group without losing any sessions. - * Note that sessions will be lost if one server is lost from both the - * a-group and the b-group. - * - * 'memcache_store.servers' => [ - * [ - * ['hostname' => 'mc_a1'], - * ['hostname' => 'mc_a2'], - * ], - * [ - * ['hostname' => 'mc_b1'], - * ['hostname' => 'mc_b2'], - * ], - * ], - * - * Example of simple configuration with only one memcache server, - * running on the same computer as the web server: - * Note that all sessions will be lost if the memcache server crashes. - * - * 'memcache_store.servers' => [ - * [ - * ['hostname' => 'localhost'], - * ], - * ], - * - * Additionally, when using the "memcached" extension, unique keys must - * be provided for each group of servers if persistent connections are - * desired. Each server group can also have an "options" indexed array - * with the options desired for the given group: - * - * 'memcache_store.servers' => [ - * 'memcache_group_1' => [ - * 'options' => [ - * \Memcached::OPT_BINARY_PROTOCOL => true, - * \Memcached::OPT_NO_BLOCK => true, - * \Memcached::OPT_TCP_NODELAY => true, - * \Memcached::OPT_LIBKETAMA_COMPATIBLE => true, - * ], - * ['hostname' => '127.0.0.1', 'port' => 11211], - * ['hostname' => '127.0.0.2', 'port' => 11211], - * ], - * - * 'memcache_group_2' => [ - * 'options' => [ - * \Memcached::OPT_BINARY_PROTOCOL => true, - * \Memcached::OPT_NO_BLOCK => true, - * \Memcached::OPT_TCP_NODELAY => true, - * \Memcached::OPT_LIBKETAMA_COMPATIBLE => true, - * ], - * ['hostname' => '127.0.0.3', 'port' => 11211], - * ['hostname' => '127.0.0.4', 'port' => 11211], - * ], - * ], - * - */ -// 'memcache_store.servers' => [ -// [ -// [ -// 'hostname' => 'localhost', -// ], -// ], -// ], - - /* - * This value allows you to set a prefix for memcache-keys. The default - * for this value is 'simpleSAMLphp', which is fine in most cases. - * - * When running multiple instances of SSP on the same host, and more - * than one instance is using memcache, you probably want to assign - * a unique value per instance to this setting to avoid data collision. - */ -// 'memcache_store.prefix' => '', - - /* - * This value is the duration data should be stored in memcache. Data - * will be dropped from the memcache servers when this time expires. - * The time will be reset every time the data is written to the - * memcache servers. - * - * This value should always be larger than the 'session.duration' - * option. Not doing this may result in the session being deleted from - * the memcache servers while it is still in use. - * - * Set this value to 0 if you don't want data to expire. - * - * Note: The oldest data will always be deleted if the memcache server - * runs out of storage space. - */ -// 'memcache_store.expires' => 36 * (60 * 60), // 36 hours. - - - - /************************************* - | LANGUAGE AND INTERNATIONALIZATION | - *************************************/ - - /* - * Language-related options. - */ - 'language' => [ - /* - * An array in the form 'language' => . - * - * Each key in the array is the ISO 639 two-letter code for a language, - * and its value is an array with a list of alternative languages that - * can be used if the given language is not available at some point. - * Each alternative language is also specified by its ISO 639 code. - * - * For example, for the "no" language code (Norwegian), we would have: - * - * 'priorities' => [ - * 'no' => ['nb', 'nn', 'en', 'se'], - * ... - * ], - * - * establishing that if a translation for the "no" language code is - * not available, we look for translations in "nb" (Norwegian Bokmål), - * and so on, in that order. - */ - 'priorities' => [ - 'no' => ['nb', 'nn', 'en', 'se'], - 'nb' => ['no', 'nn', 'en', 'se'], - 'nn' => ['no', 'nb', 'en', 'se'], - 'se' => ['nb', 'no', 'nn', 'en'], - 'nr' => ['zu', 'en'], - 'nd' => ['zu', 'en'], - ], - ], - - /* - * Languages available, RTL languages, and what language is the default. - */ - 'language.available' => [ - 'en', 'no', 'nn', 'se', 'da', 'de', 'sv', 'fi', 'es', 'ca', 'fr', 'it', 'nl', 'lb', - 'cs', 'sl', 'lt', 'hr', 'hu', 'pl', 'pt', 'pt-br', 'tr', 'ja', 'zh', 'zh-tw', 'ru', - 'et', 'he', 'id', 'sr', 'lv', 'ro', 'eu', 'el', 'af', 'zu', 'xh', - ], - 'language.rtl' => ['ar', 'dv', 'fa', 'ur', 'he'], - 'language.default' => 'en', - - /* - * Options to override the default settings for the language parameter - */ - 'language.parameter.name' => 'language', - 'language.parameter.setcookie' => true, - - /* - * Options to override the default settings for the language cookie - */ - 'language.cookie.name' => 'language', - 'language.cookie.domain' => null, - 'language.cookie.path' => '/', - 'language.cookie.secure' => false, - 'language.cookie.httponly' => false, - 'language.cookie.lifetime' => (60 * 60 * 24 * 900), - 'language.cookie.samesite' => null, - - /** - * Custom getLanguage function called from SimpleSAML\Locale\Language::getLanguage(). - * Function should return language code of one of the available languages or NULL. - * See SimpleSAML\Locale\Language::getLanguage() source code for more info. - * - * This option can be used to implement a custom function for determining - * the default language for the user. - * - * Example: - * 'language.get_language_function' => ['\SimpleSAML\Module\example\Template', 'getLanguage'], - */ - - /* - * Extra dictionary for attribute names. - * This can be used to define local attributes. - * - * The format of the parameter is a string with :. - * - * Specifying this option will cause us to look for modules//dictionaries/.definition.json - * The dictionary should look something like: - * - * { - * "firstattribute": { - * "en": "English name", - * "no": "Norwegian name" - * }, - * "secondattribute": { - * "en": "English name", - * "no": "Norwegian name" - * } - * } - * - * Note that all attribute names in the dictionary must in lowercase. - * - * Example: 'attributes.extradictionary' => 'ourmodule:ourattributes', - */ - 'attributes.extradictionary' => null, - - - - /************** - | APPEARANCE | - **************/ - - /* - * Which theme directory should be used? - */ - 'theme.use' => 'material:material', - - /* - * Set this option to the text you would like to appear at the header of each page. Set to false if you don't want - * any text to appear in the header. - */ - //'theme.header' => 'SimpleSAMLphp' - - /** - * A template controller, if any. - * - * Used to intercept certain parts of the template handling, while keeping away unwanted/unexpected hooks. Set - * the 'theme.controller' configuration option to a class that implements the - * \SimpleSAML\XHTML\TemplateControllerInterface interface to use it. - */ - //'theme.controller' => '', - - /* - * Templating options - * - * By default, twig templates are not cached. To turn on template caching: - * Set 'template.cache' to an absolute path pointing to a directory that - * SimpleSAMLphp has read and write permissions to. - */ - //'template.cache' => '', - - /* - * Set the 'template.auto_reload' to true if you would like SimpleSAMLphp to - * recompile the templates (when using the template cache) if the templates - * change. If you don't want to check the source templates for every request, - * set it to false. - */ - 'template.auto_reload' => false, - - /* - * Set this option to true to indicate that your installation of SimpleSAMLphp - * is running in a production environment. This will affect the way resources - * are used, offering an optimized version when running in production, and an - * easy-to-debug one when not. Set it to false when you are testing or - * developing the software, in which case a banner will be displayed to remind - * users that they're dealing with a non-production instance. - * - * Defaults to true. - */ - 'production' => true, - - /* - * SimpleSAMLphp modules can host static resources which are served through PHP. - * The serving of the resources can be configured through these settings. - */ - 'assets' => [ - /* - * These settings adjust the caching headers that are sent - * when serving static resources. - */ - 'caching' => [ - /* - * Amount of seconds before the resource should be fetched again - */ - 'max_age' => 86400, - /* - * Calculate a checksum of every file and send it to the browser - * This allows the browser to avoid downloading assets again in situations - * where the Last-Modified header cannot be trusted, - * for example in cluster setups - * - * Defaults false - */ - 'etag' => false, - ], - ], - - /* - * If using the material theme, which color scheme to use - * Options: https://github.com/silinternational/simplesamlphp-module-material/blob/develop/README.md#branding - */ - 'theme.color-scheme' => $THEME_COLOR_SCHEME, - - - - /********************* - | DISCOVERY SERVICE | - *********************/ - - /* - * Whether the discovery service should allow the user to save his choice of IdP. - */ - 'idpdisco.enableremember' => true, - 'idpdisco.rememberchecked' => true, - - /* - * The disco service only accepts entities it knows. - */ - 'idpdisco.validate' => true, - - 'idpdisco.extDiscoveryStorage' => null, - - /* - * IdP Discovery service look configuration. - * Wether to display a list of idp or to display a dropdown box. For many IdP' a dropdown box - * gives the best use experience. - * - * When using dropdown box a cookie is used to highlight the previously chosen IdP in the dropdown. - * This makes it easier for the user to choose the IdP - * - * Options: [links,dropdown] - */ - 'idpdisco.layout' => 'links', - - - /************************************* - | AUTHENTICATION PROCESSING FILTERS | - *************************************/ - - /* - * Authentication processing filters that will be executed for all IdPs - * Both Shibboleth and SAML 2.0 - */ - 'authproc.idp' => [ - /* 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', - */ - - // Adopts language from attribute to use in UI - 30 => 'core:LanguageAdaptor', - - 35 => [ - 'class' => 'core:StatisticsWithAttribute', - 'attributename' => 'realm', - 'type' => 'saml20-idp-SSO', - ], - - /* - * Copy friendly names attribute keys to oids ... - */ - 40 => [ - 'class' => 'core:AttributeMap', - 'name2oid', - '%duplicate', - ], - - /* - * Copy oid attribute keys to friendly names - */ - 41 => [ - 'class' => 'core:AttributeMap', - 'oid2name', - '%duplicate', - ], - - // 48 => *** WARNING: For Hubs this entry is added at the end of this file - - - // If no attributes are requested in the SP metadata, then these will be sent through - 50 => [ - 'class' => 'core:AttributeLimit', - 'default' => true, - 'cn', - 'eduPersonPrincipalName', - 'eduPersonTargetID', - 'sn', - 'givenName', - 'mail', - 'employeeNumber', - 'urn:oid:2.5.4.3', // cn - 'urn:oid:1.3.6.1.4.1.5923.1.1.1.6', // eduPersonPrincipalName - 'urn:oid:1.3.6.1.4.1.5923.1.1.1.10', // eduPersonTargetID - 'urn:oid:2.5.4.4', // sn - 'urn:oid:2.5.4.42', // givenName - 'urn:oid:0.9.2342.19200300.100.1.3', // mail - 'urn:oid:2.16.840.1.113730.3.1.3', // employeeNumber - ], - - // Use the uid value to populate the nameid entry - // 60 => [ - // 'class' => 'saml:AttributeNameID', - // 'attribute' => 'uid', - // 'Format' => 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent', - // ], - - /* - * Search attribute "distinguishedName" for pattern and replaces if found - */ - /* - 70 => [ - 'class' => 'core:AttributeAlter', - 'pattern' => '/OU=studerende/', - 'replacement' => 'Student', - 'subject' => 'distinguishedName', - '%replace', - ], - */ - - /* - * Consent module is enabled (with no permanent storage, using cookies). - */ - /* - 90 => [ - 'class' => 'consent:Consent', - 'store' => 'consent:Cookie', - 'focus' => 'yes', - 'checked' => true - ], - */ - // If language is set in Consent module it will be added as an attribute. - 99 => 'core:LanguageAdaptor', - ], - - /* - * Authentication processing filters that will be executed for all SPs - * Both Shibboleth and SAML 2.0 - */ - 'authproc.sp' => [ - /* - 10 => [ - 'class' => 'core:AttributeMap', 'removeurnprefix' - ], - */ - - /* - * Generate the 'group' attribute populated from other variables, including eduPersonAffiliation. - 60 => [ - 'class' => 'core:GenerateGroups', 'eduPersonAffiliation' - ], - */ - /* - * All users will be members of 'users' and 'members' - */ - /* - 61 => [ - 'class' => 'core:AttributeAdd', 'groups' => ['users', 'members'] - ], - */ - - // Adopts language from attribute to use in UI - 90 => 'core:LanguageAdaptor', - ], - - - - /************************** - | METADATA CONFIGURATION | - **************************/ - - /* - * 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', - - /* - * This option configures the metadata sources. The metadata sources is given as an array with - * different metadata sources. When searching for metadata, SimpleSAMLphp will search through - * the array from start to end. - * - * Each element in the array is an associative array which configures the metadata source. - * The type of the metadata source is given by the 'type' element. For each type we have - * different configuration options. - * - * Flat file metadata handler: - * - 'type': This is always 'flatfile'. - * - 'directory': The directory we will load the metadata files from. The default value for - * this option is the value of the 'metadatadir' configuration option, or - * 'metadata/' if that option is unset. - * - * XML metadata handler: - * This metadata handler parses an XML file with either an EntityDescriptor element or an - * EntitiesDescriptor element. The XML file may be stored locally, or (for debugging) on a remote - * web server. - * The XML metadata handler defines the following options: - * - 'type': This is always 'xml'. - * - 'file': Path to the XML file with the metadata. - * - 'url': The URL to fetch metadata from. THIS IS ONLY FOR DEBUGGING - THERE IS NO CACHING OF THE RESPONSE. - * - * MDQ metadata handler: - * This metadata handler looks up for the metadata of an entity at the given MDQ server. - * The MDQ metadata handler defines the following options: - * - 'type': This is always 'mdq'. - * - 'server': Base URL of the MDQ server. Mandatory. - * - 'validateFingerprint': The fingerprint of the certificate used to sign the metadata. You don't need this - * option if you don't want to validate the signature on the metadata. Optional. - * - 'cachedir': Directory where metadata can be cached. Optional. - * - 'cachelength': Maximum time metadata can be cached, in seconds. Defaults to 24 - * hours (86400 seconds). Optional. - * - * PDO metadata handler: - * This metadata handler looks up metadata of an entity stored in a database. - * - * Note: If you are using the PDO metadata handler, you must configure the database - * options in this configuration file. - * - * The PDO metadata handler defines the following options: - * - 'type': This is always 'pdo'. - * - * Examples: - * - * This example defines two flatfile sources. One is the default metadata directory, the other - * is a metadata directory with auto-generated metadata files. - * - * 'metadata.sources' => [ - * ['type' => 'flatfile'], - * ['type' => 'flatfile', 'directory' => 'metadata-generated'], - * ], - * - * This example defines a flatfile source and an XML source. - * 'metadata.sources' => [ - * ['type' => 'flatfile'], - * ['type' => 'xml', 'file' => 'idp.example.org-idpMeta.xml'], - * ], - * - * This example defines an mdq source. - * 'metadata.sources' => [ - * [ - * 'type' => 'mdq', - * 'server' => 'http://mdq.server.com:8080', - * 'cachedir' => '/var/simplesamlphp/mdq-cache', - * 'cachelength' => 86400 - * ] - * ], - * - * This example defines an pdo source. - * 'metadata.sources' => [ - * ['type' => 'pdo'] - * ], - * - * Default: - * 'metadata.sources' => [ - * ['type' => 'flatfile'] - * ], - */ - 'metadata.sources' => [ - ['type' => 'flatfile'], - ], - - /* - * Should signing of generated metadata be enabled by default. - * - * Metadata signing can also be enabled for a individual SP or IdP by setting the - * same option in the metadata for the SP or IdP. - */ - 'metadata.sign.enable' => true, - - /* - * The default key & certificate which should be used to sign generated metadata. These - * are files stored in the cert dir. - * These values can be overridden by the options with the same names in the SP or - * IdP metadata. - * - * If these aren't specified here or in the metadata for the SP or IdP, then - * the 'certificate' and 'privatekey' option in the metadata will be used. - * if those aren't set, signing of metadata will fail. - */ - 'metadata.sign.privatekey' => 'saml.pem', - 'metadata.sign.privatekey_pass' => null, - 'metadata.sign.certificate' => 'saml.crt', - - - /**************************** - | DATA STORE CONFIGURATION | - ****************************/ - - /* - * Configure the data store for SimpleSAMLphp. - * - * - 'phpsession': Limited datastore, which uses the PHP session. - * - 'memcache': Key-value datastore, based on memcache. - * - 'sql': SQL datastore, using PDO. - * - 'redis': Key-value datastore, based on redis. - * - * The default datastore is 'phpsession'. - */ - 'store.type' => $SESSION_STORE_TYPE, - - /* - * The DSN the sql datastore should connect to. - * - * See http://www.php.net/manual/en/pdo.drivers.php for the various - * syntaxes. - */ - 'store.sql.dsn' => sprintf('mysql:host=%s;dbname=%s', $MYSQL_HOST, $MYSQL_DATABASE), - - /* - * The username and password to use when connecting to the database. - */ - 'store.sql.username' => $MYSQL_USER, - 'store.sql.password' => $MYSQL_PASSWORD, - - /* - * The prefix we should use on our tables. - */ - //'store.sql.prefix' => 'SimpleSAMLphp', - - /* - * The hostname and port of the Redis datastore instance. - */ - //'store.redis.host' => 'localhost', - //'store.redis.port' => 6379, - - /* - * The prefix we should use on our Redis datastore. - */ - //'store.redis.prefix' => 'SimpleSAMLphp', -]; - -if ($HUB_MODE) { - // prefix the 'member' (urn:oid:2.5.4.31) attribute elements with idp.idp_name. - $config['authproc.idp'][48] = 'sildisco:TagGroup'; - $config['authproc.idp'][49] = 'sildisco:AddIdp2NameId'; -} diff --git a/development/idp-local/metadata/saml20-idp-hosted.php b/development/idp-local/metadata/saml20-idp-hosted.php index 323fec43..8bfbdd1e 100644 --- a/development/idp-local/metadata/saml20-idp-hosted.php +++ b/development/idp-local/metadata/saml20-idp-hosted.php @@ -13,23 +13,23 @@ use Sil\SspBase\Features\fakes\FakeIdBrokerClient; $metadata['http://ssp-idp1.local:8085'] = [ - /* - * The hostname of the server (VHOST) that will use this SAML entity. - * - * Can be '__DEFAULT__', to use this entry by default. - */ - 'host' => '__DEFAULT__', + /* + * The hostname of the server (VHOST) that will use this SAML entity. + * + * Can be '__DEFAULT__', to use this entry by default. + */ + 'host' => '__DEFAULT__', + + // X.509 key and certificate. Relative to the cert directory. + 'privatekey' => 'ssp-hub-idp.pem', + 'certificate' => 'ssp-hub-idp.crt', - // X.509 key and certificate. Relative to the cert directory. - 'privatekey' => 'ssp-hub-idp.pem', - 'certificate' => 'ssp-hub-idp.crt', - 'logoURL' => 'https://dummyimage.com/125x125/0f4fbd/ffffff.png&text=IDP+1+8085', - /* - * Authentication source to use. Must be one that is configured in - * 'config/authsources.php'. - */ + /* + * Authentication source to use. Must be one that is configured in + * 'config/authsources.php'. + */ 'auth' => 'example-userpass', 'authproc' => [ diff --git a/development/idp-local/metadata/saml20-sp-remote.php b/development/idp-local/metadata/saml20-sp-remote.php index ad92fd8b..98114854 100644 --- a/development/idp-local/metadata/saml20-sp-remote.php +++ b/development/idp-local/metadata/saml20-sp-remote.php @@ -10,7 +10,7 @@ */ $metadata['ssp-hub.local'] = [ 'NameIDFormat' => 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent', - 'AssertionConsumerService' => 'http://ssp-hub.local/module.php/sildisco/sp/saml2-acs.php/hub-discovery', - 'SingleLogoutService' => 'http://ssp-hub.local/module.php/sildisco/sp/saml2-logout.php/hub-discovery', + 'AssertionConsumerService' => 'http://ssp-hub.local/module.php/saml/sp/saml2-acs.php/hub-discovery', + 'SingleLogoutService' => 'http://ssp-hub.local/module.php/saml/sp/saml2-logout.php/hub-discovery', 'certData' => 'MIIDzzCCAregAwIBAgIJANuvVcQPANecMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE3MTIzMTEyWhcNMjYxMDE3MTIzMTEyWjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxAimEkw4Teyf/gZelL7OuQYg/JbDIKHPXJhLPBm/HK6pM5ZZKydVXTdMgMqkl4xK+xZ2CnkozsUiMLhAuWBsX9Dcz1M4SkPRwk4puFhXzsp7fKIVP43zUhF7p2TmbernrrIQHjg6PuegKmCGyiKUpukcYvf2RXNwHwJx+Uq0zLP4PgBSrQ2t1eKZ1jQ+noBb1NqOuy969WRYmN4EmjXDuJB9d+b3GwtbZToWgiFxFjd/NN9BFJXZEaLzRj5LAq5bu2vPPDZDarHFMRUzVJ91eafoaz6zpR1iUGj9zR+y2sUPxD/fJMZ+4AHWA2LOrTBBIuuWbp96yvcJ4WjmlfhcFQIDAQABo1AwTjAdBgNVHQ4EFgQUkJFAMJdr2lXsuezS6pDXHnmJspMwHwYDVR0jBBgwFoAUkJFAMJdr2lXsuezS6pDXHnmJspMwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAOEPbchaUr45L5i+ueookevsABYnltwJZ4rYJbF9VURPcEhB6JxTMZqb4s113ftHvVYfoAfLYZ9swETaHL+esx41yAebf0kWpQ3f63S5F2FcrTj+HP0XsvW/EDrvaTKM9jnKPNmbXrpq06eaUZfkVL0TAUsxYTKkttTSTiESEzp5wzYyhp7l3kpHhEvGOlh5suYjnZ2HN0uxscCR6PS47H6TMMEZuG032DWDC016/JniWvERtpf4Yw26V+I9xevp2E2MPcZne31Pe3sCh4Wpe4cV/SCFqZHlpnH96ncz4F+KvmmhbEx5VPhQSJNFIWEvI86k+lTNQOqj6YVvGvq95LQ==', ]; diff --git a/development/idp2-local/config/authsources.php b/development/idp2-local/config/authsources.php index 197f61b1..6195508b 100644 --- a/development/idp2-local/config/authsources.php +++ b/development/idp2-local/config/authsources.php @@ -1,5 +1,7 @@ ConfigManager::getSspConfig(), + 'example-userpass' => [ 'exampleauth:UserPass', diff --git a/development/idp2-local/config/config.php b/development/idp2-local/config/config.php deleted file mode 100644 index 1c87b7ee..00000000 --- a/development/idp2-local/config/config.php +++ /dev/null @@ -1,1366 +0,0 @@ - SimpleSAML\Logger::ERR, // No statistics, only errors - 'WARNING' => SimpleSAML\Logger::WARNING, // No statistics, only warnings/errors - 'NOTICE' => SimpleSAML\Logger::NOTICE, // Statistics and errors - 'INFO' => SimpleSAML\Logger::INFO, // Verbose logs - 'DEBUG' => SimpleSAML\Logger::DEBUG, // Full debug logs - not recommended for production -]; - -try { - // Required to be defined in environment variables - $ADMIN_PASS = Env::requireEnv('ADMIN_PASS'); - $SECRET_SALT = Env::requireEnv('SECRET_SALT'); - $IDP_NAME = Env::requireEnv('IDP_NAME'); -} catch (EnvVarNotFoundException $e) { - - // Return error response code/message to HTTP request. - header('Content-Type: application/json'); - http_response_code(500); - $responseContent = json_encode([ - 'name' => 'Internal Server Error', - 'message' => $e->getMessage(), - 'status' => 500, - ]); - fwrite(fopen('php://stderr', 'w'), $responseContent . PHP_EOL); - exit($responseContent); -} - -// Defaults provided if not defined in environment -$IDP_DISPLAY_NAME = Env::get('IDP_DISPLAY_NAME', $IDP_NAME); -$BASE_URL_PATH = Env::get('BASE_URL_PATH', '/'); -$ADMIN_EMAIL = Env::get('ADMIN_EMAIL', 'na@example.org'); -$ADMIN_NAME = Env::get('ADMIN_NAME', 'SAML Admin'); -$ADMIN_PROTECT_INDEX_PAGE = Env::get('ADMIN_PROTECT_INDEX_PAGE', true); -$SHOW_SAML_ERRORS = Env::get('SHOW_SAML_ERRORS', false); -$ENABLE_DEBUG = Env::get('ENABLE_DEBUG', false); -$LOGGING_LEVEL = Env::get('LOGGING_LEVEL', 'NOTICE'); -$LOGGING_HANDLER = Env::get('LOGGING_HANDLER', 'stderr'); - -// Options: https://github.com/silinternational/simplesamlphp-module-material/blob/develop/README.md#branding -$THEME_COLOR_SCHEME = Env::get('THEME_COLOR_SCHEME', null); - -$SECURE_COOKIE = Env::get('SECURE_COOKIE', true); -$SESSION_DURATION = (int)(Env::get('SESSION_DURATION', (60 * 60 * 10))); // 10 hours. -$SESSION_STORE_TYPE = Env::get('SESSION_STORE_TYPE', 'phpsession'); -$MYSQL_HOST = Env::get('MYSQL_HOST', ''); -$MYSQL_DATABASE = Env::get('MYSQL_DATABASE', ''); -$MYSQL_USER = Env::get('MYSQL_USER', ''); -$MYSQL_PASSWORD = Env::get('MYSQL_PASSWORD', ''); - -$SAML20_IDP_ENABLE = Env::get('SAML20_IDP_ENABLE', true); -$HUB_MODE = Env::get('HUB_MODE', false); -$ANALYTICS_ID = Env::get('ANALYTICS_ID', null); -$PASSWORD_CHANGE_URL = Env::get('PASSWORD_CHANGE_URL'); -$PASSWORD_FORGOT_URL = Env::get('PASSWORD_FORGOT_URL'); -$HELP_CENTER_URL = Env::get('HELP_CENTER_URL'); - -$config = [ - - /* - * Whether this instance should act as a hub/proxy/bridge using sildisco - */ - 'hubmode' => $HUB_MODE, - - /* - * Name of this IdP - */ - 'idp_name' => $IDP_NAME, - - /* - * Name of this IdP to display to the user - */ - 'idp_display_name' => $IDP_DISPLAY_NAME, - - /* - * The tracking Id for Google Analytics or some other similar service - */ - 'analytics.trackingId' => $ANALYTICS_ID, - - 'passwordChangeUrl' => $PASSWORD_CHANGE_URL, - 'passwordForgotUrl' => $PASSWORD_FORGOT_URL, - 'helpCenterUrl' => $HELP_CENTER_URL, - - /******************************* - | BASIC CONFIGURATION OPTIONS | - *******************************/ - - /* - * Setup the following parameters to match your installation. - * See the user manual for more details. - */ - - /* - * baseurlpath is a *URL path* (not a filesystem path). - * A valid format for 'baseurlpath' is: - * [(http|https)://(hostname|fqdn)[:port]]/[path/to/simplesaml/] - * - * The full url format is useful if your SimpleSAMLphp setup is hosted behind - * a reverse proxy. In that case you can specify the external url here. - * - * Please note that SimpleSAMLphp will then redirect all queries to the - * external url, no matter where you come from (direct access or via the - * reverse proxy). - */ - 'baseurlpath' => $BASE_URL_PATH, - - /* - * The 'application' configuration array groups a set configuration options - * relative to an application protected by SimpleSAMLphp. - */ - //'application' => [ - /* - * The 'baseURL' configuration option allows you to specify a protocol, - * host and optionally a port that serves as the canonical base for all - * your application's URLs. This is useful when the environment - * observed in the server differs from the one observed by end users, - * for example, when using a load balancer to offload TLS. - * - * Note that this configuration option does not allow setting a path as - * part of the URL. If your setup involves URL rewriting or any other - * tricks that would result in SimpleSAMLphp observing a URL for your - * application's scripts different than the canonical one, you will - * need to compute the right URLs yourself and pass them dynamically - * to SimpleSAMLphp's API. - */ - //'baseURL' => 'https://example.com', - //], - - /* - * The following settings are *filesystem paths* which define where - * SimpleSAMLphp can find or write the following things: - * - 'certdir': The base directory for certificate and key material. - * - 'loggingdir': Where to write logs. - * - 'datadir': Storage of general data. - * - 'tempdir': Saving temporary files. SimpleSAMLphp will attempt to create - * this directory if it doesn't exist. - * When specified as a relative path, this is relative to the SimpleSAMLphp - * root directory. - */ - 'certdir' => 'cert/', - 'loggingdir' => 'log/', - 'datadir' => 'data/', - 'tempdir' => '/tmp/simplesaml', - - /* - * Some information about the technical persons running this installation. - * The email address will be used as the recipient address for error reports, and - * also as the technical contact in generated metadata. - */ - 'technicalcontact_name' => $ADMIN_NAME, - 'technicalcontact_email' => $ADMIN_EMAIL, - - /* - * (Optional) The method by which email is delivered. Defaults to mail which utilizes the - * PHP mail() function. - * - * Valid options are: mail, sendmail and smtp. - */ - //'mail.transport.method' => 'smtp', - - /* - * Set the transport options for the transport method specified. The valid settings are relative to the - * selected transport method. - */ - // // smtp mail transport options - // 'mail.transport.options' => [ - // 'host' => 'mail.example.org', // required - // 'port' => 25, // optional - // 'username' => 'user@example.org', // optional: if set, enables smtp authentication - // 'password' => 'password', // optional: if set, enables smtp authentication - // 'security' => 'tls', // optional: defaults to no smtp security - // ], - // // sendmail mail transport options - // 'mail.transport.options' => [ - // 'path' => '/usr/sbin/sendmail' // optional: defaults to php.ini path - // ], - - /* - * The envelope from address for outgoing emails. - * This should be in a domain that has your application's IP addresses in its SPF record - * to prevent it from being rejected by mail filters. - */ - //'sendmail_from' => 'no-reply@example.org', - - /* - * The timezone of the server. This option should be set to the timezone you want - * SimpleSAMLphp to report the time in. The default is to guess the timezone based - * on your system timezone. - * - * See this page for a list of valid timezones: http://php.net/manual/en/timezones.php - */ - 'timezone' => 'GMT', - - - - /********************************** - | SECURITY CONFIGURATION OPTIONS | - **********************************/ - - /* - * This is a secret salt used by SimpleSAMLphp when it needs to generate a secure hash - * of a value. It must be changed from its default value to a secret value. The value of - * 'secretsalt' can be any valid string of any length. - * - * A possible way to generate a random salt is by running the following command from a unix shell: - * LC_CTYPE=C tr -c -d '0123456789abcdefghijklmnopqrstuvwxyz' /dev/null;echo - */ - 'secretsalt' => $SECRET_SALT, - - /* - * This password must be kept secret, and modified from the default value 123. - * This password will give access to the installation page of SimpleSAMLphp with - * metadata listing and diagnostics pages. - * You can also put a hash here; run "bin/pwgen.php" to generate one. - */ - 'auth.adminpassword' => $ADMIN_PASS, - - /* - * Set this options to true if you want to require administrator password to access the web interface - * or the metadata pages, respectively. - */ - 'admin.protectindexpage' => $ADMIN_PROTECT_INDEX_PAGE, - 'admin.protectmetadata' => true, - - /* - * Set this option to false if you don't want SimpleSAMLphp to check for new stable releases when - * visiting the configuration tab in the web interface. - */ - 'admin.checkforupdates' => false, - - /* - * Array of domains that are allowed when generating links or redirects - * to URLs. SimpleSAMLphp will use this option to determine whether to - * to consider a given URL valid or not, but you should always validate - * URLs obtained from the input on your own (i.e. ReturnTo or RelayState - * parameters obtained from the $_REQUEST array). - * - * SimpleSAMLphp will automatically add your own domain (either by checking - * it dynamically, or by using the domain defined in the 'baseurlpath' - * directive, the latter having precedence) to the list of trusted domains, - * in case this option is NOT set to NULL. In that case, you are explicitly - * telling SimpleSAMLphp to verify URLs. - * - * Set to an empty array to disallow ALL redirects or links pointing to - * an external URL other than your own domain. This is the default behaviour. - * - * Set to NULL to disable checking of URLs. DO NOT DO THIS UNLESS YOU KNOW - * WHAT YOU ARE DOING! - * - * Example: - * 'trusted.url.domains' => ['sp.example.com', 'app.example.com'], - */ - 'trusted.url.domains' => null, - - /* - * Enable regular expression matching of trusted.url.domains. - * - * Set to true to treat the values in trusted.url.domains as regular - * expressions. Set to false to do exact string matching. - * - * If enabled, the start and end delimiters ('^' and '$') will be added to - * all regular expressions in trusted.url.domains. - */ - 'trusted.url.regex' => false, - - /* - * Enable secure POST from HTTPS to HTTP. - * - * If you have some SP's on HTTP and IdP is normally on HTTPS, this option - * enables secure POSTing to HTTP endpoint without warning from browser. - * - * For this to work, module.php/core/postredirect.php must be accessible - * also via HTTP on IdP, e.g. if your IdP is on - * https://idp.example.org/ssp/, then - * http://idp.example.org/ssp/module.php/core/postredirect.php must be accessible. - */ - 'enable.http_post' => false, - - /* - * Set the allowed clock skew between encrypting/decrypting assertions - * - * If you have an server that is constantly out of sync, this option - * allows you to adjust the allowed clock-skew. - * - * Allowed range: 180 - 300 - * Defaults to 180. - */ - 'assertion.allowed_clock_skew' => 180, - - - /************************ - | ERRORS AND DEBUGGING | - ************************/ - - /* - * The 'debug' option allows you to control how SimpleSAMLphp behaves in certain - * situations where further action may be taken - * - * It can be left unset, in which case, debugging is switched off for all actions. - * If set, it MUST be an array containing the actions that you want to enable, or - * alternatively a hashed array where the keys are the actions and their - * corresponding values are booleans enabling or disabling each particular action. - * - * SimpleSAMLphp provides some pre-defined actions, though modules could add new - * actions here. Refer to the documentation of every module to learn if they - * allow you to set any more debugging actions. - * - * The pre-defined actions are: - * - * - 'saml': this action controls the logging of SAML messages exchanged with other - * entities. When enabled ('saml' is present in this option, or set to true), all - * SAML messages will be logged, including plaintext versions of encrypted - * messages. - * - * - 'backtraces': this action controls the logging of error backtraces. If you - * want to log backtraces so that you can debug any possible errors happening in - * SimpleSAMLphp, enable this action (add it to the array or set it to true). - * - * - 'validatexml': this action allows you to validate SAML documents against all - * the relevant XML schemas. SAML 1.1 messages or SAML metadata parsed with - * the XML to SimpleSAMLphp metadata converter or the metaedit module will - * validate the SAML documents if this option is enabled. - * - * If you want to disable debugging completely, unset this option or set it to an - * empty array. - */ - 'debug' => [ - 'saml' => $ENABLE_DEBUG, - 'backtraces' => true, - 'validatexml' => $ENABLE_DEBUG, - ], - - /* - * When 'showerrors' is enabled, all error messages and stack traces will be output - * to the browser. - * - * When 'errorreporting' is enabled, a form will be presented for the user to report - * the error to 'technicalcontact_email'. - */ - 'showerrors' => $SHOW_SAML_ERRORS, - 'errorreporting' => false, - - /* - * Custom error show function called from SimpleSAML\Error\Error::show. - * See docs/simplesamlphp-errorhandling.txt for function code example. - * - * Example: - * 'errors.show_function' => ['SimpleSAML\Module\example\Error', 'show'], - */ - - - - /************************** - | LOGGING AND STATISTICS | - **************************/ - - /* - * Define the minimum log level to log. Available levels: - * - SimpleSAML\Logger::ERR No statistics, only errors - * - SimpleSAML\Logger::WARNING No statistics, only warnings/errors - * - SimpleSAML\Logger::NOTICE Statistics and errors - * - SimpleSAML\Logger::INFO Verbose logs - * - SimpleSAML\Logger::DEBUG Full debug logs - not recommended for production - * - * Choose logging handler. - * - * Options: [syslog,file,errorlog,stderr] - * - */ - 'logging.level' => $logLevels[$LOGGING_LEVEL], - 'logging.handler' => $LOGGING_HANDLER, - - /* - * Specify the format of the logs. Its use varies depending on the log handler used (for instance, you cannot - * control here how dates are displayed when using the syslog or errorlog handlers), but in general the options - * are: - * - * - %date{}: the date and time, with its format specified inside the brackets. See the PHP documentation - * of the strftime() function for more information on the format. If the brackets are omitted, the standard - * format is applied. This can be useful if you just want to control the placement of the date, but don't care - * about the format. - * - * - %process: the name of the SimpleSAMLphp process. Remember you can configure this in the 'logging.processname' - * option below. - * - * - %level: the log level (name or number depending on the handler used). - * - * - %stat: if the log entry is intended for statistical purposes, it will print the string 'STAT ' (bear in mind - * the trailing space). - * - * - %trackid: the track ID, an identifier that allows you to track a single session. - * - * - %srcip: the IP address of the client. If you are behind a proxy, make sure to modify the - * $_SERVER['REMOTE_ADDR'] variable on your code accordingly to the X-Forwarded-For header. - * - * - %msg: the message to be logged. - * - */ - //'logging.format' => '%date{%b %d %H:%M:%S} %process %level %stat[%trackid] %msg', - - /* - * Choose which facility should be used when logging with syslog. - * - * These can be used for filtering the syslog output from SimpleSAMLphp into its - * own file by configuring the syslog daemon. - * - * See the documentation for openlog (http://php.net/manual/en/function.openlog.php) for available - * facilities. Note that only LOG_USER is valid on windows. - * - * The default is to use LOG_LOCAL5 if available, and fall back to LOG_USER if not. - */ - 'logging.facility' => defined('LOG_LOCAL5') ? constant('LOG_LOCAL5') : LOG_USER, - - /* - * The process name that should be used when logging to syslog. - * The value is also written out by the other logging handlers. - */ - 'logging.processname' => 'simplesamlphp', - - /* - * Logging: file - Logfilename in the loggingdir from above. - */ - 'logging.logfile' => 'simplesamlphp.log', - - /* - * This is an array of outputs. Each output has at least a 'class' option, which - * selects the output. - */ - 'statistics.out' => [// Log statistics to the normal log. - /* - [ - 'class' => 'core:Log', - 'level' => 'notice', - ], - */ - // Log statistics to files in a directory. One file per day. - /* - [ - 'class' => 'core:File', - 'directory' => '/var/log/stats', - ], - */ - ], - - - - /*********************** - | PROXY CONFIGURATION | - ***********************/ - - /* - * Proxy to use for retrieving URLs. - * - * Example: - * 'proxy' => 'tcp://proxy.example.com:5100' - */ - 'proxy' => null, - - /* - * Username/password authentication to proxy (Proxy-Authorization: Basic) - * Example: - * 'proxy.auth' = 'myuser:password' - */ - //'proxy.auth' => 'myuser:password', - - - - /************************** - | DATABASE CONFIGURATION | - **************************/ - - /* - * This database configuration is optional. If you are not using - * core functionality or modules that require a database, you can - * skip this configuration. - */ - - /* - * Database connection string. - * Ensure that you have the required PDO database driver installed - * for your connection string. - */ - //'database.dsn' => 'mysql:host=localhost;dbname=saml', - - /* - * SQL database credentials - */ - //'database.username' => 'simplesamlphp', - //'database.password' => 'secret', - //'database.options' => [], - - /* - * (Optional) Table prefix - */ - //'database.prefix' => '', - - /* - * (Optional) Driver options - */ - //'database.driver_options' => [], - - /* - * True or false if you would like a persistent database connection - */ - //'database.persistent' => false, - - /* - * Database slave configuration is optional as well. If you are only - * running a single database server, leave this blank. If you have - * a master/slave configuration, you can define as many slave servers - * as you want here. Slaves will be picked at random to be queried from. - * - * Configuration options in the slave array are exactly the same as the - * options for the master (shown above) with the exception of the table - * prefix and driver options. - */ - //'database.slaves' => [ - // /* - // [ - // 'dsn' => 'mysql:host=myslave;dbname=saml', - // 'username' => 'simplesamlphp', - // 'password' => 'secret', - // 'persistent' => false, - // ], - // */ - //], - - - - /************* - | PROTOCOLS | - *************/ - - /* - * Which functionality in SimpleSAMLphp do you want to enable. Normally you would enable only - * one of the functionalities below, but in some cases you could run multiple functionalities. - * In example when you are setting up a federation bridge. - */ - 'enable.saml20-idp' => $SAML20_IDP_ENABLE, - 'enable.shib13-idp' => false, - 'enable.adfs-idp' => false, - - /* - * Whether SimpleSAMLphp should sign the response or the assertion in SAML 1.1 authentication - * responses. - * - * The default is to sign the assertion element, but that can be overridden by setting this - * option to TRUE. It can also be overridden on a pr. SP basis by adding an option with the - * same name to the metadata of the SP. - */ - 'shib13.signresponse' => true, - - - - /*********** - | MODULES | - ***********/ - - /* - * Configuration to override module enabling/disabling. - * - * Example: - * - * 'module.enable' => [ - * 'exampleauth' => true, // Setting to TRUE enables. - * 'consent' => false, // Setting to FALSE disables. - * 'core' => null, // Unset or NULL uses default. - * ], - * - */ - - 'module.enable' => [ - 'saml' => true, - 'core' => true, - 'admin' => true, - 'expirychecker' => true, - 'material' => true, - 'mfa' => true, - 'profilereview' => true, - 'silauth' => true, - 'sildisco' => true, - 'exampleauth' => true, - ], - - - - /************************* - | SESSION CONFIGURATION | - *************************/ - - /* - * This value is the duration of the session in seconds. Make sure that the time duration of - * cookies both at the SP and the IdP exceeds this duration. - */ - 'session.duration' => $SESSION_DURATION, - - /* - * Sets the duration, in seconds, data should be stored in the datastore. As the data store is used for - * login and logout requests, this option will control the maximum time these operations can take. - * The default is 4 hours (4*60*60) seconds, which should be more than enough for these operations. - */ - 'session.datastore.timeout' => $SESSION_DURATION, - - /* - * Sets the duration, in seconds, auth state should be stored. - */ - 'session.state.timeout' => $SESSION_DURATION, - - /* - * Option to override the default settings for the session cookie name - */ - 'session.cookie.name' => 'SSPSESSID', - - /* - * Expiration time for the session cookie, in seconds. - * - * Defaults to 0, which means that the cookie expires when the browser is closed. - * - * Example: - * 'session.cookie.lifetime' => 30*60, - */ - 'session.cookie.lifetime' => 0, - - /* - * Limit the path of the cookies. - * - * Can be used to limit the path of the cookies to a specific subdirectory. - * - * Example: - * 'session.cookie.path' => '/simplesaml/', - */ - 'session.cookie.path' => '/', - - /* - * Cookie domain. - * - * Can be used to make the session cookie available to several domains. - * - * Example: - * 'session.cookie.domain' => '.example.org', - */ - 'session.cookie.domain' => null, - - /* - * Set the secure flag in the cookie. - * - * Set this to TRUE if the user only accesses your service - * through https. If the user can access the service through - * both http and https, this must be set to FALSE. - */ - 'session.cookie.secure' => $SECURE_COOKIE, - - /* - * Set the SameSite attribute in the cookie. - * - * You can set this to the strings 'None', 'Lax', or 'Strict' to support - * the RFC6265bis SameSite cookie attribute. If set to null, no SameSite - * attribute will be sent. - * - * Example: - * 'session.cookie.samesite' => 'None', - */ - 'session.cookie.samesite' => null, - - /* - * Options to override the default settings for php sessions. - */ - 'session.phpsession.cookiename' => 'SimpleSAML', - 'session.phpsession.savepath' => null, - 'session.phpsession.httponly' => true, - - /* - * Option to override the default settings for the auth token cookie - */ - 'session.authtoken.cookiename' => 'SSPAUTHTOKEN', - - /* - * Options for remember me feature for IdP sessions. Remember me feature - * has to be also implemented in authentication source used. - * - * Option 'session.cookie.lifetime' should be set to zero (0), i.e. cookie - * expires on browser session if remember me is not checked. - * - * Session duration ('session.duration' option) should be set according to - * 'session.rememberme.lifetime' option. - * - * It's advised to use remember me feature with session checking function - * defined with 'session.check_function' option. - */ - 'session.rememberme.enable' => false, - 'session.rememberme.checked' => false, - 'session.rememberme.lifetime' => (14 * 86400), // 14 days - - /* - * Custom function for session checking called on session init and loading. - * See docs/simplesamlphp-advancedfeatures.txt for function code example. - * - * Example: - * 'session.check_function' => ['\SimpleSAML\Module\example\Util', 'checkSession'], - */ - - - - /************************** - | MEMCACHE CONFIGURATION | - **************************/ - - /* - * Configuration for the 'memcache' session store. This allows you to store - * multiple redundant copies of sessions on different memcache servers. - * - * 'memcache_store.servers' is an array of server groups. Every data - * item will be mirrored in every server group. - * - * Each server group is an array of servers. The data items will be - * load-balanced between all servers in each server group. - * - * Each server is an array of parameters for the server. The following - * options are available: - * - 'hostname': This is the hostname or ip address where the - * memcache server runs. This is the only required option. - * - 'port': This is the port number of the memcache server. If this - * option isn't set, then we will use the 'memcache.default_port' - * ini setting. This is 11211 by default. - * - * When using the "memcache" extension, the following options are also - * supported: - * - 'weight': This sets the weight of this server in this server - * group. http://php.net/manual/en/function.Memcache-addServer.php - * contains more information about the weight option. - * - 'timeout': The timeout for this server. By default, the timeout - * is 3 seconds. - * - * Example of redundant configuration with load balancing: - * This configuration makes it possible to lose both servers in the - * a-group or both servers in the b-group without losing any sessions. - * Note that sessions will be lost if one server is lost from both the - * a-group and the b-group. - * - * 'memcache_store.servers' => [ - * [ - * ['hostname' => 'mc_a1'], - * ['hostname' => 'mc_a2'], - * ], - * [ - * ['hostname' => 'mc_b1'], - * ['hostname' => 'mc_b2'], - * ], - * ], - * - * Example of simple configuration with only one memcache server, - * running on the same computer as the web server: - * Note that all sessions will be lost if the memcache server crashes. - * - * 'memcache_store.servers' => [ - * [ - * ['hostname' => 'localhost'], - * ], - * ], - * - * Additionally, when using the "memcached" extension, unique keys must - * be provided for each group of servers if persistent connections are - * desired. Each server group can also have an "options" indexed array - * with the options desired for the given group: - * - * 'memcache_store.servers' => [ - * 'memcache_group_1' => [ - * 'options' => [ - * \Memcached::OPT_BINARY_PROTOCOL => true, - * \Memcached::OPT_NO_BLOCK => true, - * \Memcached::OPT_TCP_NODELAY => true, - * \Memcached::OPT_LIBKETAMA_COMPATIBLE => true, - * ], - * ['hostname' => '127.0.0.1', 'port' => 11211], - * ['hostname' => '127.0.0.2', 'port' => 11211], - * ], - * - * 'memcache_group_2' => [ - * 'options' => [ - * \Memcached::OPT_BINARY_PROTOCOL => true, - * \Memcached::OPT_NO_BLOCK => true, - * \Memcached::OPT_TCP_NODELAY => true, - * \Memcached::OPT_LIBKETAMA_COMPATIBLE => true, - * ], - * ['hostname' => '127.0.0.3', 'port' => 11211], - * ['hostname' => '127.0.0.4', 'port' => 11211], - * ], - * ], - * - */ -// 'memcache_store.servers' => [ -// [ -// [ -// 'hostname' => 'localhost', -// ], -// ], -// ], - - /* - * This value allows you to set a prefix for memcache-keys. The default - * for this value is 'simpleSAMLphp', which is fine in most cases. - * - * When running multiple instances of SSP on the same host, and more - * than one instance is using memcache, you probably want to assign - * a unique value per instance to this setting to avoid data collision. - */ -// 'memcache_store.prefix' => '', - - /* - * This value is the duration data should be stored in memcache. Data - * will be dropped from the memcache servers when this time expires. - * The time will be reset every time the data is written to the - * memcache servers. - * - * This value should always be larger than the 'session.duration' - * option. Not doing this may result in the session being deleted from - * the memcache servers while it is still in use. - * - * Set this value to 0 if you don't want data to expire. - * - * Note: The oldest data will always be deleted if the memcache server - * runs out of storage space. - */ -// 'memcache_store.expires' => 36 * (60 * 60), // 36 hours. - - - - /************************************* - | LANGUAGE AND INTERNATIONALIZATION | - *************************************/ - - /* - * Language-related options. - */ - 'language' => [ - /* - * An array in the form 'language' => . - * - * Each key in the array is the ISO 639 two-letter code for a language, - * and its value is an array with a list of alternative languages that - * can be used if the given language is not available at some point. - * Each alternative language is also specified by its ISO 639 code. - * - * For example, for the "no" language code (Norwegian), we would have: - * - * 'priorities' => [ - * 'no' => ['nb', 'nn', 'en', 'se'], - * ... - * ], - * - * establishing that if a translation for the "no" language code is - * not available, we look for translations in "nb" (Norwegian Bokmål), - * and so on, in that order. - */ - 'priorities' => [ - 'no' => ['nb', 'nn', 'en', 'se'], - 'nb' => ['no', 'nn', 'en', 'se'], - 'nn' => ['no', 'nb', 'en', 'se'], - 'se' => ['nb', 'no', 'nn', 'en'], - 'nr' => ['zu', 'en'], - 'nd' => ['zu', 'en'], - ], - ], - - /* - * Languages available, RTL languages, and what language is the default. - */ - 'language.available' => [ - 'en', 'no', 'nn', 'se', 'da', 'de', 'sv', 'fi', 'es', 'ca', 'fr', 'it', 'nl', 'lb', - 'cs', 'sl', 'lt', 'hr', 'hu', 'pl', 'pt', 'pt-br', 'tr', 'ja', 'zh', 'zh-tw', 'ru', - 'et', 'he', 'id', 'sr', 'lv', 'ro', 'eu', 'el', 'af', 'zu', 'xh', - ], - 'language.rtl' => ['ar', 'dv', 'fa', 'ur', 'he'], - 'language.default' => 'en', - - /* - * Options to override the default settings for the language parameter - */ - 'language.parameter.name' => 'language', - 'language.parameter.setcookie' => true, - - /* - * Options to override the default settings for the language cookie - */ - 'language.cookie.name' => 'language', - 'language.cookie.domain' => null, - 'language.cookie.path' => '/', - 'language.cookie.secure' => false, - 'language.cookie.httponly' => false, - 'language.cookie.lifetime' => (60 * 60 * 24 * 900), - 'language.cookie.samesite' => null, - - /** - * Custom getLanguage function called from SimpleSAML\Locale\Language::getLanguage(). - * Function should return language code of one of the available languages or NULL. - * See SimpleSAML\Locale\Language::getLanguage() source code for more info. - * - * This option can be used to implement a custom function for determining - * the default language for the user. - * - * Example: - * 'language.get_language_function' => ['\SimpleSAML\Module\example\Template', 'getLanguage'], - */ - - /* - * Extra dictionary for attribute names. - * This can be used to define local attributes. - * - * The format of the parameter is a string with :. - * - * Specifying this option will cause us to look for modules//dictionaries/.definition.json - * The dictionary should look something like: - * - * { - * "firstattribute": { - * "en": "English name", - * "no": "Norwegian name" - * }, - * "secondattribute": { - * "en": "English name", - * "no": "Norwegian name" - * } - * } - * - * Note that all attribute names in the dictionary must in lowercase. - * - * Example: 'attributes.extradictionary' => 'ourmodule:ourattributes', - */ - 'attributes.extradictionary' => null, - - - - /************** - | APPEARANCE | - **************/ - - /* - * Which theme directory should be used? - */ - 'theme.use' => 'material:material', - - /* - * Set this option to the text you would like to appear at the header of each page. Set to false if you don't want - * any text to appear in the header. - */ - //'theme.header' => 'SimpleSAMLphp' - - /** - * A template controller, if any. - * - * Used to intercept certain parts of the template handling, while keeping away unwanted/unexpected hooks. Set - * the 'theme.controller' configuration option to a class that implements the - * \SimpleSAML\XHTML\TemplateControllerInterface interface to use it. - */ - //'theme.controller' => '', - - /* - * Templating options - * - * By default, twig templates are not cached. To turn on template caching: - * Set 'template.cache' to an absolute path pointing to a directory that - * SimpleSAMLphp has read and write permissions to. - */ - //'template.cache' => '', - - /* - * Set the 'template.auto_reload' to true if you would like SimpleSAMLphp to - * recompile the templates (when using the template cache) if the templates - * change. If you don't want to check the source templates for every request, - * set it to false. - */ - 'template.auto_reload' => false, - - /* - * Set this option to true to indicate that your installation of SimpleSAMLphp - * is running in a production environment. This will affect the way resources - * are used, offering an optimized version when running in production, and an - * easy-to-debug one when not. Set it to false when you are testing or - * developing the software, in which case a banner will be displayed to remind - * users that they're dealing with a non-production instance. - * - * Defaults to true. - */ - 'production' => true, - - /* - * SimpleSAMLphp modules can host static resources which are served through PHP. - * The serving of the resources can be configured through these settings. - */ - 'assets' => [ - /* - * These settings adjust the caching headers that are sent - * when serving static resources. - */ - 'caching' => [ - /* - * Amount of seconds before the resource should be fetched again - */ - 'max_age' => 86400, - /* - * Calculate a checksum of every file and send it to the browser - * This allows the browser to avoid downloading assets again in situations - * where the Last-Modified header cannot be trusted, - * for example in cluster setups - * - * Defaults false - */ - 'etag' => false, - ], - ], - - /* - * If using the material theme, which color scheme to use - * Options: https://github.com/silinternational/simplesamlphp-module-material/blob/develop/README.md#branding - */ - 'theme.color-scheme' => $THEME_COLOR_SCHEME, - - - - /********************* - | DISCOVERY SERVICE | - *********************/ - - /* - * Whether the discovery service should allow the user to save his choice of IdP. - */ - 'idpdisco.enableremember' => true, - 'idpdisco.rememberchecked' => true, - - /* - * The disco service only accepts entities it knows. - */ - 'idpdisco.validate' => true, - - 'idpdisco.extDiscoveryStorage' => null, - - /* - * IdP Discovery service look configuration. - * Wether to display a list of idp or to display a dropdown box. For many IdP' a dropdown box - * gives the best use experience. - * - * When using dropdown box a cookie is used to highlight the previously chosen IdP in the dropdown. - * This makes it easier for the user to choose the IdP - * - * Options: [links,dropdown] - */ - 'idpdisco.layout' => 'links', - - - /************************************* - | AUTHENTICATION PROCESSING FILTERS | - *************************************/ - - /* - * Authentication processing filters that will be executed for all IdPs - * Both Shibboleth and SAML 2.0 - */ - 'authproc.idp' => [ - /* 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', - */ - - // Adopts language from attribute to use in UI - 30 => 'core:LanguageAdaptor', - - 35 => [ - 'class' => 'core:StatisticsWithAttribute', - 'attributename' => 'realm', - 'type' => 'saml20-idp-SSO', - ], - - /* - * Copy friendly names attribute keys to oids ... - */ - 40 => [ - 'class' => 'core:AttributeMap', - 'name2oid', - '%duplicate', - ], - - /* - * Copy oid attribute keys to friendly names - */ - 41 => [ - 'class' => 'core:AttributeMap', - 'oid2name', - '%duplicate', - ], - - // 48 => *** WARNING: For Hubs this entry is added at the end of this file - - - // If no attributes are requested in the SP metadata, then these will be sent through - 50 => [ - 'class' => 'core:AttributeLimit', - 'default' => true, - 'cn', - 'eduPersonPrincipalName', - 'eduPersonTargetID', - 'sn', - 'givenName', - 'mail', - 'employeeNumber', - 'urn:oid:2.5.4.3', // cn - 'urn:oid:1.3.6.1.4.1.5923.1.1.1.6', // eduPersonPrincipalName - 'urn:oid:1.3.6.1.4.1.5923.1.1.1.10', // eduPersonTargetID - 'urn:oid:2.5.4.4', // sn - 'urn:oid:2.5.4.42', // givenName - 'urn:oid:0.9.2342.19200300.100.1.3', // mail - 'urn:oid:2.16.840.1.113730.3.1.3', // employeeNumber - ], - - // Use the uid value to populate the nameid entry - // 60 => [ - // 'class' => 'saml:AttributeNameID', - // 'attribute' => 'uid', - // 'Format' => 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent', - // ], - - /* - * Search attribute "distinguishedName" for pattern and replaces if found - */ - /* - 70 => [ - 'class' => 'core:AttributeAlter', - 'pattern' => '/OU=studerende/', - 'replacement' => 'Student', - 'subject' => 'distinguishedName', - '%replace', - ], - */ - - /* - * Consent module is enabled (with no permanent storage, using cookies). - */ - /* - 90 => [ - 'class' => 'consent:Consent', - 'store' => 'consent:Cookie', - 'focus' => 'yes', - 'checked' => true - ], - */ - // If language is set in Consent module it will be added as an attribute. - 99 => 'core:LanguageAdaptor', - ], - - /* - * Authentication processing filters that will be executed for all SPs - * Both Shibboleth and SAML 2.0 - */ - 'authproc.sp' => [ - /* - 10 => [ - 'class' => 'core:AttributeMap', 'removeurnprefix' - ], - */ - - /* - * Generate the 'group' attribute populated from other variables, including eduPersonAffiliation. - 60 => [ - 'class' => 'core:GenerateGroups', 'eduPersonAffiliation' - ], - */ - /* - * All users will be members of 'users' and 'members' - */ - /* - 61 => [ - 'class' => 'core:AttributeAdd', 'groups' => ['users', 'members'] - ], - */ - - // Adopts language from attribute to use in UI - 90 => 'core:LanguageAdaptor', - ], - - - - /************************** - | METADATA CONFIGURATION | - **************************/ - - /* - * 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', - - /* - * This option configures the metadata sources. The metadata sources is given as an array with - * different metadata sources. When searching for metadata, SimpleSAMLphp will search through - * the array from start to end. - * - * Each element in the array is an associative array which configures the metadata source. - * The type of the metadata source is given by the 'type' element. For each type we have - * different configuration options. - * - * Flat file metadata handler: - * - 'type': This is always 'flatfile'. - * - 'directory': The directory we will load the metadata files from. The default value for - * this option is the value of the 'metadatadir' configuration option, or - * 'metadata/' if that option is unset. - * - * XML metadata handler: - * This metadata handler parses an XML file with either an EntityDescriptor element or an - * EntitiesDescriptor element. The XML file may be stored locally, or (for debugging) on a remote - * web server. - * The XML metadata handler defines the following options: - * - 'type': This is always 'xml'. - * - 'file': Path to the XML file with the metadata. - * - 'url': The URL to fetch metadata from. THIS IS ONLY FOR DEBUGGING - THERE IS NO CACHING OF THE RESPONSE. - * - * MDQ metadata handler: - * This metadata handler looks up for the metadata of an entity at the given MDQ server. - * The MDQ metadata handler defines the following options: - * - 'type': This is always 'mdq'. - * - 'server': Base URL of the MDQ server. Mandatory. - * - 'validateFingerprint': The fingerprint of the certificate used to sign the metadata. You don't need this - * option if you don't want to validate the signature on the metadata. Optional. - * - 'cachedir': Directory where metadata can be cached. Optional. - * - 'cachelength': Maximum time metadata can be cached, in seconds. Defaults to 24 - * hours (86400 seconds). Optional. - * - * PDO metadata handler: - * This metadata handler looks up metadata of an entity stored in a database. - * - * Note: If you are using the PDO metadata handler, you must configure the database - * options in this configuration file. - * - * The PDO metadata handler defines the following options: - * - 'type': This is always 'pdo'. - * - * Examples: - * - * This example defines two flatfile sources. One is the default metadata directory, the other - * is a metadata directory with auto-generated metadata files. - * - * 'metadata.sources' => [ - * ['type' => 'flatfile'], - * ['type' => 'flatfile', 'directory' => 'metadata-generated'], - * ], - * - * This example defines a flatfile source and an XML source. - * 'metadata.sources' => [ - * ['type' => 'flatfile'], - * ['type' => 'xml', 'file' => 'idp.example.org-idpMeta.xml'], - * ], - * - * This example defines an mdq source. - * 'metadata.sources' => [ - * [ - * 'type' => 'mdq', - * 'server' => 'http://mdq.server.com:8080', - * 'cachedir' => '/var/simplesamlphp/mdq-cache', - * 'cachelength' => 86400 - * ] - * ], - * - * This example defines an pdo source. - * 'metadata.sources' => [ - * ['type' => 'pdo'] - * ], - * - * Default: - * 'metadata.sources' => [ - * ['type' => 'flatfile'] - * ], - */ - 'metadata.sources' => [ - ['type' => 'flatfile'], - ], - - /* - * Should signing of generated metadata be enabled by default. - * - * Metadata signing can also be enabled for a individual SP or IdP by setting the - * same option in the metadata for the SP or IdP. - */ - 'metadata.sign.enable' => true, - - /* - * The default key & certificate which should be used to sign generated metadata. These - * are files stored in the cert dir. - * These values can be overridden by the options with the same names in the SP or - * IdP metadata. - * - * If these aren't specified here or in the metadata for the SP or IdP, then - * the 'certificate' and 'privatekey' option in the metadata will be used. - * if those aren't set, signing of metadata will fail. - */ - 'metadata.sign.privatekey' => 'saml.pem', - 'metadata.sign.privatekey_pass' => null, - 'metadata.sign.certificate' => 'saml.crt', - - - /**************************** - | DATA STORE CONFIGURATION | - ****************************/ - - /* - * Configure the data store for SimpleSAMLphp. - * - * - 'phpsession': Limited datastore, which uses the PHP session. - * - 'memcache': Key-value datastore, based on memcache. - * - 'sql': SQL datastore, using PDO. - * - 'redis': Key-value datastore, based on redis. - * - * The default datastore is 'phpsession'. - */ - 'store.type' => $SESSION_STORE_TYPE, - - /* - * The DSN the sql datastore should connect to. - * - * See http://www.php.net/manual/en/pdo.drivers.php for the various - * syntaxes. - */ - 'store.sql.dsn' => sprintf('mysql:host=%s;dbname=%s', $MYSQL_HOST, $MYSQL_DATABASE), - - /* - * The username and password to use when connecting to the database. - */ - 'store.sql.username' => $MYSQL_USER, - 'store.sql.password' => $MYSQL_PASSWORD, - - /* - * The prefix we should use on our tables. - */ - //'store.sql.prefix' => 'SimpleSAMLphp', - - /* - * The hostname and port of the Redis datastore instance. - */ - //'store.redis.host' => 'localhost', - //'store.redis.port' => 6379, - - /* - * The prefix we should use on our Redis datastore. - */ - //'store.redis.prefix' => 'SimpleSAMLphp', -]; - -if ($HUB_MODE) { - // prefix the 'member' (urn:oid:2.5.4.31) attribute elements with idp.idp_name. - $config['authproc.idp'][48] = 'sildisco:TagGroup'; - $config['authproc.idp'][49] = 'sildisco:AddIdp2NameId'; -} diff --git a/development/idp2-local/metadata/saml20-idp-hosted.php b/development/idp2-local/metadata/saml20-idp-hosted.php index ad7b8705..e0d19e01 100644 --- a/development/idp2-local/metadata/saml20-idp-hosted.php +++ b/development/idp2-local/metadata/saml20-idp-hosted.php @@ -6,22 +6,22 @@ */ $metadata['http://ssp-idp2.local:8086'] = [ - /* - * The hostname of the server (VHOST) that will use this SAML entity. - * - * Can be '__DEFAULT__', to use this entry by default. - */ - 'host' => '__DEFAULT__', + /* + * The hostname of the server (VHOST) that will use this SAML entity. + * + * Can be '__DEFAULT__', to use this entry by default. + */ + 'host' => '__DEFAULT__', - // X.509 key and certificate. Relative to the cert directory. - 'privatekey' => 'ssp-hub-idp2.pem', - 'certificate' => 'ssp-hub-idp2.crt', + // X.509 key and certificate. Relative to the cert directory. + 'privatekey' => 'ssp-hub-idp2.pem', + 'certificate' => 'ssp-hub-idp2.crt', - /* - * Authentication source to use. Must be one that is configured in - * 'config/authsources.php'. - */ - 'auth' => 'example-userpass', + /* + * Authentication source to use. Must be one that is configured in + * 'config/authsources.php'. + */ + 'auth' => 'silauth', ]; // Copy configuration for port 80 and modify host. diff --git a/development/idp2-local/metadata/saml20-sp-remote.php b/development/idp2-local/metadata/saml20-sp-remote.php index ad92fd8b..98114854 100644 --- a/development/idp2-local/metadata/saml20-sp-remote.php +++ b/development/idp2-local/metadata/saml20-sp-remote.php @@ -10,7 +10,7 @@ */ $metadata['ssp-hub.local'] = [ 'NameIDFormat' => 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent', - 'AssertionConsumerService' => 'http://ssp-hub.local/module.php/sildisco/sp/saml2-acs.php/hub-discovery', - 'SingleLogoutService' => 'http://ssp-hub.local/module.php/sildisco/sp/saml2-logout.php/hub-discovery', + 'AssertionConsumerService' => 'http://ssp-hub.local/module.php/saml/sp/saml2-acs.php/hub-discovery', + 'SingleLogoutService' => 'http://ssp-hub.local/module.php/saml/sp/saml2-logout.php/hub-discovery', 'certData' => 'MIIDzzCCAregAwIBAgIJANuvVcQPANecMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE3MTIzMTEyWhcNMjYxMDE3MTIzMTEyWjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxAimEkw4Teyf/gZelL7OuQYg/JbDIKHPXJhLPBm/HK6pM5ZZKydVXTdMgMqkl4xK+xZ2CnkozsUiMLhAuWBsX9Dcz1M4SkPRwk4puFhXzsp7fKIVP43zUhF7p2TmbernrrIQHjg6PuegKmCGyiKUpukcYvf2RXNwHwJx+Uq0zLP4PgBSrQ2t1eKZ1jQ+noBb1NqOuy969WRYmN4EmjXDuJB9d+b3GwtbZToWgiFxFjd/NN9BFJXZEaLzRj5LAq5bu2vPPDZDarHFMRUzVJ91eafoaz6zpR1iUGj9zR+y2sUPxD/fJMZ+4AHWA2LOrTBBIuuWbp96yvcJ4WjmlfhcFQIDAQABo1AwTjAdBgNVHQ4EFgQUkJFAMJdr2lXsuezS6pDXHnmJspMwHwYDVR0jBBgwFoAUkJFAMJdr2lXsuezS6pDXHnmJspMwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAOEPbchaUr45L5i+ueookevsABYnltwJZ4rYJbF9VURPcEhB6JxTMZqb4s113ftHvVYfoAfLYZ9swETaHL+esx41yAebf0kWpQ3f63S5F2FcrTj+HP0XsvW/EDrvaTKM9jnKPNmbXrpq06eaUZfkVL0TAUsxYTKkttTSTiESEzp5wzYyhp7l3kpHhEvGOlh5suYjnZ2HN0uxscCR6PS47H6TMMEZuG032DWDC016/JniWvERtpf4Yw26V+I9xevp2E2MPcZne31Pe3sCh4Wpe4cV/SCFqZHlpnH96ncz4F+KvmmhbEx5VPhQSJNFIWEvI86k+lTNQOqj6YVvGvq95LQ==', ]; diff --git a/development/idp3-local/config/config.php b/development/idp3-local/config/config.php deleted file mode 100644 index 0082751d..00000000 --- a/development/idp3-local/config/config.php +++ /dev/null @@ -1,810 +0,0 @@ - $BASE_URL_PATH, - 'certdir' => 'cert/', - 'loggingdir' => 'log/', - 'datadir' => 'data/', - - /* - * A directory where simpleSAMLphp can save temporary files. - * - * SimpleSAMLphp will attempt to create this directory if it doesn't exist. - */ - 'tempdir' => '/tmp/simplesaml', - - - /* - * If you enable this option, simpleSAMLphp will log all sent and received messages - * to the log file. - * - * This option also enables logging of the messages that are encrypted and decrypted. - * - * Note: The messages are logged with the DEBUG log level, so you also need to set - * the 'logging.level' option to LOG_DEBUG. - */ - 'debug' => false, - - /* - * When showerrors is enabled, all error messages and stack traces will be output - * to the browser. - * - * When errorreporting is enabled, a form will be presented for the user to report - * the error to technicalcontact_email. - */ - 'showerrors' => $SHOW_SAML_ERRORS, - 'errorreporting' => false, - - /* - * Custom error show function called from \SimpleSAML\Error\Error::show. - * See docs/simplesamlphp-errorhandling.txt for function code example. - * - * Example: - * 'errors.show_function' => array('\SimpleSAML\Module\example\Error\Show', 'show'), - */ - - /* - * This option allows you to enable validation of XML data against its - * schemas. A warning will be written to the log if validation fails. - */ - 'debug.validatexml' => false, - - /* - * This password must be kept secret, and modified from the default value 123. - * This password will give access to the installation page of simpleSAMLphp with - * metadata listing and diagnostics pages. - * You can also put a hash here; run "bin/pwgen.php" to generate one. - */ - 'auth.adminpassword' => $ADMIN_PASS, - 'admin.protectindexpage' => $ADMIN_PROTECT_INDEX_PAGE, - 'admin.protectmetadata' => true, - - /* - * This is a secret salt used by simpleSAMLphp when it needs to generate a secure hash - * of a value. It must be changed from its default value to a secret value. The value of - * 'secretsalt' can be any valid string of any length. - * - * A possible way to generate a random salt is by running the following command from a unix shell: - * tr -c -d '0123456789abcdefghijklmnopqrstuvwxyz' /dev/null;echo - */ - 'secretsalt' => $SECRET_SALT, - - /* - * Some information about the technical persons running this installation. - * The email address will be used as the recipient address for error reports, and - * also as the technical contact in generated metadata. - */ - 'technicalcontact_name' => $ADMIN_NAME, - 'technicalcontact_email' => $ADMIN_EMAIL, - - /* - * The timezone of the server. This option should be set to the timezone you want - * simpleSAMLphp to report the time in. The default is to guess the timezone based - * on your system timezone. - * - * See this page for a list of valid timezones: http://php.net/manual/en/timezones.php - */ - 'timezone' => 'GMT', - - /* - * Logging. - * - * define the minimum log level to log - * \SimpleSAML\Logger::ERR No statistics, only errors - * \SimpleSAML\Logger::WARNING No statistics, only warnings/errors - * \SimpleSAML\Logger::NOTICE Statistics and errors - * \SimpleSAML\Logger::INFO Verbose logs - * \SimpleSAML\Logger::DEBUG Full debug logs - not reccomended for production - * - * Choose logging handler. - * - * Options: [syslog,file,errorlog] - * - */ - 'logging.level' => \SimpleSAML\Logger::NOTICE, - 'logging.handler' => $LOGGING_HANDLER, - - /* - * Specify the format of the logs. Its use varies depending on the log handler used (for instance, you cannot - * control here how dates are displayed when using the syslog or errorlog handlers), but in general the options - * are: - * - * - %date{}: the date and time, with its format specified inside the brackets. See the PHP documentation - * of the strftime() function for more information on the format. If the brackets are omitted, the standard - * format is applied. This can be useful if you just want to control the placement of the date, but don't care - * about the format. - * - * - %process: the name of the SimpleSAMLphp process. Remember you can configure this in the 'logging.processname' - * option below. - * - * - %level: the log level (name or number depending on the handler used). - * - * - %stat: if the log entry is intended for statistical purposes, it will print the string 'STAT ' (bear in mind - * the trailing space). - * - * - %trackid: the track ID, an identifier that allows you to track a single session. - * - * - %srcip: the IP address of the client. If you are behind a proxy, make sure to modify the - * $_SERVER['REMOTE_ADDR'] variable on your code accordingly to the X-Forwarded-For header. - * - * - %msg: the message to be logged. - * - */ - //'logging.format' => '%date{%b %d %H:%M:%S} %process %level %stat[%trackid] %msg', - - /* - * Choose which facility should be used when logging with syslog. - * - * These can be used for filtering the syslog output from simpleSAMLphp into its - * own file by configuring the syslog daemon. - * - * See the documentation for openlog (http://php.net/manual/en/function.openlog.php) for available - * facilities. Note that only LOG_USER is valid on windows. - * - * The default is to use LOG_LOCAL5 if available, and fall back to LOG_USER if not. - */ - 'logging.facility' => defined('LOG_LOCAL5') ? constant('LOG_LOCAL5') : LOG_USER, - - /* - * The process name that should be used when logging to syslog. - * The value is also written out by the other logging handlers. - */ - 'logging.processname' => 'simplesamlphp', - - /* Logging: file - Logfilename in the loggingdir from above. - */ - 'logging.logfile' => 'simplesamlphp.log', - - /* (New) statistics output configuration. - * - * This is an array of outputs. Each output has at least a 'class' option, which - * selects the output. - */ - 'statistics.out' => [// Log statistics to the normal log. - /* - [ - 'class' => 'core:Log', - 'level' => 'notice', - ], - */ - // Log statistics to files in a directory. One file per day. - /* - [ - 'class' => 'core:File', - 'directory' => '/var/log/stats', - ], - */ - ], - - - /* - * Enable - * - * Which functionality in simpleSAMLphp do you want to enable. Normally you would enable only - * one of the functionalities below, but in some cases you could run multiple functionalities. - * In example when you are setting up a federation bridge. - */ - 'enable.saml20-idp' => $SAML20_IDP_ENABLE, - 'enable.shib13-idp' => false, - 'enable.adfs-idp' => false, - 'enable.wsfed-sp' => false, - 'enable.authmemcookie' => false, - - - /* - * Module enable configuration - * - * Configuration to override module enabling/disabling. - * - * Example: - * - * 'module.enable' => array( - * // Setting to TRUE enables. - * 'exampleauth' => true, - * // Setting to FALSE disables. - * 'saml' => false, - * // Unset or NULL uses default. - * 'core' => NULL, - * ), - * - */ - - 'module.enable' => [ - 'saml' => true, - 'core' => true, - 'admin' => true, - ], - - /* - * This value is the duration of the session in seconds. Make sure that the time duration of - * cookies both at the SP and the IdP exceeds this duration. - */ - 'session.duration' => $SESSION_DURATION, - - /* - * Sets the duration, in seconds, data should be stored in the datastore. As the datastore is used for - * login and logout requests, thid option will control the maximum time these operations can take. - * The default is 4 hours (4*60*60) seconds, which should be more than enough for these operations. - */ - 'session.datastore.timeout' => $SESSION_DATASTORE_TIMEOUT, - - /* - * Sets the duration, in seconds, auth state should be stored. - */ - 'session.state.timeout' => $SESSION_STATE_TIMEOUT, - - /* - * Option to override the default settings for the session cookie name - */ - 'session.cookie.name' => 'SSPSESSID', - - /* - * Expiration time for the session cookie, in seconds. - * - * Defaults to 0, which means that the cookie expires when the browser is closed. - * - * Example: - * 'session.cookie.lifetime' => 30*60, - */ - 'session.cookie.lifetime' => $SESSION_COOKIE_LIFETIME, - - /* - * Limit the path of the cookies. - * - * Can be used to limit the path of the cookies to a specific subdirectory. - * - * Example: - * 'session.cookie.path' => '/simplesaml/', - */ - 'session.cookie.path' => '/', - - /* - * Cookie domain. - * - * Can be used to make the session cookie available to several domains. - * - * Example: - * 'session.cookie.domain' => '.example.org', - */ - 'session.cookie.domain' => null, - - /* - * Set the secure flag in the cookie. - * - * Set this to TRUE if the user only accesses your service - * through https. If the user can access the service through - * both http and https, this must be set to FALSE. - */ - 'session.cookie.secure' => $SECURE_COOKIE, - - /* - * When set to FALSE fallback to transient session on session initialization - * failure, throw exception otherwise. - */ - 'session.disable_fallback' => false, - - /* - * Enable secure POST from HTTPS to HTTP. - * - * If you have some SP's on HTTP and IdP is normally on HTTPS, this option - * enables secure POSTing to HTTP endpoint without warning from browser. - * - * For this to work, module.php/core/postredirect.php must be accessible - * also via HTTP on IdP, e.g. if your IdP is on - * https://idp.example.org/ssp/, then - * http://idp.example.org/ssp/module.php/core/postredirect.php must be accessible. - */ - 'enable.http_post' => false, - - /* - * Options to override the default settings for php sessions. - */ - 'session.phpsession.cookiename' => null, - 'session.phpsession.savepath' => null, - 'session.phpsession.httponly' => true, - - /* - * Option to override the default settings for the auth token cookie - */ - 'session.authtoken.cookiename' => 'SSPAUTHTOKEN', - - /* - * Options for remember me feature for IdP sessions. Remember me feature - * has to be also implemented in authentication source used. - * - * Option 'session.cookie.lifetime' should be set to zero (0), i.e. cookie - * expires on browser session if remember me is not checked. - * - * Session duration ('session.duration' option) should be set according to - * 'session.rememberme.lifetime' option. - * - * It's advised to use remember me feature with session checking function - * defined with 'session.check_function' option. - */ - 'session.rememberme.enable' => false, - 'session.rememberme.checked' => false, - 'session.rememberme.lifetime' => $SESSION_REMEMBERME_LIFETIME, - - /** - * Custom function for session checking called on session init and loading. - * See docs/simplesamlphp-advancedfeatures.txt for function code example. - * - * Example: - * 'session.check_function' => array('\SimpleSAML\Module\example\Util', 'checkSession'), - */ - - /* - * Languages available, RTL languages, and what language is default - */ - 'language.available' => array( - 'en', 'es', 'fr', 'pt', - ), - 'language.rtl' => array('ar', 'dv', 'fa', 'ur', 'he'), - 'language.default' => 'en', - - /* - * Options to override the default settings for the language parameter - */ - 'language.parameter.name' => 'language', - 'language.parameter.setcookie' => true, - - /* - * Options to override the default settings for the language cookie - */ - 'language.cookie.name' => 'language', - 'language.cookie.domain' => null, - 'language.cookie.path' => '/', - 'language.cookie.lifetime' => (60 * 60 * 24 * 900), - - /** - * Custom getLanguage function called from \SimpleSAML\XHTML\Template::getLanguage(). - * Function should return language code of one of the available languages or NULL. - * See \SimpleSAML\XHTML\Template::getLanguage() source code for more info. - * - * This option can be used to implement a custom function for determining - * the default language for the user. - * - * Example: - * 'language.get_language_function' => array('\SimpleSAML\Module\example\Template', 'getLanguage'), - */ - - /* - * Extra dictionary for attribute names. - * This can be used to define local attributes. - * - * The format of the parameter is a string with :. - * - * Specifying this option will cause us to look for modules//dictionaries/.definition.json - * The dictionary should look something like: - * - * { - * "firstattribute": { - * "en": "English name", - * "no": "Norwegian name" - * }, - * "secondattribute": { - * "en": "English name", - * "no": "Norwegian name" - * } - * } - * - * Note that all attribute names in the dictionary must in lowercase. - * - * Example: 'attributes.extradictionary' => 'ourmodule:ourattributes', - */ - 'attributes.extradictionary' => null, - - /* - * Which theme directory should be used? - */ - 'theme.use' => 'material:material', - - - /* - * Default IdP for WS-Fed. - */ - // 'default-wsfed-idp' => 'urn:federation:pingfederate:localhost', - - /* - * Whether the discovery service should allow the user to save his choice of IdP. - */ - 'idpdisco.enableremember' => true, - 'idpdisco.rememberchecked' => true, - - // Disco service only accepts entities it knows. - 'idpdisco.validate' => true, - - 'idpdisco.extDiscoveryStorage' => null, - - /* - * IdP Discovery service look configuration. - * Wether to display a list of idp or to display a dropdown box. For many IdP' a dropdown box - * gives the best use experience. - * - * When using dropdown box a cookie is used to highlight the previously chosen IdP in the dropdown. - * This makes it easier for the user to choose the IdP - * - * Options: [links,dropdown] - * - */ - 'idpdisco.layout' => 'links', - - /* - * Whether simpleSAMLphp should sign the response or the assertion in SAML 1.1 authentication - * responses. - * - * The default is to sign the assertion element, but that can be overridden by setting this - * option to TRUE. It can also be overridden on a pr. SP basis by adding an option with the - * same name to the metadata of the SP. - */ - 'shib13.signresponse' => true, - - - /* - * Authentication processing filters that will be executed for all IdPs - * Both Shibboleth and SAML 2.0 - */ - 'authproc.idp' => [ - /* Enable the authproc filter below to add URN Prefixces to all attributes - 10 => array( - 'class' => 'core:AttributeMap', 'addurnprefix' - ), */ - /* Enable the authproc filter below to automatically generated eduPersonTargetedID. - 20 => 'core:TargetedID', - */ - - // Adopts language from attribute to use in UI - 30 => 'core:LanguageAdaptor', - - /* Add a realm attribute from edupersonprincipalname - 40 => 'core:AttributeRealm', - */ - 45 => [ - 'class' => 'core:StatisticsWithAttribute', - 'attributename' => 'realm', - 'type' => 'saml20-idp-SSO', - ], - - // Add one to help with testing - 50 => [ - 'class' => 'core:AttributeAdd', - 'eduPersonPrincipalName' => 'TEST_ADMIN', - 'urn:oid:0.9.2342.19200300.100.1.3' => 'test_admin@idp3.org', - 'uid' => '333366', - ], - - // Use the uid value to populate the nameid entry - 60 => [ - 'class' => 'saml:AttributeNameID', - 'attribute' => 'uid', - 'Format' => 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent', - ], - - /* - * Search attribute "distinguishedName" for pattern and replaces if found - - 70 => array( - 'class' => 'core:AttributeAlter', - 'pattern' => '/OU=studerende/', - 'replacement' => 'Student', - 'subject' => 'distinguishedName', - '%replace', - ), - */ - - /* - * Consent module is enabled (with no permanent storage, using cookies). - - 90 => array( - 'class' => 'consent:Consent', - 'store' => 'consent:Cookie', - 'focus' => 'yes', - 'checked' => true - ), - */ - - - // If language is set in Consent module it will be added as an attribute. - 99 => 'core:LanguageAdaptor', - ], - /* - * Authentication processing filters that will be executed for all SPs - * Both Shibboleth and SAML 2.0 - */ - 'authproc.sp' => [ - /* - 10 => array( - 'class' => 'core:AttributeMap', 'removeurnprefix' - ), - */ - - /* - * Generate the 'group' attribute populated from other variables, including eduPersonAffiliation. - 60 => array( - 'class' => 'core:GenerateGroups', 'eduPersonAffiliation' - ), - */ - /* - * All users will be members of 'users' and 'members' - 61 => array( - 'class' => 'core:AttributeAdd', 'groups' => array('users', 'members') - ), - */ - - // Adopts language from attribute to use in UI - 90 => 'core:LanguageAdaptor', - - ], - - - /* - * This option configures the metadata sources. The metadata sources is given as an array with - * different metadata sources. When searching for metadata, simpleSAMPphp will search through - * the array from start to end. - * - * Each element in the array is an associative array which configures the metadata source. - * The type of the metadata source is given by the 'type' element. For each type we have - * different configuration options. - * - * Flat file metadata handler: - * - 'type': This is always 'flatfile'. - * - 'directory': The directory we will load the metadata files from. The default value for - * this option is the value of the 'metadatadir' configuration option, or - * 'metadata/' if that option is unset. - * - * XML metadata handler: - * This metadata handler parses an XML file with either an EntityDescriptor element or an - * EntitiesDescriptor element. The XML file may be stored locally, or (for debugging) on a remote - * web server. - * The XML hetadata handler defines the following options: - * - 'type': This is always 'xml'. - * - 'file': Path to the XML file with the metadata. - * - 'url': The URL to fetch metadata from. THIS IS ONLY FOR DEBUGGING - THERE IS NO CACHING OF THE RESPONSE. - * - * - * Examples: - * - * This example defines two flatfile sources. One is the default metadata directory, the other - * is a metadata directory with autogenerated metadata files. - * - * 'metadata.sources' => array( - * array('type' => 'flatfile'), - * array('type' => 'flatfile', 'directory' => 'metadata-generated'), - * ), - * - * This example defines a flatfile source and an XML source. - * 'metadata.sources' => array( - * array('type' => 'flatfile'), - * array('type' => 'xml', 'file' => 'idp.example.org-idpMeta.xml'), - * ), - * - * - * Default: - * 'metadata.sources' => array( - * array('type' => 'flatfile') - * ), - */ - 'metadata.sources' => [ - ['type' => 'flatfile'], - ], - - - /* - * Configure the datastore for simpleSAMLphp. - * - * - 'phpsession': Limited datastore, which uses the PHP session. - * - 'memcache': Key-value datastore, based on memcache. - * - 'sql': SQL datastore, using PDO. - * - * The default datastore is 'phpsession'. - * - * (This option replaces the old 'session.handler'-option.) - */ - 'store.type' => 'phpsession', - - - /* - * The DSN the sql datastore should connect to. - * - * See http://www.php.net/manual/en/pdo.drivers.php for the various - * syntaxes. - */ - 'store.sql.dsn' => 'sqlite:/path/to/sqlitedatabase.sq3', - - /* - * The username and password to use when connecting to the database. - */ - 'store.sql.username' => null, - 'store.sql.password' => null, - - /* - * The prefix we should use on our tables. - */ - 'store.sql.prefix' => 'simpleSAMLphp', - - - /* - * Configuration for the MemcacheStore class. This allows you to store - * multiple redudant copies of sessions on different memcache servers. - * - * 'memcache_store.servers' is an array of server groups. Every data - * item will be mirrored in every server group. - * - * Each server group is an array of servers. The data items will be - * load-balanced between all servers in each server group. - * - * Each server is an array of parameters for the server. The following - * options are available: - * - 'hostname': This is the hostname or ip address where the - * memcache server runs. This is the only required option. - * - 'port': This is the port number of the memcache server. If this - * option isn't set, then we will use the 'memcache.default_port' - * ini setting. This is 11211 by default. - * - 'weight': This sets the weight of this server in this server - * group. http://php.net/manual/en/function.Memcache-addServer.php - * contains more information about the weight option. - * - 'timeout': The timeout for this server. By default, the timeout - * is 3 seconds. - * - * Example of redudant configuration with load balancing: - * This configuration makes it possible to lose both servers in the - * a-group or both servers in the b-group without losing any sessions. - * Note that sessions will be lost if one server is lost from both the - * a-group and the b-group. - * - * 'memcache_store.servers' => array( - * array( - * array('hostname' => 'mc_a1'), - * array('hostname' => 'mc_a2'), - * ), - * array( - * array('hostname' => 'mc_b1'), - * array('hostname' => 'mc_b2'), - * ), - * ), - * - * Example of simple configuration with only one memcache server, - * running on the same computer as the web server: - * Note that all sessions will be lost if the memcache server crashes. - * - * 'memcache_store.servers' => array( - * array( - * array('hostname' => 'localhost'), - * ), - * ), - * - */ -// 'memcache_store.servers' => [ -// [ -// ['hostname' => 'localhost'], -// ], -// ], - - /* - * This value allows you to set a prefix for memcache-keys. The default - * for this value is 'simpleSAMLphp', which is fine in most cases. - * - * When running multiple instances of SSP on the same host, and more - * than one instance is using memcache, you probably want to assign - * a unique value per instance to this setting to avoid data collision. - */ -// 'memcache_store.prefix' => '', - - /* - * This value is the duration data should be stored in memcache. Data - * will be dropped from the memcache servers when this time expires. - * The time will be reset every time the data is written to the - * memcache servers. - * - * This value should always be larger than the 'session.duration' - * option. Not doing this may result in the session being deleted from - * the memcache servers while it is still in use. - * - * Set this value to 0 if you don't want data to expire. - * - * Note: The oldest data will always be deleted if the memcache server - * runs out of storage space. - */ -// 'memcache_store.expires' => 36 * (60 * 60), // 36 hours. - - - /* - * Should signing of generated metadata be enabled by default. - * - * Metadata signing can also be enabled for a individual SP or IdP by setting the - * same option in the metadata for the SP or IdP. - */ - 'metadata.sign.enable' => true, - - /* - * The default key & certificate which should be used to sign generated metadata. These - * are files stored in the cert dir. - * These values can be overridden by the options with the same names in the SP or - * IdP metadata. - * - * If these aren't specified here or in the metadata for the SP or IdP, then - * the 'certificate' and 'privatekey' option in the metadata will be used. - * if those aren't set, signing of metadata will fail. - */ - 'metadata.sign.privatekey' => 'ssp-hub.pem', - 'metadata.sign.privatekey_pass' => null, - 'metadata.sign.certificate' => 'ssp-hub.crt', - - - /* - * Proxy to use for retrieving URLs. - * - * Example: - * 'proxy' => 'tcp://proxy.example.com:5100' - */ - 'proxy' => null, - - /* - * Array of domains that are allowed when generating links or redirections - * to URLs. simpleSAMLphp will use this option to determine whether to - * to consider a given URL valid or not, but you should always validate - * URLs obtained from the input on your own (i.e. ReturnTo or RelayState - * parameters obtained from the $_REQUEST array). - * - * Set to NULL to disable checking of URLs. - * - * simpleSAMLphp will automatically add your own domain (either by checking - * it dinamically, or by using the domain defined in the 'baseurlpath' - * directive, the latter having precedence) to the list of trusted domains, - * in case this option is NOT set to NULL. In that case, you are explicitly - * telling simpleSAMLphp to verify URLs. - * - * Set to an empty array to disallow ALL redirections or links pointing to - * an external URL other than your own domain. - * - * Example: - * 'trusted.url.domains' => array('sp.example.com', 'app.example.com'), - */ - 'trusted.url.domains' => null, - -]; diff --git a/development/idp3-local/metadata/saml20-idp-hosted.php b/development/idp3-local/metadata/saml20-idp-hosted.php index 37d487af..cedd5362 100644 --- a/development/idp3-local/metadata/saml20-idp-hosted.php +++ b/development/idp3-local/metadata/saml20-idp-hosted.php @@ -6,20 +6,20 @@ */ $metadata['http://ssp-idp3.local:8087'] = [ - /* - * The hostname of the server (VHOST) that will use this SAML entity. - * - * Can be '__DEFAULT__', to use this entry by default. - */ - 'host' => '__DEFAULT__', + /* + * The hostname of the server (VHOST) that will use this SAML entity. + * + * Can be '__DEFAULT__', to use this entry by default. + */ + 'host' => '__DEFAULT__', - // X.509 key and certificate. Relative to the cert directory. - 'privatekey' => 'ssp-hub-idp2.pem', - 'certificate' => 'ssp-hub-idp2.crt', + // X.509 key and certificate. Relative to the cert directory. + 'privatekey' => 'ssp-hub-idp2.pem', + 'certificate' => 'ssp-hub-idp2.crt', - /* - * Authentication source to use. Must be one that is configured in - * 'config/authsources.php'. - */ - 'auth' => 'admin', + /* + * Authentication source to use. Must be one that is configured in + * 'config/authsources.php'. + */ + 'auth' => 'admin', ]; diff --git a/development/idp3-local/metadata/saml20-sp-remote.php b/development/idp3-local/metadata/saml20-sp-remote.php index ad92fd8b..98114854 100644 --- a/development/idp3-local/metadata/saml20-sp-remote.php +++ b/development/idp3-local/metadata/saml20-sp-remote.php @@ -10,7 +10,7 @@ */ $metadata['ssp-hub.local'] = [ 'NameIDFormat' => 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent', - 'AssertionConsumerService' => 'http://ssp-hub.local/module.php/sildisco/sp/saml2-acs.php/hub-discovery', - 'SingleLogoutService' => 'http://ssp-hub.local/module.php/sildisco/sp/saml2-logout.php/hub-discovery', + 'AssertionConsumerService' => 'http://ssp-hub.local/module.php/saml/sp/saml2-acs.php/hub-discovery', + 'SingleLogoutService' => 'http://ssp-hub.local/module.php/saml/sp/saml2-logout.php/hub-discovery', 'certData' => 'MIIDzzCCAregAwIBAgIJANuvVcQPANecMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE3MTIzMTEyWhcNMjYxMDE3MTIzMTEyWjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxAimEkw4Teyf/gZelL7OuQYg/JbDIKHPXJhLPBm/HK6pM5ZZKydVXTdMgMqkl4xK+xZ2CnkozsUiMLhAuWBsX9Dcz1M4SkPRwk4puFhXzsp7fKIVP43zUhF7p2TmbernrrIQHjg6PuegKmCGyiKUpukcYvf2RXNwHwJx+Uq0zLP4PgBSrQ2t1eKZ1jQ+noBb1NqOuy969WRYmN4EmjXDuJB9d+b3GwtbZToWgiFxFjd/NN9BFJXZEaLzRj5LAq5bu2vPPDZDarHFMRUzVJ91eafoaz6zpR1iUGj9zR+y2sUPxD/fJMZ+4AHWA2LOrTBBIuuWbp96yvcJ4WjmlfhcFQIDAQABo1AwTjAdBgNVHQ4EFgQUkJFAMJdr2lXsuezS6pDXHnmJspMwHwYDVR0jBBgwFoAUkJFAMJdr2lXsuezS6pDXHnmJspMwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAOEPbchaUr45L5i+ueookevsABYnltwJZ4rYJbF9VURPcEhB6JxTMZqb4s113ftHvVYfoAfLYZ9swETaHL+esx41yAebf0kWpQ3f63S5F2FcrTj+HP0XsvW/EDrvaTKM9jnKPNmbXrpq06eaUZfkVL0TAUsxYTKkttTSTiESEzp5wzYyhp7l3kpHhEvGOlh5suYjnZ2HN0uxscCR6PS47H6TMMEZuG032DWDC016/JniWvERtpf4Yw26V+I9xevp2E2MPcZne31Pe3sCh4Wpe4cV/SCFqZHlpnH96ncz4F+KvmmhbEx5VPhQSJNFIWEvI86k+lTNQOqj6YVvGvq95LQ==', ]; diff --git a/development/m991231_235959_insert_test_users.php b/development/m991231_235959_insert_test_users.php new file mode 100644 index 00000000..aa1f10f3 --- /dev/null +++ b/development/m991231_235959_insert_test_users.php @@ -0,0 +1,43 @@ +batchInsert('{{user}}', + ['id', 'employee_id', 'username', 'email', 'require_mfa', 'review_profile_after', 'nag_for_mfa_after', 'nag_for_method_after', 'manager_email', 'first_name', 'last_name', 'last_changed_utc', 'last_synced_utc', 'active', 'locked', 'uuid'], + $users); + + $nextYear = MySqlDateTime::relative('+1 year'); + $passwords = [1, 1, $now, $nextYear, $nextYear, password_hash('sildisco_password', PASSWORD_BCRYPT)]; + $this->batchInsert('{{password}}', + ['id', 'user_id', 'created_utc', 'expires_on', 'grace_period_ends_on', 'hash'], [ + $passwords, + ]); + + for ($i = 1; $i <= count($users); $i++) { + $this->update('{{user}}', ['current_password_id' => $i], 'id=' . $i); + } + } + + public function safeDown() + { + $this->delete('{{email_log}}'); + $this->delete('{{mfa_backupcode}}'); + $this->delete('{{mfa_failed_attempt}}'); + $this->delete('{{mfa}}'); + $this->delete('{{method}}'); + $this->delete('{{user}}'); + $this->delete('{{password}}'); + + } +} diff --git a/development/sp-local/cert/ssp-hub-sp1.crt b/development/sp-local/cert/saml.crt similarity index 100% rename from development/sp-local/cert/ssp-hub-sp1.crt rename to development/sp-local/cert/saml.crt diff --git a/development/sp-local/cert/ssp-hub-sp1.pem b/development/sp-local/cert/saml.pem similarity index 100% rename from development/sp-local/cert/ssp-hub-sp1.pem rename to development/sp-local/cert/saml.pem diff --git a/development/sp-local/config/authsources-pwmanager.php b/development/sp-local/config/authsources-pwmanager.php index 80aee9c9..9a4669b1 100644 --- a/development/sp-local/config/authsources-pwmanager.php +++ b/development/sp-local/config/authsources-pwmanager.php @@ -12,10 +12,13 @@ 'mfa-idp' => [ 'saml:SP', - 'entityID' => 'http://pwmanager.local:8084', + 'entityID' => 'http://pwmanager.local', 'idp' => 'http://ssp-idp1.local:8085', 'discoURL' => null, - 'NameIDPolicy' => "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + 'NameIDPolicy' => [ + 'Format' => 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent', + 'AllowCreate' => true, + ], ], 'mfa-idp-no-port' => [ @@ -23,6 +26,9 @@ 'entityID' => 'http://pwmanager.local', 'idp' => 'http://ssp-idp1.local', 'discoURL' => null, - 'NameIDPolicy' => "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + 'NameIDPolicy' => [ + 'Format' => 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent', + 'AllowCreate' => true, + ], ], ]; diff --git a/development/sp-local/config/authsources.php b/development/sp-local/config/authsources.php index def226f1..ed5cc3a1 100644 --- a/development/sp-local/config/authsources.php +++ b/development/sp-local/config/authsources.php @@ -29,10 +29,13 @@ 'discoURL' => null, // Tell the Hub which format to use for the NameID - 'NameIDPolicy' => "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", - + 'NameIDPolicy' => [ + 'Format' => 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent', + 'AllowCreate' => true, + ], + // Specify what private key to use (such as for decrypting assertions). - 'privatekey' => 'ssp-hub-sp1.pem', + 'privatekey' => 'saml.pem', ], 'ssp-hub-custom-port' => [ @@ -51,9 +54,12 @@ 'discoURL' => null, // Tell the Hub which format to use for the NameID - 'NameIDPolicy' => "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + 'NameIDPolicy' => [ + 'Format' => 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent', + 'AllowCreate' => true, + ], // Specify what private key to use (such as for decrypting assertions). - 'privatekey' => 'ssp-hub-sp1.pem', + 'privatekey' => 'saml.pem', ], ]; diff --git a/development/sp-local/config/config.php b/development/sp-local/config/config.php deleted file mode 100644 index 451af8ee..00000000 --- a/development/sp-local/config/config.php +++ /dev/null @@ -1,836 +0,0 @@ - SimpleSAML\Logger::ERR, // No statistics, only errors - 'WARNING' => SimpleSAML\Logger::WARNING, // No statistics, only warnings/errors - 'NOTICE' => SimpleSAML\Logger::NOTICE, // Statistics and errors - 'INFO' => SimpleSAML\Logger::INFO, // Verbose logs - 'DEBUG' => SimpleSAML\Logger::DEBUG, // Full debug logs - not recommended for production -]; - -/* - * Get config settings from ENV vars or set defaults - */ - -// Required to be defined in environment -$ADMIN_EMAIL = Env::get('ADMIN_EMAIL'); -$ADMIN_PASS = Env::get('ADMIN_PASS'); -$SECRET_SALT = Env::get('SECRET_SALT'); - -// Defaults provided if not defined in environment -$BASE_URL_PATH = Env::get('BASE_URL_PATH', '/'); -$ADMIN_NAME = Env::get('ADMIN_NAME', 'SAML Admin'); -$ADMIN_PROTECT_INDEX_PAGE = Env::get('ADMIN_PROTECT_INDEX_PAGE', true); -$SHOW_SAML_ERRORS = Env::get('SHOW_SAML_ERRORS', false); -$ENABLE_DEBUG = Env::get('ENABLE_DEBUG', false); -$LOGGING_LEVEL = Env::get('LOGGING_LEVEL', 'NOTICE'); -$LOGGING_HANDLER = Env::get('LOGGING_HANDLER', 'stderr'); -$SESSION_DURATION = (int)(Env::get('SESSION_DURATION', 540)); -$SESSION_DATASTORE_TIMEOUT = (int)(Env::get('SESSION_DATASTORE_TIMEOUT', (4 * 60 * 60))); // 4 hours -$SESSION_STATE_TIMEOUT = (int)(Env::get('SESSION_STATE_TIMEOUT', (60 * 60))); // 1 hour -$SESSION_COOKIE_LIFETIME = (int)(Env::get('SESSION_COOKIE_LIFETIME', 0)); -$SESSION_REMEMBERME_LIFETIME = (int)(Env::get('SESSION_REMEMBERME_LIFETIME', (14 * 86400))); // 14 days -$SECURE_COOKIE = Env::get('SECURE_COOKIE', true); -$SAML20_IDP_ENABLE = Env::get('SAML20_IDP_ENABLE', true); - -$config = [ - - /* - * Setup the following parameters to match the directory of your installation. - * See the user manual for more details. - * - * Valid format for baseurlpath is: - * [(http|https)://(hostname|fqdn)[:port]]/[path/to/simplesaml/] - * (note that it must end with a '/') - * - * The full url format is useful if your simpleSAMLphp setup is hosted behind - * a reverse proxy. In that case you can specify the external url here. - * - * Please note that simpleSAMLphp will then redirect all queries to the - * external url, no matter where you come from (direct access or via the - * reverse proxy). - */ - 'baseurlpath' => $BASE_URL_PATH, - 'certdir' => 'cert/', - 'loggingdir' => 'log/', - 'datadir' => 'data/', - - /* - * A directory where simpleSAMLphp can save temporary files. - * - * SimpleSAMLphp will attempt to create this directory if it doesn't exist. - */ - 'tempdir' => '/tmp/simplesaml', - - - /* - * The 'debug' option allows you to control how SimpleSAMLphp behaves in certain - * situations where further action may be taken - * - * It can be left unset, in which case, debugging is switched off for all actions. - * If set, it MUST be an array containing the actions that you want to enable, or - * alternatively a hashed array where the keys are the actions and their - * corresponding values are booleans enabling or disabling each particular action. - * - * SimpleSAMLphp provides some pre-defined actions, though modules could add new - * actions here. Refer to the documentation of every module to learn if they - * allow you to set any more debugging actions. - * - * The pre-defined actions are: - * - * - 'saml': this action controls the logging of SAML messages exchanged with other - * entities. When enabled ('saml' is present in this option, or set to true), all - * SAML messages will be logged, including plaintext versions of encrypted - * messages. - * - * - 'backtraces': this action controls the logging of error backtraces. If you - * want to log backtraces so that you can debug any possible errors happening in - * SimpleSAMLphp, enable this action (add it to the array or set it to true). - * - * - 'validatexml': this action allows you to validate SAML documents against all - * the relevant XML schemas. SAML 1.1 messages or SAML metadata parsed with - * the XML to SimpleSAMLphp metadata converter or the metaedit module will - * validate the SAML documents if this option is enabled. - * - * If you want to disable debugging completely, unset this option or set it to an - * empty array. - */ - 'debug' => [ - 'saml' => $ENABLE_DEBUG, - 'backtraces' => true, - 'validatexml' => $ENABLE_DEBUG, - ], - - /* - * When showerrors is enabled, all error messages and stack traces will be output - * to the browser. - * - * When errorreporting is enabled, a form will be presented for the user to report - * the error to technicalcontact_email. - */ - 'showerrors' => $SHOW_SAML_ERRORS, - 'errorreporting' => false, - - /* - * Custom error show function called from SimpleSAML_Error_Error::show. - * See docs/simplesamlphp-errorhandling.txt for function code example. - * - * Example: - * 'errors.show_function' => array('sspmod_example_Error_Show', 'show'), - */ - - /* - * This option allows you to enable validation of XML data against its - * schemas. A warning will be written to the log if validation fails. - */ - 'debug.validatexml' => false, - - /* - * This password must be kept secret, and modified from the default value 123. - * This password will give access to the installation page of simpleSAMLphp with - * metadata listing and diagnostics pages. - * You can also put a hash here; run "bin/pwgen.php" to generate one. - */ - 'auth.adminpassword' => $ADMIN_PASS, - 'admin.protectindexpage' => $ADMIN_PROTECT_INDEX_PAGE, - 'admin.protectmetadata' => true, - - /* - * This is a secret salt used by simpleSAMLphp when it needs to generate a secure hash - * of a value. It must be changed from its default value to a secret value. The value of - * 'secretsalt' can be any valid string of any length. - * - * A possible way to generate a random salt is by running the following command from a unix shell: - * tr -c -d '0123456789abcdefghijklmnopqrstuvwxyz' /dev/null;echo - */ - 'secretsalt' => $SECRET_SALT, - - /* - * Some information about the technical persons running this installation. - * The email address will be used as the recipient address for error reports, and - * also as the technical contact in generated metadata. - */ - 'technicalcontact_name' => $ADMIN_NAME, - 'technicalcontact_email' => $ADMIN_EMAIL, - - /* - * The timezone of the server. This option should be set to the timezone you want - * simpleSAMLphp to report the time in. The default is to guess the timezone based - * on your system timezone. - * - * See this page for a list of valid timezones: http://php.net/manual/en/timezones.php - */ - 'timezone' => 'GMT', - - /* - * Logging. - * - * define the minimum log level to log - * SimpleSAML\Logger::ERR No statistics, only errors - * SimpleSAML\Logger::WARNING No statistics, only warnings/errors - * SimpleSAML\Logger::NOTICE Statistics and errors - * SimpleSAML\Logger::INFO Verbose logs - * SimpleSAML\Logger::DEBUG Full debug logs - not reccomended for production - * - * Choose logging handler. - * - * Options: [syslog,file,errorlog,stderr] - * - */ - 'logging.level' => $logLevels[$LOGGING_LEVEL], - 'logging.handler' => $LOGGING_HANDLER, - - /* - * Specify the format of the logs. Its use varies depending on the log handler used (for instance, you cannot - * control here how dates are displayed when using the syslog or errorlog handlers), but in general the options - * are: - * - * - %date{}: the date and time, with its format specified inside the brackets. See the PHP documentation - * of the strftime() function for more information on the format. If the brackets are omitted, the standard - * format is applied. This can be useful if you just want to control the placement of the date, but don't care - * about the format. - * - * - %process: the name of the SimpleSAMLphp process. Remember you can configure this in the 'logging.processname' - * option below. - * - * - %level: the log level (name or number depending on the handler used). - * - * - %stat: if the log entry is intended for statistical purposes, it will print the string 'STAT ' (bear in mind - * the trailing space). - * - * - %trackid: the track ID, an identifier that allows you to track a single session. - * - * - %srcip: the IP address of the client. If you are behind a proxy, make sure to modify the - * $_SERVER['REMOTE_ADDR'] variable on your code accordingly to the X-Forwarded-For header. - * - * - %msg: the message to be logged. - * - */ - //'logging.format' => '%date{%b %d %H:%M:%S} %process %level %stat[%trackid] %msg', - - /* - * Choose which facility should be used when logging with syslog. - * - * These can be used for filtering the syslog output from simpleSAMLphp into its - * own file by configuring the syslog daemon. - * - * See the documentation for openlog (http://php.net/manual/en/function.openlog.php) for available - * facilities. Note that only LOG_USER is valid on windows. - * - * The default is to use LOG_LOCAL5 if available, and fall back to LOG_USER if not. - */ - 'logging.facility' => defined('LOG_LOCAL5') ? constant('LOG_LOCAL5') : LOG_USER, - - /* - * The process name that should be used when logging to syslog. - * The value is also written out by the other logging handlers. - */ - 'logging.processname' => 'simplesamlphp', - - /* Logging: file - Logfilename in the loggingdir from above. - */ - 'logging.logfile' => 'simplesamlphp.log', - - /* (New) statistics output configuration. - * - * This is an array of outputs. Each output has at least a 'class' option, which - * selects the output. - */ - 'statistics.out' => [// Log statistics to the normal log. - /* - [ - 'class' => 'core:Log', - 'level' => 'notice', - ], - */ - // Log statistics to files in a directory. One file per day. - /* - [ - 'class' => 'core:File', - 'directory' => '/var/log/stats', - ], - */ - ], - - - /* - * Enable - * - * Which functionality in simpleSAMLphp do you want to enable. Normally you would enable only - * one of the functionalities below, but in some cases you could run multiple functionalities. - * In example when you are setting up a federation bridge. - */ - 'enable.saml20-idp' => $SAML20_IDP_ENABLE, - 'enable.shib13-idp' => false, - 'enable.adfs-idp' => false, - 'enable.wsfed-sp' => false, - 'enable.authmemcookie' => false, - - - /* - * Module enable configuration - * - * Configuration to override module enabling/disabling. - * - * Example: - * - * 'module.enable' => array( - * // Setting to TRUE enables. - * 'exampleauth' => TRUE, - * // Setting to FALSE disables. - * 'saml' => FALSE, - * // Unset or NULL uses default. - * 'core' => NULL, - * ), - * - */ - - 'module.enable' => [ - 'saml' => true, - 'core' => true, - 'admin' => true, - ], - - /* - * This value is the duration of the session in seconds. Make sure that the time duration of - * cookies both at the SP and the IdP exceeds this duration. - */ - 'session.duration' => $SESSION_DURATION, - - /* - * Sets the duration, in seconds, data should be stored in the datastore. As the datastore is used for - * login and logout requests, thid option will control the maximum time these operations can take. - * The default is 4 hours (4*60*60) seconds, which should be more than enough for these operations. - */ - 'session.datastore.timeout' => $SESSION_DATASTORE_TIMEOUT, - - /* - * Sets the duration, in seconds, auth state should be stored. - */ - 'session.state.timeout' => $SESSION_STATE_TIMEOUT, - - /* - * Option to override the default settings for the session cookie name - */ - 'session.cookie.name' => 'SSPSESSID', - - /* - * Expiration time for the session cookie, in seconds. - * - * Defaults to 0, which means that the cookie expires when the browser is closed. - * - * Example: - * 'session.cookie.lifetime' => 30*60, - */ - 'session.cookie.lifetime' => $SESSION_COOKIE_LIFETIME, - - /* - * Limit the path of the cookies. - * - * Can be used to limit the path of the cookies to a specific subdirectory. - * - * Example: - * 'session.cookie.path' => '/simplesaml/', - */ - 'session.cookie.path' => '/', - - /* - * Cookie domain. - * - * Can be used to make the session cookie available to several domains. - * - * Example: - * 'session.cookie.domain' => '.example.org', - */ - 'session.cookie.domain' => null, - - /* - * Set the secure flag in the cookie. - * - * Set this to TRUE if the user only accesses your service - * through https. If the user can access the service through - * both http and https, this must be set to FALSE. - */ - 'session.cookie.secure' => $SECURE_COOKIE, - - /* - * When set to FALSE fallback to transient session on session initialization - * failure, throw exception otherwise. - */ - 'session.disable_fallback' => false, - - /* - * Enable secure POST from HTTPS to HTTP. - * - * If you have some SP's on HTTP and IdP is normally on HTTPS, this option - * enables secure POSTing to HTTP endpoint without warning from browser. - * - * For this to work, module.php/core/postredirect.php must be accessible - * also via HTTP on IdP, e.g. if your IdP is on - * https://idp.example.org/ssp/, then - * http://idp.example.org/ssp/module.php/core/postredirect.php must be accessible. - */ - 'enable.http_post' => false, - - /* - * Options to override the default settings for php sessions. - */ - 'session.phpsession.cookiename' => null, - 'session.phpsession.savepath' => null, - 'session.phpsession.httponly' => true, - - /* - * Option to override the default settings for the auth token cookie - */ - 'session.authtoken.cookiename' => 'SSPAUTHTOKEN', - - /* - * Options for remember me feature for IdP sessions. Remember me feature - * has to be also implemented in authentication source used. - * - * Option 'session.cookie.lifetime' should be set to zero (0), i.e. cookie - * expires on browser session if remember me is not checked. - * - * Session duration ('session.duration' option) should be set according to - * 'session.rememberme.lifetime' option. - * - * It's advised to use remember me feature with session checking function - * defined with 'session.check_function' option. - */ - 'session.rememberme.enable' => false, - 'session.rememberme.checked' => false, - 'session.rememberme.lifetime' => $SESSION_REMEMBERME_LIFETIME, - - /** - * Custom function for session checking called on session init and loading. - * See docs/simplesamlphp-advancedfeatures.txt for function code example. - * - * Example: - * 'session.check_function' => array('sspmod_example_Util', 'checkSession'), - */ - - /* - * Languages available, RTL languages, and what language is default - */ - 'language.available' => array( - 'en', 'es', 'fr', 'pt', - ), - 'language.rtl' => array('ar', 'dv', 'fa', 'ur', 'he'), - 'language.default' => 'en', - - /* - * Options to override the default settings for the language parameter - */ - 'language.parameter.name' => 'language', - 'language.parameter.setcookie' => true, - - /* - * Options to override the default settings for the language cookie - */ - 'language.cookie.name' => 'language', - 'language.cookie.domain' => null, - 'language.cookie.path' => '/', - 'language.cookie.lifetime' => (60 * 60 * 24 * 900), - - /** - * Custom getLanguage function called from SimpleSAML_XHTML_Template::getLanguage(). - * Function should return language code of one of the available languages or NULL. - * See SimpleSAML_XHTML_Template::getLanguage() source code for more info. - * - * This option can be used to implement a custom function for determining - * the default language for the user. - * - * Example: - * 'language.get_language_function' => array('sspmod_example_Template', 'getLanguage'), - */ - - /* - * Extra dictionary for attribute names. - * This can be used to define local attributes. - * - * The format of the parameter is a string with :. - * - * Specifying this option will cause us to look for modules//dictionaries/.definition.json - * The dictionary should look something like: - * - * { - * "firstattribute": { - * "en": "English name", - * "no": "Norwegian name" - * }, - * "secondattribute": { - * "en": "English name", - * "no": "Norwegian name" - * } - * } - * - * Note that all attribute names in the dictionary must in lowercase. - * - * Example: 'attributes.extradictionary' => 'ourmodule:ourattributes', - */ - 'attributes.extradictionary' => null, - - /* - * Which theme directory should be used? - */ - 'theme.use' => 'material:material', - - - /* - * Default IdP for WS-Fed. - */ - // 'default-wsfed-idp' => 'urn:federation:pingfederate:localhost', - - /* - * Whether the discovery service should allow the user to save his choice of IdP. - */ - 'idpdisco.enableremember' => true, - 'idpdisco.rememberchecked' => true, - - // Disco service only accepts entities it knows. - 'idpdisco.validate' => true, - - 'idpdisco.extDiscoveryStorage' => null, - - /* - * IdP Discovery service look configuration. - * Wether to display a list of idp or to display a dropdown box. For many IdP' a dropdown box - * gives the best use experience. - * - * When using dropdown box a cookie is used to highlight the previously chosen IdP in the dropdown. - * This makes it easier for the user to choose the IdP - * - * Options: [links,dropdown] - * - */ - 'idpdisco.layout' => 'links', - - /* - * Whether simpleSAMLphp should sign the response or the assertion in SAML 1.1 authentication - * responses. - * - * The default is to sign the assertion element, but that can be overridden by setting this - * option to TRUE. It can also be overridden on a pr. SP basis by adding an option with the - * same name to the metadata of the SP. - */ - 'shib13.signresponse' => true, - - - /* - * Authentication processing filters that will be executed for all IdPs - * Both Shibboleth and SAML 2.0 - */ - 'authproc.idp' => [ - /* Enable the authproc filter below to add URN Prefixces to all attributes - 10 => array( - 'class' => 'core:AttributeMap', 'addurnprefix' - ), */ - /* Enable the authproc filter below to automatically generated eduPersonTargetedID. - 20 => 'core:TargetedID', - */ - - // Adopts language from attribute to use in UI - 30 => 'core:LanguageAdaptor', - - /* Add a realm attribute from edupersonprincipalname - 40 => 'core:AttributeRealm', - */ - 45 => [ - 'class' => 'core:StatisticsWithAttribute', - 'attributename' => 'realm', - 'type' => 'saml20-idp-SSO', - ], - - // If no attributes are requested in the SP metadata, then these will be sent through - 50 => [ - 'class' => 'core:AttributeLimit', - 'default' => true, - 'eduPersonPrincipalName', 'sn', 'givenName', 'mail', - ], - - // Use the uid value to populate the nameid entry - // 60 => [ - // 'class' => 'saml:AttributeNameID', - // 'attribute' => 'uid', - // 'Format' => 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient', - // ], - - /* - * Search attribute "distinguishedName" for pattern and replaces if found - - 70 => array( - 'class' => 'core:AttributeAlter', - 'pattern' => '/OU=studerende/', - 'replacement' => 'Student', - 'subject' => 'distinguishedName', - '%replace', - ), - */ - - /* - * Consent module is enabled (with no permanent storage, using cookies). - - 90 => array( - 'class' => 'consent:Consent', - 'store' => 'consent:Cookie', - 'focus' => 'yes', - 'checked' => TRUE - ), - */ - - - // If language is set in Consent module it will be added as an attribute. - 99 => 'core:LanguageAdaptor', - ], - /* - * Authentication processing filters that will be executed for all SPs - * Both Shibboleth and SAML 2.0 - */ - 'authproc.sp' => [ - /* - 10 => array( - 'class' => 'core:AttributeMap', 'removeurnprefix' - ), - */ - - /* - * Generate the 'group' attribute populated from other variables, including eduPersonAffiliation. - 60 => array( - 'class' => 'core:GenerateGroups', 'eduPersonAffiliation' - ), - */ - /* - * All users will be members of 'users' and 'members' - 61 => array( - 'class' => 'core:AttributeAdd', 'groups' => array('users', 'members') - ), - */ - - // Adopts language from attribute to use in UI - 90 => 'core:LanguageAdaptor', - - ], - - - /* - * This option configures the metadata sources. The metadata sources is given as an array with - * different metadata sources. When searching for metadata, simpleSAMPphp will search through - * the array from start to end. - * - * Each element in the array is an associative array which configures the metadata source. - * The type of the metadata source is given by the 'type' element. For each type we have - * different configuration options. - * - * Flat file metadata handler: - * - 'type': This is always 'flatfile'. - * - 'directory': The directory we will load the metadata files from. The default value for - * this option is the value of the 'metadatadir' configuration option, or - * 'metadata/' if that option is unset. - * - * XML metadata handler: - * This metadata handler parses an XML file with either an EntityDescriptor element or an - * EntitiesDescriptor element. The XML file may be stored locally, or (for debugging) on a remote - * web server. - * The XML hetadata handler defines the following options: - * - 'type': This is always 'xml'. - * - 'file': Path to the XML file with the metadata. - * - 'url': The URL to fetch metadata from. THIS IS ONLY FOR DEBUGGING - THERE IS NO CACHING OF THE RESPONSE. - * - * - * Examples: - * - * This example defines two flatfile sources. One is the default metadata directory, the other - * is a metadata directory with autogenerated metadata files. - * - * 'metadata.sources' => array( - * array('type' => 'flatfile'), - * array('type' => 'flatfile', 'directory' => 'metadata-generated'), - * ), - * - * This example defines a flatfile source and an XML source. - * 'metadata.sources' => array( - * array('type' => 'flatfile'), - * array('type' => 'xml', 'file' => 'idp.example.org-idpMeta.xml'), - * ), - * - * - * Default: - * 'metadata.sources' => array( - * array('type' => 'flatfile') - * ), - */ - 'metadata.sources' => [ - ['type' => 'flatfile'], - ], - - - /* - * Configure the datastore for simpleSAMLphp. - * - * - 'phpsession': Limited datastore, which uses the PHP session. - * - 'memcache': Key-value datastore, based on memcache. - * - 'sql': SQL datastore, using PDO. - * - * The default datastore is 'phpsession'. - * - * (This option replaces the old 'session.handler'-option.) - */ - 'store.type' => 'phpsession', - - - /* - * The DSN the sql datastore should connect to. - * - * See http://www.php.net/manual/en/pdo.drivers.php for the various - * syntaxes. - */ - 'store.sql.dsn' => 'sqlite:/path/to/sqlitedatabase.sq3', - - /* - * The username and password to use when connecting to the database. - */ - 'store.sql.username' => null, - 'store.sql.password' => null, - - /* - * The prefix we should use on our tables. - */ - 'store.sql.prefix' => 'simpleSAMLphp', - - - /* - * Configuration for the MemcacheStore class. This allows you to store - * multiple redudant copies of sessions on different memcache servers. - * - * 'memcache_store.servers' is an array of server groups. Every data - * item will be mirrored in every server group. - * - * Each server group is an array of servers. The data items will be - * load-balanced between all servers in each server group. - * - * Each server is an array of parameters for the server. The following - * options are available: - * - 'hostname': This is the hostname or ip address where the - * memcache server runs. This is the only required option. - * - 'port': This is the port number of the memcache server. If this - * option isn't set, then we will use the 'memcache.default_port' - * ini setting. This is 11211 by default. - * - 'weight': This sets the weight of this server in this server - * group. http://php.net/manual/en/function.Memcache-addServer.php - * contains more information about the weight option. - * - 'timeout': The timeout for this server. By default, the timeout - * is 3 seconds. - * - * Example of redudant configuration with load balancing: - * This configuration makes it possible to lose both servers in the - * a-group or both servers in the b-group without losing any sessions. - * Note that sessions will be lost if one server is lost from both the - * a-group and the b-group. - * - * 'memcache_store.servers' => array( - * array( - * array('hostname' => 'mc_a1'), - * array('hostname' => 'mc_a2'), - * ), - * array( - * array('hostname' => 'mc_b1'), - * array('hostname' => 'mc_b2'), - * ), - * ), - * - * Example of simple configuration with only one memcache server, - * running on the same computer as the web server: - * Note that all sessions will be lost if the memcache server crashes. - * - * 'memcache_store.servers' => array( - * array( - * array('hostname' => 'localhost'), - * ), - * ), - * - */ - 'memcache_store.servers' => [ - [ - ['hostname' => 'localhost'], - ], - ], - - - /* - * This value is the duration data should be stored in memcache. Data - * will be dropped from the memcache servers when this time expires. - * The time will be reset every time the data is written to the - * memcache servers. - * - * This value should always be larger than the 'session.duration' - * option. Not doing this may result in the session being deleted from - * the memcache servers while it is still in use. - * - * Set this value to 0 if you don't want data to expire. - * - * Note: The oldest data will always be deleted if the memcache server - * runs out of storage space. - */ - 'memcache_store.expires' => 36 * (60 * 60), // 36 hours. - - - /* - * Should signing of generated metadata be enabled by default. - * - * Metadata signing can also be enabled for a individual SP or IdP by setting the - * same option in the metadata for the SP or IdP. - */ - 'metadata.sign.enable' => true, - - /* - * The default key & certificate which should be used to sign generated metadata. These - * are files stored in the cert dir. - * These values can be overridden by the options with the same names in the SP or - * IdP metadata. - * - * If these aren't specified here or in the metadata for the SP or IdP, then - * the 'certificate' and 'privatekey' option in the metadata will be used. - * if those aren't set, signing of metadata will fail. - */ - 'metadata.sign.privatekey' => 'ssp-hub-sp1.pem', - 'metadata.sign.privatekey_pass' => null, - 'metadata.sign.certificate' => 'ssp-hub-sp1.crt', - - - /* - * Proxy to use for retrieving URLs. - * - * Example: - * 'proxy' => 'tcp://proxy.example.com:5100' - */ - 'proxy' => null, - - /* - * Array of domains that are allowed when generating links or redirections - * to URLs. simpleSAMLphp will use this option to determine whether to - * to consider a given URL valid or not, but you should always validate - * URLs obtained from the input on your own (i.e. ReturnTo or RelayState - * parameters obtained from the $_REQUEST array). - * - * Set to NULL to disable checking of URLs. - * - * simpleSAMLphp will automatically add your own domain (either by checking - * it dinamically, or by using the domain defined in the 'baseurlpath' - * directive, the latter having precedence) to the list of trusted domains, - * in case this option is NOT set to NULL. In that case, you are explicitly - * telling simpleSAMLphp to verify URLs. - * - * Set to an empty array to disallow ALL redirections or links pointing to - * an external URL other than your own domain. - * - * Example: - * 'trusted.url.domains' => array('sp.example.com', 'app.example.com'), - */ - 'trusted.url.domains' => null, - -]; diff --git a/development/sp-local/metadata/saml20-idp-remote.php b/development/sp-local/metadata/saml20-idp-remote.php index f518f827..8558a9f2 100644 --- a/development/sp-local/metadata/saml20-idp-remote.php +++ b/development/sp-local/metadata/saml20-idp-remote.php @@ -4,16 +4,16 @@ * * Remember to remove the IdPs you don't use from this file. * - * See: https://simplesamlphp.org/docs/stable/simplesamlphp-reference-idp-remote + * See: https://simplesamlphp.org/docs/stable/simplesamlphp-reference-idp-remote */ /* * Guest IdP. allows users to sign up and register. Great for testing! */ $metadata['ssp-hub.local'] = [ - 'SingleSignOnService' => 'http://ssp-hub.local/saml2/idp/SSOService.php', - 'SingleLogoutService' => 'http://ssp-hub.local/saml2/idp/SingleLogoutService.php', - 'certData' =>'MIIDzzCCAregAwIBAgIJANuvVcQPANecMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE3MTIzMTEyWhcNMjYxMDE3MTIzMTEyWjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxAimEkw4Teyf/gZelL7OuQYg/JbDIKHPXJhLPBm/HK6pM5ZZKydVXTdMgMqkl4xK+xZ2CnkozsUiMLhAuWBsX9Dcz1M4SkPRwk4puFhXzsp7fKIVP43zUhF7p2TmbernrrIQHjg6PuegKmCGyiKUpukcYvf2RXNwHwJx+Uq0zLP4PgBSrQ2t1eKZ1jQ+noBb1NqOuy969WRYmN4EmjXDuJB9d+b3GwtbZToWgiFxFjd/NN9BFJXZEaLzRj5LAq5bu2vPPDZDarHFMRUzVJ91eafoaz6zpR1iUGj9zR+y2sUPxD/fJMZ+4AHWA2LOrTBBIuuWbp96yvcJ4WjmlfhcFQIDAQABo1AwTjAdBgNVHQ4EFgQUkJFAMJdr2lXsuezS6pDXHnmJspMwHwYDVR0jBBgwFoAUkJFAMJdr2lXsuezS6pDXHnmJspMwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAOEPbchaUr45L5i+ueookevsABYnltwJZ4rYJbF9VURPcEhB6JxTMZqb4s113ftHvVYfoAfLYZ9swETaHL+esx41yAebf0kWpQ3f63S5F2FcrTj+HP0XsvW/EDrvaTKM9jnKPNmbXrpq06eaUZfkVL0TAUsxYTKkttTSTiESEzp5wzYyhp7l3kpHhEvGOlh5suYjnZ2HN0uxscCR6PS47H6TMMEZuG032DWDC016/JniWvERtpf4Yw26V+I9xevp2E2MPcZne31Pe3sCh4Wpe4cV/SCFqZHlpnH96ncz4F+KvmmhbEx5VPhQSJNFIWEvI86k+lTNQOqj6YVvGvq95LQ==', - + 'SingleSignOnService' => 'http://ssp-hub.local/saml2/idp/SSOService.php', + 'SingleLogoutService' => 'http://ssp-hub.local/saml2/idp/SingleLogoutService.php', + 'certData' => 'MIIDzzCCAregAwIBAgIJANuvVcQPANecMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE3MTIzMTEyWhcNMjYxMDE3MTIzMTEyWjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxAimEkw4Teyf/gZelL7OuQYg/JbDIKHPXJhLPBm/HK6pM5ZZKydVXTdMgMqkl4xK+xZ2CnkozsUiMLhAuWBsX9Dcz1M4SkPRwk4puFhXzsp7fKIVP43zUhF7p2TmbernrrIQHjg6PuegKmCGyiKUpukcYvf2RXNwHwJx+Uq0zLP4PgBSrQ2t1eKZ1jQ+noBb1NqOuy969WRYmN4EmjXDuJB9d+b3GwtbZToWgiFxFjd/NN9BFJXZEaLzRj5LAq5bu2vPPDZDarHFMRUzVJ91eafoaz6zpR1iUGj9zR+y2sUPxD/fJMZ+4AHWA2LOrTBBIuuWbp96yvcJ4WjmlfhcFQIDAQABo1AwTjAdBgNVHQ4EFgQUkJFAMJdr2lXsuezS6pDXHnmJspMwHwYDVR0jBBgwFoAUkJFAMJdr2lXsuezS6pDXHnmJspMwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAOEPbchaUr45L5i+ueookevsABYnltwJZ4rYJbF9VURPcEhB6JxTMZqb4s113ftHvVYfoAfLYZ9swETaHL+esx41yAebf0kWpQ3f63S5F2FcrTj+HP0XsvW/EDrvaTKM9jnKPNmbXrpq06eaUZfkVL0TAUsxYTKkttTSTiESEzp5wzYyhp7l3kpHhEvGOlh5suYjnZ2HN0uxscCR6PS47H6TMMEZuG032DWDC016/JniWvERtpf4Yw26V+I9xevp2E2MPcZne31Pe3sCh4Wpe4cV/SCFqZHlpnH96ncz4F+KvmmhbEx5VPhQSJNFIWEvI86k+lTNQOqj6YVvGvq95LQ==', + ]; diff --git a/development/sp2-local/cert/ssp-hub-sp2.crt b/development/sp2-local/cert/saml.crt similarity index 100% rename from development/sp2-local/cert/ssp-hub-sp2.crt rename to development/sp2-local/cert/saml.crt diff --git a/development/sp2-local/cert/ssp-hub-sp2.pem b/development/sp2-local/cert/saml.pem similarity index 100% rename from development/sp2-local/cert/ssp-hub-sp2.pem rename to development/sp2-local/cert/saml.pem diff --git a/development/sp2-local/config/authsources.php b/development/sp2-local/config/authsources.php index 60f76215..5f919b06 100644 --- a/development/sp2-local/config/authsources.php +++ b/development/sp2-local/config/authsources.php @@ -29,7 +29,7 @@ 'discoURL' => null, // Specify what private key to use (such as for decrypting assertions). - 'privatekey' => 'ssp-hub-sp2.pem', + 'privatekey' => 'saml.pem', ], 'ssp-hub-custom-port' => [ @@ -48,6 +48,6 @@ 'discoURL' => null, // Specify what private key to use (such as for decrypting assertions). - 'privatekey' => 'ssp-hub-sp2.pem', + 'privatekey' => 'saml.pem', ], ]; diff --git a/development/sp2-local/config/config.php b/development/sp2-local/config/config.php deleted file mode 100644 index 0c027f86..00000000 --- a/development/sp2-local/config/config.php +++ /dev/null @@ -1,836 +0,0 @@ - SimpleSAML\Logger::ERR, // No statistics, only errors - 'WARNING' => SimpleSAML\Logger::WARNING, // No statistics, only warnings/errors - 'NOTICE' => SimpleSAML\Logger::NOTICE, // Statistics and errors - 'INFO' => SimpleSAML\Logger::INFO, // Verbose logs - 'DEBUG' => SimpleSAML\Logger::DEBUG, // Full debug logs - not recommended for production -]; - -/* - * Get config settings from ENV vars or set defaults - */ - -// Required to be defined in environment -$ADMIN_EMAIL = Env::get('ADMIN_EMAIL'); -$ADMIN_PASS = Env::get('ADMIN_PASS'); -$SECRET_SALT = Env::get('SECRET_SALT'); - -// Defaults provided if not defined in environment -$BASE_URL_PATH = Env::get('BASE_URL_PATH', '/'); -$ADMIN_NAME = Env::get('ADMIN_NAME', 'SAML Admin'); -$ADMIN_PROTECT_INDEX_PAGE = Env::get('ADMIN_PROTECT_INDEX_PAGE', true); -$SHOW_SAML_ERRORS = Env::get('SHOW_SAML_ERRORS', false); -$ENABLE_DEBUG = Env::get('ENABLE_DEBUG', false); -$LOGGING_LEVEL = Env::get('LOGGING_LEVEL', 'NOTICE'); -$LOGGING_HANDLER = Env::get('LOGGING_HANDLER', 'stderr'); -$SESSION_DURATION = (int)(Env::get('SESSION_DURATION', 540)); -$SESSION_DATASTORE_TIMEOUT = (int)(Env::get('SESSION_DATASTORE_TIMEOUT', (4 * 60 * 60))); // 4 hours -$SESSION_STATE_TIMEOUT = (int)(Env::get('SESSION_STATE_TIMEOUT', (60 * 60))); // 1 hour -$SESSION_COOKIE_LIFETIME = (int)(Env::get('SESSION_COOKIE_LIFETIME', 0)); -$SESSION_REMEMBERME_LIFETIME = (int)(Env::get('SESSION_REMEMBERME_LIFETIME', (14 * 86400))); // 14 days -$SECURE_COOKIE = Env::get('SECURE_COOKIE', true); -$SAML20_IDP_ENABLE = Env::get('SAML20_IDP_ENABLE', true); - -$config = [ - - /* - * Setup the following parameters to match the directory of your installation. - * See the user manual for more details. - * - * Valid format for baseurlpath is: - * [(http|https)://(hostname|fqdn)[:port]]/[path/to/simplesaml/] - * (note that it must end with a '/') - * - * The full url format is useful if your simpleSAMLphp setup is hosted behind - * a reverse proxy. In that case you can specify the external url here. - * - * Please note that simpleSAMLphp will then redirect all queries to the - * external url, no matter where you come from (direct access or via the - * reverse proxy). - */ - 'baseurlpath' => $BASE_URL_PATH, - 'certdir' => 'cert/', - 'loggingdir' => 'log/', - 'datadir' => 'data/', - - /* - * A directory where simpleSAMLphp can save temporary files. - * - * SimpleSAMLphp will attempt to create this directory if it doesn't exist. - */ - 'tempdir' => '/tmp/simplesaml', - - - /* - * The 'debug' option allows you to control how SimpleSAMLphp behaves in certain - * situations where further action may be taken - * - * It can be left unset, in which case, debugging is switched off for all actions. - * If set, it MUST be an array containing the actions that you want to enable, or - * alternatively a hashed array where the keys are the actions and their - * corresponding values are booleans enabling or disabling each particular action. - * - * SimpleSAMLphp provides some pre-defined actions, though modules could add new - * actions here. Refer to the documentation of every module to learn if they - * allow you to set any more debugging actions. - * - * The pre-defined actions are: - * - * - 'saml': this action controls the logging of SAML messages exchanged with other - * entities. When enabled ('saml' is present in this option, or set to true), all - * SAML messages will be logged, including plaintext versions of encrypted - * messages. - * - * - 'backtraces': this action controls the logging of error backtraces. If you - * want to log backtraces so that you can debug any possible errors happening in - * SimpleSAMLphp, enable this action (add it to the array or set it to true). - * - * - 'validatexml': this action allows you to validate SAML documents against all - * the relevant XML schemas. SAML 1.1 messages or SAML metadata parsed with - * the XML to SimpleSAMLphp metadata converter or the metaedit module will - * validate the SAML documents if this option is enabled. - * - * If you want to disable debugging completely, unset this option or set it to an - * empty array. - */ - 'debug' => [ - 'saml' => $ENABLE_DEBUG, - 'backtraces' => true, - 'validatexml' => $ENABLE_DEBUG, - ], - - /* - * When showerrors is enabled, all error messages and stack traces will be output - * to the browser. - * - * When errorreporting is enabled, a form will be presented for the user to report - * the error to technicalcontact_email. - */ - 'showerrors' => $SHOW_SAML_ERRORS, - 'errorreporting' => false, - - /* - * Custom error show function called from SimpleSAML_Error_Error::show. - * See docs/simplesamlphp-errorhandling.txt for function code example. - * - * Example: - * 'errors.show_function' => array('sspmod_example_Error_Show', 'show'), - */ - - /* - * This option allows you to enable validation of XML data against its - * schemas. A warning will be written to the log if validation fails. - */ - 'debug.validatexml' => false, - - /* - * This password must be kept secret, and modified from the default value 123. - * This password will give access to the installation page of simpleSAMLphp with - * metadata listing and diagnostics pages. - * You can also put a hash here; run "bin/pwgen.php" to generate one. - */ - 'auth.adminpassword' => $ADMIN_PASS, - 'admin.protectindexpage' => $ADMIN_PROTECT_INDEX_PAGE, - 'admin.protectmetadata' => true, - - /* - * This is a secret salt used by simpleSAMLphp when it needs to generate a secure hash - * of a value. It must be changed from its default value to a secret value. The value of - * 'secretsalt' can be any valid string of any length. - * - * A possible way to generate a random salt is by running the following command from a unix shell: - * tr -c -d '0123456789abcdefghijklmnopqrstuvwxyz' /dev/null;echo - */ - 'secretsalt' => $SECRET_SALT, - - /* - * Some information about the technical persons running this installation. - * The email address will be used as the recipient address for error reports, and - * also as the technical contact in generated metadata. - */ - 'technicalcontact_name' => $ADMIN_NAME, - 'technicalcontact_email' => $ADMIN_EMAIL, - - /* - * The timezone of the server. This option should be set to the timezone you want - * simpleSAMLphp to report the time in. The default is to guess the timezone based - * on your system timezone. - * - * See this page for a list of valid timezones: http://php.net/manual/en/timezones.php - */ - 'timezone' => 'GMT', - - /* - * Logging. - * - * define the minimum log level to log - * SimpleSAML\Logger::ERR No statistics, only errors - * SimpleSAML\Logger::WARNING No statistics, only warnings/errors - * SimpleSAML\Logger::NOTICE Statistics and errors - * SimpleSAML\Logger::INFO Verbose logs - * SimpleSAML\Logger::DEBUG Full debug logs - not reccomended for production - * - * Choose logging handler. - * - * Options: [syslog,file,errorlog,stderr] - * - */ - 'logging.level' => $logLevels[$LOGGING_LEVEL], - 'logging.handler' => $LOGGING_HANDLER, - - /* - * Specify the format of the logs. Its use varies depending on the log handler used (for instance, you cannot - * control here how dates are displayed when using the syslog or errorlog handlers), but in general the options - * are: - * - * - %date{}: the date and time, with its format specified inside the brackets. See the PHP documentation - * of the strftime() function for more information on the format. If the brackets are omitted, the standard - * format is applied. This can be useful if you just want to control the placement of the date, but don't care - * about the format. - * - * - %process: the name of the SimpleSAMLphp process. Remember you can configure this in the 'logging.processname' - * option below. - * - * - %level: the log level (name or number depending on the handler used). - * - * - %stat: if the log entry is intended for statistical purposes, it will print the string 'STAT ' (bear in mind - * the trailing space). - * - * - %trackid: the track ID, an identifier that allows you to track a single session. - * - * - %srcip: the IP address of the client. If you are behind a proxy, make sure to modify the - * $_SERVER['REMOTE_ADDR'] variable on your code accordingly to the X-Forwarded-For header. - * - * - %msg: the message to be logged. - * - */ - //'logging.format' => '%date{%b %d %H:%M:%S} %process %level %stat[%trackid] %msg', - - /* - * Choose which facility should be used when logging with syslog. - * - * These can be used for filtering the syslog output from simpleSAMLphp into its - * own file by configuring the syslog daemon. - * - * See the documentation for openlog (http://php.net/manual/en/function.openlog.php) for available - * facilities. Note that only LOG_USER is valid on windows. - * - * The default is to use LOG_LOCAL5 if available, and fall back to LOG_USER if not. - */ - 'logging.facility' => defined('LOG_LOCAL5') ? constant('LOG_LOCAL5') : LOG_USER, - - /* - * The process name that should be used when logging to syslog. - * The value is also written out by the other logging handlers. - */ - 'logging.processname' => 'simplesamlphp', - - /* Logging: file - Logfilename in the loggingdir from above. - */ - 'logging.logfile' => 'simplesamlphp.log', - - /* (New) statistics output configuration. - * - * This is an array of outputs. Each output has at least a 'class' option, which - * selects the output. - */ - 'statistics.out' => [// Log statistics to the normal log. - /* - [ - 'class' => 'core:Log', - 'level' => 'notice', - ], - */ - // Log statistics to files in a directory. One file per day. - /* - [ - 'class' => 'core:File', - 'directory' => '/var/log/stats', - ], - */ - ], - - - /* - * Enable - * - * Which functionality in simpleSAMLphp do you want to enable. Normally you would enable only - * one of the functionalities below, but in some cases you could run multiple functionalities. - * In example when you are setting up a federation bridge. - */ - 'enable.saml20-idp' => $SAML20_IDP_ENABLE, - 'enable.shib13-idp' => false, - 'enable.adfs-idp' => false, - 'enable.wsfed-sp' => false, - 'enable.authmemcookie' => false, - - - /* - * Module enable configuration - * - * Configuration to override module enabling/disabling. - * - * Example: - * - * 'module.enable' => array( - * // Setting to TRUE enables. - * 'exampleauth' => TRUE, - * // Setting to FALSE disables. - * 'saml' => FALSE, - * // Unset or NULL uses default. - * 'core' => NULL, - * ), - * - */ - - 'module.enable' => [ - 'saml' => true, - 'core' => true, - 'admin' => true, - ], - - /* - * This value is the duration of the session in seconds. Make sure that the time duration of - * cookies both at the SP and the IdP exceeds this duration. - */ - 'session.duration' => $SESSION_DURATION, - - /* - * Sets the duration, in seconds, data should be stored in the datastore. As the datastore is used for - * login and logout requests, thid option will control the maximum time these operations can take. - * The default is 4 hours (4*60*60) seconds, which should be more than enough for these operations. - */ - 'session.datastore.timeout' => $SESSION_DATASTORE_TIMEOUT, - - /* - * Sets the duration, in seconds, auth state should be stored. - */ - 'session.state.timeout' => $SESSION_STATE_TIMEOUT, - - /* - * Option to override the default settings for the session cookie name - */ - 'session.cookie.name' => 'SSPSESSID', - - /* - * Expiration time for the session cookie, in seconds. - * - * Defaults to 0, which means that the cookie expires when the browser is closed. - * - * Example: - * 'session.cookie.lifetime' => 30*60, - */ - 'session.cookie.lifetime' => $SESSION_COOKIE_LIFETIME, - - /* - * Limit the path of the cookies. - * - * Can be used to limit the path of the cookies to a specific subdirectory. - * - * Example: - * 'session.cookie.path' => '/simplesaml/', - */ - 'session.cookie.path' => '/', - - /* - * Cookie domain. - * - * Can be used to make the session cookie available to several domains. - * - * Example: - * 'session.cookie.domain' => '.example.org', - */ - 'session.cookie.domain' => null, - - /* - * Set the secure flag in the cookie. - * - * Set this to TRUE if the user only accesses your service - * through https. If the user can access the service through - * both http and https, this must be set to FALSE. - */ - 'session.cookie.secure' => $SECURE_COOKIE, - - /* - * When set to FALSE fallback to transient session on session initialization - * failure, throw exception otherwise. - */ - 'session.disable_fallback' => false, - - /* - * Enable secure POST from HTTPS to HTTP. - * - * If you have some SP's on HTTP and IdP is normally on HTTPS, this option - * enables secure POSTing to HTTP endpoint without warning from browser. - * - * For this to work, module.php/core/postredirect.php must be accessible - * also via HTTP on IdP, e.g. if your IdP is on - * https://idp.example.org/ssp/, then - * http://idp.example.org/ssp/module.php/core/postredirect.php must be accessible. - */ - 'enable.http_post' => false, - - /* - * Options to override the default settings for php sessions. - */ - 'session.phpsession.cookiename' => null, - 'session.phpsession.savepath' => null, - 'session.phpsession.httponly' => true, - - /* - * Option to override the default settings for the auth token cookie - */ - 'session.authtoken.cookiename' => 'SSPAUTHTOKEN', - - /* - * Options for remember me feature for IdP sessions. Remember me feature - * has to be also implemented in authentication source used. - * - * Option 'session.cookie.lifetime' should be set to zero (0), i.e. cookie - * expires on browser session if remember me is not checked. - * - * Session duration ('session.duration' option) should be set according to - * 'session.rememberme.lifetime' option. - * - * It's advised to use remember me feature with session checking function - * defined with 'session.check_function' option. - */ - 'session.rememberme.enable' => false, - 'session.rememberme.checked' => false, - 'session.rememberme.lifetime' => $SESSION_REMEMBERME_LIFETIME, - - /** - * Custom function for session checking called on session init and loading. - * See docs/simplesamlphp-advancedfeatures.txt for function code example. - * - * Example: - * 'session.check_function' => array('sspmod_example_Util', 'checkSession'), - */ - - /* - * Languages available, RTL languages, and what language is default - */ - 'language.available' => array( - 'en', 'es', 'fr', 'pt', - ), - 'language.rtl' => array('ar', 'dv', 'fa', 'ur', 'he'), - 'language.default' => 'en', - - /* - * Options to override the default settings for the language parameter - */ - 'language.parameter.name' => 'language', - 'language.parameter.setcookie' => true, - - /* - * Options to override the default settings for the language cookie - */ - 'language.cookie.name' => 'language', - 'language.cookie.domain' => null, - 'language.cookie.path' => '/', - 'language.cookie.lifetime' => (60 * 60 * 24 * 900), - - /** - * Custom getLanguage function called from SimpleSAML_XHTML_Template::getLanguage(). - * Function should return language code of one of the available languages or NULL. - * See SimpleSAML_XHTML_Template::getLanguage() source code for more info. - * - * This option can be used to implement a custom function for determining - * the default language for the user. - * - * Example: - * 'language.get_language_function' => array('sspmod_example_Template', 'getLanguage'), - */ - - /* - * Extra dictionary for attribute names. - * This can be used to define local attributes. - * - * The format of the parameter is a string with :. - * - * Specifying this option will cause us to look for modules//dictionaries/.definition.json - * The dictionary should look something like: - * - * { - * "firstattribute": { - * "en": "English name", - * "no": "Norwegian name" - * }, - * "secondattribute": { - * "en": "English name", - * "no": "Norwegian name" - * } - * } - * - * Note that all attribute names in the dictionary must in lowercase. - * - * Example: 'attributes.extradictionary' => 'ourmodule:ourattributes', - */ - 'attributes.extradictionary' => null, - - /* - * Which theme directory should be used? - */ - 'theme.use' => 'material:material', - - - /* - * Default IdP for WS-Fed. - */ - // 'default-wsfed-idp' => 'urn:federation:pingfederate:localhost', - - /* - * Whether the discovery service should allow the user to save his choice of IdP. - */ - 'idpdisco.enableremember' => true, - 'idpdisco.rememberchecked' => true, - - // Disco service only accepts entities it knows. - 'idpdisco.validate' => true, - - 'idpdisco.extDiscoveryStorage' => null, - - /* - * IdP Discovery service look configuration. - * Wether to display a list of idp or to display a dropdown box. For many IdP' a dropdown box - * gives the best use experience. - * - * When using dropdown box a cookie is used to highlight the previously chosen IdP in the dropdown. - * This makes it easier for the user to choose the IdP - * - * Options: [links,dropdown] - * - */ - 'idpdisco.layout' => 'links', - - /* - * Whether simpleSAMLphp should sign the response or the assertion in SAML 1.1 authentication - * responses. - * - * The default is to sign the assertion element, but that can be overridden by setting this - * option to TRUE. It can also be overridden on a pr. SP basis by adding an option with the - * same name to the metadata of the SP. - */ - 'shib13.signresponse' => true, - - - /* - * Authentication processing filters that will be executed for all IdPs - * Both Shibboleth and SAML 2.0 - */ - 'authproc.idp' => [ - /* Enable the authproc filter below to add URN Prefixces to all attributes - 10 => array( - 'class' => 'core:AttributeMap', 'addurnprefix' - ), */ - /* Enable the authproc filter below to automatically generated eduPersonTargetedID. - 20 => 'core:TargetedID', - */ - - // Adopts language from attribute to use in UI - 30 => 'core:LanguageAdaptor', - - /* Add a realm attribute from edupersonprincipalname - 40 => 'core:AttributeRealm', - */ - 45 => [ - 'class' => 'core:StatisticsWithAttribute', - 'attributename' => 'realm', - 'type' => 'saml20-idp-SSO', - ], - - // If no attributes are requested in the SP metadata, then these will be sent through - 50 => [ - 'class' => 'core:AttributeLimit', - 'default' => true, - 'eduPersonPrincipalName', 'sn', 'givenName', 'mail', - ], - - // Use the uid value to populate the nameid entry - 60 => [ - 'class' => 'saml:AttributeNameID', - 'attribute' => 'uid', - 'Format' => 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient', - ], - - /* - * Search attribute "distinguishedName" for pattern and replaces if found - - 70 => array( - 'class' => 'core:AttributeAlter', - 'pattern' => '/OU=studerende/', - 'replacement' => 'Student', - 'subject' => 'distinguishedName', - '%replace', - ), - */ - - /* - * Consent module is enabled (with no permanent storage, using cookies). - - 90 => array( - 'class' => 'consent:Consent', - 'store' => 'consent:Cookie', - 'focus' => 'yes', - 'checked' => TRUE - ), - */ - - - // If language is set in Consent module it will be added as an attribute. - 99 => 'core:LanguageAdaptor', - ], - /* - * Authentication processing filters that will be executed for all SPs - * Both Shibboleth and SAML 2.0 - */ - 'authproc.sp' => [ - /* - 10 => array( - 'class' => 'core:AttributeMap', 'removeurnprefix' - ), - */ - - /* - * Generate the 'group' attribute populated from other variables, including eduPersonAffiliation. - 60 => array( - 'class' => 'core:GenerateGroups', 'eduPersonAffiliation' - ), - */ - /* - * All users will be members of 'users' and 'members' - 61 => array( - 'class' => 'core:AttributeAdd', 'groups' => array('users', 'members') - ), - */ - - // Adopts language from attribute to use in UI - 90 => 'core:LanguageAdaptor', - - ], - - - /* - * This option configures the metadata sources. The metadata sources is given as an array with - * different metadata sources. When searching for metadata, simpleSAMPphp will search through - * the array from start to end. - * - * Each element in the array is an associative array which configures the metadata source. - * The type of the metadata source is given by the 'type' element. For each type we have - * different configuration options. - * - * Flat file metadata handler: - * - 'type': This is always 'flatfile'. - * - 'directory': The directory we will load the metadata files from. The default value for - * this option is the value of the 'metadatadir' configuration option, or - * 'metadata/' if that option is unset. - * - * XML metadata handler: - * This metadata handler parses an XML file with either an EntityDescriptor element or an - * EntitiesDescriptor element. The XML file may be stored locally, or (for debugging) on a remote - * web server. - * The XML hetadata handler defines the following options: - * - 'type': This is always 'xml'. - * - 'file': Path to the XML file with the metadata. - * - 'url': The URL to fetch metadata from. THIS IS ONLY FOR DEBUGGING - THERE IS NO CACHING OF THE RESPONSE. - * - * - * Examples: - * - * This example defines two flatfile sources. One is the default metadata directory, the other - * is a metadata directory with autogenerated metadata files. - * - * 'metadata.sources' => array( - * array('type' => 'flatfile'), - * array('type' => 'flatfile', 'directory' => 'metadata-generated'), - * ), - * - * This example defines a flatfile source and an XML source. - * 'metadata.sources' => array( - * array('type' => 'flatfile'), - * array('type' => 'xml', 'file' => 'idp.example.org-idpMeta.xml'), - * ), - * - * - * Default: - * 'metadata.sources' => array( - * array('type' => 'flatfile') - * ), - */ - 'metadata.sources' => [ - ['type' => 'flatfile'], - ], - - - /* - * Configure the datastore for simpleSAMLphp. - * - * - 'phpsession': Limited datastore, which uses the PHP session. - * - 'memcache': Key-value datastore, based on memcache. - * - 'sql': SQL datastore, using PDO. - * - * The default datastore is 'phpsession'. - * - * (This option replaces the old 'session.handler'-option.) - */ - 'store.type' => 'phpsession', - - - /* - * The DSN the sql datastore should connect to. - * - * See http://www.php.net/manual/en/pdo.drivers.php for the various - * syntaxes. - */ - 'store.sql.dsn' => 'sqlite:/path/to/sqlitedatabase.sq3', - - /* - * The username and password to use when connecting to the database. - */ - 'store.sql.username' => null, - 'store.sql.password' => null, - - /* - * The prefix we should use on our tables. - */ - 'store.sql.prefix' => 'simpleSAMLphp', - - - /* - * Configuration for the MemcacheStore class. This allows you to store - * multiple redudant copies of sessions on different memcache servers. - * - * 'memcache_store.servers' is an array of server groups. Every data - * item will be mirrored in every server group. - * - * Each server group is an array of servers. The data items will be - * load-balanced between all servers in each server group. - * - * Each server is an array of parameters for the server. The following - * options are available: - * - 'hostname': This is the hostname or ip address where the - * memcache server runs. This is the only required option. - * - 'port': This is the port number of the memcache server. If this - * option isn't set, then we will use the 'memcache.default_port' - * ini setting. This is 11211 by default. - * - 'weight': This sets the weight of this server in this server - * group. http://php.net/manual/en/function.Memcache-addServer.php - * contains more information about the weight option. - * - 'timeout': The timeout for this server. By default, the timeout - * is 3 seconds. - * - * Example of redudant configuration with load balancing: - * This configuration makes it possible to lose both servers in the - * a-group or both servers in the b-group without losing any sessions. - * Note that sessions will be lost if one server is lost from both the - * a-group and the b-group. - * - * 'memcache_store.servers' => array( - * array( - * array('hostname' => 'mc_a1'), - * array('hostname' => 'mc_a2'), - * ), - * array( - * array('hostname' => 'mc_b1'), - * array('hostname' => 'mc_b2'), - * ), - * ), - * - * Example of simple configuration with only one memcache server, - * running on the same computer as the web server: - * Note that all sessions will be lost if the memcache server crashes. - * - * 'memcache_store.servers' => array( - * array( - * array('hostname' => 'localhost'), - * ), - * ), - * - */ - 'memcache_store.servers' => [ - [ - ['hostname' => 'localhost'], - ], - ], - - - /* - * This value is the duration data should be stored in memcache. Data - * will be dropped from the memcache servers when this time expires. - * The time will be reset every time the data is written to the - * memcache servers. - * - * This value should always be larger than the 'session.duration' - * option. Not doing this may result in the session being deleted from - * the memcache servers while it is still in use. - * - * Set this value to 0 if you don't want data to expire. - * - * Note: The oldest data will always be deleted if the memcache server - * runs out of storage space. - */ - 'memcache_store.expires' => 36 * (60 * 60), // 36 hours. - - - /* - * Should signing of generated metadata be enabled by default. - * - * Metadata signing can also be enabled for a individual SP or IdP by setting the - * same option in the metadata for the SP or IdP. - */ - 'metadata.sign.enable' => true, - - /* - * The default key & certificate which should be used to sign generated metadata. These - * are files stored in the cert dir. - * These values can be overridden by the options with the same names in the SP or - * IdP metadata. - * - * If these aren't specified here or in the metadata for the SP or IdP, then - * the 'certificate' and 'privatekey' option in the metadata will be used. - * if those aren't set, signing of metadata will fail. - */ - 'metadata.sign.privatekey' => 'ssp-hub-sp2.pem', - 'metadata.sign.privatekey_pass' => null, - 'metadata.sign.certificate' => 'ssp-hub-sp2.crt', - - - /* - * Proxy to use for retrieving URLs. - * - * Example: - * 'proxy' => 'tcp://proxy.example.com:5100' - */ - 'proxy' => null, - - /* - * Array of domains that are allowed when generating links or redirections - * to URLs. simpleSAMLphp will use this option to determine whether to - * to consider a given URL valid or not, but you should always validate - * URLs obtained from the input on your own (i.e. ReturnTo or RelayState - * parameters obtained from the $_REQUEST array). - * - * Set to NULL to disable checking of URLs. - * - * simpleSAMLphp will automatically add your own domain (either by checking - * it dinamically, or by using the domain defined in the 'baseurlpath' - * directive, the latter having precedence) to the list of trusted domains, - * in case this option is NOT set to NULL. In that case, you are explicitly - * telling simpleSAMLphp to verify URLs. - * - * Set to an empty array to disallow ALL redirections or links pointing to - * an external URL other than your own domain. - * - * Example: - * 'trusted.url.domains' => array('sp.example.com', 'app.example.com'), - */ - 'trusted.url.domains' => null, - -]; diff --git a/development/sp2-local/metadata/saml20-idp-remote.php b/development/sp2-local/metadata/saml20-idp-remote.php index f518f827..8558a9f2 100644 --- a/development/sp2-local/metadata/saml20-idp-remote.php +++ b/development/sp2-local/metadata/saml20-idp-remote.php @@ -4,16 +4,16 @@ * * Remember to remove the IdPs you don't use from this file. * - * See: https://simplesamlphp.org/docs/stable/simplesamlphp-reference-idp-remote + * See: https://simplesamlphp.org/docs/stable/simplesamlphp-reference-idp-remote */ /* * Guest IdP. allows users to sign up and register. Great for testing! */ $metadata['ssp-hub.local'] = [ - 'SingleSignOnService' => 'http://ssp-hub.local/saml2/idp/SSOService.php', - 'SingleLogoutService' => 'http://ssp-hub.local/saml2/idp/SingleLogoutService.php', - 'certData' =>'MIIDzzCCAregAwIBAgIJANuvVcQPANecMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE3MTIzMTEyWhcNMjYxMDE3MTIzMTEyWjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxAimEkw4Teyf/gZelL7OuQYg/JbDIKHPXJhLPBm/HK6pM5ZZKydVXTdMgMqkl4xK+xZ2CnkozsUiMLhAuWBsX9Dcz1M4SkPRwk4puFhXzsp7fKIVP43zUhF7p2TmbernrrIQHjg6PuegKmCGyiKUpukcYvf2RXNwHwJx+Uq0zLP4PgBSrQ2t1eKZ1jQ+noBb1NqOuy969WRYmN4EmjXDuJB9d+b3GwtbZToWgiFxFjd/NN9BFJXZEaLzRj5LAq5bu2vPPDZDarHFMRUzVJ91eafoaz6zpR1iUGj9zR+y2sUPxD/fJMZ+4AHWA2LOrTBBIuuWbp96yvcJ4WjmlfhcFQIDAQABo1AwTjAdBgNVHQ4EFgQUkJFAMJdr2lXsuezS6pDXHnmJspMwHwYDVR0jBBgwFoAUkJFAMJdr2lXsuezS6pDXHnmJspMwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAOEPbchaUr45L5i+ueookevsABYnltwJZ4rYJbF9VURPcEhB6JxTMZqb4s113ftHvVYfoAfLYZ9swETaHL+esx41yAebf0kWpQ3f63S5F2FcrTj+HP0XsvW/EDrvaTKM9jnKPNmbXrpq06eaUZfkVL0TAUsxYTKkttTSTiESEzp5wzYyhp7l3kpHhEvGOlh5suYjnZ2HN0uxscCR6PS47H6TMMEZuG032DWDC016/JniWvERtpf4Yw26V+I9xevp2E2MPcZne31Pe3sCh4Wpe4cV/SCFqZHlpnH96ncz4F+KvmmhbEx5VPhQSJNFIWEvI86k+lTNQOqj6YVvGvq95LQ==', - + 'SingleSignOnService' => 'http://ssp-hub.local/saml2/idp/SSOService.php', + 'SingleLogoutService' => 'http://ssp-hub.local/saml2/idp/SingleLogoutService.php', + 'certData' => 'MIIDzzCCAregAwIBAgIJANuvVcQPANecMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE3MTIzMTEyWhcNMjYxMDE3MTIzMTEyWjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxAimEkw4Teyf/gZelL7OuQYg/JbDIKHPXJhLPBm/HK6pM5ZZKydVXTdMgMqkl4xK+xZ2CnkozsUiMLhAuWBsX9Dcz1M4SkPRwk4puFhXzsp7fKIVP43zUhF7p2TmbernrrIQHjg6PuegKmCGyiKUpukcYvf2RXNwHwJx+Uq0zLP4PgBSrQ2t1eKZ1jQ+noBb1NqOuy969WRYmN4EmjXDuJB9d+b3GwtbZToWgiFxFjd/NN9BFJXZEaLzRj5LAq5bu2vPPDZDarHFMRUzVJ91eafoaz6zpR1iUGj9zR+y2sUPxD/fJMZ+4AHWA2LOrTBBIuuWbp96yvcJ4WjmlfhcFQIDAQABo1AwTjAdBgNVHQ4EFgQUkJFAMJdr2lXsuezS6pDXHnmJspMwHwYDVR0jBBgwFoAUkJFAMJdr2lXsuezS6pDXHnmJspMwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAOEPbchaUr45L5i+ueookevsABYnltwJZ4rYJbF9VURPcEhB6JxTMZqb4s113ftHvVYfoAfLYZ9swETaHL+esx41yAebf0kWpQ3f63S5F2FcrTj+HP0XsvW/EDrvaTKM9jnKPNmbXrpq06eaUZfkVL0TAUsxYTKkttTSTiESEzp5wzYyhp7l3kpHhEvGOlh5suYjnZ2HN0uxscCR6PS47H6TMMEZuG032DWDC016/JniWvERtpf4Yw26V+I9xevp2E2MPcZne31Pe3sCh4Wpe4cV/SCFqZHlpnH96ncz4F+KvmmhbEx5VPhQSJNFIWEvI86k+lTNQOqj6YVvGvq95LQ==', + ]; diff --git a/development/sp3-local/cert/ssp-hub-sp3.crt b/development/sp3-local/cert/saml.crt similarity index 100% rename from development/sp3-local/cert/ssp-hub-sp3.crt rename to development/sp3-local/cert/saml.crt diff --git a/development/sp3-local/cert/ssp-hub-sp3.pem b/development/sp3-local/cert/saml.pem similarity index 100% rename from development/sp3-local/cert/ssp-hub-sp3.pem rename to development/sp3-local/cert/saml.pem diff --git a/development/sp3-local/config/authsources.php b/development/sp3-local/config/authsources.php index 4559d445..ae2b9f9b 100644 --- a/development/sp3-local/config/authsources.php +++ b/development/sp3-local/config/authsources.php @@ -29,7 +29,7 @@ 'discoURL' => null, // Specify what private key to use (such as for decrypting assertions). - 'privatekey' => 'ssp-hub-sp3.pem', + 'privatekey' => 'saml.pem', ], 'ssp-hub-custom-port' => [ @@ -48,6 +48,6 @@ 'discoURL' => null, // Specify what private key to use (such as for decrypting assertions). - 'privatekey' => 'ssp-hub-sp3.pem', + 'privatekey' => 'saml.pem', ], ]; diff --git a/development/sp3-local/config/config.php b/development/sp3-local/config/config.php deleted file mode 100644 index 3a6d4aaa..00000000 --- a/development/sp3-local/config/config.php +++ /dev/null @@ -1,836 +0,0 @@ - SimpleSAML\Logger::ERR, // No statistics, only errors - 'WARNING' => SimpleSAML\Logger::WARNING, // No statistics, only warnings/errors - 'NOTICE' => SimpleSAML\Logger::NOTICE, // Statistics and errors - 'INFO' => SimpleSAML\Logger::INFO, // Verbose logs - 'DEBUG' => SimpleSAML\Logger::DEBUG, // Full debug logs - not recommended for production -]; - -/* - * Get config settings from ENV vars or set defaults - */ - -// Required to be defined in environment -$ADMIN_EMAIL = Env::get('ADMIN_EMAIL'); -$ADMIN_PASS = Env::get('ADMIN_PASS'); -$SECRET_SALT = Env::get('SECRET_SALT'); - -// Defaults provided if not defined in environment -$BASE_URL_PATH = Env::get('BASE_URL_PATH', '/'); -$ADMIN_NAME = Env::get('ADMIN_NAME', 'SAML Admin'); -$ADMIN_PROTECT_INDEX_PAGE = Env::get('ADMIN_PROTECT_INDEX_PAGE', true); -$SHOW_SAML_ERRORS = Env::get('SHOW_SAML_ERRORS', false); -$ENABLE_DEBUG = Env::get('ENABLE_DEBUG', false); -$LOGGING_LEVEL = Env::get('LOGGING_LEVEL', 'NOTICE'); -$LOGGING_HANDLER = Env::get('LOGGING_HANDLER', 'stderr'); -$SESSION_DURATION = (int)(Env::get('SESSION_DURATION', 540)); -$SESSION_DATASTORE_TIMEOUT = (int)(Env::get('SESSION_DATASTORE_TIMEOUT', (4 * 60 * 60))); // 4 hours -$SESSION_STATE_TIMEOUT = (int)(Env::get('SESSION_STATE_TIMEOUT', (60 * 60))); // 1 hour -$SESSION_COOKIE_LIFETIME = (int)(Env::get('SESSION_COOKIE_LIFETIME', 0)); -$SESSION_REMEMBERME_LIFETIME = (int)(Env::get('SESSION_REMEMBERME_LIFETIME', (14 * 86400))); // 14 days -$SECURE_COOKIE = Env::get('SECURE_COOKIE', true); -$SAML20_IDP_ENABLE = Env::get('SAML20_IDP_ENABLE', true); - -$config = [ - - /* - * Setup the following parameters to match the directory of your installation. - * See the user manual for more details. - * - * Valid format for baseurlpath is: - * [(http|https)://(hostname|fqdn)[:port]]/[path/to/simplesaml/] - * (note that it must end with a '/') - * - * The full url format is useful if your simpleSAMLphp setup is hosted behind - * a reverse proxy. In that case you can specify the external url here. - * - * Please note that simpleSAMLphp will then redirect all queries to the - * external url, no matter where you come from (direct access or via the - * reverse proxy). - */ - 'baseurlpath' => $BASE_URL_PATH, - 'certdir' => 'cert/', - 'loggingdir' => 'log/', - 'datadir' => 'data/', - - /* - * A directory where simpleSAMLphp can save temporary files. - * - * SimpleSAMLphp will attempt to create this directory if it doesn't exist. - */ - 'tempdir' => '/tmp/simplesaml', - - - /* - * The 'debug' option allows you to control how SimpleSAMLphp behaves in certain - * situations where further action may be taken - * - * It can be left unset, in which case, debugging is switched off for all actions. - * If set, it MUST be an array containing the actions that you want to enable, or - * alternatively a hashed array where the keys are the actions and their - * corresponding values are booleans enabling or disabling each particular action. - * - * SimpleSAMLphp provides some pre-defined actions, though modules could add new - * actions here. Refer to the documentation of every module to learn if they - * allow you to set any more debugging actions. - * - * The pre-defined actions are: - * - * - 'saml': this action controls the logging of SAML messages exchanged with other - * entities. When enabled ('saml' is present in this option, or set to true), all - * SAML messages will be logged, including plaintext versions of encrypted - * messages. - * - * - 'backtraces': this action controls the logging of error backtraces. If you - * want to log backtraces so that you can debug any possible errors happening in - * SimpleSAMLphp, enable this action (add it to the array or set it to true). - * - * - 'validatexml': this action allows you to validate SAML documents against all - * the relevant XML schemas. SAML 1.1 messages or SAML metadata parsed with - * the XML to SimpleSAMLphp metadata converter or the metaedit module will - * validate the SAML documents if this option is enabled. - * - * If you want to disable debugging completely, unset this option or set it to an - * empty array. - */ - 'debug' => [ - 'saml' => $ENABLE_DEBUG, - 'backtraces' => true, - 'validatexml' => $ENABLE_DEBUG, - ], - - /* - * When showerrors is enabled, all error messages and stack traces will be output - * to the browser. - * - * When errorreporting is enabled, a form will be presented for the user to report - * the error to technicalcontact_email. - */ - 'showerrors' => $SHOW_SAML_ERRORS, - 'errorreporting' => false, - - /* - * Custom error show function called from SimpleSAML_Error_Error::show. - * See docs/simplesamlphp-errorhandling.txt for function code example. - * - * Example: - * 'errors.show_function' => array('sspmod_example_Error_Show', 'show'), - */ - - /* - * This option allows you to enable validation of XML data against its - * schemas. A warning will be written to the log if validation fails. - */ - 'debug.validatexml' => false, - - /* - * This password must be kept secret, and modified from the default value 123. - * This password will give access to the installation page of simpleSAMLphp with - * metadata listing and diagnostics pages. - * You can also put a hash here; run "bin/pwgen.php" to generate one. - */ - 'auth.adminpassword' => $ADMIN_PASS, - 'admin.protectindexpage' => $ADMIN_PROTECT_INDEX_PAGE, - 'admin.protectmetadata' => true, - - /* - * This is a secret salt used by simpleSAMLphp when it needs to generate a secure hash - * of a value. It must be changed from its default value to a secret value. The value of - * 'secretsalt' can be any valid string of any length. - * - * A possible way to generate a random salt is by running the following command from a unix shell: - * tr -c -d '0123456789abcdefghijklmnopqrstuvwxyz' /dev/null;echo - */ - 'secretsalt' => $SECRET_SALT, - - /* - * Some information about the technical persons running this installation. - * The email address will be used as the recipient address for error reports, and - * also as the technical contact in generated metadata. - */ - 'technicalcontact_name' => $ADMIN_NAME, - 'technicalcontact_email' => $ADMIN_EMAIL, - - /* - * The timezone of the server. This option should be set to the timezone you want - * simpleSAMLphp to report the time in. The default is to guess the timezone based - * on your system timezone. - * - * See this page for a list of valid timezones: http://php.net/manual/en/timezones.php - */ - 'timezone' => 'GMT', - - /* - * Logging. - * - * define the minimum log level to log - * SimpleSAML\Logger::ERR No statistics, only errors - * SimpleSAML\Logger::WARNING No statistics, only warnings/errors - * SimpleSAML\Logger::NOTICE Statistics and errors - * SimpleSAML\Logger::INFO Verbose logs - * SimpleSAML\Logger::DEBUG Full debug logs - not reccomended for production - * - * Choose logging handler. - * - * Options: [syslog,file,errorlog,stderr] - * - */ - 'logging.level' => $logLevels[$LOGGING_LEVEL], - 'logging.handler' => $LOGGING_HANDLER, - - /* - * Specify the format of the logs. Its use varies depending on the log handler used (for instance, you cannot - * control here how dates are displayed when using the syslog or errorlog handlers), but in general the options - * are: - * - * - %date{}: the date and time, with its format specified inside the brackets. See the PHP documentation - * of the strftime() function for more information on the format. If the brackets are omitted, the standard - * format is applied. This can be useful if you just want to control the placement of the date, but don't care - * about the format. - * - * - %process: the name of the SimpleSAMLphp process. Remember you can configure this in the 'logging.processname' - * option below. - * - * - %level: the log level (name or number depending on the handler used). - * - * - %stat: if the log entry is intended for statistical purposes, it will print the string 'STAT ' (bear in mind - * the trailing space). - * - * - %trackid: the track ID, an identifier that allows you to track a single session. - * - * - %srcip: the IP address of the client. If you are behind a proxy, make sure to modify the - * $_SERVER['REMOTE_ADDR'] variable on your code accordingly to the X-Forwarded-For header. - * - * - %msg: the message to be logged. - * - */ - //'logging.format' => '%date{%b %d %H:%M:%S} %process %level %stat[%trackid] %msg', - - /* - * Choose which facility should be used when logging with syslog. - * - * These can be used for filtering the syslog output from simpleSAMLphp into its - * own file by configuring the syslog daemon. - * - * See the documentation for openlog (http://php.net/manual/en/function.openlog.php) for available - * facilities. Note that only LOG_USER is valid on windows. - * - * The default is to use LOG_LOCAL5 if available, and fall back to LOG_USER if not. - */ - 'logging.facility' => defined('LOG_LOCAL5') ? constant('LOG_LOCAL5') : LOG_USER, - - /* - * The process name that should be used when logging to syslog. - * The value is also written out by the other logging handlers. - */ - 'logging.processname' => 'simplesamlphp', - - /* Logging: file - Logfilename in the loggingdir from above. - */ - 'logging.logfile' => 'simplesamlphp.log', - - /* (New) statistics output configuration. - * - * This is an array of outputs. Each output has at least a 'class' option, which - * selects the output. - */ - 'statistics.out' => [// Log statistics to the normal log. - /* - [ - 'class' => 'core:Log', - 'level' => 'notice', - ], - */ - // Log statistics to files in a directory. One file per day. - /* - [ - 'class' => 'core:File', - 'directory' => '/var/log/stats', - ], - */ - ], - - - /* - * Enable - * - * Which functionality in simpleSAMLphp do you want to enable. Normally you would enable only - * one of the functionalities below, but in some cases you could run multiple functionalities. - * In example when you are setting up a federation bridge. - */ - 'enable.saml20-idp' => $SAML20_IDP_ENABLE, - 'enable.shib13-idp' => false, - 'enable.adfs-idp' => false, - 'enable.wsfed-sp' => false, - 'enable.authmemcookie' => false, - - - /* - * Module enable configuration - * - * Configuration to override module enabling/disabling. - * - * Example: - * - * 'module.enable' => array( - * // Setting to TRUE enables. - * 'exampleauth' => TRUE, - * // Setting to FALSE disables. - * 'saml' => FALSE, - * // Unset or NULL uses default. - * 'core' => NULL, - * ), - * - */ - - 'module.enable' => [ - 'saml' => true, - 'core' => true, - 'admin' => true, - ], - - /* - * This value is the duration of the session in seconds. Make sure that the time duration of - * cookies both at the SP and the IdP exceeds this duration. - */ - 'session.duration' => $SESSION_DURATION, - - /* - * Sets the duration, in seconds, data should be stored in the datastore. As the datastore is used for - * login and logout requests, thid option will control the maximum time these operations can take. - * The default is 4 hours (4*60*60) seconds, which should be more than enough for these operations. - */ - 'session.datastore.timeout' => $SESSION_DATASTORE_TIMEOUT, - - /* - * Sets the duration, in seconds, auth state should be stored. - */ - 'session.state.timeout' => $SESSION_STATE_TIMEOUT, - - /* - * Option to override the default settings for the session cookie name - */ - 'session.cookie.name' => 'SSPSESSID', - - /* - * Expiration time for the session cookie, in seconds. - * - * Defaults to 0, which means that the cookie expires when the browser is closed. - * - * Example: - * 'session.cookie.lifetime' => 30*60, - */ - 'session.cookie.lifetime' => $SESSION_COOKIE_LIFETIME, - - /* - * Limit the path of the cookies. - * - * Can be used to limit the path of the cookies to a specific subdirectory. - * - * Example: - * 'session.cookie.path' => '/simplesaml/', - */ - 'session.cookie.path' => '/', - - /* - * Cookie domain. - * - * Can be used to make the session cookie available to several domains. - * - * Example: - * 'session.cookie.domain' => '.example.org', - */ - 'session.cookie.domain' => null, - - /* - * Set the secure flag in the cookie. - * - * Set this to TRUE if the user only accesses your service - * through https. If the user can access the service through - * both http and https, this must be set to FALSE. - */ - 'session.cookie.secure' => $SECURE_COOKIE, - - /* - * When set to FALSE fallback to transient session on session initialization - * failure, throw exception otherwise. - */ - 'session.disable_fallback' => false, - - /* - * Enable secure POST from HTTPS to HTTP. - * - * If you have some SP's on HTTP and IdP is normally on HTTPS, this option - * enables secure POSTing to HTTP endpoint without warning from browser. - * - * For this to work, module.php/core/postredirect.php must be accessible - * also via HTTP on IdP, e.g. if your IdP is on - * https://idp.example.org/ssp/, then - * http://idp.example.org/ssp/module.php/core/postredirect.php must be accessible. - */ - 'enable.http_post' => false, - - /* - * Options to override the default settings for php sessions. - */ - 'session.phpsession.cookiename' => null, - 'session.phpsession.savepath' => null, - 'session.phpsession.httponly' => true, - - /* - * Option to override the default settings for the auth token cookie - */ - 'session.authtoken.cookiename' => 'SSPAUTHTOKEN', - - /* - * Options for remember me feature for IdP sessions. Remember me feature - * has to be also implemented in authentication source used. - * - * Option 'session.cookie.lifetime' should be set to zero (0), i.e. cookie - * expires on browser session if remember me is not checked. - * - * Session duration ('session.duration' option) should be set according to - * 'session.rememberme.lifetime' option. - * - * It's advised to use remember me feature with session checking function - * defined with 'session.check_function' option. - */ - 'session.rememberme.enable' => false, - 'session.rememberme.checked' => false, - 'session.rememberme.lifetime' => $SESSION_REMEMBERME_LIFETIME, - - /** - * Custom function for session checking called on session init and loading. - * See docs/simplesamlphp-advancedfeatures.txt for function code example. - * - * Example: - * 'session.check_function' => array('sspmod_example_Util', 'checkSession'), - */ - - /* - * Languages available, RTL languages, and what language is default - */ - 'language.available' => array( - 'en', 'es', 'fr', 'pt', - ), - 'language.rtl' => array('ar', 'dv', 'fa', 'ur', 'he'), - 'language.default' => 'en', - - /* - * Options to override the default settings for the language parameter - */ - 'language.parameter.name' => 'language', - 'language.parameter.setcookie' => true, - - /* - * Options to override the default settings for the language cookie - */ - 'language.cookie.name' => 'language', - 'language.cookie.domain' => null, - 'language.cookie.path' => '/', - 'language.cookie.lifetime' => (60 * 60 * 24 * 900), - - /** - * Custom getLanguage function called from SimpleSAML_XHTML_Template::getLanguage(). - * Function should return language code of one of the available languages or NULL. - * See SimpleSAML_XHTML_Template::getLanguage() source code for more info. - * - * This option can be used to implement a custom function for determining - * the default language for the user. - * - * Example: - * 'language.get_language_function' => array('sspmod_example_Template', 'getLanguage'), - */ - - /* - * Extra dictionary for attribute names. - * This can be used to define local attributes. - * - * The format of the parameter is a string with :. - * - * Specifying this option will cause us to look for modules//dictionaries/.definition.json - * The dictionary should look something like: - * - * { - * "firstattribute": { - * "en": "English name", - * "no": "Norwegian name" - * }, - * "secondattribute": { - * "en": "English name", - * "no": "Norwegian name" - * } - * } - * - * Note that all attribute names in the dictionary must in lowercase. - * - * Example: 'attributes.extradictionary' => 'ourmodule:ourattributes', - */ - 'attributes.extradictionary' => null, - - /* - * Which theme directory should be used? - */ - 'theme.use' => 'material:material', - - - /* - * Default IdP for WS-Fed. - */ - // 'default-wsfed-idp' => 'urn:federation:pingfederate:localhost', - - /* - * Whether the discovery service should allow the user to save his choice of IdP. - */ - 'idpdisco.enableremember' => true, - 'idpdisco.rememberchecked' => true, - - // Disco service only accepts entities it knows. - 'idpdisco.validate' => true, - - 'idpdisco.extDiscoveryStorage' => null, - - /* - * IdP Discovery service look configuration. - * Wether to display a list of idp or to display a dropdown box. For many IdP' a dropdown box - * gives the best use experience. - * - * When using dropdown box a cookie is used to highlight the previously chosen IdP in the dropdown. - * This makes it easier for the user to choose the IdP - * - * Options: [links,dropdown] - * - */ - 'idpdisco.layout' => 'links', - - /* - * Whether simpleSAMLphp should sign the response or the assertion in SAML 1.1 authentication - * responses. - * - * The default is to sign the assertion element, but that can be overridden by setting this - * option to TRUE. It can also be overridden on a pr. SP basis by adding an option with the - * same name to the metadata of the SP. - */ - 'shib13.signresponse' => true, - - - /* - * Authentication processing filters that will be executed for all IdPs - * Both Shibboleth and SAML 2.0 - */ - 'authproc.idp' => [ - /* Enable the authproc filter below to add URN Prefixces to all attributes - 10 => array( - 'class' => 'core:AttributeMap', 'addurnprefix' - ), */ - /* Enable the authproc filter below to automatically generated eduPersonTargetedID. - 20 => 'core:TargetedID', - */ - - // Adopts language from attribute to use in UI - 30 => 'core:LanguageAdaptor', - - /* Add a realm attribute from edupersonprincipalname - 40 => 'core:AttributeRealm', - */ - 45 => [ - 'class' => 'core:StatisticsWithAttribute', - 'attributename' => 'realm', - 'type' => 'saml20-idp-SSO', - ], - - // If no attributes are requested in the SP metadata, then these will be sent through - 50 => [ - 'class' => 'core:AttributeLimit', - 'default' => true, - 'eduPersonPrincipalName', 'sn', 'givenName', 'mail', - ], - - // Use the uid value to populate the nameid entry - 60 => [ - 'class' => 'saml:AttributeNameID', - 'attribute' => 'uid', - 'Format' => 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient', - ], - - /* - * Search attribute "distinguishedName" for pattern and replaces if found - - 70 => array( - 'class' => 'core:AttributeAlter', - 'pattern' => '/OU=studerende/', - 'replacement' => 'Student', - 'subject' => 'distinguishedName', - '%replace', - ), - */ - - /* - * Consent module is enabled (with no permanent storage, using cookies). - - 90 => array( - 'class' => 'consent:Consent', - 'store' => 'consent:Cookie', - 'focus' => 'yes', - 'checked' => TRUE - ), - */ - - - // If language is set in Consent module it will be added as an attribute. - 99 => 'core:LanguageAdaptor', - ], - /* - * Authentication processing filters that will be executed for all SPs - * Both Shibboleth and SAML 2.0 - */ - 'authproc.sp' => [ - /* - 10 => array( - 'class' => 'core:AttributeMap', 'removeurnprefix' - ), - */ - - /* - * Generate the 'group' attribute populated from other variables, including eduPersonAffiliation. - 60 => array( - 'class' => 'core:GenerateGroups', 'eduPersonAffiliation' - ), - */ - /* - * All users will be members of 'users' and 'members' - 61 => array( - 'class' => 'core:AttributeAdd', 'groups' => array('users', 'members') - ), - */ - - // Adopts language from attribute to use in UI - 90 => 'core:LanguageAdaptor', - - ], - - - /* - * This option configures the metadata sources. The metadata sources is given as an array with - * different metadata sources. When searching for metadata, simpleSAMPphp will search through - * the array from start to end. - * - * Each element in the array is an associative array which configures the metadata source. - * The type of the metadata source is given by the 'type' element. For each type we have - * different configuration options. - * - * Flat file metadata handler: - * - 'type': This is always 'flatfile'. - * - 'directory': The directory we will load the metadata files from. The default value for - * this option is the value of the 'metadatadir' configuration option, or - * 'metadata/' if that option is unset. - * - * XML metadata handler: - * This metadata handler parses an XML file with either an EntityDescriptor element or an - * EntitiesDescriptor element. The XML file may be stored locally, or (for debugging) on a remote - * web server. - * The XML hetadata handler defines the following options: - * - 'type': This is always 'xml'. - * - 'file': Path to the XML file with the metadata. - * - 'url': The URL to fetch metadata from. THIS IS ONLY FOR DEBUGGING - THERE IS NO CACHING OF THE RESPONSE. - * - * - * Examples: - * - * This example defines two flatfile sources. One is the default metadata directory, the other - * is a metadata directory with autogenerated metadata files. - * - * 'metadata.sources' => array( - * array('type' => 'flatfile'), - * array('type' => 'flatfile', 'directory' => 'metadata-generated'), - * ), - * - * This example defines a flatfile source and an XML source. - * 'metadata.sources' => array( - * array('type' => 'flatfile'), - * array('type' => 'xml', 'file' => 'idp.example.org-idpMeta.xml'), - * ), - * - * - * Default: - * 'metadata.sources' => array( - * array('type' => 'flatfile') - * ), - */ - 'metadata.sources' => [ - ['type' => 'flatfile'], - ], - - - /* - * Configure the datastore for simpleSAMLphp. - * - * - 'phpsession': Limited datastore, which uses the PHP session. - * - 'memcache': Key-value datastore, based on memcache. - * - 'sql': SQL datastore, using PDO. - * - * The default datastore is 'phpsession'. - * - * (This option replaces the old 'session.handler'-option.) - */ - 'store.type' => 'phpsession', - - - /* - * The DSN the sql datastore should connect to. - * - * See http://www.php.net/manual/en/pdo.drivers.php for the various - * syntaxes. - */ - 'store.sql.dsn' => 'sqlite:/path/to/sqlitedatabase.sq3', - - /* - * The username and password to use when connecting to the database. - */ - 'store.sql.username' => null, - 'store.sql.password' => null, - - /* - * The prefix we should use on our tables. - */ - 'store.sql.prefix' => 'simpleSAMLphp', - - - /* - * Configuration for the MemcacheStore class. This allows you to store - * multiple redudant copies of sessions on different memcache servers. - * - * 'memcache_store.servers' is an array of server groups. Every data - * item will be mirrored in every server group. - * - * Each server group is an array of servers. The data items will be - * load-balanced between all servers in each server group. - * - * Each server is an array of parameters for the server. The following - * options are available: - * - 'hostname': This is the hostname or ip address where the - * memcache server runs. This is the only required option. - * - 'port': This is the port number of the memcache server. If this - * option isn't set, then we will use the 'memcache.default_port' - * ini setting. This is 11211 by default. - * - 'weight': This sets the weight of this server in this server - * group. http://php.net/manual/en/function.Memcache-addServer.php - * contains more information about the weight option. - * - 'timeout': The timeout for this server. By default, the timeout - * is 3 seconds. - * - * Example of redudant configuration with load balancing: - * This configuration makes it possible to lose both servers in the - * a-group or both servers in the b-group without losing any sessions. - * Note that sessions will be lost if one server is lost from both the - * a-group and the b-group. - * - * 'memcache_store.servers' => array( - * array( - * array('hostname' => 'mc_a1'), - * array('hostname' => 'mc_a2'), - * ), - * array( - * array('hostname' => 'mc_b1'), - * array('hostname' => 'mc_b2'), - * ), - * ), - * - * Example of simple configuration with only one memcache server, - * running on the same computer as the web server: - * Note that all sessions will be lost if the memcache server crashes. - * - * 'memcache_store.servers' => array( - * array( - * array('hostname' => 'localhost'), - * ), - * ), - * - */ - 'memcache_store.servers' => [ - [ - ['hostname' => 'localhost'], - ], - ], - - - /* - * This value is the duration data should be stored in memcache. Data - * will be dropped from the memcache servers when this time expires. - * The time will be reset every time the data is written to the - * memcache servers. - * - * This value should always be larger than the 'session.duration' - * option. Not doing this may result in the session being deleted from - * the memcache servers while it is still in use. - * - * Set this value to 0 if you don't want data to expire. - * - * Note: The oldest data will always be deleted if the memcache server - * runs out of storage space. - */ - 'memcache_store.expires' => 36 * (60 * 60), // 36 hours. - - - /* - * Should signing of generated metadata be enabled by default. - * - * Metadata signing can also be enabled for a individual SP or IdP by setting the - * same option in the metadata for the SP or IdP. - */ - 'metadata.sign.enable' => true, - - /* - * The default key & certificate which should be used to sign generated metadata. These - * are files stored in the cert dir. - * These values can be overridden by the options with the same names in the SP or - * IdP metadata. - * - * If these aren't specified here or in the metadata for the SP or IdP, then - * the 'certificate' and 'privatekey' option in the metadata will be used. - * if those aren't set, signing of metadata will fail. - */ - 'metadata.sign.privatekey' => 'ssp-hub-sp3.pem', - 'metadata.sign.privatekey_pass' => null, - 'metadata.sign.certificate' => 'ssp-hub-sp3.crt', - - - /* - * Proxy to use for retrieving URLs. - * - * Example: - * 'proxy' => 'tcp://proxy.example.com:5100' - */ - 'proxy' => null, - - /* - * Array of domains that are allowed when generating links or redirections - * to URLs. simpleSAMLphp will use this option to determine whether to - * to consider a given URL valid or not, but you should always validate - * URLs obtained from the input on your own (i.e. ReturnTo or RelayState - * parameters obtained from the $_REQUEST array). - * - * Set to NULL to disable checking of URLs. - * - * simpleSAMLphp will automatically add your own domain (either by checking - * it dinamically, or by using the domain defined in the 'baseurlpath' - * directive, the latter having precedence) to the list of trusted domains, - * in case this option is NOT set to NULL. In that case, you are explicitly - * telling simpleSAMLphp to verify URLs. - * - * Set to an empty array to disallow ALL redirections or links pointing to - * an external URL other than your own domain. - * - * Example: - * 'trusted.url.domains' => array('sp.example.com', 'app.example.com'), - */ - 'trusted.url.domains' => null, - -]; diff --git a/development/sp3-local/metadata/saml20-idp-remote.php b/development/sp3-local/metadata/saml20-idp-remote.php index f518f827..8558a9f2 100644 --- a/development/sp3-local/metadata/saml20-idp-remote.php +++ b/development/sp3-local/metadata/saml20-idp-remote.php @@ -4,16 +4,16 @@ * * Remember to remove the IdPs you don't use from this file. * - * See: https://simplesamlphp.org/docs/stable/simplesamlphp-reference-idp-remote + * See: https://simplesamlphp.org/docs/stable/simplesamlphp-reference-idp-remote */ /* * Guest IdP. allows users to sign up and register. Great for testing! */ $metadata['ssp-hub.local'] = [ - 'SingleSignOnService' => 'http://ssp-hub.local/saml2/idp/SSOService.php', - 'SingleLogoutService' => 'http://ssp-hub.local/saml2/idp/SingleLogoutService.php', - 'certData' =>'MIIDzzCCAregAwIBAgIJANuvVcQPANecMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE3MTIzMTEyWhcNMjYxMDE3MTIzMTEyWjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxAimEkw4Teyf/gZelL7OuQYg/JbDIKHPXJhLPBm/HK6pM5ZZKydVXTdMgMqkl4xK+xZ2CnkozsUiMLhAuWBsX9Dcz1M4SkPRwk4puFhXzsp7fKIVP43zUhF7p2TmbernrrIQHjg6PuegKmCGyiKUpukcYvf2RXNwHwJx+Uq0zLP4PgBSrQ2t1eKZ1jQ+noBb1NqOuy969WRYmN4EmjXDuJB9d+b3GwtbZToWgiFxFjd/NN9BFJXZEaLzRj5LAq5bu2vPPDZDarHFMRUzVJ91eafoaz6zpR1iUGj9zR+y2sUPxD/fJMZ+4AHWA2LOrTBBIuuWbp96yvcJ4WjmlfhcFQIDAQABo1AwTjAdBgNVHQ4EFgQUkJFAMJdr2lXsuezS6pDXHnmJspMwHwYDVR0jBBgwFoAUkJFAMJdr2lXsuezS6pDXHnmJspMwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAOEPbchaUr45L5i+ueookevsABYnltwJZ4rYJbF9VURPcEhB6JxTMZqb4s113ftHvVYfoAfLYZ9swETaHL+esx41yAebf0kWpQ3f63S5F2FcrTj+HP0XsvW/EDrvaTKM9jnKPNmbXrpq06eaUZfkVL0TAUsxYTKkttTSTiESEzp5wzYyhp7l3kpHhEvGOlh5suYjnZ2HN0uxscCR6PS47H6TMMEZuG032DWDC016/JniWvERtpf4Yw26V+I9xevp2E2MPcZne31Pe3sCh4Wpe4cV/SCFqZHlpnH96ncz4F+KvmmhbEx5VPhQSJNFIWEvI86k+lTNQOqj6YVvGvq95LQ==', - + 'SingleSignOnService' => 'http://ssp-hub.local/saml2/idp/SSOService.php', + 'SingleLogoutService' => 'http://ssp-hub.local/saml2/idp/SingleLogoutService.php', + 'certData' => 'MIIDzzCCAregAwIBAgIJANuvVcQPANecMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzEPMA0GA1UEBwwGV2F4aGF3MQwwCgYDVQQKDANTSUwxDTALBgNVBAsMBEdUSVMxDjAMBgNVBAMMBVN0ZXZlMSQwIgYJKoZIhvcNAQkBFhVzdGV2ZV9iYWd3ZWxsQHNpbC5vcmcwHhcNMTYxMDE3MTIzMTEyWhcNMjYxMDE3MTIzMTEyWjB+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTkMxDzANBgNVBAcMBldheGhhdzEMMAoGA1UECgwDU0lMMQ0wCwYDVQQLDARHVElTMQ4wDAYDVQQDDAVTdGV2ZTEkMCIGCSqGSIb3DQEJARYVc3RldmVfYmFnd2VsbEBzaWwub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxAimEkw4Teyf/gZelL7OuQYg/JbDIKHPXJhLPBm/HK6pM5ZZKydVXTdMgMqkl4xK+xZ2CnkozsUiMLhAuWBsX9Dcz1M4SkPRwk4puFhXzsp7fKIVP43zUhF7p2TmbernrrIQHjg6PuegKmCGyiKUpukcYvf2RXNwHwJx+Uq0zLP4PgBSrQ2t1eKZ1jQ+noBb1NqOuy969WRYmN4EmjXDuJB9d+b3GwtbZToWgiFxFjd/NN9BFJXZEaLzRj5LAq5bu2vPPDZDarHFMRUzVJ91eafoaz6zpR1iUGj9zR+y2sUPxD/fJMZ+4AHWA2LOrTBBIuuWbp96yvcJ4WjmlfhcFQIDAQABo1AwTjAdBgNVHQ4EFgQUkJFAMJdr2lXsuezS6pDXHnmJspMwHwYDVR0jBBgwFoAUkJFAMJdr2lXsuezS6pDXHnmJspMwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAOEPbchaUr45L5i+ueookevsABYnltwJZ4rYJbF9VURPcEhB6JxTMZqb4s113ftHvVYfoAfLYZ9swETaHL+esx41yAebf0kWpQ3f63S5F2FcrTj+HP0XsvW/EDrvaTKM9jnKPNmbXrpq06eaUZfkVL0TAUsxYTKkttTSTiESEzp5wzYyhp7l3kpHhEvGOlh5suYjnZ2HN0uxscCR6PS47H6TMMEZuG032DWDC016/JniWvERtpf4Yw26V+I9xevp2E2MPcZne31Pe3sCh4Wpe4cV/SCFqZHlpnH96ncz4F+KvmmhbEx5VPhQSJNFIWEvI86k+lTNQOqj6YVvGvq95LQ==', + ]; diff --git a/docker-compose.yml b/docker-compose.yml index 6f121120..4f629b27 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -10,7 +10,7 @@ services: MYSQL_PASSWORD: silauth dbadmin: - image: phpmyadmin/phpmyadmin + image: phpmyadmin ports: - "8080:80" environment: @@ -38,15 +38,11 @@ services: MYSQL_DATABASE: silauth MYSQL_USER: silauth MYSQL_PASSWORD: silauth - COMPOSER_CACHE_DIR: /composer PROFILE_URL_FOR_TESTS: http://pwmanager.local/module.php/core/authenticate.php?as=ssp-hub ADMIN_PASS: b SECRET_SALT: abc123 IDP_NAME: x volumes: - - ./composer.json:/data/composer.json - - ./composer.lock:/data/composer.lock - - ${COMPOSER_CACHE_DIR}:/composer - ./dockerbuild/run-integration-tests.sh:/data/run-integration-tests.sh - ./dockerbuild/run-metadata-tests.sh:/data/run-metadata-tests.sh - ./dockerbuild/run-tests.sh:/data/run-tests.sh @@ -60,7 +56,7 @@ services: - ./modules/silauth:/data/vendor/simplesamlphp/simplesamlphp/modules/silauth - ./modules/sildisco:/data/vendor/simplesamlphp/simplesamlphp/modules/sildisco - ./modules/material:/data/vendor/simplesamlphp/simplesamlphp/modules/material - command: ["/data/run-tests.sh"] + command: [ "/data/run-tests.sh" ] test-browser: image: justinribeiro/chrome-headless:stable @@ -77,7 +73,7 @@ services: - ./installed-packages.json:/data/installed-packages.json - ./development/update-composer-deps.sh:/data/update-composer-deps.sh - ./vendor:/data/vendor - - ${COMPOSER_CACHE_DIR}:/composer + - composer-cache:/composer env_file: - ./local.env environment: @@ -85,26 +81,17 @@ services: ssp-hub.local: build: . - depends_on: - - ssp-idp1.local - - ssp-idp2.local - - ssp-idp3.local - - ssp-sp1.local - - ssp-sp2.local - - ssp-sp3.local volumes: # Utilize custom certs - ./development/hub/cert:/data/vendor/simplesamlphp/simplesamlphp/cert # Utilize custom configs - ./development/hub/config/authsources.php:/data/vendor/simplesamlphp/simplesamlphp/config/authsources.php + - ./dockerbuild/config/config.php:/data/vendor/simplesamlphp/simplesamlphp/config/config.php - ./development/announcement.php:/data/vendor/simplesamlphp/simplesamlphp/announcement/announcement.php # Utilize custom metadata - - ./development/hub/metadata/idp-remote.php:/data/vendor/simplesamlphp/simplesamlphp/metadata/idp-remote.php - - ./development/hub/metadata/saml20-idp-hosted.php:/data/vendor/simplesamlphp/simplesamlphp/metadata/saml20-idp-hosted.php - - ./development/hub/metadata/saml20-sp-hosted.php:/data/vendor/simplesamlphp/simplesamlphp/metadata/saml20-sp-hosted.php - - ./development/hub/metadata/sp-remote.php:/data/vendor/simplesamlphp/simplesamlphp/metadata/sp-remote.php + - ./development/hub/metadata/:/data/vendor/simplesamlphp/simplesamlphp/metadata/ # Enable checking our test metadata - ./dockerbuild/run-metadata-tests.sh:/data/run-metadata-tests.sh @@ -120,33 +107,34 @@ services: - "80:80" environment: ADMIN_PASS: "abc123" - SECRET_SALT: "h57fjemb&dn^nsJFGNjweJ" + SECRET_SALT: "not-secret-h57fjemb&dn^nsJFGNjweJ" IDP_NAME: "Hub" SECURE_COOKIE: "false" - ADMIN_PROTECT_INDEX_PAGE: "false" SHOW_SAML_ERRORS: "true" THEME_COLOR_SCHEME: "orange-light_blue" HUB_MODE: "true" + HELP_CENTER_URL: "https://example.org/help" + LOGGING_LEVEL: INFO - ssp-idp1.local: # using a database session store type ("sql") + ssp-idp1.local: # using a database session store type ("sql") build: . depends_on: - db volumes: # Utilize custom certs - - ./development/idp-local/cert:/data/vendor/simplesamlphp/simplesamlphp/cert + - ./development/idp-local/cert:/data/vendor/simplesamlphp/simplesamlphp/cert # Utilize custom configs - ./development/idp-local/config/authsources.php:/data/vendor/simplesamlphp/simplesamlphp/config/authsources.php - - ./development/idp-local/config/config.php:/data/vendor/simplesamlphp/simplesamlphp/config/config.php - ./development/announcement.php:/data/vendor/simplesamlphp/simplesamlphp/announcement/announcement.php + - ./development/enable-exampleauth.sh:/data/enable-exampleauth.sh # Utilize custom metadata - ./development/idp-local/metadata/saml20-idp-hosted.php:/data/vendor/simplesamlphp/simplesamlphp/metadata/saml20-idp-hosted.php - ./development/idp-local/metadata/saml20-sp-remote.php:/data/vendor/simplesamlphp/simplesamlphp/metadata/saml20-sp-remote.php # Customized SSP code -- TODO: make a better solution that doesn't require hacking SSP code - - ./development/UserPass.php:/data/vendor/simplesamlphp/simplesamlphp/modules/exampleauth/lib/Auth/Source/UserPass.php + - ./development/UserPass.php:/data/vendor/simplesamlphp/simplesamlphp/modules/exampleauth/src/Auth/Source/UserPass.php # Enable checking our test metadata - ./dockerbuild/run-metadata-tests.sh:/data/run-metadata-tests.sh @@ -162,22 +150,23 @@ services: - ./modules/sildisco:/data/vendor/simplesamlphp/simplesamlphp/modules/sildisco - ./modules/material:/data/vendor/simplesamlphp/simplesamlphp/modules/material command: > - bash -c "whenavail db 3306 60 /data/vendor/simplesamlphp/simplesamlphp/modules/silauth/lib/Auth/Source/yii migrate --interactive=0 && + bash -c "whenavail db 3306 60 /data/vendor/simplesamlphp/simplesamlphp/modules/silauth/src/Auth/Source/yii migrate --interactive=0 && + /data/enable-exampleauth.sh && /data/run.sh" ports: - "8085:80" environment: ADMIN_PASS: "a" - SECRET_SALT: "h57fjemb&dn^nsJFGNjweJ" + SECRET_SALT: "not-secret-h57fjemb&dn^nsJFGNjweJ" IDP_NAME: "IDP 1" IDP_DOMAIN_NAME: "mfaidp" ID_BROKER_ACCESS_TOKEN: "dummy" ID_BROKER_ASSERT_VALID_IP: "false" ID_BROKER_BASE_URI: "dummy" ID_BROKER_TRUSTED_IP_RANGES: "192.168.0.1/8" - MFA_SETUP_URL: "http://pwmanager.local:8084/module.php/core/authenticate.php?as=ssp-hub-custom-port" + MFA_SETUP_URL: "http://pwmanager.local/module.php/core/authenticate.php?as=ssp-hub-custom-port" REMEMBER_ME_SECRET: "12345" - PROFILE_URL: "http://pwmanager.local:8084/module.php/core/authenticate.php?as=ssp-hub-custom-port" + PROFILE_URL: "http://pwmanager.local/module.php/core/authenticate.php?as=ssp-hub-custom-port" PROFILE_URL_FOR_TESTS: "http://pwmanager.local/module.php/core/authenticate.php?as=ssp-hub" SECURE_COOKIE: "false" SHOW_SAML_ERRORS: "true" @@ -187,23 +176,27 @@ services: MYSQL_USER: "silauth" MYSQL_PASSWORD: "silauth" BASE_URL_PATH: "http://ssp-idp1.local/" # change this to "http://ssp-idp1.local:8085" for manual browser testing + HELP_CENTER_URL: "https://example.org/help" ssp-idp2.local: build: . + depends_on: + - db + - broker volumes: # Utilize custom certs - - ./development/idp2-local/cert:/data/vendor/simplesamlphp/simplesamlphp/cert + - ./development/idp2-local/cert:/data/vendor/simplesamlphp/simplesamlphp/cert # Utilize custom configs - ./development/idp2-local/config/authsources.php:/data/vendor/simplesamlphp/simplesamlphp/config/authsources.php - - ./development/idp2-local/config/config.php:/data/vendor/simplesamlphp/simplesamlphp/config/config.php + - ./development/enable-exampleauth.sh:/data/enable-exampleauth.sh # Utilize custom metadata - ./development/idp2-local/metadata/saml20-idp-hosted.php:/data/vendor/simplesamlphp/simplesamlphp/metadata/saml20-idp-hosted.php - ./development/idp2-local/metadata/saml20-sp-remote.php:/data/vendor/simplesamlphp/simplesamlphp/metadata/saml20-sp-remote.php # Customized SSP code -- TODO: make a better solution that doesn't require hacking SSP code - - ./development/UserPass.php:/data/vendor/simplesamlphp/simplesamlphp/modules/exampleauth/lib/Auth/Source/UserPass.php + - ./development/UserPass.php:/data/vendor/simplesamlphp/simplesamlphp/modules/exampleauth/src/Auth/Source/UserPass.php # Local modules - ./modules/mfa:/data/vendor/simplesamlphp/simplesamlphp/modules/mfa @@ -212,12 +205,22 @@ services: - ./modules/silauth:/data/vendor/simplesamlphp/simplesamlphp/modules/silauth - ./modules/sildisco:/data/vendor/simplesamlphp/simplesamlphp/modules/sildisco - ./modules/material:/data/vendor/simplesamlphp/simplesamlphp/modules/material + command: bash -c "/data/enable-exampleauth.sh && /data/run.sh" ports: - "8086:80" environment: ADMIN_PASS: "b" SECRET_SALT: "h57fjemb&dn^nsJFGNjweJ" IDP_NAME: "IDP 2" + IDP_DOMAIN_NAME: "ssp-idp2.local" + ID_BROKER_ACCESS_TOKEN: "test-cli-abc123" + ID_BROKER_ASSERT_VALID_IP: "true" + ID_BROKER_BASE_URI: "http://broker" + ID_BROKER_TRUSTED_IP_RANGES: "10.20.38.0/24" + MYSQL_HOST: "db" + MYSQL_DATABASE: "silauth" + MYSQL_USER: "silauth" + MYSQL_PASSWORD: "silauth" SECURE_COOKIE: "false" SHOW_SAML_ERRORS: "true" @@ -229,7 +232,6 @@ services: # Utilize custom configs - ./development/idp3-local/config/authsources.php:/data/vendor/simplesamlphp/simplesamlphp/config/authsources.php - - ./development/idp3-local/config/config.php:/data/vendor/simplesamlphp/simplesamlphp/config/config.php # Utilize custom metadata - ./development/idp3-local/metadata/saml20-idp-hosted.php:/data/vendor/simplesamlphp/simplesamlphp/metadata/saml20-idp-hosted.php @@ -254,13 +256,12 @@ services: IDP_NAME: "IdP3" ssp-sp1.local: - build: . + image: silintl/ssp-base:9.3.0 volumes: # Utilize custom certs - ./development/sp-local/cert:/data/vendor/simplesamlphp/simplesamlphp/cert # Utilize custom configs - - ./development/sp-local/config/config.php:/data/vendor/simplesamlphp/simplesamlphp/config/config.php - ./development/sp-local/config/authsources.php:/data/vendor/simplesamlphp/simplesamlphp/config/authsources.php # Utilize custom metadata @@ -271,21 +272,22 @@ services: ports: - "8081:80" environment: + ADMIN_EMAIL: "john_doe@there.com" ADMIN_PASS: "sp1" - SECRET_SALT: "h57fjemb&dn^nsJFGNjweJz1" + IDP_NAME: "NA" + SECRET_SALT: "not-secret-h57fjemb&dn^nsJFGNjweJz1" SECURE_COOKIE: "false" SHOW_SAML_ERRORS: "true" SAML20_IDP_ENABLE: "false" ADMIN_PROTECT_INDEX_PAGE: "false" ssp-sp2.local: - build: . + image: silintl/ssp-base:9.3.0 volumes: # Utilize custom certs - ./development/sp2-local/cert:/data/vendor/simplesamlphp/simplesamlphp/cert # Utilize custom configs - - ./development/sp2-local/config/config.php:/data/vendor/simplesamlphp/simplesamlphp/config/config.php - ./development/sp2-local/config/authsources.php:/data/vendor/simplesamlphp/simplesamlphp/config/authsources.php # Utilize custom metadata @@ -293,7 +295,9 @@ services: ports: - "8082:80" environment: + ADMIN_EMAIL: "john_doe@there.com" ADMIN_PASS: "sp2" + IDP_NAME: "NA" SECRET_SALT: "h57fjemb&dn^nsJFGNjweJz2" SECURE_COOKIE: "false" SHOW_SAML_ERRORS: "true" @@ -301,13 +305,12 @@ services: ADMIN_PROTECT_INDEX_PAGE: "false" ssp-sp3.local: - build: . + image: silintl/ssp-base:9.3.0 volumes: # Utilize custom certs - ./development/sp3-local/cert:/data/vendor/simplesamlphp/simplesamlphp/cert # Utilize custom configs - - ./development/sp3-local/config/config.php:/data/vendor/simplesamlphp/simplesamlphp/config/config.php - ./development/sp3-local/config/authsources.php:/data/vendor/simplesamlphp/simplesamlphp/config/authsources.php # Utilize custom metadata @@ -317,7 +320,9 @@ services: env_file: - local.env environment: + ADMIN_EMAIL: "john_doe@there.com" ADMIN_PASS: sp3 + IDP_NAME: "NA" SECRET_SALT: h57fjemb&dn^nsJFGNjweJz3 SECURE_COOKIE: "false" SHOW_SAML_ERRORS: "true" @@ -325,7 +330,7 @@ services: ADMIN_PROTECT_INDEX_PAGE: "false" pwmanager.local: - image: silintl/ssp-base:develop + image: silintl/ssp-base:9.3.0 volumes: # Utilize custom certs - ./development/sp-local/cert:/data/vendor/simplesamlphp/simplesamlphp/cert @@ -335,9 +340,8 @@ services: # Utilize custom metadata - ./development/sp-local/metadata/saml20-idp-remote.php:/data/vendor/simplesamlphp/simplesamlphp/metadata/saml20-idp-remote.php - ports: - - "8084:80" environment: + ADMIN_EMAIL: "john_doe@there.com" ADMIN_PASS: sp1 IDP_NAME: THIS VARIABLE IS REQUIRED BUT PROBABLY NOT USED SECRET_SALT: NOT-a-secret-k49fjfkw73hjf9t87wjiw @@ -348,7 +352,7 @@ services: # the broker and brokerDb containers are used by the silauth module broker: - image: silintl/idp-id-broker:develop + image: silintl/idp-id-broker:latest ports: - "80" depends_on: @@ -371,8 +375,21 @@ services: SUPPORT_EMAIL: "support@example.org" EMAIL_SIGNATURE: "one red pill, please" API_ACCESS_KEYS: "test-cli-abc123" - APP_ENV: "dev" - command: ["bash", "-c", "whenavail brokerDb 3306 60 ./yii migrate --interactive=0 && ./run.sh"] + APP_ENV: "prod" + RP_ORIGINS: "https://ssp-idp1.local,https://ssp-idp2.local,https://ssp-idp3.local" + HIBP_CHECK_ON_LOGIN: "false" + MFA_TOTP_apiBaseUrl: dummy + MFA_TOTP_apiKey: 10345678-1234-1234-1234-123456789012 + MFA_TOTP_apiSecret: 11345678-1234-1234-1234-12345678 + MFA_WEBAUTHN_apiBaseUrl: dummy + MFA_WEBAUTHN_apiKey: 10345678-1234-1234-1234-123456789012 + MFA_WEBAUTHN_apiSecret: 11345678-1234-1234-1234-12345678 + MFA_WEBAUTHN_appId: ourApp99 + MFA_WEBAUTHN_rpDisplayName: Our App + MFA_WEBAUTHN_rpId: http://app99 + volumes: + - ./development/m991231_235959_insert_test_users.php:/data/console/migrations/m991231_235959_insert_test_users.php + command: [ "bash", "-c", "whenavail brokerDb 3306 60 ./yii migrate --interactive=0 && ./run.sh" ] brokerDb: image: mariadb:10 @@ -384,6 +401,15 @@ services: MYSQL_USER: "user" MYSQL_PASSWORD: "pass" + brokerpma: + image: phpmyadmin + ports: + - "8088:80" + environment: + PMA_HOST: brokerDb + PMA_USER: user + PMA_PASSWORD: pass + dynamo: image: cnadiminti/dynamodb-local command: "-sharedDb -inMemory" @@ -422,3 +448,6 @@ networks: config: - subnet: 10.20.38.0/24 gateway: 10.20.38.1 + +volumes: + composer-cache: { } diff --git a/dockerbuild/apply-dictionaries-overrides.php b/dockerbuild/apply-dictionaries-overrides.php index 0957ea66..30eeb1cb 100644 --- a/dockerbuild/apply-dictionaries-overrides.php +++ b/dockerbuild/apply-dictionaries-overrides.php @@ -8,7 +8,8 @@ )); } -function assertSuccess($result, $valueIndicatingFailure, $messageIfFailed) { +function assertSuccess($result, $valueIndicatingFailure, $messageIfFailed) +{ if ($result === $valueIndicatingFailure) { throw new Exception($messageIfFailed); } @@ -40,10 +41,10 @@ function assertSuccess($result, $valueIndicatingFailure, $messageIfFailed) { assertSuccess($changesData, null, 'Failed to decode the changes JSON.'); $combinedData = array_merge($originalData, $changesData); - + $combinedJson = json_encode($combinedData, JSON_PRETTY_PRINT); assertSuccess($combinedJson, false, 'Failed to encode the combined JSON.'); - + $fileWriteResult = file_put_contents($originalFile, $combinedJson); assertSuccess( $fileWriteResult, diff --git a/dockerbuild/config/config.php b/dockerbuild/config/config.php index aaa8383e..e8837743 100644 --- a/dockerbuild/config/config.php +++ b/dockerbuild/config/config.php @@ -2,12 +2,15 @@ /* * The configuration of SimpleSAMLphp * - * 2020-04-17 -- Updated to simplesamlphp/config-templates/config.php 1.18.6 + * 2024-06-14 -- Updated to simplesamlphp/config/config.php.dist 2.2.2 * */ + use Sil\PhpEnv\Env; use Sil\PhpEnv\EnvVarNotFoundException; +$httpUtils = new \SimpleSAML\Utils\HTTP(); + /* * Get config settings from ENV vars or set defaults */ @@ -44,7 +47,6 @@ $BASE_URL_PATH = Env::get('BASE_URL_PATH', '/'); $ADMIN_EMAIL = Env::get('ADMIN_EMAIL', 'na@example.org'); $ADMIN_NAME = Env::get('ADMIN_NAME', 'SAML Admin'); -$ADMIN_PROTECT_INDEX_PAGE = Env::get('ADMIN_PROTECT_INDEX_PAGE', true); $SHOW_SAML_ERRORS = Env::get('SHOW_SAML_ERRORS', false); $ENABLE_DEBUG = Env::get('ENABLE_DEBUG', false); $LOGGING_LEVEL = Env::get('LOGGING_LEVEL', 'NOTICE'); @@ -110,6 +112,8 @@ * * The full url format is useful if your SimpleSAMLphp setup is hosted behind * a reverse proxy. In that case you can specify the external url here. + * Specifying the full URL including https: will let SimpleSAMLphp know + * that it runs on HTTPS even if the backend server is plain HTTP. * * Please note that SimpleSAMLphp will then redirect all queries to the * external url, no matter where you come from (direct access or via the @@ -142,18 +146,69 @@ /* * The following settings are *filesystem paths* which define where * SimpleSAMLphp can find or write the following things: - * - 'certdir': The base directory for certificate and key material. - * - 'loggingdir': Where to write logs. + * - 'cachedir': Where SimpleSAMLphp can write its cache. + * - 'loggingdir': Where to write logs. MUST be set to NULL when using a logging + * handler other than `file`. * - 'datadir': Storage of general data. * - 'tempdir': Saving temporary files. SimpleSAMLphp will attempt to create - * this directory if it doesn't exist. + * this directory if it doesn't exist. DEPRECATED - replaced by cachedir. * When specified as a relative path, this is relative to the SimpleSAMLphp * root directory. */ + 'cachedir' => '/data/cache/simplesamlphp', + //'loggingdir' => '/var/log/', + //'datadir' => '/var/data/', + //'tempdir' => '/tmp/simplesamlphp', + + /* + * Certificate and key material can be loaded from different possible + * locations. Currently two locations are supported, the local filesystem + * and the database via pdo using the global database configuration. Locations + * are specified by a URL-link prefix before the file name/path or database + * identifier. + */ + + /* To load a certificate or key from the filesystem, it should be specified + * as 'file://' where is either a relative filename or a fully + * qualified path to a file containing the certificate or key in PEM + * format, such as 'cert.pem' or '/path/to/cert.pem'. If the path is + * relative, it will be searched for in the directory defined by the + * 'certdir' parameter below. When 'certdir' is specified as a relative + * path, it will be interpreted as relative to the SimpleSAMLphp root + * directory. Note that locations with no prefix included will be treated + * as file locations. + */ 'certdir' => 'cert/', - 'loggingdir' => 'log/', - 'datadir' => 'data/', - 'tempdir' => '/tmp/simplesaml', + + /* To load a certificate or key from the database, it should be specified + * as 'pdo://' where is the identifier in the database table that + * should be matched. While the certificate and key tables are expected to + * be in the simplesaml database, they are not created or managed by + * simplesaml. The following parameters control how the pdo location + * attempts to retrieve certificates and keys from the database: + * + * - 'cert.pdo.table': name of table where certificates are stored + * - 'cert.pdo.keytable': name of table where keys are stored + * - 'cert.pdo.apply_prefix': whether or not to prepend the database.prefix + * parameter to the table names; if you are using + * database.prefix to separate multiple SSP instances + * in the same database but want to share certificate/key + * data between them, set this to false + * - 'cert.pdo.id_column': name of column to use as identifier + * - 'cert.pdo.data_column': name of column where PEM data is stored + * + * Basically, the query executed will be: + * + * SELECT cert.pdo.data_column FROM cert.pdo.table WHERE cert.pdo.id_column = :id + * + * Defaults are shown below, to change them, uncomment the line and update as + * needed + */ + //'cert.pdo.table' => 'certificates', + //'cert.pdo.keytable' => 'private_keys', + //'cert.pdo.apply_prefix' => true, + //'cert.pdo.id_column' => 'id', + //'cert.pdo.data_column' => 'data', /* * Some information about the technical persons running this installation. @@ -175,18 +230,23 @@ * Set the transport options for the transport method specified. The valid settings are relative to the * selected transport method. */ - // // smtp mail transport options - // 'mail.transport.options' => [ - // 'host' => 'mail.example.org', // required - // 'port' => 25, // optional - // 'username' => 'user@example.org', // optional: if set, enables smtp authentication - // 'password' => 'password', // optional: if set, enables smtp authentication - // 'security' => 'tls', // optional: defaults to no smtp security - // ], - // // sendmail mail transport options - // 'mail.transport.options' => [ - // 'path' => '/usr/sbin/sendmail' // optional: defaults to php.ini path - // ], + /* + 'mail.transport.options' => [ + 'host' => 'mail.example.org', // required + 'port' => 25, // optional + 'username' => 'user@example.org', // optional: if set, enables smtp authentication + 'password' => 'password', // optional: if set, enables smtp authentication + 'security' => 'tls', // optional: defaults to no smtp security + 'smtpOptions' => [], // optional: passed to stream_context_create when connecting via SMTP + ], + */ + + // sendmail mail transport options + /* + 'mail.transport.options' => [ + 'path' => '/usr/sbin/sendmail' // optional: defaults to php.ini path + ], + */ /* * The envelope from address for outgoing emails. @@ -216,7 +276,7 @@ * 'secretsalt' can be any valid string of any length. * * A possible way to generate a random salt is by running the following command from a unix shell: - * LC_CTYPE=C tr -c -d '0123456789abcdefghijklmnopqrstuvwxyz' /dev/null;echo + * LC_ALL=C tr -c -d '0123456789abcdefghijklmnopqrstuvwxyz' /dev/null;echo */ 'secretsalt' => $SECRET_SALT, @@ -229,10 +289,8 @@ 'auth.adminpassword' => $ADMIN_PASS, /* - * Set this options to true if you want to require administrator password to access the web interface - * or the metadata pages, respectively. + * Set this option to true if you want to require administrator password to access the metadata. */ - 'admin.protectindexpage' => $ADMIN_PROTECT_INDEX_PAGE, 'admin.protectmetadata' => true, /* @@ -292,7 +350,7 @@ /* * Set the allowed clock skew between encrypting/decrypting assertions * - * If you have an server that is constantly out of sync, this option + * If you have a server that is constantly out of sync, this option * allows you to adjust the allowed clock-skew. * * Allowed range: 180 - 300 @@ -300,6 +358,21 @@ */ 'assertion.allowed_clock_skew' => 180, + /* + * Set custom security headers. The defaults can be found in \SimpleSAML\Configuration::DEFAULT_SECURITY_HEADERS + * + * NOTE: When a header is already set on the response we will NOT overrule it and leave it untouched. + * + * Whenever you change any of these headers, make sure to validate your config by running your + * hostname through a security-test like https://en.internet.nl + 'headers.security' => [ + 'Content-Security-Policy' => "default-src 'none'; frame-ancestors 'self'; object-src 'none'; script-src 'self'; style-src 'self'; font-src 'self'; connect-src 'self'; img-src 'self' data:; base-uri 'none'", + 'X-Frame-Options' => 'SAMEORIGIN', + 'X-Content-Type-Options' => 'nosniff', + 'Referrer-Policy' => 'origin-when-cross-origin', + ], + */ + /************************ | ERRORS AND DEBUGGING | @@ -354,14 +427,13 @@ /* * Custom error show function called from SimpleSAML\Error\Error::show. - * See docs/simplesamlphp-errorhandling.txt for function code example. + * See docs/simplesamlphp-errorhandling.md for function code example. * * Example: * 'errors.show_function' => ['SimpleSAML\Module\example\Error', 'show'], */ - /************************** | LOGGING AND STATISTICS | **************************/ @@ -378,6 +450,9 @@ * * Options: [syslog,file,errorlog,stderr] * + * If you set the handler to 'file', the directory specified in loggingdir above + * must exist and be writable for SimpleSAMLphp. If set to something else, set + * loggingdir above to 'null'. */ 'logging.level' => $logLevels[$LOGGING_LEVEL], 'logging.handler' => $LOGGING_HANDLER, @@ -388,7 +463,7 @@ * are: * * - %date{}: the date and time, with its format specified inside the brackets. See the PHP documentation - * of the strftime() function for more information on the format. If the brackets are omitted, the standard + * of the date() function for more information on the format. If the brackets are omitted, the standard * format is applied. This can be useful if you just want to control the placement of the date, but don't care * about the format. * @@ -408,7 +483,7 @@ * - %msg: the message to be logged. * */ - //'logging.format' => '%date{%b %d %H:%M:%S} %process %level %stat[%trackid] %msg', + //'logging.format' => '%date{M j H:i:s} %process %level %stat[%trackid] %msg', /* * Choose which facility should be used when logging with syslog. @@ -438,7 +513,8 @@ * This is an array of outputs. Each output has at least a 'class' option, which * selects the output. */ - 'statistics.out' => [// Log statistics to the normal log. + 'statistics.out' => [ + // Log statistics to the normal log. /* [ 'class' => 'core:Log', @@ -517,19 +593,19 @@ //'database.persistent' => false, /* - * Database slave configuration is optional as well. If you are only + * Database secondary configuration is optional as well. If you are only * running a single database server, leave this blank. If you have - * a master/slave configuration, you can define as many slave servers - * as you want here. Slaves will be picked at random to be queried from. + * a primary/secondary configuration, you can define as many secondary servers + * as you want here. Secondaries will be picked at random to be queried from. * - * Configuration options in the slave array are exactly the same as the - * options for the master (shown above) with the exception of the table + * Configuration options in the secondary array are exactly the same as the + * options for the primary (shown above) with the exception of the table * prefix and driver options. */ - //'database.slaves' => [ + //'database.secondaries' => [ // /* // [ - // 'dsn' => 'mysql:host=myslave;dbname=saml', + // 'dsn' => 'mysql:host=mysecondary;dbname=saml', // 'username' => 'simplesamlphp', // 'password' => 'secret', // 'persistent' => false, @@ -547,23 +623,10 @@ * Which functionality in SimpleSAMLphp do you want to enable. Normally you would enable only * one of the functionalities below, but in some cases you could run multiple functionalities. * In example when you are setting up a federation bridge. - * - * Note that shib13-idp has been deprecated and will be removed in SimpleSAMLphp 2.0. */ 'enable.saml20-idp' => $SAML20_IDP_ENABLE, - 'enable.shib13-idp' => false, 'enable.adfs-idp' => false, - /* - * Whether SimpleSAMLphp should sign the response or the assertion in SAML 1.1 authentication - * responses. - * - * The default is to sign the assertion element, but that can be overridden by setting this - * option to TRUE. It can also be overridden on a pr. SP basis by adding an option with the - * same name to the metadata of the SP. - */ - 'shib13.signresponse' => true, - /*********** @@ -571,22 +634,22 @@ ***********/ /* - * Configuration to override module enabling/disabling. + * Configuration for enabling/disabling modules. By default the 'core', 'admin' and 'saml' modules are enabled. * * Example: * * 'module.enable' => [ - * 'exampleauth' => true, // Setting to TRUE enables. - * 'consent' => false, // Setting to FALSE disables. - * 'core' => null, // Unset or NULL uses default. + * 'exampleauth' => true, // Setting to TRUE enables. + * 'consent' => false, // Setting to FALSE disables. + * 'core' => null, // Unset or NULL uses default. * ], * */ 'module.enable' => [ - 'saml' => true, 'core' => true, 'admin' => true, + 'saml' => true, 'expirychecker' => true, 'material' => true, 'mfa' => true, @@ -596,7 +659,6 @@ ], - /************************* | SESSION CONFIGURATION | *************************/ @@ -652,7 +714,7 @@ * Example: * 'session.cookie.domain' => '.example.org', */ - 'session.cookie.domain' => null, + 'session.cookie.domain' => '', /* * Set the secure flag in the cookie. @@ -660,6 +722,8 @@ * Set this to TRUE if the user only accesses your service * through https. If the user can access the service through * both http and https, this must be set to FALSE. + * + * If unset, SimpleSAMLphp will try to automatically determine the right value */ 'session.cookie.secure' => $SECURE_COOKIE, @@ -713,7 +777,7 @@ /* * Custom function for session checking called on session init and loading. - * See docs/simplesamlphp-advancedfeatures.txt for function code example. + * See docs/simplesamlphp-advancedfeatures.md for function code example. * * Example: * 'session.check_function' => ['\SimpleSAML\Module\example\Util', 'checkSession'], @@ -849,48 +913,13 @@ | LANGUAGE AND INTERNATIONALIZATION | *************************************/ - /* - * Language-related options. - */ - 'language' => [ - /* - * An array in the form 'language' => . - * - * Each key in the array is the ISO 639 two-letter code for a language, - * and its value is an array with a list of alternative languages that - * can be used if the given language is not available at some point. - * Each alternative language is also specified by its ISO 639 code. - * - * For example, for the "no" language code (Norwegian), we would have: - * - * 'priorities' => [ - * 'no' => ['nb', 'nn', 'en', 'se'], - * ... - * ], - * - * establishing that if a translation for the "no" language code is - * not available, we look for translations in "nb", - * and so on, in that order. - */ - 'priorities' => [ - 'no' => ['nb', 'nn', 'en', 'se'], - 'nb' => ['no', 'nn', 'en', 'se'], - 'nn' => ['no', 'nb', 'en', 'se'], - 'se' => ['nb', 'no', 'nn', 'en'], - 'nr' => ['zu', 'en'], - 'nd' => ['zu', 'en'], - 'tw' => ['st', 'en'], - 'nso' => ['st', 'en'], - ], - ], - /* * Languages available, RTL languages, and what language is the default. */ 'language.available' => [ 'en', 'no', 'nn', 'se', 'da', 'de', 'sv', 'fi', 'es', 'ca', 'fr', 'it', 'nl', 'lb', - 'cs', 'sl', 'lt', 'hr', 'hu', 'pl', 'pt', 'pt-br', 'tr', 'ja', 'zh', 'zh-tw', 'ru', - 'et', 'he', 'id', 'sr', 'lv', 'ro', 'eu', 'el', 'af', 'zu', 'xh', 'st', + 'cs', 'sk', 'sl', 'lt', 'hr', 'hu', 'pl', 'pt', 'pt-br', 'tr', 'ja', 'zh', 'zh-tw', + 'ru', 'et', 'he', 'id', 'sr', 'lv', 'ro', 'eu', 'el', 'af', 'zu', 'xh', 'st', ], 'language.rtl' => ['ar', 'dv', 'fa', 'ur', 'he'], 'language.default' => 'en', @@ -905,12 +934,12 @@ * Options to override the default settings for the language cookie */ 'language.cookie.name' => 'language', - 'language.cookie.domain' => null, + 'language.cookie.domain' => '', 'language.cookie.path' => '/', 'language.cookie.secure' => true, 'language.cookie.httponly' => false, 'language.cookie.lifetime' => (60 * 60 * 24 * 900), - 'language.cookie.samesite' => \SimpleSAML\Utils\HTTP::canSetSameSiteNone() ? 'None' : null, + 'language.cookie.samesite' => $httpUtils->canSetSameSiteNone() ? 'None' : null, /** * Custom getLanguage function called from SimpleSAML\Locale\Language::getLanguage(). @@ -924,34 +953,6 @@ * 'language.get_language_function' => ['\SimpleSAML\Module\example\Template', 'getLanguage'], */ - /* - * Extra dictionary for attribute names. - * This can be used to define local attributes. - * - * The format of the parameter is a string with :. - * - * Specifying this option will cause us to look for modules//dictionaries/.definition.json - * The dictionary should look something like: - * - * { - * "firstattribute": { - * "en": "English name", - * "no": "Norwegian name" - * }, - * "secondattribute": { - * "en": "English name", - * "no": "Norwegian name" - * } - * } - * - * Note that all attribute names in the dictionary must in lowercase. - * - * Example: 'attributes.extradictionary' => 'ourmodule:ourattributes', - */ - 'attributes.extradictionary' => null, - - - /************** | APPEARANCE | **************/ @@ -965,7 +966,7 @@ * Set this option to the text you would like to appear at the header of each page. Set to false if you don't want * any text to appear in the header. */ - //'theme.header' => 'SimpleSAMLphp' + //'theme.header' => 'SimpleSAMLphp', /** * A template controller, if any. @@ -1031,14 +1032,19 @@ ], ], + /** + * Set to a full URL if you want to redirect users that land on SimpleSAMLphp's + * front page to somewhere more useful. If left unset, a basic welcome message + * is shown. + */ + //'frontpage.redirect' => 'https://example.com/', + /* * color scheme to use for the material theme * Options: https://github.com/silinternational/simplesamlphp-module-material/blob/develop/README.md#branding */ 'theme.color-scheme' => $THEME_COLOR_SCHEME, - - /********************* | DISCOVERY SERVICE | *********************/ @@ -1058,7 +1064,7 @@ /* * IdP Discovery service look configuration. - * Wether to display a list of idp or to display a dropdown box. For many IdP' a dropdown box + * Whether to display a list of idp or to display a dropdown box. For many IdP' a dropdown box * gives the best use experience. * * When using dropdown box a cookie is used to highlight the previously chosen IdP in the dropdown. @@ -1069,13 +1075,13 @@ 'idpdisco.layout' => 'links', + /************************************* | AUTHENTICATION PROCESSING FILTERS | *************************************/ /* * Authentication processing filters that will be executed for all IdPs - * Both Shibboleth and SAML 2.0 */ 'authproc.idp' => [ /* Enable the authproc filter below to add URN prefixes to all attributes @@ -1090,12 +1096,6 @@ // Adopts language from attribute to use in UI 30 => 'core:LanguageAdaptor', - 35 => [ - 'class' => 'core:StatisticsWithAttribute', - 'attributename' => 'realm', - 'type' => 'saml20-idp-SSO', - ], - /* * Copy friendly names attribute keys to oids ... */ @@ -1118,6 +1118,12 @@ // 49 => *** WARNING: For Hubs this entry is added at the end of this file + + /* When called without parameters, it will fallback to filter attributes 'the old way' + * by checking the 'attributes' parameter in metadata on IdP hosted and SP remote. + */ +// 50 => 'core:AttributeLimit', + // If no attributes are requested in the SP metadata, then these will be sent through 50 => [ 'class' => 'core:AttributeLimit', @@ -1175,7 +1181,6 @@ /* * Authentication processing filters that will be executed for all SPs - * Both Shibboleth and SAML 2.0 */ 'authproc.sp' => [ /* @@ -1244,7 +1249,7 @@ * The MDQ metadata handler defines the following options: * - 'type': This is always 'mdq'. * - 'server': Base URL of the MDQ server. Mandatory. - * - 'validateFingerprint': The fingerprint of the certificate used to sign the metadata. You don't need this + * - 'validateCertificate': The certificates file that may be used to sign the metadata. You don't need this * option if you don't want to validate the signature on the metadata. Optional. * - 'cachedir': Directory where metadata can be cached. Optional. * - 'cachelength': Maximum time metadata can be cached, in seconds. Defaults to 24 @@ -1280,6 +1285,10 @@ * [ * 'type' => 'mdq', * 'server' => 'http://mdq.server.com:8080', + * 'validateCertificate' => [ + * '/var/simplesamlphp/cert/metadata-key.new.crt', + * '/var/simplesamlphp/cert/metadata-key.old.crt' + * ], * 'cachedir' => '/var/simplesamlphp/mdq-cache', * 'cachelength' => 86400 * ] @@ -1320,6 +1329,7 @@ 'metadata.sign.privatekey' => 'saml.pem', 'metadata.sign.privatekey_pass' => null, 'metadata.sign.certificate' => 'saml.crt', + 'metadata.sign.algorithm' => 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256', /**************************** @@ -1357,20 +1367,92 @@ */ //'store.sql.prefix' => 'SimpleSAMLphp', + /* + * The driver-options we should pass to the PDO-constructor. + */ + 'store.sql.options' => [], + /* * The hostname and port of the Redis datastore instance. */ //'store.redis.host' => 'localhost', //'store.redis.port' => 6379, + /* + * The credentials to use when connecting to Redis. + * + * If your Redis server is using the legacy password protection (config + * directive "requirepass" in redis.conf) then you should only provide + * a password. + * + * If your Redis server is using ACL's (which are recommended as of + * Redis 6+) then you should provide both a username and a password. + * See https://redis.io/docs/manual/security/acl/ + */ +// 'store.redis.username' => '', +// 'store.redis.password' => '', + + /* + * Communicate with Redis over a secure connection instead of plain TCP. + * + * This setting affects both single host connections as + * well as Sentinel mode. + */ +// 'store.redis.tls' => false, + + /* + * Verify the Redis server certificate. + */ +// 'store.redis.insecure' => false, + + /* + * Files related to secure communication with Redis. + * + * Files are searched in the 'certdir' when using relative paths. + */ +// 'store.redis.ca_certificate' => null, +// 'store.redis.certificate' => null, +// 'store.redis.privatekey' => null, + /* * The prefix we should use on our Redis datastore. */ - //'store.redis.prefix' => 'SimpleSAMLphp', +// 'store.redis.prefix' => 'SimpleSAMLphp', + + /* + * The master group to use for Redis Sentinel. + */ + 'store.redis.mastergroup' => 'mymaster', + + /* + * The Redis Sentinel hosts. + * Example: + * 'store.redis.sentinels' => [ + * 'tcp://[yoursentinel1]:[port]', + * 'tcp://[yoursentinel2]:[port]', + * 'tcp://[yoursentinel3]:[port] + * ], + * + * Use 'tls' instead of 'tcp' in order to make use of the additional + * TLS settings. + */ + 'store.redis.sentinels' => [], + + /********************* + | IdP/SP PROXY MODE | + *********************/ + + /* + * If the IdP in front of SimpleSAMLphp in IdP/SP proxy mode sends + * AuthnContextClassRef, decide whether the AuthnContextClassRef will be + * processed by the IdP/SP proxy or if it will be passed to the SP behind + * the IdP/SP proxy. + */ + 'proxymode.passAuthnContextClassRef' => false, ]; if ($HUB_MODE) { // prefix the 'member' (urn:oid:2.5.4.31) attribute elements with idp.idp_name. $config['authproc.idp'][48] = 'sildisco:TagGroup'; - $config['authproc.idp'][49] = 'sildisco:AddIdp2NameId'; +// $config['authproc.idp'][49] = 'sildisco:AddIdp2NameId'; } diff --git a/dockerbuild/run-idp.sh b/dockerbuild/run-idp.sh index 2f65d0f0..ab6d1ed2 100755 --- a/dockerbuild/run-idp.sh +++ b/dockerbuild/run-idp.sh @@ -8,9 +8,9 @@ set -e # Try to run database migrations cd /data/vendor/simplesamlphp/simplesamlphp -chmod a+x ./modules/silauth/lib/Auth/Source/yii +chmod a+x ./modules/silauth/src/Auth/Source/yii -./modules/silauth/lib/Auth/Source/yii migrate --interactive=0 +./modules/silauth/src/Auth/Source/yii migrate --interactive=0 cd /data ./run.sh diff --git a/dockerbuild/run-spidplinks.php b/dockerbuild/run-spidplinks.php index 7035a2d2..82e3f723 100644 --- a/dockerbuild/run-spidplinks.php +++ b/dockerbuild/run-spidplinks.php @@ -1,10 +1,11 @@ $value) { $metadata[$key] = $value; -} \ No newline at end of file +} diff --git a/dockerbuild/ssp-overrides/saml20-sp-remote.php b/dockerbuild/ssp-overrides/saml20-sp-remote.php index a617596e..c9e9758c 100644 --- a/dockerbuild/ssp-overrides/saml20-sp-remote.php +++ b/dockerbuild/ssp-overrides/saml20-sp-remote.php @@ -2,10 +2,10 @@ use Sil\SspUtils\Metadata; -$mdPath = __DIR__; +$mdPath = __DIR__; $startMetadata = Metadata::getSpMetadataEntries($mdPath); foreach ($startMetadata as $key => $value) { $metadata[$key] = $value; -} \ No newline at end of file +} diff --git a/dockerbuild/vhost.conf b/dockerbuild/vhost.conf index f2638b82..c2ea9893 100644 --- a/dockerbuild/vhost.conf +++ b/dockerbuild/vhost.conf @@ -1,9 +1,9 @@ - DocumentRoot /data/vendor/simplesamlphp/simplesamlphp/www/ + DocumentRoot /data/vendor/simplesamlphp/simplesamlphp/public/ RewriteEngine On DirectoryIndex index.php - + Options FollowSymLinks AllowOverride All Require all granted diff --git a/docs/development.md b/docs/development.md index 5b87046f..761ebddc 100644 --- a/docs/development.md +++ b/docs/development.md @@ -2,7 +2,7 @@ Four SPs, a hub (a combined IdP and SP) and three IdPs get spun up by docker com * ssp-sp1.local # to be used with port 8081 * ssp-sp2.local # to be used with port 8082 * ssp-sp3.local # to be used with port 8083 -* pwmanager.local # to be used with port 8084 +* pwmanager.local * ssp-hub.local * ssp-idp1.local # to be used with port 8085 * ssp-idp2.local # to be used with port 8086 diff --git a/docs/editing_authprocs.md b/docs/editing_authprocs.md index 42a62368..88013fa8 100644 --- a/docs/editing_authprocs.md +++ b/docs/editing_authprocs.md @@ -16,7 +16,12 @@ The IdP's metadata needs to include an `'IDPNamespace'` entry with a string valu In order for this to work, the SP needs to include a line in its authsources.php file in the Hub's entry ... -` 'NameIDPolicy' => "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent",` +``` + 'NameIDPolicy' => [ + 'Format' => 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent', + 'AllowCreate' => true, + ], +``` In addition, the IDP's sp-remote metadata stanza for the Hub needs to include ... diff --git a/docs/the_hub.md b/docs/the_hub.md index 266826f7..e366f45d 100644 --- a/docs/the_hub.md +++ b/docs/the_hub.md @@ -1,9 +1,9 @@ The hub will need its certs, `config.php` and `authsources.php` files as a normal simplesamlphp installation. Examples of these can be found in the `./development/hub` folder. (Note the `discoURL` entry in the `authsources.php` file.) Other files it will need are as follows ... -* The files in the `./lib` folder will need to go into `/data/vendor/simplesamlphp/simplesamlphp/modules/sildisco/lib` -* The files in the `./www` folder will need to go into `/data/vendor/simplesamlphp/simplesamlphp/modules/sildisco/www` -* The `./sspoverrides/www_saml2_idp/SSOService.php` file will need overwrite the same out-of-the-box file in `/data/vendor/simplesamlphp/simplesamlphp/www/saml2/idp/` +* The files in the `./src` folder will need to go into `/data/vendor/simplesamlphp/simplesamlphp/modules/sildisco/src` +* The files in the `./public` folder will need to go into `/data/vendor/simplesamlphp/simplesamlphp/modules/sildisco/public` +* The `./sspoverrides/www_saml2_idp/SSOService.php` file will need overwrite the same out-of-the-box file in `/data/vendor/simplesamlphp/simplesamlphp/public/saml2/idp/` ### Metadata files The hub should use the `saml20-*-remote.php` files from [ssp-base](https://github.com/silinternational/ssp-base) in `/data/vendor/simplesamlphp/simplesamlphp/metadata/`. These pull in metadata from all the files named `idp-*.php` and `sp-*.php` respectively, including those in sub-folders. @@ -35,6 +35,6 @@ In order to limit access to an IdP to only certain SP's, add an `'SPList'` array If you want to require SP's to list a certain IdP in their IDPList entry in order to be able to access it, add `excludeByDefault => true` to that IdP's metadata. ### Forced IdP discovery -The `.../lib/IdP/SAML2.php` file ensures that if an SP is allowed to access more than one IdP, then the user will be forced back to the IdP discovery page, even if they are already authenticated through one of those IdP's. +The `.../src/IdP/SAML2.php` file ensures that if an SP is allowed to access more than one IdP, then the user will be forced back to the IdP discovery page, even if they are already authenticated through one of those IdP's. The reason for this is to ensure that the user has a chance to decide which of their identities is used for that SP. diff --git a/features/Sp1Idp1Sp2Idp2Sp3.feature b/features/Sp1Idp1Sp2Idp2Sp3.feature index 6498fa23..aaf4ee9c 100644 --- a/features/Sp1Idp1Sp2Idp2Sp3.feature +++ b/features/Sp1Idp1Sp2Idp2Sp3.feature @@ -2,10 +2,10 @@ Feature: Ensure I can login to Sp1 through Idp1, must login to Sp2 through Idp2 Scenario: Login to SP1 through IDP1 When I go to the SP1 login page - And the url should match "sildisco/disco.php" - And I should see "to continue to SP1" - And I click on the "IDP 1" tile - And I log in using my "IDP 1" credentials + And the url should match "sildisco/disco.php" + And I should see "to continue to SP1" + And I click on the "IDP 1" tile + And I log in using my "IDP 1" credentials Then I should see my attributes on SP1 Scenario: After IDP1 login, go to SP2 through IDP2 @@ -17,9 +17,9 @@ Feature: Ensure I can login to Sp1 through Idp1, must login to Sp2 through Idp2 Scenario: After IDP1 login, go directly to SP3 without credentials Given I have authenticated with IDP1 for SP1 When I go to the SP3 login page - And the url should match "sildisco/disco.php" - And I should see "to continue to SP3" - And I click on the "IDP 1" tile + And the url should match "sildisco/disco.php" + And I should see "to continue to SP3" + And I click on the "IDP 1" tile Then I should see my attributes on SP3 Scenario: Logout of IDP1 diff --git a/features/Sp1Idp2Sp2Sp3Idp1.feature b/features/Sp1Idp2Sp2Sp3Idp1.feature index aba78e0d..fa32dcca 100644 --- a/features/Sp1Idp2Sp2Sp3Idp1.feature +++ b/features/Sp1Idp2Sp2Sp3Idp1.feature @@ -2,10 +2,10 @@ Feature: Ensure I can login to Sp1 through Idp2, am already logged in for Sp2, a Scenario: Login to SP1 through IDP2 When I go to the SP1 login page - And the url should match "sildisco/disco.php" - And I should see "to continue to SP1" - And I click on the "IDP 2" tile - And I log in using my "IDP 2" credentials + And the url should match "sildisco/disco.php" + And I should see "to continue to SP1" + And I click on the "IDP 2" tile + And I log in using my "IDP 2" credentials Then I should see my attributes on SP1 Scenario: After IDP2 login, go directly to SP2 without credentials @@ -16,7 +16,7 @@ Feature: Ensure I can login to Sp1 through Idp2, am already logged in for Sp2, a Scenario: After IDP2 login, go to SP3 through IDP1 Given I have authenticated with IDP2 for SP1 When I go to the SP3 login page - And I should see "to continue to SP3" - And I click on the "IDP 1" tile - And I log in using my "IDP 1" credentials + And I should see "to continue to SP3" + And I click on the "IDP 1" tile + And I log in using my "IDP 1" credentials Then I should see my attributes on SP3 diff --git a/features/Sp2Idp2Sp1Idp1Sp3.feature b/features/Sp2Idp2Sp1Idp1Sp3.feature index c1637991..26d54bc7 100644 --- a/features/Sp2Idp2Sp1Idp1Sp3.feature +++ b/features/Sp2Idp2Sp1Idp1Sp3.feature @@ -2,23 +2,23 @@ Feature: Ensure I can login to Sp2 through Idp2, must login to Sp1 if I choose I Scenario: Login to SP2 through IDP2 When I go to the SP2 login page - And I log in using my "IDP 2" credentials + And I log in using my "IDP 2" credentials Then I should see my attributes on SP2 Scenario: Login to SP1 through IDP1 Given I have authenticated with IDP2 for SP2 When I go to the SP1 login page - And the url should match "sildisco/disco.php" - And I click on the "IDP 1" tile - And I log in using my "IDP 1" credentials + And the url should match "sildisco/disco.php" + And I click on the "IDP 1" tile + And I log in using my "IDP 1" credentials Then I should see my attributes on SP1 Scenario: After IDP2 login, go directly to SP3 without credentials Given I have authenticated with IDP2 for SP2 - And I have authenticated with IDP1 for SP1 - And I go to the SP3 login page - And the url should match "sildisco/disco.php" - And I should see "to continue to SP3" - And I click on the "IDP 1" tile + And I have authenticated with IDP1 for SP1 + And I go to the SP3 login page + And the url should match "sildisco/disco.php" + And I should see "to continue to SP3" + And I click on the "IDP 1" tile Then I should see my attributes on SP3 diff --git a/features/Sp2Idp2Sp1Idp2Sp3.feature b/features/Sp2Idp2Sp1Idp2Sp3.feature index e54e3244..7c73a543 100644 --- a/features/Sp2Idp2Sp1Idp2Sp3.feature +++ b/features/Sp2Idp2Sp1Idp2Sp3.feature @@ -2,21 +2,21 @@ Feature: Ensure I can login to Sp2 through Idp2, get discovery page for Sp1, and Scenario: Login to SP2 through IDP2 When I go to the SP2 login page - And I log in using my "IDP 2" credentials + And I log in using my "IDP 2" credentials Then I should see my attributes on SP2 Scenario: Get discovery page for SP1 Given I have authenticated with IDP2 for SP2 When I go to the SP1 login page - And the url should match "sildisco/disco.php" - And I click on the "IDP 2" tile + And the url should match "sildisco/disco.php" + And I click on the "IDP 2" tile Then I should see my attributes on SP1 Scenario: Must login to SP3 through IDP1 Given I have authenticated with IDP2 for SP2 When I go to the SP3 login page - And the url should match "sildisco/disco.php" - And I click on the "IDP 1" tile - And I log in using my "IDP 1" credentials + And the url should match "sildisco/disco.php" + And I click on the "IDP 1" tile + And I log in using my "IDP 1" credentials Then I should see my attributes on SP3 diff --git a/features/Sp3Idp1Sp1Idp1Sp2Idp2.feature b/features/Sp3Idp1Sp1Idp1Sp2Idp2.feature index c038df65..2db76fad 100644 --- a/features/Sp3Idp1Sp1Idp1Sp2Idp2.feature +++ b/features/Sp3Idp1Sp1Idp1Sp2Idp2.feature @@ -2,21 +2,21 @@ Feature: Ensure I can login to Sp3 through Idp1, get the discovery page for Sp1 Scenario: login to SP3 using IDP1 When I go to the SP3 login page - And the url should match "sildisco/disco.php" - And I should see "to continue to SP3" - And I click on the "IDP 1" tile - And I log in using my "IDP 1" credentials + And the url should match "sildisco/disco.php" + And I should see "to continue to SP3" + And I click on the "IDP 1" tile + And I log in using my "IDP 1" credentials Then I should see my attributes on SP3 Scenario: having authenticated with IDP1 for SP3, go to SP1 via the discovery page Given I have authenticated with IDP1 for SP3 When I go to the SP1 login page - And the url should match "sildisco/disco.php" - And I click on the "IDP 1" tile + And the url should match "sildisco/disco.php" + And I click on the "IDP 1" tile Then I should see my attributes on SP1 Scenario: having authenticated with IDP1 for SP3, login to SP2 using IDP2 Given I have authenticated with IDP1 for SP3 When I go to the SP2 login page - And I log in using my "IDP 2" credentials + And I log in using my "IDP 2" credentials Then I should see my attributes on SP2 diff --git a/features/ZSp1Idp1BetaSp1Idp3.feature b/features/ZSp1Idp1BetaSp1Idp3.feature index e82b9053..b5d07091 100644 --- a/features/ZSp1Idp1BetaSp1Idp3.feature +++ b/features/ZSp1Idp1BetaSp1Idp3.feature @@ -1,13 +1,13 @@ Feature: Ensure I don't see IdP 3 at first, but after I go to the Beta Tester page I can see and login through IdP 3. -Scenario: Normally the IdP3 is disabled - When I go to the "SP1" login page - And the url should match "sildisco/disco.php" - Then the "div" element should contain "IdP 3 coming soon" + Scenario: Normally the IdP3 is disabled + When I go to the "SP1" login page + And the url should match "sildisco/disco.php" + Then the "div" element should contain "IdP 3 coming soon" -Scenario: After going to the "Beta Test" page, IdP3 is available for use - When I go to "http://ssp-hub.local/module.php/sildisco/betatest.php" - And I go to the "SP1" login page - And I click on the "IDP 3" tile - And I log in using my "IDP 3" credentials - Then I should see "test_admin@idp3.org" + Scenario: After going to the "Beta Test" page, IdP3 is available for use + When I go to "http://ssp-hub.local/module.php/sildisco/betatest.php" + And I go to the "SP1" login page + And I click on the "IDP 3" tile + And I log in using my "IDP 3" credentials + Then I should see "test_admin@idp3.org" diff --git a/features/bootstrap/ExpiryContext.php b/features/bootstrap/ExpiryContext.php index 358e1767..42aa4b5d 100644 --- a/features/bootstrap/ExpiryContext.php +++ b/features/bootstrap/ExpiryContext.php @@ -1,4 +1,5 @@ session->getPage(); - Assert::assertContains('An error occurred', $page->getHtml()); + Assert::assertContains('We could not understand the expiration date', $page->getHtml()); } /** diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php index 2734d304..bc053deb 100644 --- a/features/bootstrap/FeatureContext.php +++ b/features/bootstrap/FeatureContext.php @@ -3,21 +3,20 @@ use Behat\Behat\Hook\Scope\AfterStepScope; use Behat\Behat\Tester\Result\StepResult; use Behat\Gherkin\Node\PyStringNode; -use Behat\MinkExtension\Context\MinkContext; use Behat\Mink\Element\DocumentElement; use Behat\Mink\Element\NodeElement; use Behat\Mink\Exception\ElementNotFoundException; use Behat\Mink\Mink; use Behat\Mink\Session; -use Behat\Testwork\Tester\Result\TestResult; +use Behat\MinkExtension\Context\MinkContext; use DMore\ChromeDriver\ChromeDriver; use Webmozart\Assert\Assert; class FeatureContext extends MinkContext { - private const HUB_BAD_AUTH_SOURCE_URL = 'http://ssp-hub.local/module.php/core/authenticate.php?as=wrong'; - private const HUB_DISCO_URL = 'http://ssp-hub.local/module.php/core/authenticate.php?as=hub-discovery'; - private const HUB_HOME_URL = 'http://ssp-hub.local'; + private const HUB_BAD_AUTH_SOURCE_URL = 'http://ssp-hub.local/module.php/admin/test/wrong'; + private const HUB_DISCO_URL = 'http://ssp-hub.local/module.php/admin/test/hub-discovery'; + private const HUB_ADMIN_URL = 'http://ssp-hub.local/admin'; protected const SP1_LOGIN_PAGE = 'http://ssp-sp1.local/module.php/core/authenticate.php?as=ssp-hub'; protected const SP2_LOGIN_PAGE = 'http://ssp-sp2.local/module.php/core/authenticate.php?as=ssp-hub'; protected const SP3_LOGIN_PAGE = 'http://ssp-sp3.local/module.php/core/authenticate.php?as=ssp-hub'; @@ -53,13 +52,14 @@ public function afterStep(AfterStepScope $scope) /** * Store a screenshot. */ - private function takeScreenshot() { + private function takeScreenshot() + { $screenshot = $this->getSession()->getDriver()->getScreenshot(); if (!is_dir(self::SCREENSHOTS_PATH)) { mkdir(self::SCREENSHOTS_PATH); } if (is_dir(self::SCREENSHOTS_PATH)) { - $path = self::SCREENSHOTS_PATH . date('d-m-y') . '-' . uniqid() . '.png'; + $path = self::SCREENSHOTS_PATH . date('Y-m-d_H:i:s_') . uniqid() . '.png'; file_put_contents($path, $screenshot); print "\n\nScreenshot: " . $path; } @@ -78,7 +78,7 @@ public function iGoToTheHubsDiscoveryPage() { $this->visit(self::HUB_DISCO_URL); } - + /** * @Then I should see our material theme */ @@ -97,7 +97,7 @@ public function iShouldSeeOurMaterialTheme() */ public function iGoToTheHubsHomePage() { - $this->visit(self::HUB_HOME_URL); + $this->visit(self::HUB_ADMIN_URL); } /** @@ -116,6 +116,15 @@ public function iLogInAsAHubAdministrator() $this->logInAs('admin', 'abc123'); } + /** + * @When I provide a username and an incorrect password + */ + public function iProvideAUsernameAndAnIncorrectPassword() + { + $this->username = "sildisco_idp2"; + $this->password = "not_correct"; + } + protected function logInAs(string $username, string $password) { $this->fillField('username', $username); diff --git a/features/bootstrap/LoginContext.php b/features/bootstrap/LoginContext.php index 7425e2b7..2aea6768 100644 --- a/features/bootstrap/LoginContext.php +++ b/features/bootstrap/LoginContext.php @@ -18,6 +18,7 @@ use SimpleSAML\Module\silauth\Auth\Source\tests\unit\http\DummyRequest; use SimpleSAML\Module\silauth\Auth\Source\time\UtcTime; use Webmozart\Assert\Assert; + //use yii\helpers\ArrayHelper; /** @@ -33,13 +34,13 @@ class LoginContext extends FeatureContext /** @var Captcha */ private $captcha; - + /** @var IdBroker */ private $idBroker; - + /** @var Request */ private $request; - + /** * Initializes context. * @@ -58,9 +59,9 @@ public function __construct() 'username' => Env::get('MYSQL_USER'), 'password' => Env::get('MYSQL_PASSWORD'), ]]]); - + $this->logger = new Psr3EchoLogger(); - + $this->captcha = new Captcha(); $this->idBroker = new IdBroker( 'http://fake.example.com/api/', @@ -71,25 +72,25 @@ public function __construct() false ); $this->request = new Request(); - + $this->resetDatabase(); } - + protected function addXFailedLoginUsernames(int $number, $username) { Assert::notEmpty($username); - + for ($i = 0; $i < $number; $i++) { $newRecord = new FailedLoginUsername(['username' => $username]); Assert::true($newRecord->save()); } - + Assert::count( FailedLoginUsername::getFailedLoginsFor($username), $number ); } - + protected function login() { $this->authenticator = new Authenticator( @@ -101,20 +102,20 @@ protected function login() $this->logger ); } - + protected function loginXTimes($numberOfTimes) { for ($i = 0; $i < $numberOfTimes; $i++) { $this->login(); - } + } } - + protected function resetDatabase() { FailedLoginIpAddress::deleteAll(); FailedLoginUsername::deleteAll(); } - + /** * @Given I provide a username */ @@ -149,7 +150,7 @@ public function iShouldNotBeAllowedThrough() ); $authenticator = $this->authenticator; Assert::throws( - function() use ($authenticator) { + function () use ($authenticator) { $authenticator->getUserAttributes(); }, \Exception::class, @@ -234,7 +235,7 @@ public function iProvideAnIncorrectPassword() public function thatUsernameWillBeRateLimitedAfterOneMoreFailedAttempt() { FailedLoginUsername::resetFailedLoginsBy($this->username); - + $this->addXFailedLoginUsernames( Authenticator::BLOCK_AFTER_NTH_FAILED_LOGIN - 1, $this->username @@ -291,9 +292,9 @@ public function iTryToLogInEnoughTimesToTriggerTheRateLimit() public function thatUsernameHasMoreRecentFailedLoginsThanTheLimit($number) { Assert::true(is_numeric($number)); - + FailedLoginUsername::resetFailedLoginsBy($this->username); - + $this->addXFailedLoginUsernames( $number + Authenticator::BLOCK_AFTER_NTH_FAILED_LOGIN, $this->username @@ -318,13 +319,13 @@ public function iShouldSeeAnErrorMessageWithAndInIt($text1, $text2) public function thatUsernameHasEnoughFailedLoginsToRequireACaptcha() { FailedLoginUsername::resetFailedLoginsBy($this->username); - + $this->addXFailedLoginUsernames( Authenticator::REQUIRE_CAPTCHA_AFTER_NTH_FAILED_LOGIN, $this->username ); } - + /** * @Given that username has no recent failed login attempts */ @@ -354,10 +355,10 @@ public function thatUsernameShouldBeBlockedForAwhile() */ public function myRequestComesFromIpAddress($ipAddress) { - if ( ! $this->request instanceof DummyRequest) { + if (!$this->request instanceof DummyRequest) { $this->request = new DummyRequest(); } - + $this->request->setDummyIpAddress($ipAddress); } @@ -369,7 +370,7 @@ public function thatIpAddressShouldBeBlockedForAwhile() $ipAddresses = $this->request->getUntrustedIpAddresses(); Assert::count($ipAddresses, 1); $ipAddress = $ipAddresses[0]; - + Assert::true( FailedLoginIpAddress::isRateLimitBlocking($ipAddress) ); @@ -407,16 +408,16 @@ public function myIpAddressHasEnoughFailedLoginsToRequireACaptcha() Assert::notNull($ipAddress, 'No IP address was provided.'); FailedLoginIpAddress::deleteAll(); Assert::isEmpty(FailedLoginIpAddress::getFailedLoginsFor($ipAddress)); - + $desiredCount = Authenticator::REQUIRE_CAPTCHA_AFTER_NTH_FAILED_LOGIN; - + for ($i = 0; $i < $desiredCount; $i++) { $failedLoginIpAddress = new FailedLoginIpAddress([ 'ip_address' => $ipAddress, ]); Assert::true($failedLoginIpAddress->save()); } - + Assert::eq( Authenticator::REQUIRE_CAPTCHA_AFTER_NTH_FAILED_LOGIN, FailedLoginIpAddress::countRecentFailedLoginsFor($ipAddress) @@ -429,7 +430,7 @@ public function myIpAddressHasEnoughFailedLoginsToRequireACaptcha() public function thatUsernameHasEnoughFailedLoginsToBeBlockedByTheRateLimit() { FailedLoginUsername::resetFailedLoginsBy($this->username); - + $this->addXFailedLoginUsernames( Authenticator::BLOCK_AFTER_NTH_FAILED_LOGIN, $this->username @@ -444,19 +445,19 @@ public function thatIpAddressHasTriggeredTheRateLimit() $ipAddresses = $this->request->getUntrustedIpAddresses(); Assert::count($ipAddresses, 1); $ipAddress = $ipAddresses[0]; - + FailedLoginIpAddress::deleteAll(); Assert::isEmpty(FailedLoginIpAddress::getFailedLoginsFor($ipAddress)); - + $desiredCount = Authenticator::BLOCK_AFTER_NTH_FAILED_LOGIN; - + for ($i = 0; $i < $desiredCount; $i++) { $failedLoginIpAddress = new FailedLoginIpAddress([ 'ip_address' => $ipAddress, ]); Assert::true($failedLoginIpAddress->save()); } - + Assert::true( FailedLoginIpAddress::isRateLimitBlocking($ipAddress) ); @@ -477,28 +478,28 @@ public function thatUsernameHasMoreNonRecentFailedLoginsThanTheLimit($number) { Assert::notEmpty($this->username); Assert::true(is_numeric($number)); - + $desiredNumber = $number + Authenticator::BLOCK_AFTER_NTH_FAILED_LOGIN; - + $numTotalFailures = count(FailedLoginUsername::getFailedLoginsFor($this->username)); $numRecentFailures = FailedLoginUsername::countRecentFailedLoginsFor($this->username); $numNonRecentFailures = $numTotalFailures - $numRecentFailures; - + for ($i = $numNonRecentFailures; $i < $desiredNumber; $i++) { $failedLoginUsername = new FailedLoginUsername([ 'username' => $this->username, - + // NOTE: Use some time (UTC) longer ago than we consider "recent". 'occurred_at_utc' => new UtcTime('-1 month'), ]); // NOTE: Don't validate, as that would overwrite the datetime field. Assert::true($failedLoginUsername->save(false)); } - + $numTotalFailuresPost = count(FailedLoginUsername::getFailedLoginsFor($this->username)); $numRecentFailuresPost = FailedLoginUsername::countRecentFailedLoginsFor($this->username); $numNonRecentFailuresPost = $numTotalFailuresPost - $numRecentFailuresPost; - + Assert::eq($desiredNumber, $numNonRecentFailuresPost); } @@ -578,11 +579,11 @@ public function secondsAgoThatUsernameHadMoreFailedLoginsThanTheLimit( Assert::notEmpty($this->username); Assert::true(is_numeric($numSeconds)); Assert::true(is_numeric($numFailuresBeyondLimit)); - + FailedLoginUsername::resetFailedLoginsBy($this->username); - + $numDesiredFailuresTotal = $numFailuresBeyondLimit + Authenticator::BLOCK_AFTER_NTH_FAILED_LOGIN; - + for ($i = 0; $i < $numDesiredFailuresTotal; $i++) { $failedLoginUsername = new FailedLoginUsername([ 'username' => $this->username, @@ -594,9 +595,9 @@ public function secondsAgoThatUsernameHadMoreFailedLoginsThanTheLimit( // NOTE: Don't validate, as that would overwrite the datetime field. Assert::true($failedLoginUsername->save(false)); } - + $numTotalFailuresPost = count(FailedLoginUsername::getFailedLoginsFor($this->username)); - + Assert::eq($numDesiredFailuresTotal, $numTotalFailuresPost); } @@ -611,11 +612,11 @@ public function secondsAgoTheIpAddressHadMoreFailedLoginsThanTheLimit( Assert::notEmpty($ipAddress); Assert::true(is_numeric($numSeconds)); Assert::true(is_numeric($numFailuresBeyondLimit)); - + FailedLoginIpAddress::resetFailedLoginsBy([$ipAddress]); - + $numDesiredFailuresTotal = $numFailuresBeyondLimit + Authenticator::BLOCK_AFTER_NTH_FAILED_LOGIN; - + for ($i = 0; $i < $numDesiredFailuresTotal; $i++) { $failedLoginIpAddress = new FailedLoginIpAddress([ 'ip_address' => $ipAddress, @@ -627,9 +628,9 @@ public function secondsAgoTheIpAddressHadMoreFailedLoginsThanTheLimit( // NOTE: Don't validate, as that would overwrite the datetime field. Assert::true($failedLoginIpAddress->save(false)); } - + $numTotalFailuresPost = count(FailedLoginIpAddress::getFailedLoginsFor($ipAddress)); - + Assert::eq($numDesiredFailuresTotal, $numTotalFailuresPost); } } diff --git a/features/bootstrap/MfaContext.php b/features/bootstrap/MfaContext.php index 988f1fb6..3a5ab1bb 100644 --- a/features/bootstrap/MfaContext.php +++ b/features/bootstrap/MfaContext.php @@ -1,4 +1,5 @@ getHtml() )); } - + /** * Get the "continue" button. * @@ -94,8 +95,8 @@ protected function submitMfaForm($page) $submitMfaButton->click(); $this->submitSecondarySspFormIfPresent($page); } - - /** + + /** * @Given I provide credentials that do not need MFA */ public function iProvideCredentialsThatDoNotNeedMfa() @@ -104,7 +105,7 @@ public function iProvideCredentialsThatDoNotNeedMfa() $this->username = 'no_mfa_needed'; $this->password = 'a'; } - + /** * @Given I provide credentials that need MFA but have no MFA options available */ @@ -114,7 +115,7 @@ public function iProvideCredentialsThatNeedMfaButHaveNoMfaOptionsAvailable() $this->username = 'must_set_up_mfa'; $this->password = 'a'; } - + /** * @Then I should see a message that I have to set up MFA */ @@ -123,7 +124,7 @@ public function iShouldSeeAMessageThatIHaveToSetUpMfa() $page = $this->session->getPage(); Assert::assertContains('must set up 2-', $page->getHtml()); } - + /** * @Then there should be a way to go set up MFA now */ @@ -132,7 +133,7 @@ public function thereShouldBeAWayToGoSetUpMfaNow() $page = $this->session->getPage(); $this->assertFormContains('name="setUpMfa"', $page); } - + /** * @Given I provide credentials that need MFA and have backup codes available */ @@ -142,7 +143,7 @@ public function iProvideCredentialsThatNeedMfaAndHaveBackupCodesAvailable() $this->username = 'has_backupcode'; $this->password = 'a'; } - + /** * @Then I should see a prompt for a backup code */ @@ -153,7 +154,7 @@ public function iShouldSeeAPromptForABackupCode() Assert::assertContains('Printable code', $pageHtml); Assert::assertContains('Enter code', $pageHtml); } - + /** * @Given I provide credentials that need MFA and have TOTP available */ @@ -163,7 +164,7 @@ public function iProvideCredentialsThatNeedMfaAndHaveTotpAvailable() $this->username = 'has_totp'; $this->password = 'a'; } - + /** * @Then I should see a prompt for a TOTP (code) */ @@ -207,14 +208,14 @@ protected function submitMfaValue($mfaValue) */ public function iSubmitACorrectBackupCode() { - if (! $this->pageContainsElementWithText('h1', 'Printable code')) { - // find image of the backup code option presented in other_mfas.php + if (!$this->pageContainsElementWithText('h1', 'Printable code')) { + // find image of the backup code option presented in other_mfas.twig $printableCodeOption = $this->session->getPage()->find('css', 'img[src=mfa-backupcode\002Esvg]'); $printableCodeOption->click(); } $this->submitMfaValue(FakeIdBrokerClient::CORRECT_VALUE); } - + protected function pageContainsElementWithText($cssSelector, $text) { $page = $this->session->getPage(); @@ -442,7 +443,7 @@ public function theUsersBrowserSupportsUf() LoginBrowser::supportsWebAuthn($userAgentWithWebAuthn), 'Update USER_AGENT_WITH_WEBAUTHN_SUPPORT to a User Agent with WebAuthn support' ); - + // $this->driver->getClient()->setServerParameter('HTTP_USER_AGENT', $userAgentWithWebAuthn); } @@ -576,7 +577,7 @@ public function theUsersBrowserDoesNotSupportUf() LoginBrowser::supportsWebAuthn($userAgentWithoutWebAuthn), 'Update USER_AGENT_WITHOUT_WEBAUTHN_SUPPORT to a User Agent without WebAuthn support' ); - + // $this->driver->getClient()->setServerParameter('HTTP_USER_AGENT', $userAgentWithoutWebAuthn); } @@ -661,6 +662,7 @@ public function iShouldSeeAPromptForAManagerRescueCode() $pageHtml = $page->getHtml(); Assert::assertContains('Ask Your Recovery Contact for Help', $pageHtml); Assert::assertContains('Enter code', $pageHtml); + Assert::assertContains('m*****r@e******.c**', $pageHtml); } /** diff --git a/features/bootstrap/ProfileReviewContext.php b/features/bootstrap/ProfileReviewContext.php index 5312b09e..09cc6f22 100644 --- a/features/bootstrap/ProfileReviewContext.php +++ b/features/bootstrap/ProfileReviewContext.php @@ -1,4 +1,5 @@ true, 'http_errors' => false, ]); - $response = $client->get('http://ssp-idp1.local/module.php/core/authenticate.php?as=silauth'); + $response = $client->get('http://ssp-idp1.local/module.php/admin/test/silauth'); $this->responseCode = $response->getStatusCode(); } diff --git a/features/dictionary-overrides.feature b/features/dictionary-overrides.feature index fd02ec43..af8fe9dc 100644 --- a/features/dictionary-overrides.feature +++ b/features/dictionary-overrides.feature @@ -1,5 +1,5 @@ Feature: Applying dictionary overrides - + Scenario: Successfully merging a dictionary file Given a "/tmp/test/mfa.definition.json" file containing """ @@ -12,7 +12,7 @@ Feature: Applying dictionary overrides } } """ - And a "/tmp/test/overrides/mfa.definition.json" file containing + And a "/tmp/test/overrides/mfa.definition.json" file containing """ { "webauthn_header": { diff --git a/features/expirychecker.feature b/features/expirychecker.feature index f93f7af4..ff412f4a 100644 --- a/features/expirychecker.feature +++ b/features/expirychecker.feature @@ -1,7 +1,8 @@ Feature: Expiry Checker module + Background: Given I go to the SP1 login page - And I click on the "IDP 1" tile + And I click on the "IDP 1" tile Scenario: Password will expire in the distant future Given I provide credentials that will expire in the distant future diff --git a/features/fakes/FakeIdBrokerClient.php b/features/fakes/FakeIdBrokerClient.php index c404fb9e..10d716dc 100644 --- a/features/fakes/FakeIdBrokerClient.php +++ b/features/fakes/FakeIdBrokerClient.php @@ -1,4 +1,5 @@ 1234, diff --git a/features/material.feature b/features/material.feature index 78da2688..3cd3d5a9 100644 --- a/features/material.feature +++ b/features/material.feature @@ -1,30 +1,34 @@ Feature: Material theme - + Scenario: Hub (disco) page When I go to the Hub's discovery page + And I log in as a hub administrator Then I should see our material theme - + Scenario: Error page When I go to the Hub but specify an invalid authentication source + And I log in as a hub administrator Then I should see an "Error" page - And I should see our material theme + And I should see our material theme - Scenario: Logout page - When I go to the Hub's home page - And I click on "Authentication" - And I click on "Test configured authentication sources" - And I click on "admin" - And I log in as a hub administrator - And I click on "Logout" - Then I should see a "Logged out" page - And I should see our material theme + # TODO: if this is really used, fix it. If not, delete the test, the template, and the translation file. + # (The reason this fails is because there is no "Logout" button on the new admin interface) +# Scenario: Logout page +# When I go to the Hub's home page +# And I log in as a hub administrator +# And I click on "Logout" +# Then I should see a "Logged out" page +# And I should see our material theme Scenario: Login page When I go to the SP1 login page - And I click on the "IDP 2" tile + And I click on the "IDP 2" tile Then I should see a "Login with your IDP 2 identity" page - And I should see our material theme + And I should see our material theme - Scenario: Forgot password link - - Scenario: Help and profile links + Scenario: Login error + When I go to the SP1 login page + And I click on the "IDP 2" tile + And I provide a username and an incorrect password + And I log in + Then I should see "There was a problem with that username or password" diff --git a/features/mfa.feature b/features/mfa.feature index 5a9c948f..4486f381 100644 --- a/features/mfa.feature +++ b/features/mfa.feature @@ -13,15 +13,15 @@ Feature: Prompt for MFA credentials Given I provide credentials that need MFA but have no MFA options available When I log in Then I should see a message that I have to set up MFA - And there should be a way to go set up MFA now - And there should NOT be a way to continue to my intended destination + And there should be a way to go set up MFA now + And there should NOT be a way to continue to my intended destination Scenario: Following the requirement to go set up MFA Given I provide credentials that need MFA but have no MFA options available - And I log in + And I log in When I click the set-up-MFA button Then I should end up at the mfa-setup URL - And I should NOT be able to get to my intended destination + And I should NOT be able to get to my intended destination Scenario: Needs MFA, has backup code option available Given I provide credentials that need MFA and have backup codes available @@ -35,112 +35,112 @@ Feature: Prompt for MFA credentials Scenario: Needs MFA, has WebAuthn option available Given I provide credentials that need MFA and have WebAuthn available - And the user's browser supports WebAuthn + And the user's browser supports WebAuthn When I log in Then I should see a prompt for a WebAuthn security key Scenario: Accepting a (non-rate-limited) correct MFA value Given I provide credentials that need MFA and have backup codes available - And I have logged in + And I have logged in When I submit a correct backup code Then I should end up at my intended destination Scenario: Rejecting a (non-rate-limited) wrong MFA value Given I provide credentials that need MFA and have backup codes available - And I have logged in + And I have logged in When I submit an incorrect backup code Then I should see a message that it was incorrect Scenario: Blocking an incorrect MFA value while rate-limited Given I provide credentials that have a rate-limited MFA - And I have logged in + And I have logged in When I submit an incorrect backup code Then I should see a message that I have to wait before trying again Scenario: Blocking a correct MFA value while rate-limited Given I provide credentials that have a rate-limited MFA - And I have logged in + And I have logged in When I submit a correct backup code Then I should see a message that I have to wait before trying again Scenario: Warning when running low on backup codes Given I provide credentials that need MFA and have 4 backup codes available - And I have logged in + And I have logged in When I submit a correct backup code Then I should see a message that I am running low on backup codes - And I should be told I only have 3 backup codes left - And there should be a way to get more backup codes now - And there should be a way to continue to my intended destination + And I should be told I only have 3 backup codes left + And there should be a way to get more backup codes now + And there should be a way to continue to my intended destination Scenario: Requiring user to set up more backup codes when they run out and have no other MFA Given I provide credentials that need MFA and have 1 backup code available and no other MFA - And I have logged in + And I have logged in When I submit a correct backup code Then I should see a message that I have used up my backup codes - And there should be a way to get more backup codes now - And there should NOT be a way to continue to my intended destination + And there should be a way to get more backup codes now + And there should NOT be a way to continue to my intended destination Scenario: Warning user when they run out of backup codes but have other MFA options Given I provide credentials that need MFA and have 1 backup code available plus some other MFA - And I have logged in + And I have logged in When I submit a correct backup code Then I should see a message that I have used up my backup codes - And there should be a way to get more backup codes now - And there should be a way to continue to my intended destination + And there should be a way to get more backup codes now + And there should be a way to continue to my intended destination Scenario: Obeying the nag to set up more backup codes when low Given I provide credentials that need MFA and have 4 backup codes available - And I have logged in - And I submit a correct backup code + And I have logged in + And I submit a correct backup code When I click the get-more-backup-codes button Then I should be given more backup codes - And there should be a way to continue to my intended destination + And there should be a way to continue to my intended destination Scenario: Ignoring the nag to set up more backup codes when low Given I provide credentials that need MFA and have 4 backup codes available - And I have logged in - And I submit a correct backup code + And I have logged in + And I submit a correct backup code When I click the remind-me-later button Then I should end up at my intended destination Scenario: Obeying the requirement to set up more backup codes when out Given I provide credentials that need MFA and have 1 backup code available and no other MFA - And I have logged in - And I submit a correct backup code + And I have logged in + And I submit a correct backup code When I click the get-more-backup-codes button Then I should be given more backup codes - And there should be a way to continue to my intended destination + And there should be a way to continue to my intended destination Scenario: Obeying the nag to set up more backup codes when out Given I provide credentials that need MFA and have 1 backup code available plus some other MFA - And I have logged in - And I submit a correct backup code + And I have logged in + And I submit a correct backup code When I click the get-more-backup-codes button Then I should be given more backup codes - And there should be a way to continue to my intended destination + And there should be a way to continue to my intended destination Scenario: Ignoring the nag to set up more backup codes when out Given I provide credentials that need MFA and have 1 backup code available plus some other MFA - And I have logged in - And I submit a correct backup code + And I have logged in + And I submit a correct backup code When I click the remind-me-later button Then I should end up at my intended destination Scenario Outline: Defaulting to another option when WebAuthn is not supported Given I provide credentials that have - And the user's browser + And the user's browser When I log in Then I should see a prompt for a Examples: - | WebAuthn? | TOTP? | backup codes? | supports WebAuthn or not | default MFA type | - | WebAuthn | | | supports WebAuthn | WebAuthn | - | WebAuthn | , TOTP | | supports WebAuthn | WebAuthn | - | WebAuthn | | , backup codes | supports WebAuthn | WebAuthn | - | WebAuthn | , TOTP | , backup codes | supports WebAuthn | WebAuthn | - | | TOTP | | supports WebAuthn | TOTP | - | | TOTP | , backup codes | supports WebAuthn | TOTP | - | | | backup codes | supports WebAuthn | backup code | + | WebAuthn? | TOTP? | backup codes? | supports WebAuthn or not | default MFA type | + | WebAuthn | | | supports WebAuthn | WebAuthn | + | WebAuthn | , TOTP | | supports WebAuthn | WebAuthn | + | WebAuthn | | , backup codes | supports WebAuthn | WebAuthn | + | WebAuthn | , TOTP | , backup codes | supports WebAuthn | WebAuthn | + | | TOTP | | supports WebAuthn | TOTP | + | | TOTP | , backup codes | supports WebAuthn | TOTP | + | | | backup codes | supports WebAuthn | backup code | # The following cases are disabled due to lack of test support for changing web client user agent # | WebAuthn | | | does not support WebAuthn | WebAuthn | # | WebAuthn | , TOTP | | does not support WebAuthn | TOTP | @@ -153,35 +153,35 @@ Feature: Prompt for MFA credentials Scenario Outline: Defaulting to the most recently used mfa option Given I provide credentials that have a used - And and I have a more recently used - And the user's browser + And and I have a more recently used + And the user's browser When I log in Then I should see a prompt for a Examples: - | MFA type | recent MFA type | supports WebAuthn or not | default MFA type | - | WebAuthn | TOTP | supports WebAuthn | TOTP | - | TOTP | WebAuthn | supports WebAuthn | WebAuthn | - | TOTP | backup code | supports WebAuthn | backup code | - | backup code | TOTP | supports WebAuthn | TOTP | + | MFA type | recent MFA type | supports WebAuthn or not | default MFA type | + | WebAuthn | TOTP | supports WebAuthn | TOTP | + | TOTP | WebAuthn | supports WebAuthn | WebAuthn | + | TOTP | backup code | supports WebAuthn | backup code | + | backup code | TOTP | supports WebAuthn | TOTP | # The following case is disabled due to lack of test support for changing web client user agent # | TOTP | WebAuthn | does not support WebAuthn | TOTP | Scenario: Defaulting to the manager code despite having a used mfa Given I provide credentials that have a manager code, a WebAuthn and a more recently used TOTP - And the user's browser supports WebAuthn + And the user's browser supports WebAuthn When I log in Then I should see a prompt for a manager rescue code Scenario Outline: When to show the WebAuthn-not-supported error message Given I provide credentials that have WebAuthn - And the user's browser + And the user's browser When I log in Then I see an error message about WebAuthn being unsupported Examples: - | supports WebAuthn or not | should or not | - | supports WebAuthn | should not | + | supports WebAuthn or not | should or not | + | supports WebAuthn | should not | # The following case is disabled due to lack of test support for changing web client user agent # | does not support WebAuthn | should | @@ -192,54 +192,54 @@ Feature: Prompt for MFA credentials Then I see a link to send a code to the user's manager Examples: - | WebAuthn? | TOTP? | backup codes? | has or does not have | should or should not | - | WebAuthn | | | has | should | - | WebAuthn | , TOTP | | has | should | - | WebAuthn | | , backup codes | has | should | - | WebAuthn | , TOTP | , backup codes | has | should | - | | TOTP | | has | should | - | | TOTP | , backup codes | has | should | - | | | backup codes | has | should | - | WebAuthn | | | does not have | should not | - | WebAuthn | , TOTP | | does not have | should not | - | WebAuthn | | , backup codes | does not have | should not | - | WebAuthn | , TOTP | , backup codes | does not have | should not | - | | TOTP | | does not have | should not | - | | TOTP | , backup codes | does not have | should not | - | | | backup codes | does not have | should not | + | WebAuthn? | TOTP? | backup codes? | has or does not have | should or should not | + | WebAuthn | | | has | should | + | WebAuthn | , TOTP | | has | should | + | WebAuthn | | , backup codes | has | should | + | WebAuthn | , TOTP | , backup codes | has | should | + | | TOTP | | has | should | + | | TOTP | , backup codes | has | should | + | | | backup codes | has | should | + | WebAuthn | | | does not have | should not | + | WebAuthn | , TOTP | | does not have | should not | + | WebAuthn | | , backup codes | does not have | should not | + | WebAuthn | , TOTP | , backup codes | does not have | should not | + | | TOTP | | does not have | should not | + | | TOTP | , backup codes | does not have | should not | + | | | backup codes | does not have | should not | Scenario: Ask for a code to be sent to my manager Given I provide credentials that have backup codes - And the user has a manager email - And I log in + And the user has a manager email + And I log in When I click the Request Assistance link Then there should be a way to request a manager code Scenario: Submit a code sent to my manager at an earlier time Given I provide credentials that have a manager code - And I log in + And I log in When I submit the correct manager code # because profile review is required after using a manager code: - And I click the remind-me-later button + And I click the remind-me-later button Then I should end up at my intended destination Scenario: Submit a correct manager code Given I provide credentials that have backup codes - And the user has a manager email - And I log in - And I click the Request Assistance link - And I click the Send a code link + And the user has a manager email + And I log in + And I click the Request Assistance link + And I click the Send a code link When I submit the correct manager code # because profile review is required after using a manager code: - And I click the remind-me-later button + And I click the remind-me-later button Then I should end up at my intended destination Scenario: Submit an incorrect manager code Given I provide credentials that have backup codes - And the user has a manager email - And I log in - And I click the Request Assistance link - And I click the Send a code link + And the user has a manager email + And I log in + And I click the Request Assistance link + And I click the Send a code link When I submit an incorrect manager code Then I should see a message that it was incorrect diff --git a/features/profilereview.feature b/features/profilereview.feature index be4f84e3..0e5f6651 100644 --- a/features/profilereview.feature +++ b/features/profilereview.feature @@ -1,4 +1,5 @@ Feature: Prompt to review profile information + Background: Given I go to the SP1 login page And I click on the "IDP 1" tile @@ -16,9 +17,9 @@ Feature: Prompt to review profile information And there should be a way to continue to my intended destination Examples: - | category | nag type | message | - | mfa | add | "2-Step Verification" | - | method | add | "alternate email address" | + | category | nag type | message | + | mfa | add | "2-Step Verification" | + | method | add | "alternate email address" | Scenario: Present profile review as required by the user profile Given I provide credentials that are due for a profile review diff --git a/installed-packages.json b/installed-packages.json index 7347d5ab..8f9c735e 100644 --- a/installed-packages.json +++ b/installed-packages.json @@ -5,7 +5,7 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.313.0" + "version": "3.314.1" }, { "name": "cebe/markdown", @@ -25,39 +25,43 @@ }, { "name": "gettext/gettext", - "version": "4.x-dev ed5535a" + "version": "v5.7.0" }, { "name": "gettext/languages", "version": "2.10.0" }, + { + "name": "gettext/translator", + "version": "v1.2.0" + }, { "name": "google/recaptcha", "version": "1.3.0" }, { "name": "guzzlehttp/command", - "version": "1.3.0" + "version": "1.3.1" }, { "name": "guzzlehttp/guzzle", - "version": "7.7.0" + "version": "7.8.1" }, { "name": "guzzlehttp/guzzle-services", - "version": "1.4.0" + "version": "1.4.1" }, { "name": "guzzlehttp/promises", - "version": "1.5.3" + "version": "2.0.2" }, { "name": "guzzlehttp/psr7", - "version": "2.5.0" + "version": "2.6.2" }, { "name": "guzzlehttp/uri-template", - "version": "v1.0.1" + "version": "v1.0.3" }, { "name": "mlocati/ip-lib", @@ -65,7 +69,7 @@ }, { "name": "monolog/monolog", - "version": "1.27.1" + "version": "3.6.0" }, { "name": "mtdowling/jmespath.php", @@ -75,13 +79,9 @@ "name": "paragonie/random_compat", "version": "v9.99.100" }, - { - "name": "phpfastcache/riak-client", - "version": "3.4.3" - }, { "name": "phpmailer/phpmailer", - "version": "v6.8.0" + "version": "v6.9.1" }, { "name": "phpspec/php-diff", @@ -89,19 +89,23 @@ }, { "name": "psr/cache", - "version": "2.0.0" + "version": "3.0.0" }, { "name": "psr/container", - "version": "1.1.2" + "version": "2.0.2" + }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0" }, { "name": "psr/http-client", - "version": "1.0.2" + "version": "1.0.3" }, { "name": "psr/http-factory", - "version": "1.0.2" + "version": "1.1.0" }, { "name": "psr/http-message", @@ -109,7 +113,7 @@ }, { "name": "psr/log", - "version": "1.1.4" + "version": "3.0.0" }, { "name": "ralouphie/getallheaders", @@ -121,7 +125,7 @@ }, { "name": "roave/security-advisories", - "version": "dev-master 69dafab" + "version": "dev-master 2e530fa" }, { "name": "robrichards/xmlseclibs", @@ -137,11 +141,11 @@ }, { "name": "silinternational/psr3-adapters", - "version": "3.1.0" + "version": "dev-develop 3c9bf52" }, { "name": "silinternational/ssp-utilities", - "version": "1.1.0" + "version": "dev-develop d62cbee" }, { "name": "silinternational/yii2-json-log-targets", @@ -149,135 +153,23 @@ }, { "name": "simplesamlphp/assert", - "version": "v0.0.13" + "version": "v1.1.8" }, { "name": "simplesamlphp/composer-module-installer", - "version": "v1.1.8" + "version": "v1.3.4" }, { "name": "simplesamlphp/saml2", - "version": "v4.6.10" + "version": "v4.6.12" }, { "name": "simplesamlphp/simplesamlphp", - "version": "1.19.8" - }, - { - "name": "simplesamlphp/simplesamlphp-module-adfs", - "version": "v1.0.9" - }, - { - "name": "simplesamlphp/simplesamlphp-module-authcrypt", - "version": "v0.9.4" - }, - { - "name": "simplesamlphp/simplesamlphp-module-authfacebook", - "version": "v0.9.3" - }, - { - "name": "simplesamlphp/simplesamlphp-module-authorize", - "version": "v0.9.4" - }, - { - "name": "simplesamlphp/simplesamlphp-module-authtwitter", - "version": "v0.9.3" + "version": "v2.2.2" }, { - "name": "simplesamlphp/simplesamlphp-module-authwindowslive", - "version": "v0.9.1" - }, - { - "name": "simplesamlphp/simplesamlphp-module-authx509", - "version": "v0.9.9" - }, - { - "name": "simplesamlphp/simplesamlphp-module-authyubikey", - "version": "v0.9.3" - }, - { - "name": "simplesamlphp/simplesamlphp-module-cas", - "version": "v0.9.1" - }, - { - "name": "simplesamlphp/simplesamlphp-module-cdc", - "version": "v0.9.2" - }, - { - "name": "simplesamlphp/simplesamlphp-module-consent", - "version": "v0.9.8" - }, - { - "name": "simplesamlphp/simplesamlphp-module-consentadmin", - "version": "v0.9.2" - }, - { - "name": "simplesamlphp/simplesamlphp-module-discopower", - "version": "v0.10.1" - }, - { - "name": "simplesamlphp/simplesamlphp-module-exampleattributeserver", - "version": "v1.0.0" - }, - { - "name": "simplesamlphp/simplesamlphp-module-expirycheck", - "version": "v0.9.4" - }, - { - "name": "simplesamlphp/simplesamlphp-module-ldap", - "version": "v0.9.17" - }, - { - "name": "simplesamlphp/simplesamlphp-module-memcachemonitor", - "version": "v0.9.3" - }, - { - "name": "simplesamlphp/simplesamlphp-module-memcookie", - "version": "v1.2.2" - }, - { - "name": "simplesamlphp/simplesamlphp-module-metarefresh", - "version": "v0.10.0" - }, - { - "name": "simplesamlphp/simplesamlphp-module-negotiate", - "version": "v0.9.12" - }, - { - "name": "simplesamlphp/simplesamlphp-module-oauth", - "version": "v0.9.3" - }, - { - "name": "simplesamlphp/simplesamlphp-module-preprodwarning", - "version": "v0.9.3" - }, - { - "name": "simplesamlphp/simplesamlphp-module-radius", - "version": "v0.9.4" - }, - { - "name": "simplesamlphp/simplesamlphp-module-riak", - "version": "v0.9.1" - }, - { - "name": "simplesamlphp/simplesamlphp-module-sanitycheck", - "version": "v0.9.1" - }, - { - "name": "simplesamlphp/simplesamlphp-module-smartattributes", - "version": "v0.9.2" - }, - { - "name": "simplesamlphp/simplesamlphp-module-sqlauth", - "version": "v0.9.4" - }, - { - "name": "simplesamlphp/simplesamlphp-module-statistics", - "version": "v0.9.6" - }, - { - "name": "simplesamlphp/twig-configurable-i18n", - "version": "v2.3.5" + "name": "simplesamlphp/simplesamlphp-assets-base", + "version": "v2.2.1" }, { "name": "sinergi/browser-detector", @@ -285,131 +177,143 @@ }, { "name": "symfony/cache", - "version": "v5.4.25" + "version": "v6.4.8" }, { "name": "symfony/cache-contracts", - "version": "v2.5.2" + "version": "v3.5.0" }, { "name": "symfony/config", - "version": "v4.4.44" + "version": "v6.4.8" }, { "name": "symfony/console", - "version": "v4.4.49" - }, - { - "name": "symfony/debug", - "version": "v4.4.44" + "version": "v6.4.8" }, { "name": "symfony/dependency-injection", - "version": "v4.4.49" + "version": "v6.4.8" }, { "name": "symfony/deprecation-contracts", - "version": "v3.3.0" + "version": "v3.5.0" }, { "name": "symfony/error-handler", - "version": "v4.4.44" + "version": "v6.4.8" }, { "name": "symfony/event-dispatcher", - "version": "v4.4.44" + "version": "v6.4.8" }, { "name": "symfony/event-dispatcher-contracts", - "version": "v1.1.13" + "version": "v3.5.0" }, { "name": "symfony/filesystem", - "version": "v5.4.25" + "version": "v6.4.8" }, { "name": "symfony/finder", - "version": "v5.4.27" + "version": "v6.4.8" }, { "name": "symfony/framework-bundle", - "version": "v4.4.49" - }, - { - "name": "symfony/http-client-contracts", - "version": "v2.5.2" + "version": "v6.4.8" }, { "name": "symfony/http-foundation", - "version": "v5.4.26" + "version": "v6.4.8" }, { "name": "symfony/http-kernel", - "version": "v4.4.50" + "version": "v6.4.8" + }, + { + "name": "symfony/intl", + "version": "v6.4.8" }, { "name": "symfony/polyfill-ctype", - "version": "v1.27.0" + "version": "v1.29.0" }, { - "name": "symfony/polyfill-mbstring", - "version": "v1.27.0" + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.29.0" }, { - "name": "symfony/polyfill-php72", - "version": "v1.27.0" + "name": "symfony/polyfill-intl-icu", + "version": "v1.29.0" }, { - "name": "symfony/polyfill-php73", - "version": "v1.27.0" + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.29.0" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.29.0" }, { "name": "symfony/polyfill-php80", "version": "v1.29.0" }, { - "name": "symfony/polyfill-php81", - "version": "v1.27.0" + "name": "symfony/polyfill-php83", + "version": "v1.29.0" }, { "name": "symfony/routing", - "version": "v4.4.44" + "version": "v6.4.8" }, { "name": "symfony/service-contracts", - "version": "v2.5.2" + "version": "v3.5.0" + }, + { + "name": "symfony/string", + "version": "v6.4.8" + }, + { + "name": "symfony/translation-contracts", + "version": "v3.5.0" + }, + { + "name": "symfony/twig-bridge", + "version": "v6.4.8" }, { "name": "symfony/var-dumper", - "version": "v5.4.26" + "version": "v6.4.8" }, { "name": "symfony/var-exporter", - "version": "v5.4.26" + "version": "v6.4.8" }, { "name": "symfony/yaml", - "version": "v5.0.11" + "version": "v6.4.8" }, { - "name": "twig/extensions", - "version": "v1.5.4" + "name": "twig/intl-extra", + "version": "v3.10.0" }, { "name": "twig/twig", - "version": "v2.15.5" + "version": "v3.10.3" }, { "name": "webmozart/assert", "version": "1.11.0" }, { - "name": "whitehat101/apr1-md5", - "version": "v1.0.0" + "name": "yidas/yii2-composer-bower-skip", + "version": "2.0.13" }, { "name": "yiisoft/yii2", - "version": "2.0.49.3" + "version": "2.0.50" }, { "name": "yiisoft/yii2-composer", diff --git a/local.env.dist b/local.env.dist index 2507b067..c09c0e96 100644 --- a/local.env.dist +++ b/local.env.dist @@ -6,7 +6,6 @@ SECRET_SALT= # These are Optional ADMIN_EMAIL= ADMIN_NAME= -ADMIN_PROTECT_INDEX_PAGE= ANALYTICS_ID= BASE_URL_PATH= COMPOSER_ALLOW_SUPERUSER=1 diff --git a/modules/expirychecker/locales/en/LC_MESSAGES/.gitkeep b/modules/expirychecker/locales/en/LC_MESSAGES/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/modules/expirychecker/locales/es/LC_MESSAGES/.gitkeep b/modules/expirychecker/locales/es/LC_MESSAGES/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/modules/expirychecker/locales/fr/LC_MESSAGES/.gitkeep b/modules/expirychecker/locales/fr/LC_MESSAGES/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/modules/expirychecker/locales/ko/LC_MESSAGES/.gitkeep b/modules/expirychecker/locales/ko/LC_MESSAGES/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/modules/expirychecker/www/about2expire.php b/modules/expirychecker/public/about2expire.php similarity index 90% rename from modules/expirychecker/www/about2expire.php rename to modules/expirychecker/public/about2expire.php index 9e38ac03..05f2de15 100644 --- a/modules/expirychecker/www/about2expire.php +++ b/modules/expirychecker/public/about2expire.php @@ -43,23 +43,24 @@ $returnTo = Utilities::getUrlFromRelayState( $state['saml:RelayState'] ); - if (! empty($returnTo)) { + if (!empty($returnTo)) { $passwordChangeUrl .= '?returnTo=' . $returnTo; } } - HTTP::redirectTrustedURL($passwordChangeUrl, array()); + $httpUtils = new HTTP(); + $httpUtils->redirectTrustedURL($passwordChangeUrl, array()); } $globalConfig = Configuration::getInstance(); -$t = new Template($globalConfig, 'expirychecker:about2expire.php'); +$t = new Template($globalConfig, 'expirychecker:about2expire'); $t->data['formTarget'] = Module::getModuleURL('expirychecker/about2expire.php'); $t->data['formData'] = ['StateId' => $stateId]; $t->data['daysLeft'] = $state['daysLeft']; $t->data['dayOrDays'] = (intval($state['daysLeft']) === 1 ? 'day' : 'days'); $t->data['expiresAtTimestamp'] = $state['expiresAtTimestamp']; $t->data['accountName'] = $state['accountName']; -$t->show(); +$t->send(); Logger::info('expirychecker - User has been warned that their password will expire soon.'); diff --git a/modules/expirychecker/www/expired.php b/modules/expirychecker/public/expired.php similarity index 89% rename from modules/expirychecker/www/expired.php rename to modules/expirychecker/public/expired.php index c4c0b8c9..07f8a552 100644 --- a/modules/expirychecker/www/expired.php +++ b/modules/expirychecker/public/expired.php @@ -18,39 +18,40 @@ $state = State::loadState($stateId, 'expirychecker:expired'); if (array_key_exists('changepwd', $_REQUEST)) { - + /* Now that they've clicked change-password, skip the splash pages very * briefly, to let the user get to the change-password website. */ ExpiryDate::skipSplashPagesFor(60); // 60 seconds = 1 minute - + // The user has pressed the change-password button. $passwordChangeUrl = $state['passwordChangeUrl']; - + // Add the original url as a parameter if (array_key_exists('saml:RelayState', $state)) { $stateId = State::saveState( $state, 'expirychecker:about2expire' ); - + $returnTo = Utilities::getUrlFromRelayState( $state['saml:RelayState'] ); - if (! empty($returnTo)) { + if (!empty($returnTo)) { $passwordChangeUrl .= '?returnTo=' . $returnTo; } } - HTTP::redirectTrustedURL($passwordChangeUrl, array()); + $httpUtils = new HTTP(); + $httpUtils->redirectTrustedURL($passwordChangeUrl, array()); } $globalConfig = Configuration::getInstance(); -$t = new Template($globalConfig, 'expirychecker:expired.php'); +$t = new Template($globalConfig, 'expirychecker:expired'); $t->data['formTarget'] = Module::getModuleURL('expirychecker/expired.php'); $t->data['formData'] = ['StateId' => $stateId]; $t->data['expiresAtTimestamp'] = $state['expiresAtTimestamp']; $t->data['accountName'] = $state['accountName']; -$t->show(); +$t->send(); Logger::info('expirychecker - User has been told that their password has expired.'); diff --git a/modules/expirychecker/lib/Auth/Process/ExpiryDate.php b/modules/expirychecker/src/Auth/Process/ExpiryDate.php similarity index 93% rename from modules/expirychecker/lib/Auth/Process/ExpiryDate.php rename to modules/expirychecker/src/Auth/Process/ExpiryDate.php index 30322af4..8503f16e 100644 --- a/modules/expirychecker/lib/Auth/Process/ExpiryDate.php +++ b/modules/expirychecker/src/Auth/Process/ExpiryDate.php @@ -24,7 +24,7 @@ class ExpiryDate extends ProcessingFilter { const HAS_SEEN_SPLASH_PAGE = 'has_seen_splash_page'; const SESSION_TYPE = 'expirychecker'; - + private int $warnDaysBefore = 14; private string $originalUrlParam = 'originalurl'; private string|null $passwordChangeUrl = null; @@ -32,23 +32,23 @@ class ExpiryDate extends ProcessingFilter private string $employeeIdAttr = 'employeeNumber'; private string|null $expiryDateAttr = null; private string $dateFormat = 'Y-m-d'; - + protected LoggerInterface $logger; - + /** * Initialize this filter. * - * @param array $config Configuration information about this filter. - * @param mixed $reserved For future use. + * @param array $config Configuration information about this filter. + * @param mixed $reserved For future use. */ public function __construct(array $config, mixed $reserved) { parent::__construct($config, $reserved); assert('is_array($config)'); - + $this->initLogger($config); - + $this->loadValuesFromConfig($config, [ 'warnDaysBefore' => [ Validator::INT, @@ -75,18 +75,18 @@ public function __construct(array $config, mixed $reserved) ], ]); } - + protected function loadValuesFromConfig(array $config, array $attributeRules): void { foreach ($attributeRules as $attribute => $rules) { if (array_key_exists($attribute, $config)) { $this->$attribute = $config[$attribute]; } - + Validator::validate($this->$attribute, $rules, $this->logger, $attribute); } } - + /** * Get the specified attribute from the given state data. * @@ -101,14 +101,14 @@ protected function loadValuesFromConfig(array $config, array $attributeRules): v protected function getAttribute(string $attributeName, array $state): mixed { $attributeData = $state['Attributes'][$attributeName] ?? null; - + if (is_array($attributeData)) { return $attributeData[0] ?? null; } - + return $attributeData; } - + /** * Calculate how many days remain between now and when the password will * expire. @@ -121,9 +121,9 @@ protected function getDaysLeftBeforeExpiry(int $expiryTimestamp): int { $now = time(); $end = $expiryTimestamp; - return round(($end - $now) / (24*60*60)); + return round(($end - $now) / (24 * 60 * 60)); } - + /** * Get the timestamp for when the user's password will expire, throwing an * exception if unable to do so. @@ -137,7 +137,7 @@ protected function getDaysLeftBeforeExpiry(int $expiryTimestamp): int protected function getExpiryTimestamp(string $expiryDateAttr, array $state): int { $expiryDateString = $this->getAttribute($expiryDateAttr, $state); - + // Ensure that EVERY user login provides a usable password expiration date. $expiryTimestamp = strtotime($expiryDateString) ?: null; if (empty($expiryTimestamp)) { @@ -151,7 +151,7 @@ protected function getExpiryTimestamp(string $expiryDateAttr, array $state): int } return $expiryTimestamp; } - + public static function hasSeenSplashPageRecently(): bool { $session = Session::getSessionFromRequest(); @@ -160,7 +160,7 @@ public static function hasSeenSplashPageRecently(): bool self::HAS_SEEN_SPLASH_PAGE ); } - + public static function skipSplashPagesFor(int $seconds): void { $session = Session::getSessionFromRequest(); @@ -177,7 +177,7 @@ protected function initLogger(array $config): void { $loggerClass = $config['loggerClass'] ?? Psr3SamlLogger::class; $this->logger = new $loggerClass(); - if (! $this->logger instanceof LoggerInterface) { + if (!$this->logger instanceof LoggerInterface) { throw new \Exception(sprintf( 'The specified loggerClass (%s) does not implement ' . '\\Psr\\Log\\LoggerInterface.', @@ -185,7 +185,7 @@ protected function initLogger(array $config): void ), 1496928725); } } - + /** * See if the given timestamp is in the past. * @@ -196,7 +196,7 @@ public function isDateInPast(int $timestamp): bool { return ($timestamp < time()); } - + /** * Check whether the user's password has expired. * @@ -208,7 +208,7 @@ public function isExpired(int $expiryTimestamp): bool { return $this->isDateInPast($expiryTimestamp); } - + /** * Check whether it's time to warn the user that they will need to change * their password soon. @@ -239,8 +239,7 @@ public function redirect2PasswordChange( string $passwordChangeUrl, string $change_pwd_session, int $expiryTimestamp - ): void - { + ): void { $sessionType = 'expirychecker'; /* Save state and redirect. */ $state['expiresAtTimestamp'] = $expiryTimestamp; @@ -253,7 +252,7 @@ public function redirect2PasswordChange( $session = Session::getSessionFromRequest(); $idpExpirySession = $session->getData($sessionType, $change_pwd_session); - + // If the session shows that the User already passed this way, // don't redirect to change password page if ($idpExpirySession !== null) { @@ -269,8 +268,8 @@ public function redirect2PasswordChange( ); $session->save(); } - - + + /* If state already has the change password url, go straight there to * avoid eternal loop between that and the idp. Otherwise add the * original destination url as a parameter. */ @@ -282,7 +281,7 @@ public function redirect2PasswordChange( $returnTo = Utilities::getUrlFromRelayState( $relayState ); - if (! empty($returnTo)) { + if (!empty($returnTo)) { $passwordChangeUrl .= '?returnTo=' . $returnTo; } } @@ -294,18 +293,17 @@ public function redirect2PasswordChange( 'passwordChangeUrl' => $passwordChangeUrl, ])); - HTTP::redirectTrustedURL($passwordChangeUrl, array()); + $httpUtils = new HTTP(); + $httpUtils->redirectTrustedURL($passwordChangeUrl, array()); } - + /** - * Apply this AuthProc Filter. - * - * @param array &$state The current state. + * @inheritDoc */ - public function process(&$state): void + public function process(array &$state): void { $employeeId = $this->getAttribute($this->employeeIdAttr, $state); - + /* If the user has already seen a splash page from this AuthProc * recently, simply let them pass on through (so they can get into the * change-password website, for example). */ @@ -316,11 +314,11 @@ public function process(&$state): void ])); return; } - + // Get the necessary info from the state data. $accountName = $this->getAttribute($this->accountNameAttr, $state); $expiryTimestamp = $this->getExpiryTimestamp($this->expiryDateAttr, $state); - + $this->logger->warning(json_encode([ 'event' => 'expirychecker: will check expiration date', 'employeeId' => $employeeId, @@ -328,22 +326,22 @@ public function process(&$state): void 'expiryDateAttrValue' => $this->getAttribute($this->expiryDateAttr, $state), 'expiryTimestamp' => $expiryTimestamp, ])); - + if ($this->isExpired($expiryTimestamp)) { $this->redirectToExpiredPage($state, $accountName, $expiryTimestamp); } - + // Display a password expiration warning page if it's time to do so. if ($this->isTimeToWarn($expiryTimestamp, $this->warnDaysBefore)) { $this->redirectToWarningPage($state, $accountName, $expiryTimestamp); } - + $this->logger->warning(json_encode([ 'event' => 'expirychecker: no action necessary', 'employeeId' => $employeeId, ])); } - + /** * Redirect the user to the expired-password page. * @@ -354,7 +352,7 @@ public function process(&$state): void public function redirectToExpiredPage(array &$state, string $accountName, int $expiryTimestamp): void { assert('is_array($state)'); - + $this->logger->warning(json_encode([ 'event' => 'expirychecker: password expired', 'accountName' => $accountName, @@ -365,13 +363,14 @@ public function redirectToExpiredPage(array &$state, string $accountName, int $e $state['accountName'] = $accountName; $state['passwordChangeUrl'] = $this->passwordChangeUrl; $state['originalUrlParam'] = $this->originalUrlParam; - + $id = State::saveState($state, 'expirychecker:expired'); $url = Module::getModuleURL('expirychecker/expired.php'); - HTTP::redirectTrustedURL($url, array('StateId' => $id)); + $httpUtils = new HTTP(); + $httpUtils->redirectTrustedURL($url, array('StateId' => $id)); } - + /** * Redirect the user to the warning page. * @@ -382,29 +381,30 @@ public function redirectToExpiredPage(array &$state, string $accountName, int $e protected function redirectToWarningPage(array &$state, string $accountName, int $expiryTimestamp): void { assert('is_array($state)'); - + $this->logger->warning(json_encode([ 'event' => 'expirychecker: about to expire', 'accountName' => $accountName, ])); - + $daysLeft = $this->getDaysLeftBeforeExpiry($expiryTimestamp); $state['daysLeft'] = (string)$daysLeft; - + if (isset($state['isPassive']) && $state['isPassive'] === true) { /* We have a passive request. Skip the warning. */ return; } - + /* Save state and redirect. */ $state['expiresAtTimestamp'] = $expiryTimestamp; $state['accountName'] = $accountName; $state['passwordChangeUrl'] = $this->passwordChangeUrl; $state['originalUrlParam'] = $this->originalUrlParam; - + $id = State::saveState($state, 'expirychecker:about2expire'); $url = Module::getModuleURL('expirychecker/about2expire.php'); - HTTP::redirectTrustedURL($url, array('StateId' => $id)); + $httpUtils = new HTTP(); + $httpUtils->redirectTrustedURL($url, array('StateId' => $id)); } } diff --git a/modules/expirychecker/lib/Utilities.php b/modules/expirychecker/src/Utilities.php similarity index 52% rename from modules/expirychecker/lib/Utilities.php rename to modules/expirychecker/src/Utilities.php index e7ca7e8b..871d3884 100644 --- a/modules/expirychecker/lib/Utilities.php +++ b/modules/expirychecker/src/Utilities.php @@ -2,61 +2,69 @@ namespace SimpleSAML\Module\expirychecker; -class Utilities { +class Utilities +{ - /** - * Expects three strings for a url and what marks out the beginning - * and end of the domain. - * - * Returns a string with the domain portion of the url (e.g. www.insitehome.org) - */ - public static function getUrlDomain(string $in_url, string $start_marker='//', string $end_marker='/'): string + /** + * Expects three strings for a url and what marks out the beginning + * and end of the domain. + * + * Returns a string with the domain portion of the url (e.g. www.insitehome.org) + */ + public static function getUrlDomain(string $in_url, string $start_marker = '//', string $end_marker = '/'): string { - + $sm_len = strlen($start_marker); $em_len = strlen($end_marker); $start_pos = strpos($in_url, $start_marker); $domain = substr($in_url, $start_pos + $sm_len); - + $end_pos = strpos($domain, $end_marker); $domain = substr($domain, 0, $end_pos); return $domain; } - /** - * Expects six strings for a url and what marks out the beginning - * and end of its domain and then the same again for a second url. - * - * Returns 1 if the domains of the two urls are the same and 0 otherwise. - */ - public static function haveSameDomain(string $url1, string $start_marker1, - string $end_marker1, string $url2, string $start_marker2='//', - string $end_marker2='/'): int - { + /** + * Expects six strings for a url and what marks out the beginning + * and end of its domain and then the same again for a second url. + * + * Returns 1 if the domains of the two urls are the same and 0 otherwise. + */ + public static function haveSameDomain( + string $url1, + string $start_marker1, + string $end_marker1, + string $url2, + string $start_marker2 = '//', + string $end_marker2 = '/' + ): int { $domain1 = self::getUrlDomain($url1, $start_marker1, $end_marker1); $domain2 = self::getUrlDomain($url2, $start_marker2, $end_marker2); - + if ($domain1 === $domain2) { - return 1; + return 1; } return 0; } - /** - * Expects four strings for ... - * - the url for changing the user's password, - * - the parameter label for the original url the user was headed to - * - the original url the user was headed to - * - the StateId parameter to add to the end of the new version of the url - * Returns a string with special symbols urlencoded and then also encoded - * for apex to use. If the domains of the change password url and the - * original url are different, it appends the StateId to the output. - */ - public static function convertOriginalUrl(string $passwordChangeUrl, - string $originalUrlParam, string $originalUrl, string $stateId): string - { + /** + * Expects four strings for ... + * - the url for changing the user's password, + * - the parameter label for the original url the user was headed to + * - the original url the user was headed to + * - the StateId parameter to add to the end of the new version of the url + * Returns a string with special symbols urlencoded and then also encoded + * for apex to use. If the domains of the change password url and the + * original url are different, it appends the StateId to the output. + */ + public static function convertOriginalUrl( + string $passwordChangeUrl, + string $originalUrlParam, + string $originalUrl, + string $stateId + ): string { $sameDomain = self::haveSameDomain($passwordChangeUrl, - '//', '/', $originalUrl, '//', '/'); + '//', '/', $originalUrl, '//', '/'); $original = $originalUrlParam . ":" . urlencode($originalUrl); // make changes that insite/apex needs in url $original = str_replace('%3A', '*COLON*', $original); @@ -75,7 +83,7 @@ public static function convertOriginalUrl(string $passwordChangeUrl, } return $original; } - + /** * If the $relayState begins with "http", returns it. * Otherwise, returns empty string. @@ -87,7 +95,7 @@ public static function getUrlFromRelayState(string $relayState): string if (strpos($relayState, "http") === 0) { return $relayState; } - + return ''; } } diff --git a/modules/expirychecker/lib/Validator.php b/modules/expirychecker/src/Validator.php similarity index 92% rename from modules/expirychecker/lib/Validator.php rename to modules/expirychecker/src/Validator.php index f17be246..6c38c448 100644 --- a/modules/expirychecker/lib/Validator.php +++ b/modules/expirychecker/src/Validator.php @@ -11,7 +11,7 @@ class Validator const INT = 'int'; const NOT_EMPTY = 'not empty'; const STRING = 'string'; - + /** * Validate the given value against the specified rules. * @@ -23,21 +23,21 @@ class Validator public static function validate(mixed $value, array $rules, LoggerInterface $logger, string $attribute): void { foreach ($rules as $rule) { - if ( ! self::isValid($value, $rule, $logger)) { - + if (!self::isValid($value, $rule, $logger)) { + $exception = new Exception(sprintf( 'The value we have for %s (%s) does not meet the following validation rule: %s.', $attribute, var_export($value, true), $rule ), 1496867717); - + $logger->critical($exception->getMessage()); throw $exception; } } } - + /** * See if the given value satisfies the specified rule. * @@ -52,19 +52,19 @@ protected static function isValid(mixed $value, string $rule, LoggerInterface $l switch ($rule) { case self::INT: return is_int($value); - + case self::NOT_EMPTY: return !empty($value); - + case self::STRING: return is_string($value); - + default: $exception = new InvalidArgumentException(sprintf( 'Unknown validation rule: %s', var_export($rule, true) ), 1496866914); - + $logger->critical($exception->getMessage()); throw $exception; } diff --git a/modules/expirychecker/templates/.gitkeep b/modules/expirychecker/templates/.gitkeep new file mode 100644 index 00000000..57da54a3 --- /dev/null +++ b/modules/expirychecker/templates/.gitkeep @@ -0,0 +1 @@ +this directory will be filled in the Docker image with a copy of the material module templates diff --git a/modules/material/dictionaries/about2expire.definition.json b/modules/material/dictionaries/about2expire.definition.json deleted file mode 100644 index b39acd50..00000000 --- a/modules/material/dictionaries/about2expire.definition.json +++ /dev/null @@ -1,45 +0,0 @@ - -{ - "title": { - "en": "Expiring password", - "es": "Contraseña vencida", - "fr": "Mot de passe expiré", - "ko": "만료 된 암호" - }, - "header": { - "en": "Password expiring soon", - "es": "Contraseña caducada pronto", - "fr": "Mot de passe expire bientôt", - "ko": "곧 만료되는 암호" - }, - "expiring_in_a_day": { - "en": "Your password will expire in one day.", - "es": "Su contraseña caducará en un día.", - "fr": "Votre mot de passe expirera en un jour.", - "ko": "암호는 하루 만료됩니다." - }, - "expiring_soon": { - "en": "Your password will expire in {daysLeft} days.", - "es": "Su contraseña caducará en {daysLeft} días.", - "fr": "Votre mot de passe expirera en {daysLeft} jours.", - "ko": "비밀번호는 {daysLeft} 일 후에 만료됩니다." - }, - "change_now": { - "en": "Would you like to change it now?", - "es": "¿Quieres cambiarlo ahora?", - "fr": "Voulez-vous le changer maintenant?", - "ko": "지금 변경 하시겠습니까?" - }, - "button_change": { - "en": "Yes", - "es": "Sí", - "fr": "Oui", - "ko": "예" - }, - "button_continue": { - "en": "Later", - "es": "Después", - "fr": "Plus tard", - "ko": "후에" - } -} diff --git a/modules/material/dictionaries/error.definition.json b/modules/material/dictionaries/error.definition.json deleted file mode 100644 index 1cff9bba..00000000 --- a/modules/material/dictionaries/error.definition.json +++ /dev/null @@ -1,21 +0,0 @@ - -{ - "title": { - "en": "Error", - "es": "Error", - "fr": "Erreur", - "ko": "오류" - }, - "header": { - "en": "Error", - "es": "Error", - "fr": "Erreur", - "ko": "오류" - }, - "message": { - "en": "An error occurred, please contact your help desk for further assistance.", - "es": "Se ha producido un error, póngase en contacto con su asistencia técnica para obtener más ayuda.", - "fr": "Une erreur s'est produite, s'il vous plaît contacter votre service d'assistance pour plus d'assistance.", - "ko": "오류가 발생했습니다. 도움을 받으려면 헬프 데스크에 문의하십시오." - } -} diff --git a/modules/material/dictionaries/expired.definition.json b/modules/material/dictionaries/expired.definition.json deleted file mode 100644 index 0915a459..00000000 --- a/modules/material/dictionaries/expired.definition.json +++ /dev/null @@ -1,27 +0,0 @@ - -{ - "title": { - "en": "Expired password", - "es": "Contraseña caducada", - "fr": "Mot de passe expiré", - "ko": "만료 된 암호" - }, - "header": { - "en": "Password expired", - "es": "La contraseña expiró", - "fr": "Mot de passe expiré", - "ko": "암호가 만료되었습니다." - }, - "expired": { - "en": "Your password has expired and must be changed before continuing.", - "es": "Su contraseña ha caducado y debe cambiarse antes de continuar.", - "fr": "Votre mot de passe a expiré et doit être modifié avant de continuer.", - "ko": "비밀번호가 만료되었으므로 계속하기 전에 비밀번호를 변경해야합니다." - }, - "button_change": { - "en": "Change", - "es": "Cambiar", - "fr": "Changer", - "ko": "바꾸다" - } -} diff --git a/modules/material/dictionaries/footer.definition.json b/modules/material/dictionaries/footer.definition.json deleted file mode 100644 index 0ee65023..00000000 --- a/modules/material/dictionaries/footer.definition.json +++ /dev/null @@ -1,9 +0,0 @@ - -{ - "copyright": { - "en": "Unauthorized use of this site is prohibited and may be subjected to civil and criminal prosecution.", - "es": "El uso no autorizado de este sitio está prohibido y puede ser sometido a procesamiento civil y penal.", - "fr": "L'utilisation non autorisée de ce site est interdite et peut faire l'objet de poursuites civiles et pénales.", - "ko": "이 사이트의 무단 사용은 금지되어 있으며 민사 및 형사 고발의 대상이 될 수 있습니다." - } -} diff --git a/modules/material/dictionaries/login.definition.json b/modules/material/dictionaries/login.definition.json deleted file mode 100644 index e5d1d69b..00000000 --- a/modules/material/dictionaries/login.definition.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "title": { - "en": "Login with your {idpName} identity", - "es": "Inicie sesión con su identidad de {idpName}", - "fr": "Connectez-vous avec votre identité {idpName}", - "ko": "{idpName} 신원 계정으로 로그인하십시오." - }, - "header": { - "en": "Login with your {idpName} identity", - "es": "Inicie sesión con su identidad de {idpName}", - "fr": "Connectez-vous avec votre identité {idpName}", - "ko": "{idpName} 신원 계정으로 로그인하십시오." - }, - "label_username": { - "en": "Username", - "es": "Nombre de usuario", - "fr": "Nom d'utilisateur", - "ko": "사용자 이름" - }, - "label_password": { - "en": "Password", - "es": "Contraseña", - "fr": "Mot de passe", - "ko": "암호" - }, - "error_wronguserpass": { - "en": "Something is wrong with that username or password, please verify and try again.", - "es": "Algo está mal con ese nombre de usuario o contraseña, compruebe e inténtelo de nuevo.", - "fr": "Quelque chose ne va pas avec ce nom d'utilisateur ou ce mot de passe, veuillez vérifier et essayer à nouveau.", - "ko": "해당 사용자 이름 또는 비밀번호가 잘못되었습니다. 다시 확인하고 다시 시도하십시오." - }, - "button_login": { - "en": "Login", - "es": "Iniciar sesión", - "fr": "Connexion", - "ko": "로그인" - }, - "forgot": { - "en": "Forgot password?", - "es": "¿Se te olvidó tu contraseña?", - "fr": "Mot de passe oublié?", - "ko": "비밀번호를 잊으 셨나요?" - }, - "logo": { - "en": "{idpName} logo", - "es": "Logotipo de {idpName}", - "fr": "Logo {idpName}", - "ko": "{idpName} 로고" - }, - "help": { - "en": "I need help", - "es": "necesito ayuda", - "fr": "j'ai besoin d'aide", - "ko": "도움이 필요해." - }, - "profile": { - "en": "Manage my profile", - "es": "Administrar mi perfil", - "fr": "Gérer mon profil", - "ko": "내 프로필 관리" - } -} diff --git a/modules/material/dictionaries/logout.definition.json b/modules/material/dictionaries/logout.definition.json index 61324e70..b59b325b 100644 --- a/modules/material/dictionaries/logout.definition.json +++ b/modules/material/dictionaries/logout.definition.json @@ -1,21 +1,20 @@ - { - "title": { - "en": "Logged out", - "es": "Desconectado", - "fr": "Déconnecté", - "ko": "로그 아웃 됨" - }, - "header": { - "en": "Logged out", - "es": "Desconectado", - "fr": "Déconnecté", - "ko": "로그 아웃 됨" - }, - "message": { - "en": "You have now been logged out.", - "es": "Se ha desconectado.", - "fr": "Vous êtes maintenant déconnecté.", - "ko": "이제 로그 아웃되었습니다." - } + "title": { + "en": "Logged out", + "es": "Desconectado", + "fr": "Déconnecté", + "ko": "로그 아웃 됨" + }, + "header": { + "en": "Logged out", + "es": "Desconectado", + "fr": "Déconnecté", + "ko": "로그 아웃 됨" + }, + "message": { + "en": "You have now been logged out.", + "es": "Se ha desconectado.", + "fr": "Vous êtes maintenant déconnecté.", + "ko": "이제 로그 아웃되었습니다." + } } diff --git a/modules/material/dictionaries/mfa.definition.json b/modules/material/dictionaries/mfa.definition.json deleted file mode 100644 index 287648eb..00000000 --- a/modules/material/dictionaries/mfa.definition.json +++ /dev/null @@ -1,399 +0,0 @@ - -{ - "title": { - "en": "2-Step Verification", - "es": "Verificación en 2 pasos", - "fr": "Vérification en deux étapes", - "ko": "2 단계 인증" - }, - "header": { - "en": "2-Step Verification", - "es": "Verificación en 2 pasos", - "fr": "Vérification en deux étapes", - "ko": "2 단계 인증" - }, - "backupcode_header": { - "en": "Printable code", - "es": "código imprimible", - "fr": "code imprimable", - "ko": "인쇄 가능한 코드" - }, - "backupcode_icon": { - "en": "Printable code icon", - "es": "icono de código imprimible", - "fr": "icône de code imprimable", - "ko": "인쇄 가능한 코드 아이콘" - }, - "backupcode_reminder": { - "en": "Each code can only be used once, so the code you enter this time will be used up and will not be available again.", - "es": "Cada código solo se puede usar una vez, por lo que el código que ingrese esta vez se agotará y no estará disponible nuevamente.", - "fr": "Chaque code ne peut être utilisé qu'une seule fois, de sorte que le code que vous entrez cette fois sera épuisé et ne sera plus disponible.", - "ko": "각 코드는 한번만 사용할 수 있으므로 이번에 입력한 코드는 소멸되어 다시 사용할 수 없습니다." - }, - "backupcode_input": { - "en": "Enter code", - "es": "Introduzca el código", - "fr": "Entrer le code", - "ko": "코드 입력" - }, - "totp_header": { - "en": "Get a code from your authenticator app", - "es": "Obtenga un código de su aplicación de autenticación", - "fr": "Obtenez un code depuis votre application d'authentification", - "ko": "인증 앱에서 코드 받기" - }, - "totp_icon": { - "en": "Authenticator app icon", - "es": "Icono de aplicación de teléfono inteligente", - "fr": "Icône de l'application Smartphone", - "ko": "인증 응용 프로그램 아이콘" - }, - "totp_instructions": { - "en": "You will need to check your authenticator app for the current code.", - "es": "Deberá verificar la aplicación de autenticación para ver el código actual.", - "fr": "Vous devriez vérifier l'application d'authentification pour voir le code actuel.", - "ko": "인증 앱에서 현재 코드를 확인해야합니다." - }, - "totp_input": { - "en": "Enter 6-digit code", - "es": "Ingrese el código de 6 dígitos", - "fr": "Entrer le code à 6 chiffres", - "ko": "6 자리 코드 입력" - }, - "u2f_header": { - "en": "Security key", - "es": "Clave de seguridad", - "fr": "Clé de sécurité", - "ko": "보안키" - }, - "webauthn_header": { - "en": "Security key", - "es": "Clave de seguridad", - "fr": "Clé de sécurité", - "ko": "보안키" - }, - "u2f_icon": { - "en": "USB key icon", - "es": "Icono de la llave USB", - "fr": "Icône de clé USB", - "ko": "USB 키 아이콘" - }, - "webauthn_icon": { - "en": "USB key icon", - "es": "Icono de la llave USB", - "fr": "Icône de clé USB", - "ko": "USB 키 아이콘" - }, - "u2f_instructions": { - "en": "You may now insert your security key and press its button.", - "es": "Ahora puede insertar su clave de seguridad y presionar su botón.", - "fr": "Vous pouvez maintenant insérer votre clé de sécurité et appuyer sur le bouton.", - "ko": "이제 보안 키를 삽입하고 단추를 누를 수 있습니다." - }, - "webauthn_instructions": { - "en": "You may now insert your security key and press its button.", - "es": "Ahora puede insertar su clave de seguridad y presionar su botón.", - "fr": "Vous pouvez maintenant insérer votre clé de sécurité et appuyer sur le bouton.", - "ko": "이제 보안 키를 삽입하고 단추를 누를 수 있습니다." - }, - "u2f_unsupported": { - "en": "Unsupported in your current browser. Please consider a more secure browser like Google Chrome.", - "es": "No compatible en su navegador actual. Considere un navegador más seguro como Google Chrome.", - "fr": "Non compatible avec votre navigateur actuel. Veuillez considérer un navigateur plus sûr comme Google Chrome.", - "ko": "현재 브라우저에서 지원되지 않습니다. Chrome과 같은 보다 안전한 브라우저를 고려하십시오." - }, - "webauthn_unsupported": { - "en": "Unsupported in your current browser. Please consider a more secure browser like Google Chrome.", - "es": "No compatible en su navegador actual. Considere un navegador más seguro como Google Chrome.", - "fr": "Non compatible avec votre navigateur actuel. Veuillez considérer un navigateur plus sûr comme Google Chrome.", - "ko": "현재 브라우저에서 지원되지 않습니다. Chrome과 같은 보다 안전한 브라우저를 고려하십시오." - }, - "u2f_error_unknown": { - "en": "Something went wrong with that request, unable to verify at this time.", - "es": "Algo salió mal con esa solicitud, no se pudo verificar en este momento.", - "fr": "Quelque chose s'est mal passé avec cette demande, impossible de vérifier pour le moment.", - "ko": "요청에 문제가 발생하여 지금은 확인할 수 없습니다." - }, - "webauthn_error_unknown": { - "en": "Something went wrong with that request, unable to verify at this time.", - "es": "Algo salió mal con esa solicitud, no se pudo verificar en este momento.", - "fr": "Quelque chose s'est mal passé avec cette demande, impossible de vérifier pour le moment.", - "ko": "요청에 문제가 발생하여 지금은 확인할 수 없습니다." - }, - "u2f_error_wrong_key": { - "en": "This may not be the correct key for this site.", - "es": "Esta puede no ser la clave correcta para este sitio.", - "fr": "Ce n'est peut-être pas la bonne clé pour ce site.", - "ko": "이 사이트의 올바른 키가 아닐 수도 있습니다." - }, - "u2f_error_timeout": { - "en": "That took a little too long, check to make sure your key is inserted right-side up.", - "es": "Eso llevó demasiado tiempo, verifique que su clave esté insertada boca arriba.", - "fr": "Cela a pris un peu trop de temps, vérifiez que votre clé est insérée dans le bons sens.", - "ko": "오랜 시간이 경과 되었으니 키가 오른쪽 위로 삽입되었는지 확인 하십시오." - }, - "webauthn_error_abort": { - "en": "It looks like you clicked cancel. Would you like us to try again?", - "es": "Parece que has hecho clic en cancelar. ¿Quieres que lo intentemos de nuevo?", - "fr": "Il semble que vous ayez cliqué sur annuler. Souhaitez-vous que nous essayions à nouveau ?", - "ko": "취소를 클릭하신 것 같습니다. 다시 시도해 보시겠어요?" - }, - "webauthn_error_not_allowed": { - "en": "Something about that didn't work. Please ensure that your security key is plugged in and that you touch it within 60 seconds when it blinks.", - "es": "Algo de eso no funcionó. Por favor, asegúrese de que su clave de seguridad está conectada y de que la toca en un plazo de 60 segundos cuando parpadea.", - "fr": "Quelque chose n'a pas fonctionné avec ça. Veuillez vous assurer que votre clé de sécurité est insérée et que vous la touchez dans les 60 secondes lorsqu'elle clignote.", - "ko": "문제가 해결되지 않았습니다. 보안 키가 연결되어 있고 깜박일 때 60초 이내에 터치했는지 확인하세요." - }, - "manager_icon": { - "en": "Recovery contact icon", - "es": "Icono de contacto de recuperación", - "fr": "Icône du contact de récupération", - "ko": "복구 연락처 아이콘" - }, - "manager_header": { - "en": "Ask Your Recovery Contact for Help", - "es": "Pida ayuda de contacto de recuperación", - "fr": "Demandez de l'aide à votre contact de récupération", - "ko": "복구 담당자에게 도움을 요청하십시오" - }, - "manager_info": { - "en": "You can send a 2-step verification code to your recovery contact (usually your supervisor). The email we have for your recovery contact is:

{managerEmail}

We've hidden most of the letters for your contact's protection.", - "es": "Puede enviar un código de verificación de dos pasos a su contacto de recuperación (normalmente su supervisor). La dirección de correo electrónico que tenemos para su contacto de recuperación es:

{managerEmail}

Ocultamos la mayoría de las letras para proteger a su contacto.", - "fr": "Vous pouvez envoyer un code de vérification en deux étapes à votre contact de récupération (en général votre superviseur). L'adresse électronique que nous avons pour votre contact de récupération est:

{managerEmail}

. Nous avons caché la plupart des lettres pour la protection de votre contact.", - "ko": "2단계 인증 코드를 복구 연락처(보통 상사)에게 보낼 수 있습니다. 복구 연락처에 대한 이메일은 다음과 같습니다.

{managerEmail}

연락처 보호를 위해 대부분의 편지를 숨겼습니다." - }, - "manager_sent": { - "en": "A temporary code was sent your recovery contact at {managerEmail}.", - "es": "Se envió un código temporal a su contacto de recuperación en {managerEmail}.", - "fr": "Un code temporaire a été envoyé à votre contact de récupération à l'adresse {managerEmail}.", - "ko": "{managerEmail} (으)로 복구 담당자에게 임시 코드를 보냈습니다." - }, - "manager_input": { - "en": "Enter code", - "es": "Introduzca el código", - "fr": "Entrer le code", - "ko": "코드 입력" - }, - "shield_icon": { - "en": "Shield icon", - "es": "Icono de escudo", - "fr": "Icône de bouclier", - "ko": "방패 아이콘" - }, - "required_header": { - "en": "Protect this account", - "es": "Protege esta cuenta", - "fr": "Protéger ce compte", - "ko": "이 계정 보호" - }, - "required_info": { - "en": "Your identity account requires additional security, you must set up 2-Step Verification at this time.", - "es": "Su cuenta de identidad requiere seguridad adicional, debe configurar la verificación en dos pasos en este momento.", - "fr": "Votre compte d'identité nécessite une sécurité supplémentaire, vous devez configurer la vérification en deux étapes en ce moment.", - "ko": "신원 계정에 추가 보안이 필요하므로 현재 2 단계 인증을 설정해야합니다." - }, - "running_out_header": { - "en": "Almost out of printable codes", - "es": "Casi sin códigos imprimibles", - "fr": "Codes imprimables presque épuisés", - "ko": "인쇄 ​가능한 ​코드​가 거의 남지 않았습니다" - }, - "running_out_info": { - "en": "You only have {numBackupCodesRemaining} more left.", - "es": "Solo tiene {numBackupCodesRemaining} más disponible.", - "fr": "Vous avez seulement {numBackupCodesRemaining} qui restent.", - "ko": "{numBackupCodesRemaining} 만 남았습니다." - }, - "no_more_codes_header": { - "en": "Last printable code used", - "es": "Último código imprimible utilizado", - "fr": "Dernier code imprimable utilisé", - "ko": "​​마지막 인쇄 가능 코드가​​ ​사용되었습니다." - }, - "new_codes_header": { - "en": "New printable codes", - "es": "Nuevos códigos imprimibles", - "fr": "Nouveaux codes imprimables", - "ko": "​​새로운 인쇄 가능 코드" - }, - "old_codes_gone": { - "en": "You may now discard any of your previous codes, they have been deleted.", - "es": "Ahora puede descartar cualquiera de sus códigos anteriores, se han eliminado.", - "fr": "Vous pouvez maintenant jeter tous vos codes précédents, ils ont été supprimés.", - "ko": "​​이제 이전 코드를 삭제해도 삭제 될 수 있습니다." - }, - "new_codes_info": { - "en": "Printable codes should be treated with the same level of attention as any password.", - "es": "Los códigos imprimibles deben tratarse con el mismo nivel de atención que cualquier contraseña.", - "fr": "Les codes imprimables doivent être traités avec le même niveau d'attention que les mots de passe.", - "ko": "​​인쇄 가능한 코드는 모든 비밀번호와 동일한주의 수준으로 처리되어야합니다." - }, - "new_codes_only_once": { - "en": "Each code may only be used once.", - "es": "Cada código solo puede usarse una vez.", - "fr": "Chaque code ne peut être utilisé qu'une seule fois.", - "ko": "​​각 코드는 한 번만 사용할 수 있습니다." - }, - "new_codes_failed": { - "en": "Something went wrong while creating new printable codes for you. We are sorry for the inconvenience, please check your configuration at the following address after continuing: ", - "es": "Algo salió mal al crear nuevos códigos imprimibles para usted. Disculpe las molestias, compruebe su configuración en la siguiente dirección después de continuar: ", - "fr": "Une erreur s'est produite lors de la création de nouveaux codes imprimables. Nous sommes désolés pour le dérangement. Veuillez vérifier votre configuration à l'adresse suivante après avoir continué: ", - "ko": "새로운 인쇄 가능한 코드를 만드는 동안 문제가 발생했습니다. 불편을 끼쳐 드려 죄송합니다. 계속 진행 한 후 다음 주소로 구성을 확인하십시오. " - }, - "new_codes_saved": { - "en": "I saved a personal copy of these for later use", - "es": "Guardé una copia personal de estos para uso posterior", - "fr": "J'ai sauvegardé une copie personnelle de ceux-ci pour une utilisation ultérieure", - "ko": "나는 나중에 사용하기 위해 이들의 개인 사본을 저장했다." - }, - "account": { - "en": "{idpName} identity account", - "es": "Cuenta de identidad de {idpName}", - "fr": "Compte d'identité {idpName}", - "ko": "{idpName} 신원 계정" - }, - "has_options_besides_codes": { - "en": "Thankfully you do have other 2-Step Verification options set up but you should create more Printable codes if you plan to need them in the future.", - "es": "Afortunadamente, tiene otras opciones de verificación en dos pasos configuradas, pero debe crear más códigos imprimibles si planea necesitarlos en el futuro.", - "fr": "Heureusement, vous avez d'autres options de vérification en deux étapes, mais vous devriez créer plus de codes imprimables si vous prévoyez en avoir besoin à l'avenir.", - "ko": "다른 2 단계 인증 옵션​은​ 설정​ 되었으나​ ​인쇄 가능 코드가 나중에 ​필요할 ​것으로 ​예상되면​ 코드를 ​더 ​만들어야​ ​합니다." - }, - "has_no_more_options": { - "en": "Since you do not have any other 2-Step Verification options set up at this time, you will need to get more Printable codes before another one is required.", - "es": "Como no tiene configuradas otras opciones de verificación en dos pasos en este momento, necesitará obtener más códigos imprimibles antes de que se requiera otro.", - "fr": "Comme aucune autre option de vérification en deux étapes n'est configurée pour l'instant, vous devez obtenir davantage de codes imprimables avant d'en avoir besoin d'un autre.", - "ko": "코드​가 요구되기 전에 인쇄 가능 코드를​ 더 가져와야​ ​합니다." - }, - "use_others": { - "en": "More options", - "es": "Mas opciones", - "fr": "Davantage d'options", - "ko": "추가 옵션" - }, - "use_u2f": { - "en": "Use my security key instead", - "es": "Use mi clave de seguridad en su lugar", - "fr": "Utiliser plutôt ma clé de sécurité", - "ko": "내 보안키 사용" - }, - "use_webauthn": { - "en": "Use my security key instead", - "es": "Use mi clave de seguridad en su lugar", - "fr": "Utiliser plutôt ma clé de sécurité", - "ko": "내 보안키 사용" - }, - "use_totp": { - "en": "Use my authenticator app instead", - "es": "Use la aplicación autenticación en su lugar", - "fr": "Utiliser plutôt mon application d'authentification", - "ko": "내 인증 앱 사용" - }, - "use_backupcode": { - "en": "Use a printable code instead", - "es": "Use un código imprimible en su lugar", - "fr": "Utiliser plutôt un code imprimable", - "ko": "인쇄 가능한 코드 사용" - }, - "use_help": { - "en": "I need help", - "es": "necesito ayuda", - "fr": "j'ai besoin d'aide", - "ko": "도움이 필요해." - }, - "use_manager": { - "en": "Use code from my recovery contact", - "es": "Usar código de mi contacto de recuperación", - "fr": "Utiliser le code de mon contact de récupération", - "ko": "복구 담당자의 코드 사용" - }, - "button_verify": { - "en": "Verify", - "es": "Verificar", - "fr": "Vérifier", - "ko": "검증" - }, - "button_later": { - "en": "Remind me later", - "es": "Recuérdame más tarde", - "fr": "Rappelez-moi plus tard", - "ko": "추후 알림" - }, - "button_enable": { - "en": "Enable now", - "es": "Habilite ahora", - "fr": "Activer maintenant", - "ko": "지금 사용" - }, - "button_set_up": { - "en": "Set up now", - "es": "Configurar ahora", - "fr": "Configurer maintenant", - "ko": "지금 설정" - }, - "button_try_again": { - "en": "Try again", - "es": "Inténtalo de nuevo", - "fr": "Essayer de nouveau", - "ko": "다시 시도" - }, - "button_get_more": { - "en": "Get more", - "es": "Obtenga más", - "fr": "Avoir plus", - "ko": "더​ ​​가져오기" - }, - "button_continue": { - "en": "Continue", - "es": "Continuar", - "fr": "Continuer", - "ko": "계속하다" - }, - "button_print": { - "en": "Print", - "es": "Imprimir", - "fr": "Imprimer", - "ko": "인쇄" - }, - "button_download": { - "en": "Download", - "es": "Descargar", - "fr": "Télécharger", - "ko": "다운로드" - }, - "button_copy": { - "en": "Copy", - "es": "Copiar", - "fr": "Copier", - "ko": "사본" - }, - "button_send": { - "en": "Send code", - "es": "Enviar código", - "fr": "Envoyer code", - "ko": "코드 보내기" - }, - "button_cancel": { - "en": "Cancel", - "es": "Cancelar", - "fr": "Annuler", - "ko": "취소" - }, - "button_copied": { - "en": "Copied ✓", - "es": "Copiado ✓", - "fr": "Copié ✓", - "ko": "복사 됨 ✓" - }, - "remember_this": { - "en": "Remember this browser for 30 days", - "es": "Recuerde esta navegador por 30 días", - "fr": "Se rappeler de ce navigatuer pour 30 jours", - "ko": "이 브라우저를 30일간 기억" - }, - "unsupported": { - "en": "Not supported in this browser", - "es": "No compatible con este navegador", - "fr": "Non pris en charge dans ce navigateur", - "ko": "이 브라우저에서는 지원되지 않습니다." - } -} diff --git a/modules/material/dictionaries/nag.definition.json b/modules/material/dictionaries/nag.definition.json deleted file mode 100644 index 9c450e90..00000000 --- a/modules/material/dictionaries/nag.definition.json +++ /dev/null @@ -1,75 +0,0 @@ - -{ - "mfa_title": { - "en": "2-Step Verification", - "es": "Verificación en 2 pasos", - "fr": "Vérification en deux étapes", - "ko": "2 단계 인증" - }, - "mfa_header": { - "en": "2-Step Verification", - "es": "Verificación en 2 pasos", - "fr": "Vérification en deux étapes", - "ko": "2 단계 인증" - }, - "method_title": { - "en": "Password recovery methods", - "es": "Métodos de recuperación de contraseña", - "fr": "Méthodes de récupération de mot de passe", - "ko": "비밀번호 복구 방법" - }, - "method_header": { - "en": "Password recovery methods", - "es": "Métodos de recuperación de contraseña", - "fr": "Méthodes de récupération de mot de passe", - "ko": "비밀번호 복구 방법" - }, - "shield_icon": { - "en": "Shield icon", - "es": "Icono de escudo", - "fr": "Icône de bouclier", - "ko": "방패 아이콘" - }, - "header": { - "en": "Protect yourself", - "es": "Protéjase", - "fr": "Protégez-vous", - "ko": "자기 보호" - }, - "mfa_info": { - "en": "Did you know you could easily increase the security of your identity account by enabling 2-Step Verification?", - "es": "¿Sabía que podría aumentar fácilmente la seguridad de su cuenta de identidad al habilitar la verificación en dos pasos?", - "fr": "Savez-vous que vous pouvez facilement augmenter la sécurité de votre compte d'identité en activant la vérification en deux étapes?", - "ko": "2 단계 인증을 사용하여 신원 계정의 보안을 쉽게 높일 수 있다는 사실을 알고 계셨습니까?" - }, - "method_info": { - "en": "Do you forget your password sometimes? Did you know it is very easy to add an alternate email address for password recovery just in case?", - "es": "¿Olvidas tu contraseña a veces? ¿Sabía que es muy fácil agregar una dirección de correo electrónico alternativa para recuperar la contraseña por si acaso?", - "fr": "Avez-vous oublié votre mot de passe parfois? Saviez-vous qu'il est très facile d'ajouter une adresse électronique de remplacement pour la récupération du mot de passe au cas où?", - "ko": "가끔 암호를 잊어 버리십니까? 혹시라도 비밀번호 복구를 위해 보조 이메일 주소를 추가하는 것이 매우 쉽다는 것을 알고 계셨습니까?" - }, - "button_later": { - "en": "Remind me later", - "es": "Recuérdame más tarde", - "fr": "Rappelez-moi plus tard", - "ko": "추후 알림" - }, - "button_learn_more": { - "en": "Learn more", - "es": "Aprende más", - "fr": "Apprendre encore plus", - "ko": "더 알아보기" - }, - "button_enable": { - "en": "Enable now", - "es": "Habilite ahora", - "fr": "Activer maintenant", - "ko": "지금 사용" - }, - "button_add": { - "en": "Add one now", - "es": "Agrega uno ahora", - "fr": "Ajouter un maintenant", - "ko": "지금 하나 추가" - } -} diff --git a/modules/material/dictionaries/review.definition.json b/modules/material/dictionaries/review.definition.json index 96764c14..d51ced85 100644 --- a/modules/material/dictionaries/review.definition.json +++ b/modules/material/dictionaries/review.definition.json @@ -1,75 +1,74 @@ - { - "title": { - "en": "Profile review", - "es": "Revisión del perfil", - "fr": "Examen du profil", - "ko": "프로필 검토" - }, - "header": { - "en": "Profile review", - "es": "Revisión del perfil", - "fr": "Examen du profil", - "ko": "프로필 검토" - }, - "info": { - "en": "Are these still correct?", - "es": "¿Siguen siendo correctos?", - "fr": "Sont-ils toujours corrects?", - "ko": "여전히 맞습니까?" - }, - "mfa_header": { - "en": "2-Step Verification", - "es": "Verificación en 2 pasos", - "fr": "Vérification en 2 étapes", - "ko": "2 단계 인증" - }, - "methods_header": { - "en": "Password Recovery Methods", - "es": "Métodos de recuperación de contraseña", - "fr": "Méthodes de récupération de mot de passe", - "ko": "비밀번호 복구 방법" - }, - "remaining": { - "en": "({count} remaining)", - "es": "({count} restante)", - "fr": "({count} restant)", - "ko": "({count} 남음)" - }, - "used": { - "en": "last used: {when}", - "es": "último uso: {when}", - "fr": "dernière utilisation: {when}", - "ko": "마지막 사용 시간 : {when}" - }, - "used_never": { - "en": "last used: Never", - "es": "último uso: nunca", - "fr": "Dernière utilisation: Jamais", - "ko": "마지막 사용 : Never" - }, - "verified": { - "en": "Verified", - "es": "Verificado", - "fr": "Vérifié", - "ko": "검증 된" - }, - "unverified": { - "en": "Unverified", - "es": "Inconfirmado", - "fr": "Non vérifié", - "ko": "확인되지 않음" - }, - "button_update": { - "en": "Some of these need updating", - "es": "Algunos de estos necesitan actualización", - "fr": "Certains ont besoin d'être mis à jour", - "ko": "이들 중 일부는 업데이트해야합니다." - }, - "button_continue": { - "en": "These are still correct", - "es": "Estos siguen siendo correctos", - "fr": "Ceux-ci sont toujours corrects", - "ko": "이들은 여전히 정확하다." - } + "title": { + "en": "Profile review", + "es": "Revisión del perfil", + "fr": "Examen du profil", + "ko": "프로필 검토" + }, + "header": { + "en": "Profile review", + "es": "Revisión del perfil", + "fr": "Examen du profil", + "ko": "프로필 검토" + }, + "info": { + "en": "Are these still correct?", + "es": "¿Siguen siendo correctos?", + "fr": "Sont-ils toujours corrects?", + "ko": "여전히 맞습니까?" + }, + "mfa_header": { + "en": "2-Step Verification", + "es": "Verificación en 2 pasos", + "fr": "Vérification en 2 étapes", + "ko": "2 단계 인증" + }, + "methods_header": { + "en": "Password Recovery Methods", + "es": "Métodos de recuperación de contraseña", + "fr": "Méthodes de récupération de mot de passe", + "ko": "비밀번호 복구 방법" + }, + "remaining": { + "en": "({count} remaining)", + "es": "({count} restante)", + "fr": "({count} restant)", + "ko": "({count} 남음)" + }, + "used": { + "en": "last used: {when}", + "es": "último uso: {when}", + "fr": "dernière utilisation: {when}", + "ko": "마지막 사용 시간 : {when}" + }, + "used_never": { + "en": "last used: Never", + "es": "último uso: nunca", + "fr": "Dernière utilisation: Jamais", + "ko": "마지막 사용 : Never" + }, + "verified": { + "en": "Verified", + "es": "Verificado", + "fr": "Vérifié", + "ko": "검증 된" + }, + "unverified": { + "en": "Unverified", + "es": "Inconfirmado", + "fr": "Non vérifié", + "ko": "확인되지 않음" + }, + "button_update": { + "en": "Some of these need updating", + "es": "Algunos de estos necesitan actualización", + "fr": "Certains ont besoin d'être mis à jour", + "ko": "이들 중 일부는 업데이트해야합니다." + }, + "button_continue": { + "en": "These are still correct", + "es": "Estos siguen siendo correctos", + "fr": "Ceux-ci sont toujours corrects", + "ko": "이들은 여전히 정확하다." + } } diff --git a/modules/material/dictionaries/selectidp.definition.json b/modules/material/dictionaries/selectidp.definition.json index 55a261ac..898515c7 100644 --- a/modules/material/dictionaries/selectidp.definition.json +++ b/modules/material/dictionaries/selectidp.definition.json @@ -1,38 +1,38 @@ { - "title": { - "en": "Choose an identity account", - "es": "Elige una cuenta de identidad", - "fr": "Choisissez un compte d'identité", - "ko": "ID 계정 선택" - }, - "header": { - "en": "Choose an identity account", - "es": "Elige una cuenta de identidad", - "fr": "Choisissez un compte d'identité", - "ko": "ID 계정 선택" - }, - "header-for-sp": { - "en": "Choose an identity account to continue to {spName}", - "es": "Elija una cuenta de identidad para continuar en {spName}", - "fr": "Choisissez un compte d'identité pour continuer vers {spName}", - "ko": "{spName}을 계속 진행하려면 신원 계정을 선택하십시오." - }, - "enabled": { - "en": "Login with your {idpName} identity account", - "es": "Inicie sesión con su cuenta de identidad {idpName}", - "fr": "Connectez-vous avec votre compte d'identité {idpName}", - "ko": "{idpName} 신원 계정으로 로그인하십시오." - }, - "disabled": { - "en": "{idpName} coming soon", - "es": "{IdpName} próximamente", - "fr": "{IdpName} à venir", - "ko": "{idpName} 곧 제공됨" - }, - "help": { - "en": "Help", - "es": "Ayuda", - "fr": "Aidez-moi", - "ko": "도움" - } + "title": { + "en": "Choose an identity account", + "es": "Elige una cuenta de identidad", + "fr": "Choisissez un compte d'identité", + "ko": "ID 계정 선택" + }, + "header": { + "en": "Choose an identity account", + "es": "Elige una cuenta de identidad", + "fr": "Choisissez un compte d'identité", + "ko": "ID 계정 선택" + }, + "header-for-sp": { + "en": "Choose an identity account to continue to {spName}", + "es": "Elija una cuenta de identidad para continuar en {spName}", + "fr": "Choisissez un compte d'identité pour continuer vers {spName}", + "ko": "{spName}을 계속 진행하려면 신원 계정을 선택하십시오." + }, + "enabled": { + "en": "Login with your {idpName} identity account", + "es": "Inicie sesión con su cuenta de identidad {idpName}", + "fr": "Connectez-vous avec votre compte d'identité {idpName}", + "ko": "{idpName} 신원 계정으로 로그인하십시오." + }, + "disabled": { + "en": "{idpName} coming soon", + "es": "{IdpName} próximamente", + "fr": "{IdpName} à venir", + "ko": "{idpName} 곧 제공됨" + }, + "help": { + "en": "Help", + "es": "Ayuda", + "fr": "Aidez-moi", + "ko": "도움" + } } diff --git a/modules/material/locales/en/LC_MESSAGES/material.po b/modules/material/locales/en/LC_MESSAGES/material.po new file mode 100644 index 00000000..465a43e4 --- /dev/null +++ b/modules/material/locales/en/LC_MESSAGES/material.po @@ -0,0 +1,366 @@ + +msgid "{about2expire:title}" +msgstr "Expiring password" + +msgid "{about2expire:header}" +msgstr "Password expiring soon" + +msgid "{about2expire:expiring_in_a_day}" +msgstr "Your password will expire in one day." + +msgid "{about2expire:expiring_soon}" +msgstr "Your password will expire in %daysLeft% days." + +msgid "{about2expire:change_now}" +msgstr "Would you like to change it now?" + +msgid "{about2expire:button_change}" +msgstr "Yes" + +msgid "{about2expire:button_continue}" +msgstr "Later" + +msgid "{error:title}" +msgstr "Error" + +msgid "{error:header}" +msgstr "Error" + +msgid "{error:message}" +msgstr "An error occurred, please contact your help desk for further assistance." + +msgid "{error:generic_try_later}" +msgstr "Hmm... something went wrong. Please try again later." + +msgid "{error:username_required}" +msgstr "Please provide a username." + +msgid "{error:password_required}" +msgstr "Please provide a password." + +msgid "{error:invalid_login}" +msgstr "There was a problem with that username or password (or that account is disabled). Please try again or contact your organization's help desk." + +msgid "{error:need_to_set_acct_password}" +msgstr "You need to set your password to finish setting up your account. Please use the forgot password link below." + +msgid "{error:rate_limit_seconds}" +msgstr "There have been too many failed logins for this account. Please wait about %number% seconds, then try again." + +msgid "{error:rate_limit_1_minute}" +msgstr "There have been too many failed logins for this account. Please wait a minute, then try again." + +msgid "{error:rate_limit_minutes}" +msgstr "There have been too many failed logins for this account. Please wait about %number% minutes, then try again." + +msgid "{expired:title}" +msgstr "Expired password" + +msgid "{expired:header}" +msgstr "Password expired" + +msgid "{expired:expired}" +msgstr "Your password has expired and must be changed before continuing." + +msgid "{expired:button_change}" +msgstr "Change" + +msgid "{footer:copyright}" +msgstr "Unauthorized use of this site is prohibited and may be subjected to civil and criminal prosecution." + +msgid "{login:title}" +msgstr "Login with your %idpName% identity" + +msgid "{login:header}" +msgstr "Login with your %idpName% identity" + +msgid "{login:label_username}" +msgstr "Username" + +msgid "{login:label_password}" +msgstr "Password" + +msgid "{login:error_wronguserpass}" +msgstr "Something is wrong with that username or password, please verify and try again." + +msgid "{login:button_login}" +msgstr "Login" + +msgid "{login:forgot}" +msgstr "Forgot password?" + +msgid "{login:logo}" +msgstr "%idpName% logo" + +msgid "{login:help}" +msgstr "I need help" + +msgid "{login:profile}" +msgstr "Manage my profile" + +msgid "{mfa:title}" +msgstr "2-Step Verification" + +msgid "{mfa:header}" +msgstr "2-Step Verification" + +msgid "{mfa:backupcode_header}" +msgstr "Printable code" + +msgid "{mfa:backupcode_icon}" +msgstr "Printable code icon" + +msgid "{mfa:backupcode_reminder}" +msgstr "Each code can only be used once, so the code you enter this time will be used up and will not be available again." + +msgid "{mfa:backupcode_input}" +msgstr "Enter code" + +msgid "{mfa:totp_header}" +msgstr "Get a code from your authenticator app" + +msgid "{mfa:totp_icon}" +msgstr "Authenticator app icon" + +msgid "{mfa:totp_input}" +msgstr "Enter 6-digit code" + +msgid "{mfa:webauthn_header}" +msgstr "Security key" + +msgid "{mfa:u2f_icon}" +msgstr "USB key icon" + +msgid "{mfa:webauthn_icon}" +msgstr "USB key icon" + +msgid "{mfa:webauthn_instructions}" +msgstr "You may now insert your security key and press its button." + +msgid "{mfa:webauthn_unsupported}" +msgstr "Unsupported in your current browser. Please consider a more secure browser like Google Chrome." + +msgid "{mfa:webauthn_error_unknown}" +msgstr "Something went wrong with that request, unable to verify at this time." + +msgid "{mfa:webauthn_error_abort}" +msgstr "It looks like you clicked cancel. Would you like us to try again?" + +msgid "{mfa:webauthn_error_not_allowed}" +msgstr "Something about that didn't work. Please ensure that your security key is plugged in and that you touch it within 60 seconds when it blinks." + +msgid "{mfa:manager_icon}" +msgstr "Recovery contact icon" + +msgid "{mfa:manager_header}" +msgstr "Ask Your Recovery Contact for Help" + +msgid "{mfa:manager_info}" +msgstr "You can send a 2-step verification code to your recovery contact (usually your supervisor). The email we have for your recovery contact is:

%managerEmail%

We've hidden most of the letters for your contact's protection." + +msgid "{mfa:manager_sent}" +msgstr "A temporary code was sent your recovery contact at %managerEmail%." + +msgid "{mfa:manager_input}" +msgstr "Enter code" + +msgid "{mfa:shield_icon}" +msgstr "Shield icon" + +msgid "{mfa:required_header}" +msgstr "Protect this account" + +msgid "{mfa:required_info}" +msgstr "Your identity account requires additional security, you must set up 2-Step Verification at this time." + +msgid "{mfa:running_out_header}" +msgstr "Almost out of printable codes" + +msgid "{mfa:running_out_info}" +msgstr "You only have %numBackupCodesRemaining% more left." + +msgid "{mfa:no_more_codes_header}" +msgstr "Last printable code used" + +msgid "{mfa:new_codes_header}" +msgstr "New printable codes" + +msgid "{mfa:old_codes_gone}" +msgstr "You may now discard any of your previous codes, they have been deleted." + +msgid "{mfa:new_codes_info}" +msgstr "Printable codes should be treated with the same level of attention as any password." + +msgid "{mfa:new_codes_only_once}" +msgstr "Each code may only be used once." + +msgid "{mfa:new_codes_failed}" +msgstr "Something went wrong while creating new printable codes for you. We are sorry for the inconvenience, please check your configuration at the following address after continuing: " + +msgid "{mfa:new_codes_saved}" +msgstr "I saved a personal copy of these for later use" + +msgid "{mfa:account}" +msgstr "%idpName% identity account" + +msgid "{mfa:has_options_besides_codes}" +msgstr "Thankfully you do have other 2-Step Verification options set up but you should create more Printable codes if you plan to need them in the future." + +msgid "{mfa:has_no_more_options}" +msgstr "Since you do not have any other 2-Step Verification options set up at this time, you will need to get more Printable codes before another one is required." + +msgid "{mfa:use_others}" +msgstr "More options" + +msgid "{mfa:use_u2f}" +msgstr "Use my security key instead" + +msgid "{mfa:use_webauthn}" +msgstr "Use my security key instead" + +msgid "{mfa:use_totp}" +msgstr "Use my authenticator app instead" + +msgid "{mfa:use_backupcode}" +msgstr "Use a printable code instead" + +msgid "{mfa:use_help}" +msgstr "I need help" + +msgid "{mfa:use_manager}" +msgstr "Use code from my recovery contact" + +msgid "{mfa:button_verify}" +msgstr "Verify" + +msgid "{mfa:button_later}" +msgstr "Remind me later" + +msgid "{mfa:button_enable}" +msgstr "Enable now" + +msgid "{mfa:button_set_up}" +msgstr "Set up now" + +msgid "{mfa:button_try_again}" +msgstr "Try again" + +msgid "{mfa:button_get_more}" +msgstr "Get more" + +msgid "{mfa:button_continue}" +msgstr "Continue" + +msgid "{mfa:button_print}" +msgstr "Print" + +msgid "{mfa:button_download}" +msgstr "Download" + +msgid "{mfa:button_copy}" +msgstr "Copy" + +msgid "{mfa:button_send}" +msgstr "Send code" + +msgid "{mfa:button_cancel}" +msgstr "Cancel" + +msgid "{mfa:button_copied}" +msgstr "Copied ✓" + +msgid "{mfa:remember_this}" +msgstr "Remember this browser for 30 days" + +msgid "{mfa:unsupported}" +msgstr "Not supported in this browser" + +msgid "{nag:mfa_title}" +msgstr "2-Step Verification" + +msgid "{nag:mfa_header}" +msgstr "2-Step Verification" + +msgid "{nag:method_title}" +msgstr "Password recovery methods" + +msgid "{nag:method_header}" +msgstr "Password recovery methods" + +msgid "{nag:shield_icon}" +msgstr "Shield icon" + +msgid "{nag:header}" +msgstr "Protect yourself" + +msgid "{nag:mfa_info}" +msgstr "Did you know you could easily increase the security of your identity account by enabling 2-Step Verification?" + +msgid "{nag:method_info}" +msgstr "Do you forget your password sometimes? Did you know it is very easy to add an alternate email address for password recovery just in case?" + +msgid "{nag:button_later}" +msgstr "Remind me later" + +msgid "{nag:button_learn_more}" +msgstr "Learn more" + +msgid "{nag:button_enable}" +msgstr "Enable now" + +msgid "{nag:button_add}" +msgstr "Add one now" + +msgid "{review:title}" +msgstr "Profile review" + +msgid "{review:header}" +msgstr "Profile review" + +msgid "{review:info}" +msgstr "Are these still correct?" + +msgid "{review:mfa_header}" +msgstr "2-Step Verification" + +msgid "{review:methods_header}" +msgstr "Password Recovery Methods" + +msgid "{review:remaining}" +msgstr "(%count% remaining)" + +msgid "{review:used}" +msgstr "last used: %when%" + +msgid "{review:used_never}" +msgstr "last used: Never" + +msgid "{review:verified}" +msgstr "Verified" + +msgid "{review:unverified}" +msgstr "Unverified" + +msgid "{review:button_update}" +msgstr "Some of these need updating" + +msgid "{review:button_continue}" +msgstr "These are still correct" + +msgid "{selectidp-links:title}" +msgstr "Choose an identity account" + +msgid "{selectidp-links:header}" +msgstr "Choose an identity account" + +msgid "{selectidp-links:header-for-sp}" +msgstr "Choose an identity account to continue to %spName%" + +msgid "{selectidp-links:enabled}" +msgstr "Login with your %idpName% identity account" + +msgid "{selectidp-links:disabled}" +msgstr "%idpName% coming soon" + +msgid "{selectidp-links:help}" +msgstr "Help" diff --git a/modules/material/locales/es/LC_MESSAGES/material.po b/modules/material/locales/es/LC_MESSAGES/material.po new file mode 100644 index 00000000..2c8fcbb1 --- /dev/null +++ b/modules/material/locales/es/LC_MESSAGES/material.po @@ -0,0 +1,366 @@ + +msgid "{about2expire:title}" +msgstr "Contraseña vencida" + +msgid "{about2expire:header}" +msgstr "Contraseña caducada pronto" + +msgid "{about2expire:expiring_in_a_day}" +msgstr "Su contraseña caducará en un día." + +msgid "{about2expire:expiring_soon}" +msgstr "Su contraseña caducará en %daysLeft% días." + +msgid "{about2expire:change_now}" +msgstr "¿Quieres cambiarlo ahora?" + +msgid "{about2expire:button_change}" +msgstr "Sí" + +msgid "{about2expire:button_continue}" +msgstr "Después" + +msgid "{error:title}" +msgstr "Error" + +msgid "{error:header}" +msgstr "Error" + +msgid "{error:message}" +msgstr "Se ha producido un error, póngase en contacto con su asistencia técnica para obtener más ayuda." + +msgid "{error:generic_try_later}" +msgstr "Algo salió mal. Por favor, inténtelo de nuevo más tarde." + +msgid "{error:username_required}" +msgstr "Por favor proporcione un nombre de usuario." + +msgid "{error:password_required}" +msgstr "Proporcione una contraseña." + +msgid "{error:invalid_login}" +msgstr "Hubo un problema con ese nombre de usuario o contraseña (o esa cuenta está deshabilitada). Inténtelo de nuevo o comuníquese con el servicio de asistencia técnica de su organización." + +msgid "{error:need_to_set_acct_password}" +msgstr "Debes configurar tu contraseña para terminar de configurar tu cuenta. Utilice el enlace de olvidé mi contraseña que aparece a continuación." + +msgid "{error:rate_limit_seconds}" +msgstr "Ha habido demasiados inicios de sesión fallidos para esta cuenta. Espere unos %number% segundos y vuelva a intentarlo." + +msgid "{error:rate_limit_1_minute}" +msgstr "Ha habido demasiados inicios de sesión fallidos para esta cuenta. Espere un minuto y vuelva a intentarlo." + +msgid "{error:rate_limit_minutes}" +msgstr "Ha habido demasiados inicios de sesión fallidos para esta cuenta. Espere unos %number% minutos y vuelva a intentarlo." + +msgid "{expired:title}" +msgstr "Contraseña caducada" + +msgid "{expired:header}" +msgstr "La contraseña expiró" + +msgid "{expired:expired}" +msgstr "Su contraseña ha caducado y debe cambiarse antes de continuar." + +msgid "{expired:button_change}" +msgstr "Cambiar" + +msgid "{footer:copyright}" +msgstr "El uso no autorizado de este sitio está prohibido y puede ser sometido a procesamiento civil y penal." + +msgid "{login:title}" +msgstr "Inicie sesión con su identidad de %idpName%" + +msgid "{login:header}" +msgstr "Inicie sesión con su identidad de %idpName%" + +msgid "{login:label_username}" +msgstr "Nombre de usuario" + +msgid "{login:label_password}" +msgstr "Contraseña" + +msgid "{login:error_wronguserpass}" +msgstr "Algo está mal con ese nombre de usuario o contraseña, compruebe e inténtelo de nuevo." + +msgid "{login:button_login}" +msgstr "Iniciar sesión" + +msgid "{login:forgot}" +msgstr "¿Se te olvidó tu contraseña?" + +msgid "{login:logo}" +msgstr "Logotipo de %idpName%" + +msgid "{login:help}" +msgstr "necesito ayuda" + +msgid "{login:profile}" +msgstr "Administrar mi perfil" + +msgid "{mfa:title}" +msgstr "Verificación en 2 pasos" + +msgid "{mfa:header}" +msgstr "Verificación en 2 pasos" + +msgid "{mfa:backupcode_header}" +msgstr "código imprimible" + +msgid "{mfa:backupcode_icon}" +msgstr "icono de código imprimible" + +msgid "{mfa:backupcode_reminder}" +msgstr "Cada código solo se puede usar una vez, por lo que el código que ingrese esta vez se agotará y no estará disponible nuevamente." + +msgid "{mfa:backupcode_input}" +msgstr "Introduzca el código" + +msgid "{mfa:totp_header}" +msgstr "Obtenga un código de su aplicación de autenticación" + +msgid "{mfa:totp_icon}" +msgstr "Icono de aplicación de teléfono inteligente" + +msgid "{mfa:totp_input}" +msgstr "Ingrese el código de 6 dígitos" + +msgid "{mfa:webauthn_header}" +msgstr "Clave de seguridad" + +msgid "{mfa:u2f_icon}" +msgstr "Icono de la llave USB" + +msgid "{mfa:webauthn_icon}" +msgstr "Icono de la llave USB" + +msgid "{mfa:webauthn_instructions}" +msgstr "Ahora puede insertar su clave de seguridad y presionar su botón." + +msgid "{mfa:webauthn_unsupported}" +msgstr "No compatible en su navegador actual. Considere un navegador más seguro como Google Chrome." + +msgid "{mfa:webauthn_error_unknown}" +msgstr "Algo salió mal con esa solicitud, no se pudo verificar en este momento." + +msgid "{mfa:webauthn_error_abort}" +msgstr "Parece que has hecho clic en cancelar. ¿Quieres que lo intentemos de nuevo?" + +msgid "{mfa:webauthn_error_not_allowed}" +msgstr "Algo de eso no funcionó. Por favor, asegúrese de que su clave de seguridad está conectada y de que la toca en un plazo de 60 segundos cuando parpadea." + +msgid "{mfa:manager_icon}" +msgstr "Icono de contacto de recuperación" + +msgid "{mfa:manager_header}" +msgstr "Pida ayuda de contacto de recuperación" + +msgid "{mfa:manager_info}" +msgstr "Puede enviar un código de verificación de dos pasos a su contacto de recuperación (normalmente su supervisor). La dirección de correo electrónico que tenemos para su contacto de recuperación es:

%managerEmail%

Ocultamos la mayoría de las letras para proteger a su contacto." + +msgid "{mfa:manager_sent}" +msgstr "Se envió un código temporal a su contacto de recuperación en %managerEmail%." + +msgid "{mfa:manager_input}" +msgstr "Introduzca el código" + +msgid "{mfa:shield_icon}" +msgstr "Icono de escudo" + +msgid "{mfa:required_header}" +msgstr "Protege esta cuenta" + +msgid "{mfa:required_info}" +msgstr "Su cuenta de identidad requiere seguridad adicional, debe configurar la verificación en dos pasos en este momento." + +msgid "{mfa:running_out_header}" +msgstr "Casi sin códigos imprimibles" + +msgid "{mfa:running_out_info}" +msgstr "Solo tiene %numBackupCodesRemaining% más disponible." + +msgid "{mfa:no_more_codes_header}" +msgstr "Último código imprimible utilizado" + +msgid "{mfa:new_codes_header}" +msgstr "Nuevos códigos imprimibles" + +msgid "{mfa:old_codes_gone}" +msgstr "Ahora puede descartar cualquiera de sus códigos anteriores, se han eliminado." + +msgid "{mfa:new_codes_info}" +msgstr "Los códigos imprimibles deben tratarse con el mismo nivel de atención que cualquier contraseña." + +msgid "{mfa:new_codes_only_once}" +msgstr "Cada código solo puede usarse una vez." + +msgid "{mfa:new_codes_failed}" +msgstr "Algo salió mal al crear nuevos códigos imprimibles para usted. Disculpe las molestias, compruebe su configuración en la siguiente dirección después de continuar: " + +msgid "{mfa:new_codes_saved}" +msgstr "Guardé una copia personal de estos para uso posterior" + +msgid "{mfa:account}" +msgstr "Cuenta de identidad de %idpName%" + +msgid "{mfa:has_options_besides_codes}" +msgstr "Afortunadamente, tiene otras opciones de verificación en dos pasos configuradas, pero debe crear más códigos imprimibles si planea necesitarlos en el futuro." + +msgid "{mfa:has_no_more_options}" +msgstr "Como no tiene configuradas otras opciones de verificación en dos pasos en este momento, necesitará obtener más códigos imprimibles antes de que se requiera otro." + +msgid "{mfa:use_others}" +msgstr "Mas opciones" + +msgid "{mfa:use_u2f}" +msgstr "Use mi clave de seguridad en su lugar" + +msgid "{mfa:use_webauthn}" +msgstr "Use mi clave de seguridad en su lugar" + +msgid "{mfa:use_totp}" +msgstr "Use la aplicación autenticación en su lugar" + +msgid "{mfa:use_backupcode}" +msgstr "Use un código imprimible en su lugar" + +msgid "{mfa:use_help}" +msgstr "necesito ayuda" + +msgid "{mfa:use_manager}" +msgstr "Usar código de mi contacto de recuperación" + +msgid "{mfa:button_verify}" +msgstr "Verificar" + +msgid "{mfa:button_later}" +msgstr "Recuérdame más tarde" + +msgid "{mfa:button_enable}" +msgstr "Habilite ahora" + +msgid "{mfa:button_set_up}" +msgstr "Configurar ahora" + +msgid "{mfa:button_try_again}" +msgstr "Inténtalo de nuevo" + +msgid "{mfa:button_get_more}" +msgstr "Obtenga más" + +msgid "{mfa:button_continue}" +msgstr "Continuar" + +msgid "{mfa:button_print}" +msgstr "Imprimir" + +msgid "{mfa:button_download}" +msgstr "Descargar" + +msgid "{mfa:button_copy}" +msgstr "Copiar" + +msgid "{mfa:button_send}" +msgstr "Enviar código" + +msgid "{mfa:button_cancel}" +msgstr "Cancelar" + +msgid "{mfa:button_copied}" +msgstr "Copiado ✓" + +msgid "{mfa:remember_this}" +msgstr "Recuerde esta navegador por 30 días" + +msgid "{mfa:unsupported}" +msgstr "No compatible con este navegador" + +msgid "{nag:mfa_title}" +msgstr "Verificación en 2 pasos" + +msgid "{nag:mfa_header}" +msgstr "Verificación en 2 pasos" + +msgid "{nag:method_title}" +msgstr "Métodos de recuperación de contraseña" + +msgid "{nag:method_header}" +msgstr "Métodos de recuperación de contraseña" + +msgid "{nag:shield_icon}" +msgstr "Icono de escudo" + +msgid "{nag:header}" +msgstr "Protéjase" + +msgid "{nag:mfa_info}" +msgstr "¿Sabía que podría aumentar fácilmente la seguridad de su cuenta de identidad al habilitar la verificación en dos pasos?" + +msgid "{nag:method_info}" +msgstr "¿Olvidas tu contraseña a veces? ¿Sabía que es muy fácil agregar una dirección de correo electrónico alternativa para recuperar la contraseña por si acaso?" + +msgid "{nag:button_later}" +msgstr "Recuérdame más tarde" + +msgid "{nag:button_learn_more}" +msgstr "Aprende más" + +msgid "{nag:button_enable}" +msgstr "Habilite ahora" + +msgid "{nag:button_add}" +msgstr "Agrega uno ahora" + +msgid "{review:title}" +msgstr "Revisión del perfil" + +msgid "{review:header}" +msgstr "Revisión del perfil" + +msgid "{review:info}" +msgstr "¿Siguen siendo correctos?" + +msgid "{review:mfa_header}" +msgstr "Verificación en 2 pasos" + +msgid "{review:methods_header}" +msgstr "Métodos de recuperación de contraseña" + +msgid "{review:remaining}" +msgstr "(%count% restante)" + +msgid "{review:used}" +msgstr "último uso: %when%" + +msgid "{review:used_never}" +msgstr "último uso: nunca" + +msgid "{review:verified}" +msgstr "Verificado" + +msgid "{review:unverified}" +msgstr "Inconfirmado" + +msgid "{review:button_update}" +msgstr "Algunos de estos necesitan actualización" + +msgid "{review:button_continue}" +msgstr "Estos siguen siendo correctos" + +msgid "{selectidp-links:title}" +msgstr "Elige una cuenta de identidad" + +msgid "{selectidp-links:header}" +msgstr "Elige una cuenta de identidad" + +msgid "{selectidp-links:header-for-sp}" +msgstr "Elija una cuenta de identidad para continuar en %spName%" + +msgid "{selectidp-links:enabled}" +msgstr "Inicie sesión con su cuenta de identidad %idpName%" + +msgid "{selectidp-links:disabled}" +msgstr "%idpName% próximamente" + +msgid "{selectidp-links:help}" +msgstr "Ayuda" diff --git a/modules/material/locales/fr/LC_MESSAGES/material.po b/modules/material/locales/fr/LC_MESSAGES/material.po new file mode 100644 index 00000000..579721c7 --- /dev/null +++ b/modules/material/locales/fr/LC_MESSAGES/material.po @@ -0,0 +1,366 @@ + +msgid "{about2expire:title}" +msgstr "Mot de passe expiré" + +msgid "{about2expire:header}" +msgstr "Mot de passe expire bientôt" + +msgid "{about2expire:expiring_in_a_day}" +msgstr "Votre mot de passe expirera en un jour." + +msgid "{about2expire:expiring_soon}" +msgstr "Votre mot de passe expirera en %daysLeft% jours." + +msgid "{about2expire:change_now}" +msgstr "Voulez-vous le changer maintenant?" + +msgid "{about2expire:button_change}" +msgstr "Oui" + +msgid "{about2expire:button_continue}" +msgstr "Plus tard" + +msgid "{error:title}" +msgstr "Erreur" + +msgid "{error:header}" +msgstr "Erreur" + +msgid "{error:message}" +msgstr "Une erreur s'est produite, s'il vous plaît contacter votre service d'assistance pour plus d'assistance." + +msgid "{error:generic_try_later}" +msgstr "Quelque chose s'est mal passé. Veuillez réessayer plus tard." + +msgid "{error:username_required}" +msgstr "Veuillez fournir un nom d'utilisateur." + +msgid "{error:password_required}" +msgstr "Veuillez fournir un mot de passe." + +msgid "{error:invalid_login}" +msgstr "Il y a eu un problème avec ce nom d'utilisateur ou ce mot de passe (ou ce compte est désactivé). Veuillez réessayer ou contacter le service d'assistance de votre organisation." + +msgid "{error:need_to_set_acct_password}" +msgstr "Vous devez définir votre mot de passe pour terminer la configuration de votre compte. Veuillez utiliser le lien mot de passe oublié ci-dessous." + +msgid "{error:rate_limit_seconds}" +msgstr "Il y a eu trop d'échecs de connexion pour ce compte. Veuillez patienter environ %number% secondes, puis réessayez." + +msgid "{error:rate_limit_1_minute}" +msgstr "Il y a eu trop d'échecs de connexion pour ce compte. Veuillez patienter une minute, puis réessayez." + +msgid "{error:rate_limit_minutes}" +msgstr "Il y a eu trop d'échecs de connexion pour ce compte. Veuillez patienter environ %number% minutes, puis réessayez." + +msgid "{expired:title}" +msgstr "Mot de passe expiré" + +msgid "{expired:header}" +msgstr "Mot de passe expiré" + +msgid "{expired:expired}" +msgstr "Votre mot de passe a expiré et doit être modifié avant de continuer." + +msgid "{expired:button_change}" +msgstr "Changer" + +msgid "{footer:copyright}" +msgstr "L'utilisation non autorisée de ce site est interdite et peut faire l'objet de poursuites civiles et pénales." + +msgid "{login:title}" +msgstr "Connectez-vous avec votre identité %idpName%" + +msgid "{login:header}" +msgstr "Connectez-vous avec votre identité %idpName%" + +msgid "{login:label_username}" +msgstr "Nom d'utilisateur" + +msgid "{login:label_password}" +msgstr "Mot de passe" + +msgid "{login:error_wronguserpass}" +msgstr "Quelque chose ne va pas avec ce nom d'utilisateur ou ce mot de passe, veuillez vérifier et essayer à nouveau." + +msgid "{login:button_login}" +msgstr "Connexion" + +msgid "{login:forgot}" +msgstr "Mot de passe oublié?" + +msgid "{login:logo}" +msgstr "Logo %idpName%" + +msgid "{login:help}" +msgstr "j'ai besoin d'aide" + +msgid "{login:profile}" +msgstr "Gérer mon profil" + +msgid "{mfa:title}" +msgstr "Vérification en deux étapes" + +msgid "{mfa:header}" +msgstr "Vérification en deux étapes" + +msgid "{mfa:backupcode_header}" +msgstr "code imprimable" + +msgid "{mfa:backupcode_icon}" +msgstr "icône de code imprimable" + +msgid "{mfa:backupcode_reminder}" +msgstr "Chaque code ne peut être utilisé qu'une seule fois, de sorte que le code que vous entrez cette fois sera épuisé et ne sera plus disponible." + +msgid "{mfa:backupcode_input}" +msgstr "Entrer le code" + +msgid "{mfa:totp_header}" +msgstr "Obtenez un code depuis votre application d'authentification" + +msgid "{mfa:totp_icon}" +msgstr "Icône de l'application Smartphone" + +msgid "{mfa:totp_input}" +msgstr "Entrer le code à 6 chiffres" + +msgid "{mfa:webauthn_header}" +msgstr "Clé de sécurité" + +msgid "{mfa:u2f_icon}" +msgstr "Icône de clé USB" + +msgid "{mfa:webauthn_icon}" +msgstr "Icône de clé USB" + +msgid "{mfa:webauthn_instructions}" +msgstr "Vous pouvez maintenant insérer votre clé de sécurité et appuyer sur le bouton." + +msgid "{mfa:webauthn_unsupported}" +msgstr "Non compatible avec votre navigateur actuel. Veuillez considérer un navigateur plus sûr comme Google Chrome." + +msgid "{mfa:webauthn_error_unknown}" +msgstr "Quelque chose s'est mal passé avec cette demande, impossible de vérifier pour le moment." + +msgid "{mfa:webauthn_error_abort}" +msgstr "Il semble que vous ayez cliqué sur annuler. Souhaitez-vous que nous essayions à nouveau ?" + +msgid "{mfa:webauthn_error_not_allowed}" +msgstr "Quelque chose n'a pas fonctionné avec ça. Veuillez vous assurer que votre clé de sécurité est insérée et que vous la touchez dans les 60 secondes lorsqu'elle clignote." + +msgid "{mfa:manager_icon}" +msgstr "Icône du contact de récupération" + +msgid "{mfa:manager_header}" +msgstr "Demandez de l'aide à votre contact de récupération" + +msgid "{mfa:manager_info}" +msgstr "Vous pouvez envoyer un code de vérification en deux étapes à votre contact de récupération (en général votre superviseur). L'adresse électronique que nous avons pour votre contact de récupération est:

%managerEmail%

. Nous avons caché la plupart des lettres pour la protection de votre contact." + +msgid "{mfa:manager_sent}" +msgstr "Un code temporaire a été envoyé à votre contact de récupération à l'adresse %managerEmail%." + +msgid "{mfa:manager_input}" +msgstr "Entrer le code" + +msgid "{mfa:shield_icon}" +msgstr "Icône de bouclier" + +msgid "{mfa:required_header}" +msgstr "Protéger ce compte" + +msgid "{mfa:required_info}" +msgstr "Votre compte d'identité nécessite une sécurité supplémentaire, vous devez configurer la vérification en deux étapes en ce moment." + +msgid "{mfa:running_out_header}" +msgstr "Codes imprimables presque épuisés" + +msgid "{mfa:running_out_info}" +msgstr "Vous avez seulement %numBackupCodesRemaining% qui restent." + +msgid "{mfa:no_more_codes_header}" +msgstr "Dernier code imprimable utilisé" + +msgid "{mfa:new_codes_header}" +msgstr "Nouveaux codes imprimables" + +msgid "{mfa:old_codes_gone}" +msgstr "Vous pouvez maintenant jeter tous vos codes précédents, ils ont été supprimés." + +msgid "{mfa:new_codes_info}" +msgstr "Les codes imprimables doivent être traités avec le même niveau d'attention que les mots de passe." + +msgid "{mfa:new_codes_only_once}" +msgstr "Chaque code ne peut être utilisé qu'une seule fois." + +msgid "{mfa:new_codes_failed}" +msgstr "Une erreur s'est produite lors de la création de nouveaux codes imprimables. Nous sommes désolés pour le dérangement. Veuillez vérifier votre configuration à l'adresse suivante après avoir continué: " + +msgid "{mfa:new_codes_saved}" +msgstr "J'ai sauvegardé une copie personnelle de ceux-ci pour une utilisation ultérieure" + +msgid "{mfa:account}" +msgstr "Compte d'identité %idpName%" + +msgid "{mfa:has_options_besides_codes}" +msgstr "Heureusement, vous avez d'autres options de vérification en deux étapes, mais vous devriez créer plus de codes imprimables si vous prévoyez en avoir besoin à l'avenir." + +msgid "{mfa:has_no_more_options}" +msgstr "Comme aucune autre option de vérification en deux étapes n'est configurée pour l'instant, vous devez obtenir davantage de codes imprimables avant d'en avoir besoin d'un autre." + +msgid "{mfa:use_others}" +msgstr "Davantage d'options" + +msgid "{mfa:use_u2f}" +msgstr "Utiliser plutôt ma clé de sécurité" + +msgid "{mfa:use_webauthn}" +msgstr "Utiliser plutôt ma clé de sécurité" + +msgid "{mfa:use_totp}" +msgstr "Utiliser plutôt mon application d'authentification" + +msgid "{mfa:use_backupcode}" +msgstr "Utiliser plutôt un code imprimable" + +msgid "{mfa:use_help}" +msgstr "j'ai besoin d'aide" + +msgid "{mfa:use_manager}" +msgstr "Utiliser le code de mon contact de récupération" + +msgid "{mfa:button_verify}" +msgstr "Vérifier" + +msgid "{mfa:button_later}" +msgstr "Rappelez-moi plus tard" + +msgid "{mfa:button_enable}" +msgstr "Activer maintenant" + +msgid "{mfa:button_set_up}" +msgstr "Configurer maintenant" + +msgid "{mfa:button_try_again}" +msgstr "Essayer de nouveau" + +msgid "{mfa:button_get_more}" +msgstr "Avoir plus" + +msgid "{mfa:button_continue}" +msgstr "Continuer" + +msgid "{mfa:button_print}" +msgstr "Imprimer" + +msgid "{mfa:button_download}" +msgstr "Télécharger" + +msgid "{mfa:button_copy}" +msgstr "Copier" + +msgid "{mfa:button_send}" +msgstr "Envoyer code" + +msgid "{mfa:button_cancel}" +msgstr "Annuler" + +msgid "{mfa:button_copied}" +msgstr "Copié ✓" + +msgid "{mfa:remember_this}" +msgstr "Se rappeler de ce navigatuer pour 30 jours" + +msgid "{mfa:unsupported}" +msgstr "Non pris en charge dans ce navigateur" + +msgid "{nag:mfa_title}" +msgstr "Vérification en deux étapes" + +msgid "{nag:mfa_header}" +msgstr "Vérification en deux étapes" + +msgid "{nag:method_title}" +msgstr "Méthodes de récupération de mot de passe" + +msgid "{nag:method_header}" +msgstr "Méthodes de récupération de mot de passe" + +msgid "{nag:shield_icon}" +msgstr "Icône de bouclier" + +msgid "{nag:header}" +msgstr "Protégez-vous" + +msgid "{nag:mfa_info}" +msgstr "Savez-vous que vous pouvez facilement augmenter la sécurité de votre compte d'identité en activant la vérification en deux étapes?" + +msgid "{nag:method_info}" +msgstr "Avez-vous oublié votre mot de passe parfois? Saviez-vous qu'il est très facile d'ajouter une adresse électronique de remplacement pour la récupération du mot de passe au cas où?" + +msgid "{nag:button_later}" +msgstr "Rappelez-moi plus tard" + +msgid "{nag:button_learn_more}" +msgstr "Apprendre encore plus" + +msgid "{nag:button_enable}" +msgstr "Activer maintenant" + +msgid "{nag:button_add}" +msgstr "Ajouter un maintenant" + +msgid "{review:title}" +msgstr "Examen du profil" + +msgid "{review:header}" +msgstr "Examen du profil" + +msgid "{review:info}" +msgstr "Sont-ils toujours corrects?" + +msgid "{review:mfa_header}" +msgstr "Vérification en 2 étapes" + +msgid "{review:methods_header}" +msgstr "Méthodes de récupération de mot de passe" + +msgid "{review:remaining}" +msgstr "(%count% restant)" + +msgid "{review:used}" +msgstr "dernière utilisation: %when%" + +msgid "{review:used_never}" +msgstr "Dernière utilisation: Jamais" + +msgid "{review:verified}" +msgstr "Vérifié" + +msgid "{review:unverified}" +msgstr "Non vérifié" + +msgid "{review:button_update}" +msgstr "Certains ont besoin d'être mis à jour" + +msgid "{review:button_continue}" +msgstr "Ceux-ci sont toujours corrects" + +msgid "{selectidp-links:title}" +msgstr "Choisissez un compte d'identité" + +msgid "{selectidp-links:header}" +msgstr "Choisissez un compte d'identité" + +msgid "{selectidp-links:header-for-sp}" +msgstr "Choisissez un compte d'identité pour continuer vers %spName%" + +msgid "{selectidp-links:enabled}" +msgstr "Connectez-vous avec votre compte d'identité %idpName%" + +msgid "{selectidp-links:disabled}" +msgstr "%idpName% à venir" + +msgid "{selectidp-links:help}" +msgstr "Aidez-moi" diff --git a/modules/material/locales/ko/LC_MESSAGES/material.po b/modules/material/locales/ko/LC_MESSAGES/material.po new file mode 100644 index 00000000..7cb18c09 --- /dev/null +++ b/modules/material/locales/ko/LC_MESSAGES/material.po @@ -0,0 +1,366 @@ + +msgid "{about2expire:title}" +msgstr "만료 된 암호" + +msgid "{about2expire:header}" +msgstr "곧 만료되는 암호" + +msgid "{about2expire:expiring_in_a_day}" +msgstr "암호는 하루 만료됩니다." + +msgid "{about2expire:expiring_soon}" +msgstr "비밀번호는 %daysLeft% 일 후에 만료됩니다." + +msgid "{about2expire:change_now}" +msgstr "지금 변경 하시겠습니까?" + +msgid "{about2expire:button_change}" +msgstr "예" + +msgid "{about2expire:button_continue}" +msgstr "후에" + +msgid "{error:title}" +msgstr "오류" + +msgid "{error:header}" +msgstr "오류" + +msgid "{error:message}" +msgstr "오류가 발생했습니다. 도움을 받으려면 헬프 데스크에 문의하십시오." + +msgid "{error:generic_try_later}" +msgstr "문제가 발생했습니다. 나중에 다시 시도 해주십시오." + +msgid "{error:username_required}" +msgstr "사용자 이름을 입력하세요." + +msgid "{error:password_required}" +msgstr "비밀번호를 입력하세요." + +msgid "{error:invalid_login}" +msgstr "해당 사용자 이름이나 비밀번호에 문제가 있습니다(또는 해당 계정이 비활성화되었습니다). 다시 시도하거나 조직의 지원 센터에 문의하세요." + +msgid "{error:need_to_set_acct_password}" +msgstr "계정 설정을 완료하려면 비밀번호를 설정해야 합니다. 아래 비밀번호 찾기 링크를 이용해 주세요." + +msgid "{error:rate_limit_seconds}" +msgstr "이 계정에 대한 로그인 실패 횟수가 너무 많습니다. %number%초 정도 기다린 후 다시 시도하십시오." + +msgid "{error:rate_limit_1_minute}" +msgstr "이 계정에 대한 로그인 실패 횟수가 너무 많습니다. 잠시 기다린 후 다시 시도해 주세요." + +msgid "{error:rate_limit_minutes}" +msgstr "이 계정에 대한 로그인 실패 횟수가 너무 많습니다. %number%분 정도 기다린 후 다시 시도하십시오." + +msgid "{expired:title}" +msgstr "만료 된 암호" + +msgid "{expired:header}" +msgstr "암호가 만료되었습니다." + +msgid "{expired:expired}" +msgstr "비밀번호가 만료되었으므로 계속하기 전에 비밀번호를 변경해야합니다." + +msgid "{expired:button_change}" +msgstr "바꾸다" + +msgid "{footer:copyright}" +msgstr "이 사이트의 무단 사용은 금지되어 있으며 민사 및 형사 고발의 대상이 될 수 있습니다." + +msgid "{login:title}" +msgstr "%idpName% 신원 계정으로 로그인하십시오." + +msgid "{login:header}" +msgstr "%idpName% 신원 계정으로 로그인하십시오." + +msgid "{login:label_username}" +msgstr "사용자 이름" + +msgid "{login:label_password}" +msgstr "암호" + +msgid "{login:error_wronguserpass}" +msgstr "해당 사용자 이름 또는 비밀번호가 잘못되었습니다. 다시 확인하고 다시 시도하십시오." + +msgid "{login:button_login}" +msgstr "로그인" + +msgid "{login:forgot}" +msgstr "비밀번호를 잊으 셨나요?" + +msgid "{login:logo}" +msgstr "%idpName% 로고" + +msgid "{login:help}" +msgstr "도움이 필요해." + +msgid "{login:profile}" +msgstr "내 프로필 관리" + +msgid "{mfa:title}" +msgstr "2 단계 인증" + +msgid "{mfa:header}" +msgstr "2 단계 인증" + +msgid "{mfa:backupcode_header}" +msgstr "인쇄 가능한 코드" + +msgid "{mfa:backupcode_icon}" +msgstr "인쇄 가능한 코드 아이콘" + +msgid "{mfa:backupcode_reminder}" +msgstr "각 코드는 한번만 사용할 수 있으므로 이번에 입력한 코드는 소멸되어 다시 사용할 수 없습니다." + +msgid "{mfa:backupcode_input}" +msgstr "코드 입력" + +msgid "{mfa:totp_header}" +msgstr "인증 앱에서 코드 받기" + +msgid "{mfa:totp_icon}" +msgstr "인증 응용 프로그램 아이콘" + +msgid "{mfa:totp_input}" +msgstr "6 자리 코드 입력" + +msgid "{mfa:webauthn_header}" +msgstr "보안키" + +msgid "{mfa:u2f_icon}" +msgstr "USB 키 아이콘" + +msgid "{mfa:webauthn_icon}" +msgstr "USB 키 아이콘" + +msgid "{mfa:webauthn_instructions}" +msgstr "이제 보안 키를 삽입하고 단추를 누를 수 있습니다." + +msgid "{mfa:webauthn_unsupported}" +msgstr "현재 브라우저에서 지원되지 않습니다. Chrome과 같은 보다 안전한 브라우저를 고려하십시오." + +msgid "{mfa:webauthn_error_unknown}" +msgstr "요청에 문제가 발생하여 지금은 확인할 수 없습니다." + +msgid "{mfa:webauthn_error_abort}" +msgstr "취소를 클릭하신 것 같습니다. 다시 시도해 보시겠어요?" + +msgid "{mfa:webauthn_error_not_allowed}" +msgstr "문제가 해결되지 않았습니다. 보안 키가 연결되어 있고 깜박일 때 60초 이내에 터치했는지 확인하세요." + +msgid "{mfa:manager_icon}" +msgstr "복구 연락처 아이콘" + +msgid "{mfa:manager_header}" +msgstr "복구 담당자에게 도움을 요청하십시오" + +msgid "{mfa:manager_info}" +msgstr "2단계 인증 코드를 복구 연락처(보통 상사)에게 보낼 수 있습니다. 복구 연락처에 대한 이메일은 다음과 같습니다.

%managerEmail%

연락처 보호를 위해 대부분의 편지를 숨겼습니다." + +msgid "{mfa:manager_sent}" +msgstr "%managerEmail% (으)로 복구 담당자에게 임시 코드를 보냈습니다." + +msgid "{mfa:manager_input}" +msgstr "코드 입력" + +msgid "{mfa:shield_icon}" +msgstr "방패 아이콘" + +msgid "{mfa:required_header}" +msgstr "이 계정 보호" + +msgid "{mfa:required_info}" +msgstr "신원 계정에 추가 보안이 필요하므로 현재 2 단계 인증을 설정해야합니다." + +msgid "{mfa:running_out_header}" +msgstr "인쇄 ​가능한 ​코드​가 거의 남지 않았습니다" + +msgid "{mfa:running_out_info}" +msgstr "%numBackupCodesRemaining% 만 남았습니다." + +msgid "{mfa:no_more_codes_header}" +msgstr "​​마지막 인쇄 가능 코드가​​ ​사용되었습니다." + +msgid "{mfa:new_codes_header}" +msgstr "​​새로운 인쇄 가능 코드" + +msgid "{mfa:old_codes_gone}" +msgstr "​​이제 이전 코드를 삭제해도 삭제 될 수 있습니다." + +msgid "{mfa:new_codes_info}" +msgstr "​​인쇄 가능한 코드는 모든 비밀번호와 동일한주의 수준으로 처리되어야합니다." + +msgid "{mfa:new_codes_only_once}" +msgstr "​​각 코드는 한 번만 사용할 수 있습니다." + +msgid "{mfa:new_codes_failed}" +msgstr "새로운 인쇄 가능한 코드를 만드는 동안 문제가 발생했습니다. 불편을 끼쳐 드려 죄송합니다. 계속 진행 한 후 다음 주소로 구성을 확인하십시오. " + +msgid "{mfa:new_codes_saved}" +msgstr "나는 나중에 사용하기 위해 이들의 개인 사본을 저장했다." + +msgid "{mfa:account}" +msgstr "%idpName% 신원 계정" + +msgid "{mfa:has_options_besides_codes}" +msgstr "다른 2 단계 인증 옵션​은​ 설정​ 되었으나​ ​인쇄 가능 코드가 나중에 ​필요할 ​것으로 ​예상되면​ 코드를 ​더 ​만들어야​ ​합니다." + +msgid "{mfa:has_no_more_options}" +msgstr "코드​가 요구되기 전에 인쇄 가능 코드를​ 더 가져와야​ ​합니다." + +msgid "{mfa:use_others}" +msgstr "추가 옵션" + +msgid "{mfa:use_u2f}" +msgstr "내 보안키 사용" + +msgid "{mfa:use_webauthn}" +msgstr "내 보안키 사용" + +msgid "{mfa:use_totp}" +msgstr "내 인증 앱 사용" + +msgid "{mfa:use_backupcode}" +msgstr "인쇄 가능한 코드 사용" + +msgid "{mfa:use_help}" +msgstr "도움이 필요해." + +msgid "{mfa:use_manager}" +msgstr "복구 담당자의 코드 사용" + +msgid "{mfa:button_verify}" +msgstr "검증" + +msgid "{mfa:button_later}" +msgstr "추후 알림" + +msgid "{mfa:button_enable}" +msgstr "지금 사용" + +msgid "{mfa:button_set_up}" +msgstr "지금 설정" + +msgid "{mfa:button_try_again}" +msgstr "다시 시도" + +msgid "{mfa:button_get_more}" +msgstr "더​ ​​가져오기" + +msgid "{mfa:button_continue}" +msgstr "계속하다" + +msgid "{mfa:button_print}" +msgstr "인쇄" + +msgid "{mfa:button_download}" +msgstr "다운로드" + +msgid "{mfa:button_copy}" +msgstr "사본" + +msgid "{mfa:button_send}" +msgstr "코드 보내기" + +msgid "{mfa:button_cancel}" +msgstr "취소" + +msgid "{mfa:button_copied}" +msgstr "복사 됨 ✓" + +msgid "{mfa:remember_this}" +msgstr "이 브라우저를 30일간 기억" + +msgid "{mfa:unsupported}" +msgstr "이 브라우저에서는 지원되지 않습니다." + +msgid "{nag:mfa_title}" +msgstr "2 단계 인증" + +msgid "{nag:mfa_header}" +msgstr "2 단계 인증" + +msgid "{nag:method_title}" +msgstr "비밀번호 복구 방법" + +msgid "{nag:method_header}" +msgstr "비밀번호 복구 방법" + +msgid "{nag:shield_icon}" +msgstr "방패 아이콘" + +msgid "{nag:header}" +msgstr "자기 보호" + +msgid "{nag:mfa_info}" +msgstr "2 단계 인증을 사용하여 신원 계정의 보안을 쉽게 높일 수 있다는 사실을 알고 계셨습니까?" + +msgid "{nag:method_info}" +msgstr "가끔 암호를 잊어 버리십니까? 혹시라도 비밀번호 복구를 위해 보조 이메일 주소를 추가하는 것이 매우 쉽다는 것을 알고 계셨습니까?" + +msgid "{nag:button_later}" +msgstr "추후 알림" + +msgid "{nag:button_learn_more}" +msgstr "더 알아보기" + +msgid "{nag:button_enable}" +msgstr "지금 사용" + +msgid "{nag:button_add}" +msgstr "지금 하나 추가" + +msgid "{review:title}" +msgstr "프로필 검토" + +msgid "{review:header}" +msgstr "프로필 검토" + +msgid "{review:info}" +msgstr "여전히 맞습니까?" + +msgid "{review:mfa_header}" +msgstr "2 단계 인증" + +msgid "{review:methods_header}" +msgstr "비밀번호 복구 방법" + +msgid "{review:remaining}" +msgstr "(%count% 남음)" + +msgid "{review:used}" +msgstr "마지막 사용 시간 : %when%" + +msgid "{review:used_never}" +msgstr "마지막 사용 : Never" + +msgid "{review:verified}" +msgstr "검증 된" + +msgid "{review:unverified}" +msgstr "확인되지 않음" + +msgid "{review:button_update}" +msgstr "이들 중 일부는 업데이트해야합니다." + +msgid "{review:button_continue}" +msgstr "이들은 여전히 정확하다." + +msgid "{selectidp-links:title}" +msgstr "ID 계정 선택" + +msgid "{selectidp-links:header}" +msgstr "ID 계정 선택" + +msgid "{selectidp-links:header-for-sp}" +msgstr "%spName%을 계속 진행하려면 신원 계정을 선택하십시오." + +msgid "{selectidp-links:enabled}" +msgstr "%idpName% 신원 계정으로 로그인하십시오." + +msgid "{selectidp-links:disabled}" +msgstr "%idpName% 곧 제공됨" + +msgid "{selectidp-links:help}" +msgstr "도움" diff --git a/modules/material/www/bowser.1.9.4.min.js b/modules/material/public/bowser.1.9.4.min.js similarity index 100% rename from modules/material/www/bowser.1.9.4.min.js rename to modules/material/public/bowser.1.9.4.min.js diff --git a/modules/material/www/default-favicon.ico b/modules/material/public/default-favicon.ico similarity index 100% rename from modules/material/www/default-favicon.ico rename to modules/material/public/default-favicon.ico diff --git a/modules/material/www/default-favicon.png b/modules/material/public/default-favicon.png similarity index 100% rename from modules/material/www/default-favicon.png rename to modules/material/public/default-favicon.png diff --git a/modules/material/www/default-logo.png b/modules/material/public/default-logo.png similarity index 100% rename from modules/material/www/default-logo.png rename to modules/material/public/default-logo.png diff --git a/modules/material/www/email.svg b/modules/material/public/email.svg similarity index 100% rename from modules/material/www/email.svg rename to modules/material/public/email.svg diff --git a/modules/material/www/material-icons.woff b/modules/material/public/material-icons.woff similarity index 100% rename from modules/material/www/material-icons.woff rename to modules/material/public/material-icons.woff diff --git a/modules/material/www/material-icons.woff2 b/modules/material/public/material-icons.woff2 similarity index 100% rename from modules/material/www/material-icons.woff2 rename to modules/material/public/material-icons.woff2 diff --git a/modules/material/www/material.1.2.1.min.js b/modules/material/public/material.1.2.1.min.js similarity index 100% rename from modules/material/www/material.1.2.1.min.js rename to modules/material/public/material.1.2.1.min.js diff --git a/modules/material/www/material.blue_grey-teal.1.2.1.min.css b/modules/material/public/material.blue_grey-teal.1.2.1.min.css similarity index 100% rename from modules/material/www/material.blue_grey-teal.1.2.1.min.css rename to modules/material/public/material.blue_grey-teal.1.2.1.min.css diff --git a/modules/material/www/material.brown-orange.1.2.1.min.css b/modules/material/public/material.brown-orange.1.2.1.min.css similarity index 100% rename from modules/material/www/material.brown-orange.1.2.1.min.css rename to modules/material/public/material.brown-orange.1.2.1.min.css diff --git a/modules/material/www/material.indigo-purple.1.2.1.min.css b/modules/material/public/material.indigo-purple.1.2.1.min.css similarity index 100% rename from modules/material/www/material.indigo-purple.1.2.1.min.css rename to modules/material/public/material.indigo-purple.1.2.1.min.css diff --git a/modules/material/www/material.orange-light_blue.1.2.1.min.css b/modules/material/public/material.orange-light_blue.1.2.1.min.css similarity index 100% rename from modules/material/www/material.orange-light_blue.1.2.1.min.css rename to modules/material/public/material.orange-light_blue.1.2.1.min.css diff --git a/modules/material/www/material.red-teal.1.2.1.min.css b/modules/material/public/material.red-teal.1.2.1.min.css similarity index 100% rename from modules/material/www/material.red-teal.1.2.1.min.css rename to modules/material/public/material.red-teal.1.2.1.min.css diff --git a/modules/material/www/material.teal-blue.1.2.1.min.css b/modules/material/public/material.teal-blue.1.2.1.min.css similarity index 100% rename from modules/material/www/material.teal-blue.1.2.1.min.css rename to modules/material/public/material.teal-blue.1.2.1.min.css diff --git a/modules/material/www/mfa-backupcode.svg b/modules/material/public/mfa-backupcode.svg similarity index 100% rename from modules/material/www/mfa-backupcode.svg rename to modules/material/public/mfa-backupcode.svg diff --git a/modules/material/www/mfa-manager.svg b/modules/material/public/mfa-manager.svg similarity index 100% rename from modules/material/www/mfa-manager.svg rename to modules/material/public/mfa-manager.svg diff --git a/modules/material/www/mfa-totp.svg b/modules/material/public/mfa-totp.svg similarity index 100% rename from modules/material/www/mfa-totp.svg rename to modules/material/public/mfa-totp.svg diff --git a/modules/material/www/mfa-u2f-api.js b/modules/material/public/mfa-u2f-api.js similarity index 100% rename from modules/material/www/mfa-u2f-api.js rename to modules/material/public/mfa-u2f-api.js diff --git a/modules/material/www/mfa-u2f.svg b/modules/material/public/mfa-u2f.svg similarity index 100% rename from modules/material/www/mfa-u2f.svg rename to modules/material/public/mfa-u2f.svg diff --git a/modules/material/www/mfa-webauthn.svg b/modules/material/public/mfa-webauthn.svg similarity index 100% rename from modules/material/www/mfa-webauthn.svg rename to modules/material/public/mfa-webauthn.svg diff --git a/modules/material/www/shield.svg b/modules/material/public/shield.svg similarity index 100% rename from modules/material/www/shield.svg rename to modules/material/public/shield.svg diff --git a/modules/material/www/styles.2.3.6.css b/modules/material/public/styles.2.3.6.css similarity index 100% rename from modules/material/www/styles.2.3.6.css rename to modules/material/public/styles.2.3.6.css diff --git a/modules/material/themes/material/common-footer.php b/modules/material/themes/material/common-footer.php deleted file mode 100644 index 90fb7756..00000000 --- a/modules/material/themes/material/common-footer.php +++ /dev/null @@ -1,3 +0,0 @@ -
- t('{material:footer:copyright}') ?> -
diff --git a/modules/material/themes/material/core/loginuserpass.php b/modules/material/themes/material/core/loginuserpass.php deleted file mode 100644 index d355272a..00000000 --- a/modules/material/themes/material/core/loginuserpass.php +++ /dev/null @@ -1,159 +0,0 @@ - - - - configuration->getValue( - 'idp_display_name', - $this->configuration->getValue('idp_name', '—') - )); - ?> - - <?= $this->t('{material:login:title}', ['{idpName}' => $idpName]) ?> - - - - - - data['recaptcha.siteKey']); - - if (! empty($siteKey)) { - ?> - - - - - - -
-
- - -
- - - data)) { - $csrfToken = htmlentities($this->data['csrfToken']); - ?> - - - -
-
- <?= $this->t('{material:login:logo}', ['{idpName}' => $idpName]) ?> -
- -
-

- t('{material:login:header}', ['{idpName}' => $idpName]) ?> -

-
- -
-
- - - data['username'] ?? null); - ?> - id="username"/> -
- -
- - - - id="password"/> -
-
- - data['errorcode'] ?? null; - if ($errorCode == 'WRONGUSERPASS') { - $errorMessageKey = $this->data['errorparams'][1] ?? '{material:login:error_wronguserpass}'; - $errorMessageTokens = $this->data['errorparams'][2] ?? null; - - $message = $this->t($errorMessageKey, $errorMessageTokens); - ?> -

- error - - - - -

- - - - -
- configuration->getValue('passwordForgotUrl')); - if (! empty($forgotPasswordUrl)) { - ?> - - t('{material:login:forgot}') ?> - - - - - - -
-
- -
- data['helpCenterUrl'])): ?> - - t('{material:login:help}') ?> launch - - - - data['profileUrl'])): ?> - - t('{material:login:profile}') ?> launch - - -
-
-
-
- - diff --git a/modules/material/themes/material/common-announcement.php b/modules/material/themes/material/default/announcement.twig similarity index 51% rename from modules/material/themes/material/common-announcement.php rename to modules/material/themes/material/default/announcement.twig index 0fe9dcef..4a1c4684 100644 --- a/modules/material/themes/material/common-announcement.php +++ b/modules/material/themes/material/default/announcement.twig @@ -1,11 +1,5 @@ -data['announcement'])) { -?> +{% if announcement is defined and announcement is not empty %}
- data['announcement'] ?> + {{ announcement|raw }}
- - +{% endif %} diff --git a/modules/material/themes/material/default/error.php b/modules/material/themes/material/default/error.php deleted file mode 100644 index 859b3fbf..00000000 --- a/modules/material/themes/material/default/error.php +++ /dev/null @@ -1,41 +0,0 @@ - - - - <?= $this->t('{material:error:title}') ?> - - - - -
-
-
- - t('{material:error:header}') ?> - -
-
- -
-

- t('{material:error:message}') ?> -

- - data['showerrors'] ?? false) { - ?> -

- data['error']['exceptionMsg']) ?> -

- -
-            data['error']['exceptionTrace']) ?>
-        
- -
- - -
- - diff --git a/modules/material/themes/material/default/error.twig b/modules/material/themes/material/default/error.twig new file mode 100644 index 00000000..9dfaad44 --- /dev/null +++ b/modules/material/themes/material/default/error.twig @@ -0,0 +1,37 @@ + + + + {{ '{error:title}'|trans }} + + {{ include('header.twig') }} + + +
+
+
+ + {{ '{error:header}'|trans }} + +
+
+ +
+

+ {{ '{error:message}'|trans }} +

+ + {% if showerrors ?? false %} +

+ {{ error.exceptionMsg|e }} +

+ +
+            {{ error.exceptionTrace|e }}
+          
+ {% endif %} +
+ + {{ include('footer.twig') }} +
+ + diff --git a/modules/material/themes/material/default/footer.twig b/modules/material/themes/material/default/footer.twig new file mode 100644 index 00000000..4a61ac11 --- /dev/null +++ b/modules/material/themes/material/default/footer.twig @@ -0,0 +1,3 @@ +
+ {{ '{footer:copyright}'|trans }} +
diff --git a/modules/material/themes/material/common-head-elements.php b/modules/material/themes/material/default/header.twig similarity index 51% rename from modules/material/themes/material/common-head-elements.php rename to modules/material/themes/material/default/header.twig index ceb5690d..6c0fa471 100644 --- a/modules/material/themes/material/common-head-elements.php +++ b/modules/material/themes/material/default/header.twig @@ -3,29 +3,26 @@ - + -configuration->getValue('analytics.trackingId')); -if (! empty($trackingId)) { - ?> +{% if analyticsTrackingId is defined and analyticsTrackingId is not empty %} - + - - -configuration->getValue('theme.color-scheme') ?: 'indigo-purple'); -?> - +{% endif %} + +{# FIXME: #} + diff --git a/modules/material/themes/material/default/other_mfas.twig b/modules/material/themes/material/default/other_mfas.twig new file mode 100644 index 00000000..f333cddf --- /dev/null +++ b/modules/material/themes/material/default/other_mfas.twig @@ -0,0 +1,27 @@ +{% if otherOptions|length > 0 %} +
+ {# used type=button to avoid form submission on click since this is just used to display the ul #} + +
    + {% for option in otherOptions %} + {# TODO: Non-interactive elements should not be assigned mouse or keyboard event listeners. #} +
  • + + {mfa: + {% set text = '{mfa:use_' ~ option.label ~ '}' %} + {{ text|trans }} + +
  • + {% endfor %} +
+
+{% endif %} diff --git a/modules/material/themes/material/default/selectidp-links.php b/modules/material/themes/material/default/selectidp-links.php deleted file mode 100644 index 44a3d00b..00000000 --- a/modules/material/themes/material/default/selectidp-links.php +++ /dev/null @@ -1,168 +0,0 @@ - - - - <?= $this->t('{material:selectidp:title}') ?> - - - - - - - -
-
-
- - data['spName'] ?? null; - if (empty($spName)) { - echo $this->t('{material:selectidp:header}'); - } else { - echo htmlentities($this->t('{material:selectidp:header-for-sp}', ['{spName}' => $spName])); - } - ?> - - -
- - data['helpCenterUrl'])): ?> - - -
-
- -
- - -
- - - - - data['idplist']['dummy']); - - $enabledIdps = []; - $disabledIdps = []; - foreach ($this->data['idplist'] as $idp) { - $idp['enabled'] === true ? $enabledIdps[] = $idp - : $disabledIdps[] = $idp; - } - - foreach ($enabledIdps as $idp) { - $name = htmlentities($this->t($idp['name'])); - $idpId = htmlentities($idp['entityid']); - $hoverText = $this->t('{material:selectidp:enabled}', ['{idpName}' => $name]); - ?> -
-
- -
-
- - - t($idp['name'])); - $idpId = htmlentities($idp['entityid']); - $hoverText = $this->t('{material:selectidp:disabled}', ['{idpName}' => $name]); - ?> -
-
-
-
- -
- ': htmlentities($idp['logoCaption']) ?> -
-
-
- -
-
- - - -
- - - diff --git a/modules/material/themes/material/default/selectidp-links.twig b/modules/material/themes/material/default/selectidp-links.twig new file mode 100644 index 00000000..eaa4fe4e --- /dev/null +++ b/modules/material/themes/material/default/selectidp-links.twig @@ -0,0 +1,129 @@ + + + + {{ '{selectidp-links:title}'|trans }} + + {{ include('header.twig') }} + + + + +
+
+
+ + {% if spName ?? '' is empty %} + {{ '{selectidp-links:header}'|trans }} + {% else %} + {{ '{selectidp-links:header-for-sp}'|trans({'%spName%': spName})|e }} + {% endif %} + + +
+ + {% if helpCenterUrl is defined and helpCenterUrl is not empty %} + + {% endif %} +
+
+ +
+ {{ include('announcement.twig') }} + +
+ + + + + {% for idp in idplist %} +
+
+ +
+
+ {% endfor %} +
+
+ + {{ include('footer.twig') }} +
+ + + diff --git a/modules/material/themes/material/expirychecker/about2expire.php b/modules/material/themes/material/expirychecker/about2expire.php deleted file mode 100644 index 11500f97..00000000 --- a/modules/material/themes/material/expirychecker/about2expire.php +++ /dev/null @@ -1,58 +0,0 @@ - - - - <?= $this->t('{material:about2expire:title}') ?> - - - - -
-
-
- - t('{material:about2expire:header}') ?> - -
-
-
-
- data['formData'] as $name => $value) { - ?> - - - -

- data['daysLeft'] ?? '0'; - $expiringMessage = $daysLeft < 2 ? - $this->t('{material:about2expire:expiring_in_a_day}') : - $this->t('{material:about2expire:expiring_soon}', - ['{daysLeft}' => (string)$daysLeft]); - ?> - -

- -

- t('{material:about2expire:change_now}') ?> -

- -
- - - -
-
-
- - -
- - diff --git a/modules/material/themes/material/expirychecker/about2expire.twig b/modules/material/themes/material/expirychecker/about2expire.twig new file mode 100644 index 00000000..a6468ea2 --- /dev/null +++ b/modules/material/themes/material/expirychecker/about2expire.twig @@ -0,0 +1,50 @@ + + + + {{ '{about2expire:title}'|trans }} + + {{ include('header.twig') }} + + +
+
+
+ + {{ '{about2expire:header}'|trans }} + +
+
+
+
+ {% for name, value in formData %} + + {% endfor %} + +

+ {% if daysLeft < 2 %} + {{ '{about2expire:expiring_in_a_day}'|trans }} + {% else %} + {{ '{about2expire:expiring_soon}'|trans({'%daysLeft%': daysLeft}) }} + {% endif %} +

+ +

+ {{ '{about2expire:change_now}'|trans }} +

+ +
+ + + +
+
+
+ + {{ include('footer.twig') }} +
+ + diff --git a/modules/material/themes/material/expirychecker/expired.php b/modules/material/themes/material/expirychecker/expired.php deleted file mode 100644 index 447fd685..00000000 --- a/modules/material/themes/material/expirychecker/expired.php +++ /dev/null @@ -1,41 +0,0 @@ - - - - <?= $this->t('{material:expired:title}') ?> - - - - -
-
-
- - t('{material:expired:header}') ?> - -
-
-
-
- data['formData'] as $name => $value) { - ?> - - - -

- t('{material:expired:expired}') ?> -

- - -
-
- - -
- - diff --git a/modules/material/themes/material/expirychecker/expired.twig b/modules/material/themes/material/expirychecker/expired.twig new file mode 100644 index 00000000..e0cbf915 --- /dev/null +++ b/modules/material/themes/material/expirychecker/expired.twig @@ -0,0 +1,36 @@ + + + + {{ '{expired:title}'|trans }} + + {{ include('header.twig') }} + + +
+
+
+ + {{ '{expired:header}'|trans }} + +
+
+
+
+ {% for name, value in formData %} + + {% endfor %} + +

+ {{ '{expired:expired}'|trans }} +

+ + +
+
+ + {{ include('footer.twig') }} +
+ + diff --git a/modules/material/themes/material/mfa/low-on-backup-codes.php b/modules/material/themes/material/mfa/low-on-backup-codes.php deleted file mode 100644 index b8d75d41..00000000 --- a/modules/material/themes/material/mfa/low-on-backup-codes.php +++ /dev/null @@ -1,52 +0,0 @@ - - - - <?= $this->t('{material:mfa:title}') ?> - - - - -
-
-
- - t('{material:mfa:header}') ?> - -
-
-
-
-
-
- warning -
- -
-

- t('{material:mfa:running_out_header}') ?> -

-
- -
-

- t('{material:mfa:running_out_info}', ['{numBackupCodesRemaining}' => $this->data['numBackupCodesRemaining']]) ?> -

-
- -
- - - - - -
-
-
-
-
- - diff --git a/modules/material/themes/material/mfa/low-on-backup-codes.twig b/modules/material/themes/material/mfa/low-on-backup-codes.twig new file mode 100644 index 00000000..a5e84d58 --- /dev/null +++ b/modules/material/themes/material/mfa/low-on-backup-codes.twig @@ -0,0 +1,52 @@ + + + + {{ '{mfa:title}'|trans }} + + {{ include('header.twig') }} + + +
+
+
+ + {{ '{mfa:header}'|trans }} + +
+
+
+
+
+
+ warning +
+ +
+

+ {{ '{mfa:running_out_header}'|trans }} +

+
+ +
+

+ {{ '{mfa:running_out_info}'|trans({'%numBackupCodesRemaining%':numBackupCodesRemaining}) }} +

+
+ +
+ + + + + +
+
+
+
+
+ + diff --git a/modules/material/themes/material/mfa/must-set-up-mfa.php b/modules/material/themes/material/mfa/must-set-up-mfa.php deleted file mode 100644 index 8ae5c34f..00000000 --- a/modules/material/themes/material/mfa/must-set-up-mfa.php +++ /dev/null @@ -1,48 +0,0 @@ - - - - <?= $this->t('{material:mfa:title}') ?> - - - - -
-
-
- - t('{material:mfa:header}') ?> - -
-
-
-
-
-
- <?= $this->t('{material:mfa:shield_icon}') ?> -
- -
-

- t('{material:mfa:required_header}') ?> -

-
- -
-

- t('{material:mfa:required_info}') ?> -

-
- -
- - - -
-
-
-
-
- - diff --git a/modules/material/themes/material/mfa/must-set-up-mfa.twig b/modules/material/themes/material/mfa/must-set-up-mfa.twig new file mode 100644 index 00000000..a7556a42 --- /dev/null +++ b/modules/material/themes/material/mfa/must-set-up-mfa.twig @@ -0,0 +1,48 @@ + + + + {{ '{mfa:title}|trans' }} + + {{ include('header.twig') }} + + +
+
+
+ + {{ '{mfa:header}'|trans }} + +
+
+
+
+
+
+ {{ '{mfa:shield_icon}'|trans }} +
+ +
+

+ {{ '{mfa:required_header}'|trans }} +

+
+ +
+

+ {{ '{mfa:required_info}'|trans }} +

+
+ +
+ + + +
+
+
+
+
+ + diff --git a/modules/material/themes/material/mfa/new-backup-codes.php b/modules/material/themes/material/mfa/new-backup-codes.php deleted file mode 100644 index 175f1548..00000000 --- a/modules/material/themes/material/mfa/new-backup-codes.php +++ /dev/null @@ -1,158 +0,0 @@ - - - - <?= $this->t('{material:mfa:title}') ?> - - - - - - - -
-
-
- - t('{material:mfa:header}') ?> - -
-
-
-
- data['newBackupCodes']; ?> - -

- t('{material:mfa:new_codes_header}') ?> -

- -

- t('{material:mfa:old_codes_gone}') ?> -

- -

- t('{material:mfa:new_codes_info}') ?> - t('{material:mfa:new_codes_only_once}') ?> -

- -
-
- configuration->getValue('idp_display_name', $this->configuration->getValue('idp_name', '—'))); - ?> -

- t('{material:mfa:account}', ['{idpName}' => $idpName]) ?> - -

- -
- - - -
- - t('{material:mfa:new_codes_only_once}') ?> -
- -
- - - - " - download="-printable-codes.txt" class="mdl-button mdl-button--primary"> - t('{material:mfa:button_download}') ?> - - - - -
-
- -
-
- error -
- -
-

- t('{material:error:header}') ?> -

-
- -
-

- t('{material:mfa:new_codes_failed}') ?> - data['mfaSetupUrl'] ?> -

-
-
- - - - -
- - - -
- - -
-
-
- - diff --git a/modules/material/themes/material/mfa/new-backup-codes.twig b/modules/material/themes/material/mfa/new-backup-codes.twig new file mode 100644 index 00000000..d095a0e0 --- /dev/null +++ b/modules/material/themes/material/mfa/new-backup-codes.twig @@ -0,0 +1,166 @@ + + + + {{ '{mfa:title}'|trans }} + + {{ include('header.twig') }} + + + + + +
+
+
+ + {{ '{mfa:header}'|trans }} + +
+
+
+
+ {% if newBackupCodes is not empty %} +

+ {{ '{mfa:new_codes_header}'|trans }} +

+ +

+ {{ '{mfa:old_codes_gone}'|trans }} +

+ +

+ {{ '{mfa:new_codes_info}'|trans }} + {{ '{mfa:new_codes_only_once}'|trans }} +

+ +
+
+

+ {{ '{mfa:account}'|trans({'%idpName%':idpName}) }} + {{ "now"|date("M j, Y") }} +

+ +
+ {% for newCode in newBackupCodes %} + ☐ {{ newCode }} + {% endfor %} +
+ + {{ '{mfa:new_codes_only_once}'|trans }} +
+ +
+ + + + + {{ '{mfa:button_download}'|trans }} + + + + +
+
+ {% else %} +
+
+ error +
+ +
+

+ {{ '{error:header}'|trans }} +

+
+ +
+

+ {{ '{mfa:new_codes_failed}'|trans }} + {{ mfaSetupUrl }} +

+
+
+ + + {% endif %} + +
+ + + +
+ + +
+
+
+ + diff --git a/modules/material/themes/material/mfa/other_mfas.php b/modules/material/themes/material/mfa/other_mfas.php deleted file mode 100644 index 7d466a59..00000000 --- a/modules/material/themes/material/mfa/other_mfas.php +++ /dev/null @@ -1,34 +0,0 @@ -data['otherOptions']; -if (count($otherOptions) > 0) { -?> -
- - -
    - -
  • - - <?= $this->t('{material:mfa:' . $option['type'] . '_icon}') ?> - t('{material:mfa:use_' . $option['label'] . '}') ?> - -
  • - -
-
- diff --git a/modules/material/themes/material/mfa/out-of-backup-codes.php b/modules/material/themes/material/mfa/out-of-backup-codes.php deleted file mode 100644 index cc4db6cc..00000000 --- a/modules/material/themes/material/mfa/out-of-backup-codes.php +++ /dev/null @@ -1,58 +0,0 @@ - - - - <?= $this->t('{material:mfa:title}') ?> - - - - -
-
-
- - t('{material:mfa:header}') ?> - -
-
-
-
-
-
- error -
- -
-

- t('{material:mfa:no_more_codes_header}') ?> -

-
- -
-

- data['hasOtherMfaOptions']): ?> - t('{material:mfa:has_options_besides_codes}') ?> - - t('{material:mfa:has_no_more_options}') ?> - -

-
- -
- data['hasOtherMfaOptions']): ?> - - - - - - -
-
-
-
-
- - diff --git a/modules/material/themes/material/mfa/out-of-backup-codes.twig b/modules/material/themes/material/mfa/out-of-backup-codes.twig new file mode 100644 index 00000000..4eb199ea --- /dev/null +++ b/modules/material/themes/material/mfa/out-of-backup-codes.twig @@ -0,0 +1,58 @@ + + + + {{ '{mfa:title}'|trans }} + + {{ include('header.twig') }} + + +
+
+
+ + {{ '{mfa:header}'|trans }} + +
+
+
+
+
+
+ error +
+ +
+

+ {{ '{mfa:no_more_codes_header}'|trans }} +

+
+ +
+

+ {% if hasOtherMfaOptions %} + {{ '{mfa:has_options_besides_codes}'|trans }} + {% else %} + {{ '{mfa:has_no_more_options}'|trans }} + {% endif %} +

+
+ +
+ {% if hasOtherMfaOptions %} + + {% endif %} + + + + +
+
+
+
+
+ + diff --git a/modules/material/themes/material/mfa/prompt-for-mfa-backupcode.php b/modules/material/themes/material/mfa/prompt-for-mfa-backupcode.php deleted file mode 100644 index 7520467a..00000000 --- a/modules/material/themes/material/mfa/prompt-for-mfa-backupcode.php +++ /dev/null @@ -1,92 +0,0 @@ - - - - <?= $this->t('{material:mfa:title}') ?> - - - - -
-
-
- - t('{material:mfa:header}') ?> - -
-
-
-
-
-
- <?= $this->t('{material:mfa:backupcode_icon}') ?> -
- -
-

- t('{material:mfa:backupcode_header}') ?> -

-
- -
-

- t('{material:mfa:backupcode_reminder}') ?> -

-
- -
-
- - -
-
- - data['errorMessage']; - - if (! empty($message)) { - ?> -
-

- error - - - - -

-
- - - - -
- - -
- - -
- -
- -
-
-
-
- - diff --git a/modules/material/themes/material/mfa/prompt-for-mfa-backupcode.twig b/modules/material/themes/material/mfa/prompt-for-mfa-backupcode.twig new file mode 100644 index 00000000..8dbf08ab --- /dev/null +++ b/modules/material/themes/material/mfa/prompt-for-mfa-backupcode.twig @@ -0,0 +1,83 @@ + + + + {{ '{mfa:title}'|trans }} + + {{ include('header.twig') }} + + +
+
+
+ + {{ '{mfa:header}'|trans }} + +
+
+
+
+
+
+ {{ '{mfa:backupcode_icon}'|trans }} +
+ +
+

+ {{ '{mfa:backupcode_header}'|trans }} +

+
+ +
+

+ {{ '{mfa:backupcode_reminder}'|trans }} +

+
+ +
+
+ + +
+
+ + {% if errorMessage is not empty %} +
+

+ error + + + {{ errorMessage|e }} + +

+
+ + + {% endif %} + +
+ + +
+ + {{ include('other_mfas.twig') }} +
+ +
+ +
+
+
+
+ + diff --git a/modules/material/themes/material/mfa/prompt-for-mfa-manager.php b/modules/material/themes/material/mfa/prompt-for-mfa-manager.php deleted file mode 100644 index e9899947..00000000 --- a/modules/material/themes/material/mfa/prompt-for-mfa-manager.php +++ /dev/null @@ -1,89 +0,0 @@ - - - - <?= $this->t('{material:mfa:title}') ?> - - - - -
-
-
- - t('{material:mfa:header}') ?> - -
-
-
-
-
-
- <?= $this->t('{material:mfa:manager_icon}') ?> -
- -
-

- t('{material:mfa:manager_header}') ?> -

-
- -
-

- t('{material:mfa:manager_sent}', ['{managerEmail}' => $this->data['managerEmail']]) ?> -

-
- -
-
- - -
-
- - data['errorMessage']; - - if (! empty($message)) { - ?> -
-

- error - - - - -

-
- - - - -
- - -
- - -
- -
- -
-
-
-
- - diff --git a/modules/material/themes/material/mfa/prompt-for-mfa-manager.twig b/modules/material/themes/material/mfa/prompt-for-mfa-manager.twig new file mode 100644 index 00000000..48d8ef8f --- /dev/null +++ b/modules/material/themes/material/mfa/prompt-for-mfa-manager.twig @@ -0,0 +1,83 @@ + + + + {{ '{mfa:title}'|trans }} + + {{ include('header.twig') }} + + +
+
+
+ + {{ '{mfa:header}'|trans }} + +
+
+
+
+
+
+ {{ '{mfa:manager_icon}'|trans }} +
+ +
+

+ {{ '{mfa:manager_header}'|trans }} +

+
+ +
+

+ {{ '{mfa:manager_sent}'|trans({'%managerEmail%': managerEmail}) }} +

+
+ +
+
+ + +
+
+ + {% if errorMessage is not empty %} +
+

+ error + + + {{ errorMessage|e }} + +

+
+ + + {% endif %} + +
+ + +
+ + {{ include('other_mfas.twig') }} +
+ +
+ +
+
+
+
+ + diff --git a/modules/material/themes/material/mfa/prompt-for-mfa-totp.php b/modules/material/themes/material/mfa/prompt-for-mfa-totp.php deleted file mode 100644 index b0d10248..00000000 --- a/modules/material/themes/material/mfa/prompt-for-mfa-totp.php +++ /dev/null @@ -1,93 +0,0 @@ - - - - <?= $this->t('{material:mfa:title}') ?> - - - - -
-
-
- - t('{material:mfa:header}') ?> - -
-
-
-
-
-
- <?= $this->t('{material:mfa:totp_icon}') ?> -
- -
-

- t('{material:mfa:totp_header}') ?> -

-
- -
- configuration->getValue('idp_display_name', $this->configuration->getValue('idp_name', '—'))); - echo $this->t('{material:mfa:account}', ['{idpName}' => $idpName]); - ?> -
- -
-
- - -
-
- - data['errorMessage']; - - if (! empty($message)) { - ?> -
-

- error - - - - -

-
- - - - -
- - -
- - -
- -
- -
-
-
-
- - diff --git a/modules/material/themes/material/mfa/prompt-for-mfa-totp.twig b/modules/material/themes/material/mfa/prompt-for-mfa-totp.twig new file mode 100644 index 00000000..d95926f2 --- /dev/null +++ b/modules/material/themes/material/mfa/prompt-for-mfa-totp.twig @@ -0,0 +1,81 @@ + + + + {{ '{mfa:title}'|trans }} + + {{ include('header.twig') }} + + +
+
+
+ + {{ '{mfa:header}'|trans }} + +
+
+
+
+
+
+ {{ '{mfa:totp_icon}'|trans }} +
+ +
+

+ {{ '{mfa:totp_header}'|trans }} +

+
+ +
+ {{ '{mfa:account}'|trans({'%idpName%': idpName}) }} +
+ +
+
+ + +
+
+ + {% if errorMessage is not empty %} +
+

+ error + + + {{ errorMessage|e }} + +

+
+ + + {% endif %} + +
+ + +
+ + {{ include('other_mfas.twig') }} +
+ +
+ +
+
+
+
+ + diff --git a/modules/material/themes/material/mfa/prompt-for-mfa-webauthn.php b/modules/material/themes/material/mfa/prompt-for-mfa-webauthn.php deleted file mode 100644 index 02fa6ff4..00000000 --- a/modules/material/themes/material/mfa/prompt-for-mfa-webauthn.php +++ /dev/null @@ -1,153 +0,0 @@ - - - - <?= $this->t('{material:mfa:title}') ?> - - - - - - - - -data['supportsWebAuthn']; ?> - - -
-
-
- - t('{material:mfa:header}') ?> - -
-
- -
-
-
-
- <?= $this->t('{material:mfa:webauthn_icon}') ?> -
- -
-

- t('{material:mfa:webauthn_header}') ?> -

-
- - -
-

- t('{material:mfa:webauthn_instructions}') ?> -

-
- -
-

- t('{material:mfa:webauthn_unsupported}') ?> -

-
- - - data['errorMessage']; - if (! empty($message)) { - ?> - - -
-

- error - - - - -

-
- -
- - - - -
- - -
- -
- -
-
-
-
- - diff --git a/modules/material/themes/material/mfa/prompt-for-mfa-webauthn.twig b/modules/material/themes/material/mfa/prompt-for-mfa-webauthn.twig new file mode 100644 index 00000000..df53e360 --- /dev/null +++ b/modules/material/themes/material/mfa/prompt-for-mfa-webauthn.twig @@ -0,0 +1,148 @@ + + + + {{ '{mfa:title}'|trans }} + + {{ include('header.twig') }} + + + + + + + +
+
+
+ + {{ '{mfa:header}'|trans }} + +
+
+ +
+
+
+
+ {{ '{mfa:webauthn_icon}'|trans }} +
+ +
+

+ {{ '{mfa:webauthn_header}'|trans }} +

+
+ + {% if supportsWebAuthn %} +
+

+ {{ '{mfa:webauthn_instructions}'|trans }} +

+
+ {% else %} +
+

+ {{ '{mfa:webauthn_unsupported}'|trans|raw }} +

+
+ {% endif %} + + {% if errorMessage is not empty %} + + {% endif %} +
+

+ error + + + {{ errorMessage|e }} + +

+
+ +
+ + + + +
+ + {{ include('other_mfas.twig') }} +
+ +
+ +
+
+
+
+ + diff --git a/modules/material/themes/material/mfa/send-manager-mfa.php b/modules/material/themes/material/mfa/send-manager-mfa.php deleted file mode 100644 index 14c44cac..00000000 --- a/modules/material/themes/material/mfa/send-manager-mfa.php +++ /dev/null @@ -1,69 +0,0 @@ - - - - <?= $this->t('{material:mfa:title}') ?> - - - - -
-
-
- - t('{material:mfa:header}') ?> - -
-
-
-
-
-
- <?= $this->t('{material:mfa:manager_icon}') ?> -
- -
-

- t('{material:mfa:manager_header}') ?> -

-
- -
-

- t('{material:mfa:manager_info}', ['{managerEmail}' => $this->data['managerEmail']]) ?> -

-
- - data['errorMessage']; - - if (! empty($message)) { - ?> -
-

- error - - - - -

-
- - -
- - - - -
-
-
-
-
- - diff --git a/modules/material/themes/material/mfa/send-manager-mfa.twig b/modules/material/themes/material/mfa/send-manager-mfa.twig new file mode 100644 index 00000000..1e8a4237 --- /dev/null +++ b/modules/material/themes/material/mfa/send-manager-mfa.twig @@ -0,0 +1,63 @@ + + + + {{ '{mfa:title}'|trans }} + + {{ include('header.twig') }} + + +
+
+
+ + {{ '{mfa:header}'|trans }} + +
+
+
+
+
+
+ {{ '{mfa:manager_icon}'|trans }} +
+ +
+

+ {{ '{mfa:manager_header}'|trans }} +

+
+ +
+

+ {{ '{mfa:manager_info}'|trans({'%managerEmail%':managerEmail})|raw }} +

+
+ + {% if errorMessage is not empty %} +
+

+ error + + + {{ errorMessage|e }} + +

+
+ {% endif %} + +
+ + + + +
+
+
+
+
+ + diff --git a/modules/material/themes/material/profilereview/nag-for-method.php b/modules/material/themes/material/profilereview/nag-for-method.php deleted file mode 100644 index 7e6d50d1..00000000 --- a/modules/material/themes/material/profilereview/nag-for-method.php +++ /dev/null @@ -1,52 +0,0 @@ - - - - <?= $this->t('{material:nag:method_title}') ?> - - - - -
-
-
- - t('{material:nag:method_header}') ?> - -
-
-
-
-
-
- <?= $this->t('{material:nag:shield_icon}') ?> -
- -
-

- t('{material:nag:header}') ?> -

-
- -
-

- t('{material:nag:method_info}') ?> -

-
- -
- - - - - -
-
-
-
-
- - diff --git a/modules/material/themes/material/profilereview/nag-for-method.twig b/modules/material/themes/material/profilereview/nag-for-method.twig new file mode 100644 index 00000000..3beb0852 --- /dev/null +++ b/modules/material/themes/material/profilereview/nag-for-method.twig @@ -0,0 +1,52 @@ + + + + {{ '{nag:method_title}'|trans }} + + {{ include('header.twig') }} + + +
+
+
+ + {{ '{nag:method_header}'|trans }} + +
+
+
+
+
+
+ {{ '{nag:shield_icon}'|trans }} +
+ +
+

+ {{ '{nag:header}'|trans }} +

+
+ +
+

+ {{ '{nag:method_info}'|trans }} +

+
+ +
+ + + + + +
+
+
+
+
+ + diff --git a/modules/material/themes/material/profilereview/nag-for-mfa.php b/modules/material/themes/material/profilereview/nag-for-mfa.php deleted file mode 100644 index e18c9964..00000000 --- a/modules/material/themes/material/profilereview/nag-for-mfa.php +++ /dev/null @@ -1,63 +0,0 @@ - - - - <?= $this->t('{material:nag:mfa_title}') ?> - - - - -
-
-
- - t('{material:nag:mfa_header}') ?> - -
-
-
-
-
-
- <?= $this->t('{material:nag:shield_icon}') ?> -
- -
-

- t('{material:nag:header}') ?> -

-
- -
-

- t('{material:nag:mfa_info}') ?> -

-
- -
- - - - - data['mfaLearnMoreUrl'] ?? null; - if (! empty($url)) { - ?> - - t('{material:nag:button_learn_more}') ?> - - - - -
-
-
-
-
- - diff --git a/modules/material/themes/material/profilereview/nag-for-mfa.twig b/modules/material/themes/material/profilereview/nag-for-mfa.twig new file mode 100644 index 00000000..bf0a6f31 --- /dev/null +++ b/modules/material/themes/material/profilereview/nag-for-mfa.twig @@ -0,0 +1,63 @@ + + + + {{ '{nag:mfa_title}'|trans }} + + {{ include('header.twig') }} + + +
+
+
+ + {{ '{nag:mfa_header}'|trans }} + +
+
+
+
+
+
+ {{ '{nag:shield_icon}'|trans }} +
+ +
+

+ {{ '{nag:header}'|trans }} +

+
+ +
+

+ {{ '{nag:mfa_info}'|trans }} +

+
+ +
+ + + + + {% if mfaLearnMoreUrl is not empty %} + + {{ '{nag:button_learn_more}'|trans }} + + {% endif %} + + +
+
+
+
+
+ + diff --git a/modules/material/themes/material/profilereview/review.php b/modules/material/themes/material/profilereview/review.php deleted file mode 100644 index 039f4692..00000000 --- a/modules/material/themes/material/profilereview/review.php +++ /dev/null @@ -1,128 +0,0 @@ - - - - <?= $this->t('{material:review:title}') ?> - - - - - - -
-
-
- - t('{material:review:header}') ?> - -
-
- -
-
-

-

- t('{material:review:info}') ?> -

-

- -
- data['mfaOptions']) > 0): ?> -
-
-

- t('{material:review:mfa_header}') ?> -

-
- -
-
    - data['mfaOptions'] as $mfa): ?> -
  • - - - - - - - t('{material:review:remaining}', ['{count}' => (string) $mfa['data']['count']]) ?> - - - - - t('{material:review:used_never}') ?> - - t('{material:review:used}', ['{when}' => $mfa['last_used_utc']]) ?> - - - -
  • - -
-
-
- - - data['methodOptions']) > 0): ?> - -
-
-

- t('{material:review:methods_header}') ?> -

-
- -
-
    - data['methodOptions'] as $method): ?> -
  • - - - - - - - t('{material:review:'.($method['verified'] ? 'verified' : 'unverified').'}') ?> - - -
  • - -
-
-
- -
- -
- - t('{material:review:button_update}') ?> launch - - - -
-
-
- - -
- - diff --git a/modules/material/themes/material/profilereview/review.twig b/modules/material/themes/material/profilereview/review.twig new file mode 100644 index 00000000..1f014943 --- /dev/null +++ b/modules/material/themes/material/profilereview/review.twig @@ -0,0 +1,134 @@ + + + + {{ '{review:title}'|trans }} + + {{ include('header.twig') }} + + + + +
+
+
+ + {{ '{review:header}'|trans }} + +
+
+ +
+
+

+

+ {{ '{review:info}'|trans }} +

+

+ +
+ {% if mfaOptions|length > 0 %} +
+
+

+ {{ '{review:mfa_header}'|trans }} +

+
+ +
+
    + {% for mfa in mfaOptions %} +
  • + + + + {{ mfa.label }} + + {% if mfa.type == 'backupcode' %} + {{ '{review:remaining}'|trans({'%count%':mfa.data.count}) }} + {% endif %} + + + {% if mfa.last_used_utc is empty %} + {{ '{review:used_never}'|trans }} + {% else %} + {{ '{review:used}'|trans({'%when%':mfa.last_used_utc}) }} + {% endif %} + + +
  • + {% endfor %} +
+
+
+ {% endif %} + + {% if methodOptions|length > 0 %} +
+
+

+ {{ '{review:methods_header}'|trans }} +

+
+ +
+
    + {% for method in methodOptions %} +
  • + + + + {{ method.value }} + + + {% set key = '{review:' ~ (method.verified ? 'verified' : 'unverified') ~ '}' %} + {{ key|trans }} + + +
  • + {% endfor %} +
+
+
+ {% endif %} +
+ +
+ + {{ '{review:button_update}'|trans }} launch + + + +
+
+
+ + {{ include('footer.twig') }} +
+ + diff --git a/modules/material/themes/material/silauth/loginuserpass.twig b/modules/material/themes/material/silauth/loginuserpass.twig new file mode 100644 index 00000000..7f72ecaa --- /dev/null +++ b/modules/material/themes/material/silauth/loginuserpass.twig @@ -0,0 +1,156 @@ + + + + {{ '{login:title}'|trans({'%idpName%': idpName}) }} + + {{ include('header.twig') }} + + + + {% if siteKey is not empty %} + + + + {% endif %} + + +
+
+ {{ include('announcement.twig') }} + +
+ + + {% if csrfToken is defined %} + + {% endif %} + +
+
+ {{ '{login:logo}'|trans({'%idpName%': idpName}) }} +
+ +
+

+ {{ '{login:header}'|trans({'%idpName%': idpName}) }} +

+
+ +
+
+ + + +
+ +
+ + + +
+
+ + {% if errorcode ?? '' == 'WRONGUSERPASS' %} + {% set errorMessageKey = errorparams[1] ?? '{login:error_wronguserpass}' %} + {% set errorMessageTokens = errorparams[2] ?? null %} + {% set message = errorMessageKey|trans(errorMessageTokens) %} +

+ error + + + {{ message|e }} + +

+ + + {% endif %} + +
+ {% if passwordForgotUrl is not empty %} + + {{ '{login:forgot}'|trans }} + + {% endif %} + + + + +
+ +
+ {% if helpCenterUrl is defined and helpCenterUrl is not empty %} + + {{ '{login:help}'|trans }} + launch + + {% endif %} + + {% if profileUrl is defined and profileUrl is not empty %} + + {{ '{login:profile}'|trans }} + launch + + {% endif %} +
+
+
+
+
+ + diff --git a/modules/mfa/locales/en/LC_MESSAGES/.gitkeep b/modules/mfa/locales/en/LC_MESSAGES/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/modules/mfa/locales/es/LC_MESSAGES/.gitkeep b/modules/mfa/locales/es/LC_MESSAGES/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/modules/mfa/locales/fr/LC_MESSAGES/.gitkeep b/modules/mfa/locales/fr/LC_MESSAGES/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/modules/mfa/locales/ko/LC_MESSAGES/.gitkeep b/modules/mfa/locales/ko/LC_MESSAGES/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/modules/mfa/www/low-on-backup-codes.php b/modules/mfa/public/low-on-backup-codes.php similarity index 93% rename from modules/mfa/www/low-on-backup-codes.php rename to modules/mfa/public/low-on-backup-codes.php index 8adb6d8c..6351fc72 100644 --- a/modules/mfa/www/low-on-backup-codes.php +++ b/modules/mfa/public/low-on-backup-codes.php @@ -30,9 +30,9 @@ $globalConfig = Configuration::getInstance(); -$t = new Template($globalConfig, 'mfa:low-on-backup-codes.php'); +$t = new Template($globalConfig, 'mfa:low-on-backup-codes'); $t->data['numBackupCodesRemaining'] = $state['numBackupCodesRemaining']; -$t->show(); +$t->send(); $logger->info(sprintf( 'mfa: Told Employee ID %s they are low on backup codes.', diff --git a/modules/mfa/www/must-set-up-mfa.php b/modules/mfa/public/must-set-up-mfa.php similarity index 91% rename from modules/mfa/www/must-set-up-mfa.php rename to modules/mfa/public/must-set-up-mfa.php index dbe44428..d1067c62 100644 --- a/modules/mfa/www/must-set-up-mfa.php +++ b/modules/mfa/public/must-set-up-mfa.php @@ -23,8 +23,8 @@ $globalConfig = Configuration::getInstance(); -$t = new Template($globalConfig, 'mfa:must-set-up-mfa.php'); -$t->show(); +$t = new Template($globalConfig, 'mfa:must-set-up-mfa'); +$t->send(); $logger->info(sprintf( 'mfa: Told Employee ID %s they they must set up MFA.', diff --git a/modules/mfa/www/new-backup-codes.php b/modules/mfa/public/new-backup-codes.php similarity index 74% rename from modules/mfa/www/new-backup-codes.php rename to modules/mfa/public/new-backup-codes.php index 29573a2a..d824a55e 100644 --- a/modules/mfa/www/new-backup-codes.php +++ b/modules/mfa/public/new-backup-codes.php @@ -7,13 +7,13 @@ * - newBackupCodes */ -use SimpleSAML\Module\mfa\LoggerFactory; use SimpleSAML\Auth\ProcessingChain; use SimpleSAML\Auth\State; use SimpleSAML\Configuration; use SimpleSAML\Error\BadRequest; -use SimpleSAML\XHTML\Template; use SimpleSAML\Module\mfa\Auth\Process\Mfa; +use SimpleSAML\Module\mfa\LoggerFactory; +use SimpleSAML\XHTML\Template; $stateId = filter_input(INPUT_GET, 'StateId') ?? null; if (empty($stateId)) { @@ -33,7 +33,12 @@ $globalConfig = Configuration::getInstance(); -$t = new Template($globalConfig, 'mfa:new-backup-codes.php'); +$t = new Template($globalConfig, 'mfa:new-backup-codes'); $t->data['mfaSetupUrl'] = $state['mfaSetupUrl']; $t->data['newBackupCodes'] = $state['newBackupCodes'] ?? []; -$t->show(); +$t->data['idpName'] = $globalConfig->getString('idp_display_name'); +$t->data['codesForDownload'] = urlencode( + $t->data['idpName'] . "\r\n" . join("\r\n", $t->data['newBackupCodes']) +); +$t->data['codesForClipboard'] = $t->data['idpName'] . "\n" . join("\n", $t->data['newBackupCodes']); +$t->send(); diff --git a/modules/mfa/www/out-of-backup-codes.php b/modules/mfa/public/out-of-backup-codes.php similarity index 94% rename from modules/mfa/www/out-of-backup-codes.php rename to modules/mfa/public/out-of-backup-codes.php index acb9ee65..734fdde5 100644 --- a/modules/mfa/www/out-of-backup-codes.php +++ b/modules/mfa/public/out-of-backup-codes.php @@ -31,9 +31,9 @@ $globalConfig = Configuration::getInstance(); -$t = new Template($globalConfig, 'mfa:out-of-backup-codes.php'); +$t = new Template($globalConfig, 'mfa:out-of-backup-codes'); $t->data['hasOtherMfaOptions'] = $hasOtherMfaOptions; -$t->show(); +$t->send(); $logger->info(sprintf( 'mfa: Told Employee ID %s they are out of backup codes%s.', diff --git a/modules/mfa/www/prompt-for-mfa.php b/modules/mfa/public/prompt-for-mfa.php similarity index 92% rename from modules/mfa/www/prompt-for-mfa.php rename to modules/mfa/public/prompt-for-mfa.php index a736fd69..c64205c0 100644 --- a/modules/mfa/www/prompt-for-mfa.php +++ b/modules/mfa/public/prompt-for-mfa.php @@ -53,14 +53,15 @@ 'event' => 'MFA ID missing in URL. Choosing one and doing a redirect.', 'employeeId' => $state['employeeId'], ])); - + // Pick an MFA ID and do a redirect to put that into the URL. $mfaOption = Mfa::getMfaOptionToUse($mfaOptions, $userAgent); $moduleUrl = SimpleSAML\Module::getModuleURL('mfa/prompt-for-mfa.php', [ 'mfaId' => $mfaOption['id'], 'StateId' => $stateId, ]); - HTTP::redirectTrustedURL($moduleUrl); + $httpUtils = new HTTP(); + $httpUtils->redirectTrustedURL($moduleUrl); return; } $mfaOption = Mfa::getMfaOptionById($mfaOptions, $mfaId); @@ -74,7 +75,7 @@ } $rememberMe = filter_input(INPUT_POST, 'rememberMe') ?? false; - + // NOTE: This will only return if validation fails. $errorMessage = Mfa::validateMfaSubmission( $mfaId, @@ -86,7 +87,7 @@ $mfaOption['type'], $state['rpOrigin'] ); - + $logger->warning(json_encode([ 'event' => 'MFA validation result: failed', 'employeeId' => $state['employeeId'], @@ -97,13 +98,13 @@ $globalConfig = Configuration::getInstance(); -$otherOptions = array_filter($mfaOptions, function($option) use ($mfaId) { +$otherOptions = array_filter($mfaOptions, function ($option) use ($mfaId) { return $option['id'] != $mfaId; }); -if (! empty($state['managerEmail'])) { +if (!empty($state['managerEmail'])) { $otherOptions[] = [ 'type' => 'manager', - 'callback' => '/module.php/mfa/send-manager-mfa.php?StateId='.htmlentities($stateId) + 'callback' => '/module.php/mfa/send-manager-mfa.php?StateId=' . htmlentities($stateId) ]; } foreach ($otherOptions as &$option) { @@ -121,6 +122,7 @@ $t = new Template($globalConfig, $mfaTemplateToUse); $t->data['errorMessage'] = $errorMessage ?? null; $t->data['mfaOption'] = $mfaOption; +$t->data['mfaOptionData'] = json_encode($mfaOption['data']); $t->data['mfaOptions'] = $mfaOptions; $t->data['stateId'] = $stateId; $t->data['supportsWebAuthn'] = LoginBrowser::supportsWebAuthn($userAgent); @@ -128,7 +130,8 @@ $t->data['browserJsPath'] = '/module.php/mfa/simplewebauthn/browser.js?v=' . $browserJsHash; $t->data['managerEmail'] = $state['managerEmail']; $t->data['otherOptions'] = $otherOptions; -$t->show(); +$t->data['idpName'] = $globalConfig->getString('idp_display_name'); +$t->send(); $logger->info(json_encode([ 'event' => 'Prompted user for MFA', diff --git a/modules/mfa/www/send-manager-mfa.php b/modules/mfa/public/send-manager-mfa.php similarity index 89% rename from modules/mfa/www/send-manager-mfa.php rename to modules/mfa/public/send-manager-mfa.php index cf510162..c1dab5b9 100644 --- a/modules/mfa/www/send-manager-mfa.php +++ b/modules/mfa/public/send-manager-mfa.php @@ -29,16 +29,17 @@ $moduleUrl = SimpleSAML\Module::getModuleURL('mfa/prompt-for-mfa.php', [ 'StateId' => $stateId, ]); - HTTP::redirectTrustedURL($moduleUrl); + $httpUtils = new HTTP(); + $httpUtils->redirectTrustedURL($moduleUrl); } $globalConfig = Configuration::getInstance(); -$t = new Template($globalConfig, 'mfa:send-manager-mfa.php'); +$t = new Template($globalConfig, 'mfa:send-manager-mfa'); $t->data['stateId'] = $stateId; $t->data['managerEmail'] = $state['managerEmail']; $t->data['errorMessage'] = $errorMessage ?? null; -$t->show(); +$t->send(); $logger->info(json_encode([ 'event' => 'offer to send manager code', diff --git a/modules/mfa/www/simplewebauthn/LICENSE.md b/modules/mfa/public/simplewebauthn/LICENSE.md similarity index 100% rename from modules/mfa/www/simplewebauthn/LICENSE.md rename to modules/mfa/public/simplewebauthn/LICENSE.md diff --git a/modules/mfa/www/simplewebauthn/browser.js b/modules/mfa/public/simplewebauthn/browser.js similarity index 100% rename from modules/mfa/www/simplewebauthn/browser.js rename to modules/mfa/public/simplewebauthn/browser.js diff --git a/modules/mfa/lib/Assert.php b/modules/mfa/src/Assert.php similarity index 94% rename from modules/mfa/lib/Assert.php rename to modules/mfa/src/Assert.php index 82285d1c..3bcb77e3 100644 --- a/modules/mfa/lib/Assert.php +++ b/modules/mfa/src/Assert.php @@ -1,4 +1,5 @@ initComposerAutoloader(); assert('is_array($config)'); - + $this->loggerClass = $config['loggerClass'] ?? Psr3SamlLogger::class; $this->logger = LoggerFactory::get($this->loggerClass); - + $this->loadValuesFromConfig($config, [ 'mfaSetupUrl', 'employeeIdAttr', @@ -70,20 +70,20 @@ public function __construct(array $config, mixed $reserved) 'idBrokerBaseUri', 'idpDomainName', ]); - + $tempTrustedIpRanges = $config['idBrokerTrustedIpRanges'] ?? ''; - if (! empty($tempTrustedIpRanges)) { + if (!empty($tempTrustedIpRanges)) { $this->idBrokerTrustedIpRanges = explode(',', $tempTrustedIpRanges); } $this->idBrokerAssertValidIp = (bool)($config['idBrokerAssertValidIp'] ?? true); $this->idBrokerClientClass = $config['idBrokerClientClass'] ?? IdBrokerClient::class; } - + protected function loadValuesFromConfig(array $config, array $attributes): void { foreach ($attributes as $attribute) { $this->$attribute = $config[$attribute] ?? null; - + self::validateConfigValue( $attribute, $this->$attribute, @@ -91,7 +91,7 @@ protected function loadValuesFromConfig(array $config, array $attributes): void ); } } - + /** * Validate the given config value * @@ -113,7 +113,7 @@ public static function validateConfigValue(string $attribute, mixed $value, Logg throw $exception; } } - + /** * Get the specified attribute from the given state data. * @@ -128,14 +128,14 @@ public static function validateConfigValue(string $attribute, mixed $value, Logg protected function getAttribute(string $attributeName, array $state): mixed { $attributeData = $state['Attributes'][$attributeName] ?? null; - + if (is_array($attributeData)) { return $attributeData[0] ?? null; } - + return $attributeData; } - + /** * Get all of the values for the specified attribute from the given state * data. @@ -151,10 +151,10 @@ protected function getAttribute(string $attributeName, array $state): mixed protected function getAttributeAllValues(string $attributeName, array $state): ?array { $attributeData = $state['Attributes'][$attributeName] ?? null; - + return is_null($attributeData) ? null : (array)$attributeData; } - + /** * Get an ID Broker client. * @@ -168,7 +168,7 @@ protected static function getIdBrokerClient(array $idBrokerConfig): IdBrokerClie $accessToken = $idBrokerConfig['accessToken']; $trustedIpRanges = $idBrokerConfig['trustedIpRanges']; $assertValidIp = $idBrokerConfig['assertValidIp']; - + return new $clientClass($baseUri, $accessToken, [ 'http_client_options' => [ 'timeout' => 10, @@ -192,13 +192,13 @@ public static function getMfaOptionById(array $mfaOptions, int $mfaId): array if (empty($mfaId)) { throw new \Exception('No MFA ID was provided.'); } - + foreach ($mfaOptions as $mfaOption) { if ((int)$mfaOption['id'] === (int)$mfaId) { return $mfaOption; } } - + throw new \Exception( 'No MFA option has an ID of ' . var_export($mfaId, true) ); @@ -236,7 +236,7 @@ public static function getMfaOptionToUse(array $mfaOptions, string $userAgent): } array_push($mfaTypePriority, 'totp', 'backupcode', 'webauthn'); } - + foreach ($mfaTypePriority as $mfaType) { foreach ($mfaOptions as $mfaOption) { if ($mfaOption['type'] === $mfaType) { @@ -267,7 +267,7 @@ private static function getMostRecentUsedMfaOption(array $mfaOptions): ?array } return $recentMfa; } - + /** * Get the number of backup codes that the user had left PRIOR to this login. * @@ -283,10 +283,10 @@ public static function getNumBackupCodesUserHad(array $mfaOptions): int $numBackupCodes += intval($mfaOption['data']['count'] ?? 0); } } - + return $numBackupCodes; } - + /** * Get the template identifier (string) to use for the specified MFA type. * @@ -297,13 +297,13 @@ public static function getNumBackupCodesUserHad(array $mfaOptions): int public static function getTemplateFor(string $mfaType): string { $mfaOptionTemplates = [ - 'backupcode' => 'mfa:prompt-for-mfa-backupcode.php', - 'totp' => 'mfa:prompt-for-mfa-totp.php', - 'webauthn' => 'mfa:prompt-for-mfa-webauthn.php', - 'manager' => 'mfa:prompt-for-mfa-manager.php', + 'backupcode' => 'mfa:prompt-for-mfa-backupcode', + 'totp' => 'mfa:prompt-for-mfa-totp', + 'webauthn' => 'mfa:prompt-for-mfa-webauthn', + 'manager' => 'mfa:prompt-for-mfa-manager', ]; $template = $mfaOptionTemplates[$mfaType] ?? null; - + if ($template === null) { throw new \InvalidArgumentException(sprintf( 'No %s MFA template is available.', @@ -324,7 +324,7 @@ protected static function getRelayStateUrl($state) { if (array_key_exists('saml:RelayState', $state)) { $samlRelayState = $state['saml:RelayState']; - + if (strpos($samlRelayState, "http://") === 0) { return $samlRelayState; } @@ -335,7 +335,7 @@ protected static function getRelayStateUrl($state) } return ''; } - + /** * Get new Printable Backup Codes for the user, then redirect the user to a * page showing the user their new codes. @@ -354,7 +354,7 @@ public static function giveUserNewBackupCodes(array &$state, LoggerInterface $lo 'backupcode' ); $newBackupCodes = $newMfaRecord['data']; - + $logger->warning(json_encode([ 'event' => 'New backup codes result: succeeded', 'employeeId' => $state['employeeId'], @@ -372,15 +372,16 @@ public static function giveUserNewBackupCodes(array &$state, LoggerInterface $lo $state['newBackupCodes'] = $newBackupCodes ?? null; $stateId = State::saveState($state, self::STAGE_SENT_TO_NEW_BACKUP_CODES_PAGE); $url = Module::getModuleURL('mfa/new-backup-codes.php'); - - HTTP::redirectTrustedURL($url, ['StateId' => $stateId]); + + $httpUtils = new HTTP(); + $httpUtils->redirectTrustedURL($url, ['StateId' => $stateId]); } - + protected static function hasMfaOptions(array $mfa): bool { return (count($mfa['options']) > 0); } - + /** * See if the user has any MFA options other than the specified type. * @@ -398,7 +399,7 @@ public static function hasMfaOptionsOtherThan(string $excludedMfaType, array $st } return false; } - + protected function initComposerAutoloader(): void { $path = __DIR__ . '/../../../vendor/autoload.php'; @@ -406,12 +407,12 @@ protected function initComposerAutoloader(): void require_once $path; } } - + protected static function isHeadedToMfaSetupUrl($state, $mfaSetupUrl) { if (array_key_exists('saml:RelayState', $state)) { $currentDestination = self::getRelayStateUrl($state); - if (! empty($currentDestination)) { + if (!empty($currentDestination)) { return (strpos($currentDestination, $mfaSetupUrl) === 0); } } @@ -436,14 +437,14 @@ protected static function isHeadedToMfaSetupUrl($state, $mfaSetupUrl) * @throws \Sil\PhpEnv\EnvVarNotFoundException */ public static function validateMfaSubmission( - int $mfaId, - string $employeeId, - string|array $mfaSubmission, - array $state, - bool $rememberMe, + int $mfaId, + string $employeeId, + string|array $mfaSubmission, + array $state, + bool $rememberMe, LoggerInterface $logger, - string $mfaType, - string $rpOrigin + string $mfaType, + string $rpOrigin ): string { if (empty($mfaId)) { return 'No MFA ID was provided.'; @@ -454,7 +455,7 @@ public static function validateMfaSubmission( } elseif (empty($rpOrigin)) { return 'No RP Origin was provided.'; } - + try { $idBrokerClient = self::getIdBrokerClient($state['idBrokerConfig']); $mfaDataFromBroker = $idBrokerClient->mfaVerify( @@ -473,7 +474,7 @@ public static function validateMfaSubmission( . 'codes can only be used once, please try a different code.'; } return 'Incorrect 2-step verification code.'; - } elseif ($t->httpStatusCode === 429){ + } elseif ($t->httpStatusCode === 429) { $logger->error(json_encode([ 'event' => 'MFA is rate-limited', 'employeeId' => $employeeId, @@ -487,7 +488,7 @@ public static function validateMfaSubmission( return $message; } } - + $logger->critical($t->getCode() . ': ' . $t->getMessage()); return $message; } @@ -498,20 +499,20 @@ public static function validateMfaSubmission( if ($rememberMe) { self::setRememberMeCookies($state['employeeId'], $state['mfaOptions']); } - + $logger->warning(json_encode([ 'event' => 'MFA validation result: success', 'employeeId' => $employeeId, 'mfaType' => $mfaType, ])); - + // Handle situations where the user is running low on backup codes. if ($mfaType === 'backupcode') { $numBackupCodesUserHad = self::getNumBackupCodesUserHad( $state['mfaOptions'] ?? [] ); $numBackupCodesRemaining = $numBackupCodesUserHad - 1; - + if ($numBackupCodesRemaining <= 0) { self::redirectToOutOfBackupCodesMessage($state, $employeeId); throw new \Exception('Failed to send user to out-of-backup-codes page.'); @@ -538,7 +539,7 @@ public static function validateMfaSubmission( ProcessingChain::resumeProcessing($state); throw new \Exception('Failed to resume processing auth proc chain.'); } - + /** * Redirect the user to set up MFA. * @@ -547,34 +548,32 @@ public static function validateMfaSubmission( public static function redirectToMfaSetup(array &$state): void { $mfaSetupUrl = $state['mfaSetupUrl']; - + + $httpUtils = new HTTP(); + // Tell the MFA-setup URL where the user is ultimately trying to go (if known). $currentDestination = self::getRelayStateUrl($state); - if (! empty($currentDestination)) { - $mfaSetupUrl = HTTP::addURLParameters( + if (!empty($currentDestination)) { + $mfaSetupUrl = $httpUtils->addURLParameters( $mfaSetupUrl, ['returnTo' => $currentDestination] ); } - + $logger = LoggerFactory::getAccordingToState($state); $logger->warning(sprintf( 'mfa: Sending Employee ID %s to set up MFA at %s', var_export($state['employeeId'] ?? null, true), var_export($mfaSetupUrl, true) )); - - HTTP::redirectTrustedURL($mfaSetupUrl); + + $httpUtils->redirectTrustedURL($mfaSetupUrl); } - + /** - * Apply this AuthProc Filter. It will either return (indicating that it - * has completed) or it will redirect the user, in which case it will - * later call `SimpleSAML\Auth\ProcessingChain::resumeProcessing($state)`. - * - * @param array &$state The current state. + * @inheritDoc */ - public function process(&$state): void + public function process(array &$state): void { // Get the necessary info from the state data. $employeeId = $this->getAttribute($this->employeeIdAttr, $state); @@ -595,7 +594,7 @@ public function process(&$state): void // Record to the state what logger class to use. $state['loggerClass'] = $this->loggerClass; - + // Add to the state any config data we may need for the low-on/out-of // backup codes pages. $state['mfaSetupUrl'] = $this->mfaSetupUrl; @@ -605,8 +604,8 @@ public function process(&$state): void $this->redirectToMfaPrompt($state, $employeeId, $mfa['options']); return; } - - if (! $isHeadedToMfaSetupUrl) { + + if (!$isHeadedToMfaSetupUrl) { $this->redirectToMfaNeededMessage($state, $employeeId, $this->mfaSetupUrl); return; } @@ -614,7 +613,7 @@ public function process(&$state): void unset($state['Attributes']['manager_email']); } - + /** * Redirect the user to a page telling them they must set up MFA. * @@ -625,20 +624,21 @@ public function process(&$state): void protected function redirectToMfaNeededMessage(array &$state, string $employeeId, string $mfaSetupUrl): void { assert('is_array($state)'); - + $this->logger->info(sprintf( 'mfa: Redirecting Employee ID %s to must-set-up-MFA message.', var_export($employeeId, true) )); - + /* Save state and redirect. */ $state['employeeId'] = $employeeId; $state['mfaSetupUrl'] = $mfaSetupUrl; - + $stateId = State::saveState($state, self::STAGE_SENT_TO_MFA_NEEDED_MESSAGE); $url = Module::getModuleURL('mfa/must-set-up-mfa.php'); - - HTTP::redirectTrustedURL($url, ['StateId' => $stateId]); + + $httpUtils = new HTTP(); + $httpUtils->redirectTrustedURL($url, ['StateId' => $stateId]); } /** @@ -652,9 +652,9 @@ protected function redirectToMfaNeededMessage(array &$state, string $employeeId, protected function redirectToMfaPrompt(array &$state, string $employeeId, array $mfaOptions): void { assert('is_array($state)'); - + /** @todo Check for valid remember-me cookies here rather doing a redirect first. */ - + $state['mfaOptions'] = $mfaOptions; $state['managerEmail'] = self::getManagerEmail($state); $state['idBrokerConfig'] = [ @@ -664,16 +664,16 @@ protected function redirectToMfaPrompt(array &$state, string $employeeId, array 'clientClass' => $this->idBrokerClientClass, 'trustedIpRanges' => $this->idBrokerTrustedIpRanges, ]; - + $this->logger->info(sprintf( 'mfa: Redirecting Employee ID %s to MFA prompt.', var_export($employeeId, true) )); - + /* Save state and redirect. */ $state['employeeId'] = $employeeId; $state['rpOrigin'] = 'https://' . $this->idpDomainName; - + $id = State::saveState($state, self::STAGE_SENT_TO_MFA_PROMPT); $url = Module::getModuleURL('mfa/prompt-for-mfa.php'); $userAgent = LoginBrowser::getUserAgent(); @@ -686,8 +686,9 @@ protected function redirectToMfaPrompt(array &$state, string $employeeId, array ])); $mfaOption = self::getMfaOptionToUse($mfaOptions, $userAgent); - - HTTP::redirectTrustedURL($url, [ + + $httpUtils = new HTTP(); + $httpUtils->redirectTrustedURL($url, [ 'mfaId' => $mfaOption['id'], 'StateId' => $id, ]); @@ -705,11 +706,11 @@ protected function redirectToMfaPrompt(array &$state, string $employeeId, array public static function isRememberMeCookieValid( string $cookieHash, string $expireDate, - array $mfaOptions, - array $state + array $mfaOptions, + array $state ): bool { $rememberSecret = Env::requireEnv('REMEMBER_ME_SECRET'); - if (! empty($cookieHash) && ! empty($expireDate) && is_numeric($expireDate)) { + if (!empty($cookieHash) && !empty($expireDate) && is_numeric($expireDate)) { // Check if value of expireDate is in future if ((int)$expireDate > time()) { $expectedString = self::generateRememberMeCookieString($rememberSecret, $state['employeeId'], $expireDate, $mfaOptions); @@ -731,8 +732,8 @@ public static function isRememberMeCookieValid( public static function generateRememberMeCookieString( string $rememberSecret, string $employeeId, - int $expireDate, - array $mfaOptions + int $expireDate, + array $mfaOptions ): string { $allMfaIds = ''; foreach ($mfaOptions as $opt) { @@ -744,7 +745,7 @@ public static function generateRememberMeCookieString( $string = $rememberSecret . $employeeId . $expireDate . $allMfaIds; return $string; } - + /** * Redirect the user to a page telling them they are running low on backup * codes and encouraging them to create more now. @@ -757,19 +758,20 @@ public static function generateRememberMeCookieString( * user has left (now that they have used up one for this login). */ protected static function redirectToLowOnBackupCodesNag( - array &$state, + array &$state, string $employeeId, - int $numBackupCodesRemaining + int $numBackupCodesRemaining ): void { $state['employeeId'] = $employeeId; $state['numBackupCodesRemaining'] = (string)$numBackupCodesRemaining; - + $stateId = State::saveState($state, self::STAGE_SENT_TO_LOW_ON_BACKUP_CODES_NAG); $url = Module::getModuleURL('mfa/low-on-backup-codes.php'); - - HTTP::redirectTrustedURL($url, ['StateId' => $stateId]); + + $httpUtils = new HTTP(); + $httpUtils->redirectTrustedURL($url, ['StateId' => $stateId]); } - + /** * Redirect the user to a page telling them they just used up their last * backup code. @@ -782,11 +784,12 @@ protected static function redirectToLowOnBackupCodesNag( protected static function redirectToOutOfBackupCodesMessage(array &$state, string $employeeId): void { $state['employeeId'] = $employeeId; - + $stateId = State::saveState($state, self::STAGE_SENT_TO_OUT_OF_BACKUP_CODES_MESSAGE); $url = Module::getModuleURL('mfa/out-of-backup-codes.php'); - - HTTP::redirectTrustedURL($url, ['StateId' => $stateId]); + + $httpUtils = new HTTP(); + $httpUtils->redirectTrustedURL($url, ['StateId' => $stateId]); } /** @@ -798,7 +801,7 @@ protected static function redirectToOutOfBackupCodesMessage(array &$state, strin */ public static function setRememberMeCookies( string $employeeId, - array $mfaOptions, + array $mfaOptions, string $rememberDuration = '+30 days' ): void { $rememberSecret = Env::requireEnv('REMEMBER_ME_SECRET'); @@ -809,7 +812,7 @@ public static function setRememberMeCookies( setcookie('c1', base64_encode($cookieHash), $expireDate, '/', null, $secureCookie, true); setcookie('c2', $expireDate, $expireDate, '/', null, $secureCookie, true); } - + protected static function shouldPromptForMfa(array $mfa): bool { return (strtolower($mfa['prompt']) !== 'no'); @@ -857,7 +860,8 @@ public static function sendManagerCode(array &$state, LoggerInterface $logger): $url = Module::getModuleURL('mfa/prompt-for-mfa.php'); - HTTP::redirectTrustedURL($url, ['mfaId' => $mfaOption['id'], 'StateId' => $stateId]); + $httpUtils = new HTTP(); + $httpUtils->redirectTrustedURL($url, ['mfaId' => $mfaOption['id'], 'StateId' => $stateId]); } /** diff --git a/modules/mfa/lib/LoggerFactory.php b/modules/mfa/src/LoggerFactory.php similarity index 99% rename from modules/mfa/lib/LoggerFactory.php rename to modules/mfa/src/LoggerFactory.php index b42c6beb..35d8cd34 100644 --- a/modules/mfa/lib/LoggerFactory.php +++ b/modules/mfa/src/LoggerFactory.php @@ -1,4 +1,5 @@ getName(); - + // For now, simply set these to approximate the results shown on caniuse: // https://caniuse.com/?search=webauthn return in_array( diff --git a/modules/mfa/templates/.gitkeep b/modules/mfa/templates/.gitkeep new file mode 100644 index 00000000..57da54a3 --- /dev/null +++ b/modules/mfa/templates/.gitkeep @@ -0,0 +1 @@ +this directory will be filled in the Docker image with a copy of the material module templates diff --git a/modules/profilereview/locales/en/LC_MESSAGES/.gitkeep b/modules/profilereview/locales/en/LC_MESSAGES/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/modules/profilereview/locales/es/LC_MESSAGES/.gitkeep b/modules/profilereview/locales/es/LC_MESSAGES/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/modules/profilereview/locales/fr/LC_MESSAGES/.gitkeep b/modules/profilereview/locales/fr/LC_MESSAGES/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/modules/profilereview/locales/ko/LC_MESSAGES/.gitkeep b/modules/profilereview/locales/ko/LC_MESSAGES/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/modules/profilereview/www/nag.php b/modules/profilereview/public/nag.php similarity index 99% rename from modules/profilereview/www/nag.php rename to modules/profilereview/public/nag.php index 7418418b..7dae2575 100644 --- a/modules/profilereview/www/nag.php +++ b/modules/profilereview/public/nag.php @@ -35,7 +35,7 @@ $t->data['methodOptions'] = $state['methodOptions'] ?? []; $t->data['mfaOptions'] = $state['mfaOptions'] ?? []; $t->data['mfaLearnMoreUrl'] = $state['mfaLearnMoreUrl']; -$t->show(); +$t->send(); $logger->warning(json_encode([ 'module' => 'profilereview', diff --git a/modules/profilereview/www/review.php b/modules/profilereview/public/review.php similarity index 95% rename from modules/profilereview/www/review.php rename to modules/profilereview/public/review.php index aa0cae04..c8f8b3f7 100644 --- a/modules/profilereview/www/review.php +++ b/modules/profilereview/public/review.php @@ -34,11 +34,11 @@ $globalConfig = Configuration::getInstance(); -$t = new Template($globalConfig, 'profilereview:review.php'); +$t = new Template($globalConfig, 'profilereview:review'); $t->data['profileUrl'] = $state['profileUrl']; $t->data['methodOptions'] = $state['methodOptions']; $t->data['mfaOptions'] = $state['mfaOptions']; -$t->show(); +$t->send(); $logger->warning(json_encode([ 'module' => 'profilereview', diff --git a/modules/profilereview/lib/Assert.php b/modules/profilereview/src/Assert.php similarity index 94% rename from modules/profilereview/lib/Assert.php rename to modules/profilereview/src/Assert.php index af7bf7dc..b99276b9 100644 --- a/modules/profilereview/lib/Assert.php +++ b/modules/profilereview/src/Assert.php @@ -1,4 +1,5 @@ initComposerAutoloader(); assert('is_array($config)'); - + $this->loggerClass = $config['loggerClass'] ?? Psr3SamlLogger::class; $this->logger = LoggerFactory::get($this->loggerClass); - + $this->loadValuesFromConfig($config, [ 'profileUrl', 'employeeIdAttr', @@ -67,7 +67,7 @@ protected function loadValuesFromConfig(array $config, array $attributes): void { foreach ($attributes as $attribute) { $this->$attribute = $config[$attribute] ?? null; - + self::validateConfigValue( $attribute, $this->$attribute, @@ -75,7 +75,7 @@ protected function loadValuesFromConfig(array $config, array $attributes): void ); } } - + /** * Validate the given config value * @@ -97,7 +97,7 @@ public static function validateConfigValue($attribute, $value, $logger) throw $exception; } } - + /** * Get the specified attribute from the given state data. * @@ -112,14 +112,14 @@ public static function validateConfigValue($attribute, $value, $logger) protected function getAttribute($attributeName, $state) { $attributeData = $state['Attributes'][$attributeName] ?? null; - + if (is_array($attributeData)) { return $attributeData[0] ?? null; } - + return $attributeData; } - + /** * Get all of the values for the specified attribute from the given state * data. @@ -135,7 +135,7 @@ protected function getAttribute($attributeName, $state) protected function getAttributeAllValues($attributeName, $state) { $attributeData = $state['Attributes'][$attributeName] ?? null; - + return is_null($attributeData) ? null : (array)$attributeData; } @@ -151,7 +151,7 @@ protected static function getRelayStateUrl($state) { if (array_key_exists('saml:RelayState', $state)) { $samlRelayState = $state['saml:RelayState']; - + if (strpos($samlRelayState, "http://") === 0) { return $samlRelayState; } @@ -170,12 +170,12 @@ protected function initComposerAutoloader() require_once $path; } } - + protected static function isHeadedToProfileUrl($state, $ProfileUrl) { if (array_key_exists('saml:RelayState', $state)) { $currentDestination = self::getRelayStateUrl($state); - if (! empty($currentDestination)) { + if (!empty($currentDestination)) { return (strpos($currentDestination, $ProfileUrl) === 0); } } @@ -192,8 +192,9 @@ public static function redirectToProfile(&$state) $profileUrl = $state['ProfileUrl']; // Tell the profile-setup URL where the user is ultimately trying to go (if known). $currentDestination = self::getRelayStateUrl($state); - if (! empty($currentDestination)) { - $profileUrl = HTTP::addURLParameters( + $httpUtils = new HTTP(); + if (!empty($currentDestination)) { + $profileUrl = $httpUtils->addURLParameters( $profileUrl, ['returnTo' => $currentDestination] ); @@ -207,17 +208,13 @@ public static function redirectToProfile(&$state) 'profileUrl' => $profileUrl, ])); - HTTP::redirectTrustedURL($profileUrl); + $httpUtils->redirectTrustedURL($profileUrl); } /** - * Apply this AuthProc Filter. It will either return (indicating that it - * has completed) or it will redirect the user, in which case it will - * later call `SimpleSAML\Auth\ProcessingChain::resumeProcessing($state)`. - * - * @param array &$state The current state. + * @inheritDoc */ - public function process(&$state) + public function process(array &$state): void { // Get the necessary info from the state data. $employeeId = $this->getAttribute($this->employeeIdAttr, $state); @@ -227,7 +224,7 @@ public function process(&$state) $method = $this->getAttributeAllValues('method', $state); $profileReview = $this->getAttribute('profile_review', $state); - if (! $isHeadedToProfileUrl) { + if (!$isHeadedToProfileUrl) { // Record to the state what logger class to use. $state['loggerClass'] = $this->loggerClass; @@ -241,8 +238,7 @@ public function process(&$state) $this->redirectToNag($state, $employeeId, self::METHOD_ADD_PAGE); } - if (self::needToShow($profileReview, self::REVIEW_PAGE)) - { + if (self::needToShow($profileReview, self::REVIEW_PAGE)) { $this->redirectToProfileReview($state, $employeeId, $mfa['options'], $method['options']); } } @@ -289,12 +285,13 @@ protected function redirectToProfileReview(&$state, $employeeId, $mfaOptions, $m $state['profileUrl'] = $this->profileUrl; $state['mfaOptions'] = $mfaOptions; $state['methodOptions'] = $methodOptions; - $state['template'] = 'review.php'; + $state['template'] = 'review'; $stateId = State::saveState($state, self::STAGE_SENT_TO_NAG); $url = Module::getModuleURL('profilereview/nag.php'); - HTTP::redirectTrustedURL($url, array('StateId' => $stateId)); + $httpUtils = new HTTP(); + $httpUtils->redirectTrustedURL($url, array('StateId' => $stateId)); } /** @@ -313,7 +310,8 @@ protected function redirectToNag(&$state, $employeeId, $template) $stateId = State::saveState($state, self::STAGE_SENT_TO_NAG); $url = Module::getModuleURL('profilereview/nag.php'); - HTTP::redirectTrustedURL($url, array('StateId' => $stateId)); + $httpUtils = new HTTP(); + $httpUtils->redirectTrustedURL($url, array('StateId' => $stateId)); } public static function hasSeenSplashPageRecently(string $page) @@ -340,7 +338,7 @@ public static function skipSplashPagesFor($seconds, string $page) public static function needToShow($flag, $page) { $oneDay = 24 * 60 * 60; - if ($flag === 'yes' && ! self::hasSeenSplashPageRecently($page)) { + if ($flag === 'yes' && !self::hasSeenSplashPageRecently($page)) { self::skipSplashPagesFor($oneDay, $page); return true; } diff --git a/modules/profilereview/lib/LoggerFactory.php b/modules/profilereview/src/LoggerFactory.php similarity index 99% rename from modules/profilereview/lib/LoggerFactory.php rename to modules/profilereview/src/LoggerFactory.php index 8381476a..5ab4585a 100644 --- a/modules/profilereview/lib/LoggerFactory.php +++ b/modules/profilereview/src/LoggerFactory.php @@ -1,4 +1,5 @@ createIndex('uq_user_employee_id', '{{user}}', 'employee_id', true); $this->createIndex('uq_user_username', '{{user}}', 'username', true); $this->createIndex('uq_user_email', '{{user}}', 'email', true); - + $this->createTable('{{previous_password}}', [ 'id' => 'pk', 'user_id' => 'integer NOT NULL', @@ -52,7 +52,7 @@ public function safeDown(): void '{{previous_password}}' ); $this->dropTable('{{previous_password}}'); - + $this->dropIndex('uq_user_uuid', '{{user}}'); $this->dropIndex('uq_user_employee_id', '{{user}}'); $this->dropIndex('uq_user_username', '{{user}}'); diff --git a/modules/silauth/migrations/M170214145629RemoveOldTables.php b/modules/silauth/migrations/M170214145629RemoveOldTables.php index 24031976..dd111b92 100644 --- a/modules/silauth/migrations/M170214145629RemoveOldTables.php +++ b/modules/silauth/migrations/M170214145629RemoveOldTables.php @@ -13,7 +13,7 @@ public function safeUp(): void '{{previous_password}}' ); $this->dropTable('{{previous_password}}'); - + $this->dropIndex('uq_user_uuid', '{{user}}'); $this->dropIndex('uq_user_employee_id', '{{user}}'); $this->dropIndex('uq_user_username', '{{user}}'); diff --git a/modules/silauth/migrations/M170215141724SplitFailedLoginsTable.php b/modules/silauth/migrations/M170215141724SplitFailedLoginsTable.php index e71ebef5..62e7190e 100644 --- a/modules/silauth/migrations/M170215141724SplitFailedLoginsTable.php +++ b/modules/silauth/migrations/M170215141724SplitFailedLoginsTable.php @@ -11,7 +11,7 @@ public function safeUp(): void // Remove old indexes. $this->dropIndex('idx_failed_logins_ip_address', '{{failed_logins}}'); $this->dropIndex('idx_failed_logins_username', '{{failed_logins}}'); - + // Split/update table and add new indexes. $this->dropColumn('{{failed_logins}}', 'ip_address'); $this->renameTable('{{failed_logins}}', '{{failed_login_username}}'); diff --git a/modules/silauth/www/loginuserpass.php b/modules/silauth/public/loginuserpass.php similarity index 88% rename from modules/silauth/www/loginuserpass.php rename to modules/silauth/public/loginuserpass.php index dcddce3a..1884316c 100644 --- a/modules/silauth/www/loginuserpass.php +++ b/modules/silauth/public/loginuserpass.php @@ -2,14 +2,14 @@ use Sil\Psr3Adapters\Psr3StdOutLogger; use Sil\SspUtils\AnnouncementUtils; -use SimpleSAML\Module\silauth\Auth\Source\auth\Authenticator; -use SimpleSAML\Module\silauth\Auth\Source\csrf\CsrfProtector; -use SimpleSAML\Module\silauth\Auth\Source\http\Request; use SimpleSAML\Auth\Source; use SimpleSAML\Auth\State; use SimpleSAML\Configuration; use SimpleSAML\Error\BadRequest; use SimpleSAML\Error\Error as SimpleSAMLError; +use SimpleSAML\Module\silauth\Auth\Source\auth\Authenticator; +use SimpleSAML\Module\silauth\Auth\Source\csrf\CsrfProtector; +use SimpleSAML\Module\silauth\Auth\Source\http\Request; use SimpleSAML\Module\silauth\Auth\Source\SilAuth; use SimpleSAML\Session; use SimpleSAML\XHTML\Template; @@ -20,7 +20,7 @@ */ // Retrieve the authentication state -if ( ! array_key_exists('AuthState', $_REQUEST)) { +if (!array_key_exists('AuthState', $_REQUEST)) { throw new BadRequest('Missing AuthState parameter.'); } $authStateId = $_REQUEST['AuthState']; @@ -45,13 +45,13 @@ $authSourcesConfig = $globalConfig->getConfig('authsources.php'); $silAuthConfig = $authSourcesConfig->getConfigItem('silauth'); -$recaptchaSiteKey = $silAuthConfig->getString('recaptcha.siteKey', null); +$recaptchaSiteKey = $silAuthConfig->getOptionalString('recaptcha.siteKey', null); if ($_SERVER['REQUEST_METHOD'] === 'POST') { try { $logger = new Psr3StdOutLogger(); - $csrfFromRequest = Request::sanitizeInputString(INPUT_POST, 'csrf-token'); + $csrfFromRequest = Request::sanitizeInputString(INPUT_POST, 'csrf-token'); if ($csrfProtector->isTokenCorrect($csrfFromRequest)) { $username = Request::sanitizeInputString(INPUT_POST, 'username'); @@ -79,7 +79,7 @@ $csrfProtector->changeMasterToken(); } -$t = new Template($globalConfig, 'core:loginuserpass.php'); +$t = new Template($globalConfig, 'silauth:loginuserpass'); $t->data['stateparams'] = array('AuthState' => $authStateId); $t->data['username'] = $username; $t->data['forceUsername'] = false; @@ -91,15 +91,17 @@ $t->data['profileUrl'] = $state['templateData']['profileUrl'] ?? ''; $t->data['helpCenterUrl'] = $state['templateData']['helpCenterUrl'] ?? ''; $t->data['announcement'] = AnnouncementUtils::getAnnouncement(); +$t->data['idpName'] = $globalConfig->getString('idp_display_name'); +$t->data['passwordForgotUrl'] = $globalConfig->getOptionalString('passwordForgotUrl', ''); /* For simplicity's sake, don't bother telling this Request to trust any IP * addresses. This is okay because we only track the failures of untrusted * IP addresses, so there will be no failed logins of IP addresses we trust. */ $request = new Request(); if (Authenticator::isCaptchaRequired($username, $request->getUntrustedIpAddresses())) { - $t->data['recaptcha.siteKey'] = $recaptchaSiteKey; + $t->data['siteKey'] = $recaptchaSiteKey; } else { - $t->data['recaptcha.siteKey'] = null; + $t->data['siteKey'] = null; } if (isset($state['SPMetadata'])) { @@ -108,5 +110,5 @@ $t->data['SPMetadata'] = null; } -$t->show(); +$t->send(); exit(); diff --git a/modules/silauth/www/status.php b/modules/silauth/public/status.php similarity index 98% rename from modules/silauth/www/status.php rename to modules/silauth/public/status.php index d062a805..9b345357 100644 --- a/modules/silauth/www/status.php +++ b/modules/silauth/public/status.php @@ -7,7 +7,7 @@ try { header('Content-Type: text/plain'); - + ConfigManager::initializeYii2WebApp(['components' => ['db' => [ 'dsn' => sprintf( 'mysql:host=%s;dbname=%s', @@ -20,9 +20,9 @@ $logger = new Psr3StdOutLogger(); $system = new System($logger); $system->reportStatus(); - + } catch (Throwable $t) { - + echo sprintf( '%s (%s)', $t->getMessage(), diff --git a/modules/silauth/lib/Auth/Source/SilAuth.php b/modules/silauth/src/Auth/Source/SilAuth.php similarity index 90% rename from modules/silauth/lib/Auth/Source/SilAuth.php rename to modules/silauth/src/Auth/Source/SilAuth.php index f7c0624f..00b3714b 100644 --- a/modules/silauth/lib/Auth/Source/SilAuth.php +++ b/modules/silauth/src/Auth/Source/SilAuth.php @@ -41,7 +41,7 @@ class SilAuth extends UserPassBase public function __construct(array $info, array $config) { parent::__construct($info, $config); - + $this->authConfig = ConfigManager::getConfigFor('auth', $config); $this->idBrokerConfig = ConfigManager::getConfigFor('idBroker', $config); $this->mysqlConfig = ConfigManager::getConfigFor('mysql', $config); @@ -59,15 +59,7 @@ public function __construct(array $info, array $config) ]]]); } - /** - * Initialize login. - * - * This function saves the information about the login, and redirects to a - * login page. - * - * @param array &$state Information about the current authentication. - */ - public function authenticate(&$state): void + public function authenticate(array &$state): void { assert('is_array($state)'); @@ -89,26 +81,27 @@ public function authenticate(&$state): void */ $url = Module::getModuleURL('silauth/loginuserpass.php'); $params = array('AuthState' => $id); - HTTP::redirectTrustedURL($url, $params); + $httpUtils = new HTTP(); + $httpUtils->redirectTrustedURL($url, $params); /* The previous function never returns, so this code is never executed. */ assert('FALSE'); } - + protected function getTrustedIpAddresses(): array { $trustedIpAddresses = []; $ipAddressesString = $this->authConfig['trustedIpAddresses'] ?? ''; $stringPieces = explode(',', $ipAddressesString); foreach ($stringPieces as $stringPiece) { - if (! empty($stringPiece)) { + if (!empty($stringPiece)) { $trustedIpAddresses[] = $stringPiece; } } return $trustedIpAddresses; } - - protected function login($username, $password): ?array + + protected function login(string $username, string $password): array { $logger = new Psr3StdOutLogger(); $captcha = new Captcha($this->recaptchaConfig['secret'] ?? null); @@ -130,8 +123,8 @@ protected function login($username, $password): ?array $idBroker, $logger ); - - if (! $authenticator->isAuthenticated()) { + + if (!$authenticator->isAuthenticated()) { $authError = $authenticator->getAuthError(); $logger->warning(json_encode([ 'event' => 'User/pass authentication result: failure', @@ -147,14 +140,14 @@ protected function login($username, $password): ?array $authError->getMessageParams() ]); } - + $logger->warning(json_encode([ 'event' => 'User/pass authentication result: success', 'username' => $username, 'ipAddresses' => join(',', $request->getIpAddresses()), 'userAgent' => $userAgent, ])); - + return $authenticator->getUserAttributes(); } } diff --git a/modules/silauth/lib/Auth/Source/auth/AuthError.php b/modules/silauth/src/Auth/Source/auth/AuthError.php similarity index 96% rename from modules/silauth/lib/Auth/Source/auth/AuthError.php rename to modules/silauth/src/Auth/Source/auth/AuthError.php index 6eefe024..c173de86 100644 --- a/modules/silauth/lib/Auth/Source/auth/AuthError.php +++ b/modules/silauth/src/Auth/Source/auth/AuthError.php @@ -1,4 +1,5 @@ code = $code; $this->messageParams = $messageParams; } - + public function __toString() { return var_export([ @@ -38,7 +39,7 @@ public function __toString() 'messageParams' => $this->messageParams, ], true); } - + /** * Get the error code, which will be one of the AuthError::CODE_* constants. * @@ -48,7 +49,7 @@ public function getCode(): string { return $this->code; } - + /** * Get the error string that should be passed to simpleSAMLphp's translate * function for this AuthError. It will correspond to an entry in the @@ -59,12 +60,11 @@ public function getCode(): string public function getFullSspErrorTag(): string { return sprintf( - '{%s:%s}', - 'silauth:error', + '{error:%s}', $this->getCode() ); } - + public function getMessageParams(): array { return $this->messageParams; diff --git a/modules/silauth/lib/Auth/Source/auth/Authenticator.php b/modules/silauth/src/Auth/Source/auth/Authenticator.php similarity index 93% rename from modules/silauth/lib/Auth/Source/auth/Authenticator.php rename to modules/silauth/src/Auth/Source/auth/Authenticator.php index dc8d10ca..73501785 100644 --- a/modules/silauth/lib/Auth/Source/auth/Authenticator.php +++ b/modules/silauth/src/Auth/Source/auth/Authenticator.php @@ -1,4 +1,5 @@ logger = $logger; - + /** @todo Check CSRF here, too, if feasible. */ - + if (empty($username)) { $this->setErrorUsernameRequired(); return; } - + if (empty($password)) { $this->setErrorPasswordRequired(); return; } - + $ipAddresses = $request->getUntrustedIpAddresses(); - + if ($this->isBlockedByRateLimit($username, $ipAddresses)) { $logger->warning(json_encode([ 'event' => 'Preventing login attempt due to existing rate limit', @@ -71,14 +72,14 @@ public function __construct( ); return; } - + if (self::isCaptchaRequired($username, $ipAddresses)) { $logger->warning(json_encode([ 'event' => 'Requiring captcha', 'username' => $username, 'ipAddresses' => join(',', $ipAddresses), ])); - if ( ! $captcha->isValidIn($request)) { + if (!$captcha->isValidIn($request)) { $logger->warning(json_encode([ 'event' => 'Invalid/missing captcha', 'username' => $username, @@ -88,7 +89,7 @@ public function __construct( return; } } - + try { $authenticatedUser = $idBroker->getAuthenticatedUser( $username, @@ -105,10 +106,10 @@ public function __construct( $this->setErrorGenericTryLater(); return; } - + if ($authenticatedUser === null) { $this->recordFailedLoginBy($username, $ipAddresses); - + if ($this->isBlockedByRateLimit($username, $ipAddresses)) { $logger->warning(json_encode([ 'event' => 'Activating rate-limit block', @@ -123,14 +124,14 @@ public function __construct( } return; } - + // NOTE: If we reach this point, the user successfully authenticated. - + $this->resetFailedLoginsBy($username, $ipAddresses); - + $this->setUserAttributes($authenticatedUser); } - + /** * Calculate how many seconds of delay should be required for the given * number of recent failed login attempts. @@ -141,30 +142,30 @@ public function __construct( */ public static function calculateSecondsToDelay(int $numRecentFailures): int { - if ( ! self::isEnoughFailedLoginsToBlock($numRecentFailures)) { + if (!self::isEnoughFailedLoginsToBlock($numRecentFailures)) { return 0; } - + $limit = self::BLOCK_AFTER_NTH_FAILED_LOGIN; $numFailuresPastLimit = $numRecentFailures - $limit; $numberToUse = max($numFailuresPastLimit, 3); - + return min( $numberToUse * $numberToUse, self::MAX_SECONDS_TO_BLOCK ); } - + /** * Get the error information (if any). - * + * * @return AuthError|null */ public function getAuthError(): ?AuthError { return $this->authError; } - + /** * Get the number of seconds to continue blocking, based on the given number * of recent failures and the given date/time of the most recent failed @@ -179,28 +180,27 @@ public function getAuthError(): ?AuthError * for `$mostRecentFailureAt`. */ public static function getSecondsUntilUnblocked( - int $numRecentFailures, + int $numRecentFailures, ?string $mostRecentFailureAt - ): int - { + ): int { if ($mostRecentFailureAt === null) { return 0; } - + $totalSecondsToBlock = self::calculateSecondsToDelay( $numRecentFailures ); - + $secondsSinceLastFailure = UtcTime::getSecondsSinceDateTime( $mostRecentFailureAt ); - + return UtcTime::getRemainingSeconds( $totalSecondsToBlock, $secondsSinceLastFailure ); } - + /** * Get the attributes about the authenticated user. * @@ -213,7 +213,7 @@ public static function getSecondsUntilUnblocked( * * @throws \Exception */ - public function getUserAttributes(): ?array + public function getUserAttributes(): array { if ($this->userAttributes === null) { throw new \Exception( @@ -221,10 +221,10 @@ public function getUserAttributes(): ?array 1482270373 ); } - + return $this->userAttributes; } - + /** * Get a (user friendly) wait time representing how long the user must wait * until they will no longer be blocked by a rate limit (regardless of @@ -244,69 +244,69 @@ protected function getWaitTimeUntilUnblocked(string $username, array $ipAddresse $durationsInSeconds = [ FailedLoginUsername::getSecondsUntilUnblocked($username), ]; - + foreach ($ipAddresses as $ipAddress) { $durationsInSeconds[] = FailedLoginIpAddress::getSecondsUntilUnblocked($ipAddress); } - + return WaitTime::getLongestWaitTime($durationsInSeconds); } - + protected function hasError(): bool { return ($this->authError !== null); } - + /** * Check whether authentication was successful. If not, call * getErrorMessage() and/or getErrorCode() to find out why not. - * + * * @return bool */ public function isAuthenticated(): bool { - return ( ! $this->hasError()); + return (!$this->hasError()); } - + protected function isBlockedByRateLimit(string $username, array $ipAddresses): bool { return FailedLoginUsername::isRateLimitBlocking($username) || - FailedLoginIpAddress::isRateLimitBlockingAnyOfThese($ipAddresses); + FailedLoginIpAddress::isRateLimitBlockingAnyOfThese($ipAddresses); } - + public static function isCaptchaRequired(?string $username, array $ipAddresses): bool { return FailedLoginUsername::isCaptchaRequiredFor($username) || - FailedLoginIpAddress::isCaptchaRequiredForAnyOfThese($ipAddresses); + FailedLoginIpAddress::isCaptchaRequiredForAnyOfThese($ipAddresses); } - + public static function isEnoughFailedLoginsToBlock(int $numFailedLogins): bool { return ($numFailedLogins >= self::BLOCK_AFTER_NTH_FAILED_LOGIN); } - + public static function isEnoughFailedLoginsToRequireCaptcha(int $numFailedLogins): bool { return ($numFailedLogins >= self::REQUIRE_CAPTCHA_AFTER_NTH_FAILED_LOGIN); } - + protected function recordFailedLoginBy(string $username, array $ipAddresses): void { FailedLoginUsername::recordFailedLoginBy($username, $this->logger); FailedLoginIpAddress::recordFailedLoginBy($ipAddresses, $this->logger); } - + protected function resetFailedLoginsBy(string $username, array $ipAddresses): void { FailedLoginUsername::resetFailedLoginsBy($username); FailedLoginIpAddress::resetFailedLoginsBy($ipAddresses); } - + protected function setError(string $code, array $messageParams = []): void { $this->authError = new AuthError($code, $messageParams); } - + /** * @param WaitTime $waitTime */ @@ -314,7 +314,7 @@ protected function setErrorBlockedByRateLimit(WaitTime $waitTime): void { $unit = $waitTime->getUnit(); $number = $waitTime->getFriendlyNumber(); - + if ($unit === WaitTime::UNIT_SECOND) { $errorCode = AuthError::CODE_RATE_LIMIT_SECONDS; } else { // = minute @@ -324,35 +324,35 @@ protected function setErrorBlockedByRateLimit(WaitTime $waitTime): void $errorCode = AuthError::CODE_RATE_LIMIT_MINUTES; } } - - $this->setError($errorCode, ['{number}' => $number]); + + $this->setError($errorCode, ['%number%' => $number]); } - + protected function setErrorGenericTryLater(): void { $this->setError(AuthError::CODE_GENERIC_TRY_LATER); } - + protected function setErrorInvalidLogin(): void { $this->setError(AuthError::CODE_INVALID_LOGIN); } - + protected function setErrorNeedToSetAcctPassword(): void { $this->setError(AuthError::CODE_NEED_TO_SET_ACCT_PASSWORD); } - + protected function setErrorPasswordRequired(): void { $this->setError(AuthError::CODE_PASSWORD_REQUIRED); } - + protected function setErrorUsernameRequired(): void { $this->setError(AuthError::CODE_USERNAME_REQUIRED); } - + protected function setUserAttributes(?array $attributes): void { $this->userAttributes = $attributes; diff --git a/modules/silauth/lib/Auth/Source/auth/IdBroker.php b/modules/silauth/src/Auth/Source/auth/IdBroker.php similarity index 94% rename from modules/silauth/lib/Auth/Source/auth/IdBroker.php rename to modules/silauth/src/Auth/Source/auth/IdBroker.php index d542efa5..1c8f86f3 100644 --- a/modules/silauth/lib/Auth/Source/auth/IdBroker.php +++ b/modules/silauth/src/Auth/Source/auth/IdBroker.php @@ -1,4 +1,5 @@ logger = $logger; $this->idpDomainName = $idpDomainName; @@ -48,7 +49,7 @@ public function __construct( IdBrokerClient::ASSERT_VALID_BROKER_IP_CONFIG => $assertValidIp, ]); } - + /** * Attempt to authenticate with the given username and password, returning * the attributes for that user if the credentials were acceptable (or null @@ -68,16 +69,16 @@ public function getAuthenticatedUser(string $username, string $password): ?array { $rpOrigin = 'https://' . $this->idpDomainName; $userInfo = $this->client->authenticate($username, $password, $rpOrigin); - + if ($userInfo === null) { return null; } - + $pwExpDate = $userInfo['password']['expires_on'] ?? null; if ($pwExpDate !== null) { $schacExpiryDate = gmdate('YmdHis\Z', strtotime($pwExpDate)); } - + return SamlUser::convertToSamlFieldNames( $userInfo['employee_id'], $userInfo['first_name'], @@ -94,7 +95,7 @@ public function getAuthenticatedUser(string $username, string $password): ?array $userInfo['member'] ?? [] ); } - + /** * Ping the /site/status URL. If the ID Broker's status is fine, the * response string is returned. If not, an exception is thrown. diff --git a/modules/silauth/lib/Auth/Source/behaviors/CreatedAtUtcBehavior.php b/modules/silauth/src/Auth/Source/behaviors/CreatedAtUtcBehavior.php similarity index 99% rename from modules/silauth/lib/Auth/Source/behaviors/CreatedAtUtcBehavior.php rename to modules/silauth/src/Auth/Source/behaviors/CreatedAtUtcBehavior.php index cc04d8f5..edaddade 100644 --- a/modules/silauth/lib/Auth/Source/behaviors/CreatedAtUtcBehavior.php +++ b/modules/silauth/src/Auth/Source/behaviors/CreatedAtUtcBehavior.php @@ -1,4 +1,5 @@ secret = $secret; } - + public function isValidIn(Request $request): bool { if (empty($this->secret)) { throw new \RuntimeException('No captcha secret available.', 1487342411); } - + $captchaResponse = $request->getCaptchaResponse(); $ipAddress = $request->getMostLikelyIpAddress(); - + $recaptcha = new \ReCaptcha\ReCaptcha($this->secret); $rcResponse = $recaptcha->verify($captchaResponse, $ipAddress); - + return $rcResponse->isSuccess(); } } diff --git a/modules/silauth/lib/Auth/Source/config/ConfigManager.php b/modules/silauth/src/Auth/Source/config/ConfigManager.php similarity index 98% rename from modules/silauth/lib/Auth/Source/config/ConfigManager.php rename to modules/silauth/src/Auth/Source/config/ConfigManager.php index 4216b01d..a6c7b25e 100644 --- a/modules/silauth/lib/Auth/Source/config/ConfigManager.php +++ b/modules/silauth/src/Auth/Source/config/ConfigManager.php @@ -1,4 +1,5 @@ [ 'Sil\\SilAuth\\migrations\\', ], - + // Disable non-namespaced migrations. 'migrationPath' => null, ], diff --git a/modules/silauth/lib/Auth/Source/csrf/CsrfProtector.php b/modules/silauth/src/Auth/Source/csrf/CsrfProtector.php similarity index 98% rename from modules/silauth/lib/Auth/Source/csrf/CsrfProtector.php rename to modules/silauth/src/Auth/Source/csrf/CsrfProtector.php index 966b36ed..653041f8 100644 --- a/modules/silauth/lib/Auth/Source/csrf/CsrfProtector.php +++ b/modules/silauth/src/Auth/Source/csrf/CsrfProtector.php @@ -1,4 +1,5 @@ session = $session; } - + public function changeMasterToken(): void { $newMasterToken = $this->generateToken(); $this->setTokenInSession($newMasterToken); } - + protected function generateToken(): string { return bin2hex(random_bytes(32)); } - + /** * Get the CSRF protection token from the session. If not found, a new one * will be generated and stored in the session. @@ -49,7 +50,7 @@ public function getMasterToken(): string } return $masterToken; } - + protected function getTokenFromSession(): mixed { return $this->session->getData( @@ -57,7 +58,7 @@ protected function getTokenFromSession(): mixed $this->csrfSessionKey ); } - + /** * Check the given CSRF token to see if it was correct. * @@ -69,7 +70,7 @@ public function isTokenCorrect(string $submittedToken): bool { return hash_equals($this->getMasterToken(), $submittedToken); } - + protected function setTokenInSession(string $masterToken): void { $this->session->setData( diff --git a/modules/silauth/lib/Auth/Source/http/Request.php b/modules/silauth/src/Auth/Source/http/Request.php similarity index 98% rename from modules/silauth/lib/Auth/Source/http/Request.php rename to modules/silauth/src/Auth/Source/http/Request.php index fda2d155..14e3bbcd 100644 --- a/modules/silauth/lib/Auth/Source/http/Request.php +++ b/modules/silauth/src/Auth/Source/http/Request.php @@ -1,4 +1,5 @@ getIpAddresses() as $ipAddress) { - if ( ! $this->isTrustedIpAddress($ipAddress)) { + if (!$this->isTrustedIpAddress($ipAddress)) { $untrustedIpAddresses[] = $ipAddress; } } @@ -195,7 +196,7 @@ public static function sanitizeInputString(int $inputType, string $variableName) public function trustIpAddress(string $ipAddress): void { - if ( ! self::isValidIpAddress($ipAddress)) { + if (!self::isValidIpAddress($ipAddress)) { throw new \InvalidArgumentException(sprintf( '%s is not a valid IP address.', var_export($ipAddress, true) diff --git a/modules/silauth/lib/Auth/Source/models/FailedLoginIpAddress.php b/modules/silauth/src/Auth/Source/models/FailedLoginIpAddress.php similarity index 92% rename from modules/silauth/lib/Auth/Source/models/FailedLoginIpAddress.php rename to modules/silauth/src/Auth/Source/models/FailedLoginIpAddress.php index eefb2573..fd443ea3 100644 --- a/modules/silauth/lib/Auth/Source/models/FailedLoginIpAddress.php +++ b/modules/silauth/src/Auth/Source/models/FailedLoginIpAddress.php @@ -1,4 +1,5 @@ Yii::t('app', 'Occurred At (UTC)'), ]); } - + public function behaviors(): array { return [ @@ -37,7 +38,7 @@ public function behaviors(): array ], ]; } - + public static function countRecentFailedLoginsFor(string $ipAddress): int { $count = self::find()->where([ @@ -46,23 +47,23 @@ public static function countRecentFailedLoginsFor(string $ipAddress): int '>=', 'occurred_at_utc', UtcTime::format('-60 minutes') ])->count(); if (!is_numeric($count)) { - throw new \Exception('expected a numeric value for recent failed logins by IP address, got '. $count); + throw new \Exception('expected a numeric value for recent failed logins by IP address, got ' . $count); } return (int)$count; } - + public static function getFailedLoginsFor(string $ipAddress): array { - if ( ! Request::isValidIpAddress($ipAddress)) { + if (!Request::isValidIpAddress($ipAddress)) { throw new \InvalidArgumentException(sprintf( '%s is not a valid IP address.', var_export($ipAddress, true) )); } - + return self::findAll(['ip_address' => strtolower($ipAddress)]); } - + /** * Get the most recent failed-login record for the given IP address, or null * if none is found. @@ -78,38 +79,38 @@ public static function getMostRecentFailedLoginFor(string $ipAddress): ?FailedLo 'occurred_at_utc' => SORT_DESC, ])->one(); } - + /** * Get the number of seconds remaining until the specified IP address is * no longer blocked by a rate-limit. Returns zero if it is not currently * blocked. - * + * * @param string $ipAddress The IP address in question * @return int The number of seconds */ public static function getSecondsUntilUnblocked(string $ipAddress): int { $failedLogin = self::getMostRecentFailedLoginFor($ipAddress); - + return Authenticator::getSecondsUntilUnblocked( self::countRecentFailedLoginsFor($ipAddress), $failedLogin->occurred_at_utc ?? null ); } - + public function init(): void { $this->initializeLogger(); parent::init(); } - + public static function isCaptchaRequiredFor(string $ipAddress): bool { return Authenticator::isEnoughFailedLoginsToRequireCaptcha( self::countRecentFailedLoginsFor($ipAddress) ); } - + public static function isCaptchaRequiredForAnyOfThese(array $ipAddresses): bool { foreach ($ipAddresses as $ipAddress) { @@ -119,13 +120,13 @@ public static function isCaptchaRequiredForAnyOfThese(array $ipAddresses): bool } return false; } - + public static function isRateLimitBlocking(string $ipAddress): bool { $secondsUntilUnblocked = self::getSecondsUntilUnblocked($ipAddress); return ($secondsUntilUnblocked > 0); } - + public static function isRateLimitBlockingAnyOfThese(array $ipAddresses): bool { foreach ($ipAddresses as $ipAddress) { @@ -135,26 +136,25 @@ public static function isRateLimitBlockingAnyOfThese(array $ipAddresses): bool } return false; } - + public static function recordFailedLoginBy( - array $ipAddresses, + array $ipAddresses, LoggerInterface $logger - ): void - { + ): void { foreach ($ipAddresses as $ipAddress) { $newRecord = new FailedLoginIpAddress(['ip_address' => strtolower($ipAddress)]); - - if ( ! $newRecord->save()) { + + if (!$newRecord->save()) { $logger->critical(json_encode([ 'event' => 'Failed to update login attempts counter in ' - . 'database, so unable to rate limit that IP address.', + . 'database, so unable to rate limit that IP address.', 'ipAddress' => $ipAddress, 'errors' => $newRecord->getErrors(), ])); } } } - + public static function resetFailedLoginsBy(array $ipAddresses): void { foreach ($ipAddresses as $ipAddress) { diff --git a/modules/silauth/lib/Auth/Source/models/FailedLoginIpAddressBase.php b/modules/silauth/src/Auth/Source/models/FailedLoginIpAddressBase.php similarity index 100% rename from modules/silauth/lib/Auth/Source/models/FailedLoginIpAddressBase.php rename to modules/silauth/src/Auth/Source/models/FailedLoginIpAddressBase.php diff --git a/modules/silauth/lib/Auth/Source/models/FailedLoginUsername.php b/modules/silauth/src/Auth/Source/models/FailedLoginUsername.php similarity index 93% rename from modules/silauth/lib/Auth/Source/models/FailedLoginUsername.php rename to modules/silauth/src/Auth/Source/models/FailedLoginUsername.php index 771e1076..e1bc4ff0 100644 --- a/modules/silauth/lib/Auth/Source/models/FailedLoginUsername.php +++ b/modules/silauth/src/Auth/Source/models/FailedLoginUsername.php @@ -1,4 +1,5 @@ Yii::t('app', 'Occurred At (UTC)'), ]); } - + public function behaviors(): array { return [ @@ -35,7 +36,7 @@ public function behaviors(): array ], ]; } - + public static function countRecentFailedLoginsFor(string $username): int { $count = self::find()->where([ @@ -44,14 +45,14 @@ public static function countRecentFailedLoginsFor(string $username): int '>=', 'occurred_at_utc', UtcTime::format('-60 minutes') ])->count(); if (!is_numeric($count)) { - throw new \Exception('expected a numeric value for recent failed logins by username, got '. $count); + throw new \Exception('expected a numeric value for recent failed logins by username, got ' . $count); } return (int)$count; } - + /** * Find the records with the given username (if any). - * + * * @param string $username The username. * @return FailedLoginUsername[] An array of any matching records. */ @@ -59,7 +60,7 @@ public static function getFailedLoginsFor(string $username): array { return self::findAll(['username' => strtolower($username)]); } - + /** * Get the most recent failed-login record for the given username, or null * if none is found. @@ -75,31 +76,31 @@ public static function getMostRecentFailedLoginFor(string $username): ?FailedLog 'occurred_at_utc' => SORT_DESC, ])->one(); } - + /** * Get the number of seconds remaining until the specified username is * no longer blocked by a rate-limit. Returns zero if the user is not * currently blocked. - * + * * @param string $username The username in question * @return int The number of seconds */ public static function getSecondsUntilUnblocked(string $username): int { $failedLogin = self::getMostRecentFailedLoginFor($username); - + return Authenticator::getSecondsUntilUnblocked( self::countRecentFailedLoginsFor($username), $failedLogin->occurred_at_utc ?? null ); } - + public function init(): void { $this->initializeLogger(); parent::init(); } - + /** * Find out whether a rate limit is blocking the specified username. * @@ -111,7 +112,7 @@ public static function isRateLimitBlocking(string $username): bool $secondsUntilUnblocked = self::getSecondsUntilUnblocked($username); return ($secondsUntilUnblocked > 0); } - + public static function isCaptchaRequiredFor(?string $username): bool { if (empty($username)) { @@ -121,23 +122,22 @@ public static function isCaptchaRequiredFor(?string $username): bool self::countRecentFailedLoginsFor($username) ); } - + public static function recordFailedLoginBy( - string $username, + string $username, LoggerInterface $logger - ): void - { + ): void { $newRecord = new FailedLoginUsername(['username' => strtolower($username)]); - if ( ! $newRecord->save()) { + if (!$newRecord->save()) { $logger->critical(json_encode([ 'event' => 'Failed to update login attempts counter in ' - . 'database, so unable to rate limit that username.', + . 'database, so unable to rate limit that username.', 'username' => $username, 'errors' => $newRecord->getErrors(), ])); } } - + public static function resetFailedLoginsBy(string $username): void { self::deleteAll(['username' => strtolower($username)]); diff --git a/modules/silauth/lib/Auth/Source/models/FailedLoginUsernameBase.php b/modules/silauth/src/Auth/Source/models/FailedLoginUsernameBase.php similarity index 100% rename from modules/silauth/lib/Auth/Source/models/FailedLoginUsernameBase.php rename to modules/silauth/src/Auth/Source/models/FailedLoginUsernameBase.php diff --git a/modules/silauth/lib/Auth/Source/rebuildbasemodels.sh b/modules/silauth/src/Auth/Source/rebuildbasemodels.sh similarity index 100% rename from modules/silauth/lib/Auth/Source/rebuildbasemodels.sh rename to modules/silauth/src/Auth/Source/rebuildbasemodels.sh diff --git a/modules/silauth/lib/Auth/Source/saml/User.php b/modules/silauth/src/Auth/Source/saml/User.php similarity index 84% rename from modules/silauth/lib/Auth/Source/saml/User.php rename to modules/silauth/src/Auth/Source/saml/User.php index 864fe118..6e4df4a1 100644 --- a/modules/silauth/lib/Auth/Source/saml/User.php +++ b/modules/silauth/src/Auth/Source/saml/User.php @@ -1,24 +1,24 @@ logError($t->getMessage()); + $this->logError('isDatabaseOkay database check returned error: ' . $t->getMessage()); return false; } } @@ -47,6 +48,9 @@ protected function isRequiredConfigPresent(): bool */ $baseURL = $globalConfig->getString('baseurlpath', ''); $avoidsSecurityHole = (preg_match('#^https?://.*/$#D', $baseURL) === 1); + if (!$avoidsSecurityHole) { + $this->logError('isRequiredConfigPresent failed: baseurlpath (' . $baseURL . ') does not meet requirements'); + } return $avoidsSecurityHole; } @@ -59,11 +63,11 @@ protected function isRequiredConfigPresent(): bool */ public function reportStatus(): void { - if ( ! $this->isRequiredConfigPresent()) { + if (!$this->isRequiredConfigPresent()) { $this->reportError('Config problem', 1485984755); } - if ( ! $this->isDatabaseOkay()) { + if (!$this->isDatabaseOkay()) { $this->reportError('Database problem', 1485284407); } diff --git a/modules/silauth/lib/Auth/Source/tests/bootstrap.php b/modules/silauth/src/Auth/Source/tests/bootstrap.php similarity index 100% rename from modules/silauth/lib/Auth/Source/tests/bootstrap.php rename to modules/silauth/src/Auth/Source/tests/bootstrap.php diff --git a/modules/silauth/lib/Auth/Source/tests/fakes/FakeFailedIdBroker.php b/modules/silauth/src/Auth/Source/tests/fakes/FakeFailedIdBroker.php similarity index 99% rename from modules/silauth/lib/Auth/Source/tests/fakes/FakeFailedIdBroker.php rename to modules/silauth/src/Auth/Source/tests/fakes/FakeFailedIdBroker.php index aee14acd..8317fc29 100644 --- a/modules/silauth/lib/Auth/Source/tests/fakes/FakeFailedIdBroker.php +++ b/modules/silauth/src/Auth/Source/tests/fakes/FakeFailedIdBroker.php @@ -1,4 +1,5 @@ client = new IdBrokerClient($baseUri, $accessToken, [ 'http_client_options' => [ 'handler' => HandlerStack::create(new MockHandler( - - /* Set up several, since this may be called multiple times - * during a test: */ + + /* Set up several, since this may be called multiple times + * during a test: */ array_fill( 0, Authenticator::BLOCK_AFTER_NTH_FAILED_LOGIN * 2, @@ -42,6 +43,6 @@ public function __construct( IdBrokerClient::ASSERT_VALID_BROKER_IP_CONFIG => false, ]); } - + abstract protected function getDesiredResponse(); } diff --git a/modules/silauth/lib/Auth/Source/tests/fakes/FakeInvalidIdBroker.php b/modules/silauth/src/Auth/Source/tests/fakes/FakeInvalidIdBroker.php similarity index 98% rename from modules/silauth/lib/Auth/Source/tests/fakes/FakeInvalidIdBroker.php rename to modules/silauth/src/Auth/Source/tests/fakes/FakeInvalidIdBroker.php index a22c85c1..b57f7b19 100644 --- a/modules/silauth/lib/Auth/Source/tests/fakes/FakeInvalidIdBroker.php +++ b/modules/silauth/src/Auth/Source/tests/fakes/FakeInvalidIdBroker.php @@ -1,4 +1,5 @@ logger->info('FAKE ERROR: invalid/unexpected response.'); return parent::getAuthenticatedUser($username, $password); } - + protected function getDesiredResponse(): Response { return new Response(404); diff --git a/modules/silauth/lib/Auth/Source/tests/fakes/FakeSuccessfulIdBroker.php b/modules/silauth/src/Auth/Source/tests/fakes/FakeSuccessfulIdBroker.php similarity index 99% rename from modules/silauth/lib/Auth/Source/tests/fakes/FakeSuccessfulIdBroker.php rename to modules/silauth/src/Auth/Source/tests/fakes/FakeSuccessfulIdBroker.php index d385fa11..8f8dd599 100644 --- a/modules/silauth/lib/Auth/Source/tests/fakes/FakeSuccessfulIdBroker.php +++ b/modules/silauth/src/Auth/Source/tests/fakes/FakeSuccessfulIdBroker.php @@ -1,4 +1,5 @@ $blockAfterNth + 100, 'expected' => 3600], ]; foreach ($testCases as $testCase) { - + // Act: $actual = Authenticator::calculateSecondsToDelay( $testCase['failedLoginAttempts'] ); - + // Assert: $this->assertSame($testCase['expected'], $actual, sprintf( 'Expected %s failed login attempts to result in %s second(s), not %s.', @@ -44,7 +45,7 @@ public function testCalculateSecondsToDelay() )); } } - + public function testGetSecondsUntilUnblocked() { // Arrange: @@ -62,18 +63,18 @@ public function testGetSecondsUntilUnblocked() 'expected' => 20, ]]; foreach ($testCases as $testCase) { - + // Act: $actual = Authenticator::getSecondsUntilUnblocked( $testCase['numRecentFailures'], $testCase['mostRecentFailureAt'] ); - + // Assert: $this->assertSame($testCase['expected'], $actual); } } - + public function testIsEnoughFailedLoginsToBlock() { // Arrange: @@ -84,12 +85,12 @@ public function testIsEnoughFailedLoginsToBlock() ['expected' => true, 'failedLogins' => Authenticator::BLOCK_AFTER_NTH_FAILED_LOGIN + 1], ]; foreach ($testCases as $testCase) { - + // Act: $actual = Authenticator::isEnoughFailedLoginsToBlock( $testCase['failedLogins'] ); - + // Assert: $this->assertSame($testCase['expected'], $actual); } diff --git a/modules/silauth/lib/Auth/Source/tests/unit/captcha/DummyFailedCaptcha.php b/modules/silauth/src/Auth/Source/tests/unit/captcha/DummyFailedCaptcha.php similarity index 99% rename from modules/silauth/lib/Auth/Source/tests/unit/captcha/DummyFailedCaptcha.php rename to modules/silauth/src/Auth/Source/tests/unit/captcha/DummyFailedCaptcha.php index 9ddb58e6..8ff8c6cb 100644 --- a/modules/silauth/lib/Auth/Source/tests/unit/captcha/DummyFailedCaptcha.php +++ b/modules/silauth/src/Auth/Source/tests/unit/captcha/DummyFailedCaptcha.php @@ -1,4 +1,5 @@ assertTrue(is_array($sspConfig), sprintf( 'Expected an array, got this: %s', var_export($sspConfig, true) )); } - + public function testGetSspConfigFor() { // Arrange: $category = 'mysql'; - + // Act: $result = ConfigManager::getSspConfigFor($category); - + // Assert: $this->assertArrayHasKey('database', $result, var_export($result, true)); } - + public function testRemoveCategory() { // Arrange: @@ -44,10 +45,10 @@ public function testRemoveCategory() ['key' => 'category.subCategory.subKey', 'expected' => 'subCategory.subKey'], ]; foreach ($testCases as $testCase) { - + // Act: $actual = ConfigManager::removeCategory($testCase['key']); - + // Assert: $this->assertSame($testCase['expected'], $actual, sprintf( 'Expected removing the category from %s result in %s, not %s.', diff --git a/modules/silauth/lib/Auth/Source/tests/unit/csrf/CsrfProtectorTest.php b/modules/silauth/src/Auth/Source/tests/unit/csrf/CsrfProtectorTest.php similarity index 97% rename from modules/silauth/lib/Auth/Source/tests/unit/csrf/CsrfProtectorTest.php rename to modules/silauth/src/Auth/Source/tests/unit/csrf/CsrfProtectorTest.php index fc7e97d3..7aa1c443 100644 --- a/modules/silauth/lib/Auth/Source/tests/unit/csrf/CsrfProtectorTest.php +++ b/modules/silauth/src/Auth/Source/tests/unit/csrf/CsrfProtectorTest.php @@ -1,4 +1,5 @@ getMasterToken(); $firstTokenAgain = $csrfProtector->getMasterToken(); - + // Act: $csrfProtector->changeMasterToken(); $secondToken = $csrfProtector->getMasterToken(); $secondTokenAgain = $csrfProtector->getMasterToken(); - + // Assert: $this->assertSame($firstToken, $firstTokenAgain); $this->assertNotEquals($firstToken, $secondToken); diff --git a/modules/silauth/lib/Auth/Source/tests/unit/csrf/FakeSession.php b/modules/silauth/src/Auth/Source/tests/unit/csrf/FakeSession.php similarity index 59% rename from modules/silauth/lib/Auth/Source/tests/unit/csrf/FakeSession.php rename to modules/silauth/src/Auth/Source/tests/unit/csrf/FakeSession.php index 41d1fa48..fe4542dd 100644 --- a/modules/silauth/lib/Auth/Source/tests/unit/csrf/FakeSession.php +++ b/modules/silauth/src/Auth/Source/tests/unit/csrf/FakeSession.php @@ -2,39 +2,36 @@ namespace SimpleSAML\Module\silauth\Auth\Source\tests\unit\csrf; +use SimpleSAML\Session; + /** * Class to mimic the bare basics of the SimpleSAML\Session class in order to * allow good testing of the CsrfProtector class. */ -class FakeSession extends \SimpleSAML\Session +class FakeSession extends Session { - private $inMemoryDataStore; - - private function __construct($transient = false) + private array $inMemoryDataStore; + + private function __construct(bool $transient = false) { $this->inMemoryDataStore = []; } - - /** - * @param string $type - * @param string|null $id - * @return mixed - */ - public function getData($type, $id) + + public function getData(string $type, ?string $id): mixed { return $this->inMemoryDataStore[$type][$id] ?? null; } - - public static function getSessionFromRequest($sessionId = null) + + public static function getSessionFromRequest(): Session { return new self(); } - - public function setData($type, $id, $data, $timeout = null) + + public function setData(string $type, string $id, mixed $data, int|string|null $timeout = null): void { // Make sure an array exists for that type of data. $this->inMemoryDataStore[$type] = $this->inMemoryDataStore[$type] ?? []; - + // Store the given data. $this->inMemoryDataStore[$type][$id] = $data; } diff --git a/modules/silauth/lib/Auth/Source/tests/unit/http/DummyRequest.php b/modules/silauth/src/Auth/Source/tests/unit/http/DummyRequest.php similarity index 90% rename from modules/silauth/lib/Auth/Source/tests/unit/http/DummyRequest.php rename to modules/silauth/src/Auth/Source/tests/unit/http/DummyRequest.php index f2334110..a375e42c 100644 --- a/modules/silauth/lib/Auth/Source/tests/unit/http/DummyRequest.php +++ b/modules/silauth/src/Auth/Source/tests/unit/http/DummyRequest.php @@ -1,4 +1,5 @@ dummyIpAddress]; } - + public function setDummyIpAddress(string $dummyIpAddress): void { - if ( ! self::isValidIpAddress($dummyIpAddress)) { + if (!self::isValidIpAddress($dummyIpAddress)) { throw new \InvalidArgumentException(sprintf( '%s is not a valid IP address.', var_export($dummyIpAddress, true) )); } - + $this->dummyIpAddress = $dummyIpAddress; } } diff --git a/modules/silauth/lib/Auth/Source/tests/unit/http/RequestTest.php b/modules/silauth/src/Auth/Source/tests/unit/http/RequestTest.php similarity index 99% rename from modules/silauth/lib/Auth/Source/tests/unit/http/RequestTest.php rename to modules/silauth/src/Auth/Source/tests/unit/http/RequestTest.php index 7db3f7bb..b2d1e366 100644 --- a/modules/silauth/lib/Auth/Source/tests/unit/http/RequestTest.php +++ b/modules/silauth/src/Auth/Source/tests/unit/http/RequestTest.php @@ -1,4 +1,5 @@ isTrustedIpAddress($testCase['ipAddress']); - + // Assert: $this->assertSame($testCase['expected'], $actual, sprintf( 'Expected %s %sto be trusted.', diff --git a/modules/silauth/lib/Auth/Source/tests/unit/models/FailedLoginIpAddressTest.php b/modules/silauth/src/Auth/Source/tests/unit/models/FailedLoginIpAddressTest.php similarity index 98% rename from modules/silauth/lib/Auth/Source/tests/unit/models/FailedLoginIpAddressTest.php rename to modules/silauth/src/Auth/Source/tests/unit/models/FailedLoginIpAddressTest.php index 8b1c3daf..3c1bc6fb 100644 --- a/modules/silauth/lib/Auth/Source/tests/unit/models/FailedLoginIpAddressTest.php +++ b/modules/silauth/src/Auth/Source/tests/unit/models/FailedLoginIpAddressTest.php @@ -1,4 +1,5 @@ assertTrue($model->insert(false)); } } - + public function testCountRecentFailedLoginsFor() { // Arrange: @@ -33,7 +34,7 @@ public function testCountRecentFailedLoginsFor() 'occurred_at_utc' => UtcTime::format(), // Now (thus, recent). ]]; $this->setDbFixture($fixtures); - + // Pre-assert: $this->assertCount( count($fixtures), @@ -46,7 +47,7 @@ public function testCountRecentFailedLoginsFor() // Assert: $this->assertEquals(2, $result); } - + public function testGetMostRecentFailedLoginFor() { // Arrange: @@ -63,14 +64,14 @@ public function testGetMostRecentFailedLoginFor() 'occurred_at_utc' => UtcTime::format('-59 minutes'), ]]; $this->setDbFixture($fixtures); - + // Act: $fliaRecord = FailedLoginIpAddress::getMostRecentFailedLoginFor($ipAddress); // Assert: $this->assertSame($nowDateTimeString, $fliaRecord->occurred_at_utc); } - + public function testIsCaptchaRequiredFor() { // Arrange: @@ -102,7 +103,7 @@ public function testIsCaptchaRequiredFor() $this->assertSame($testCase['expected'], $actual); } } - + public function testIsRateLimitBlocking() { // Arrange: @@ -134,7 +135,7 @@ public function testIsRateLimitBlocking() $this->assertSame($testCase['expected'], $actual); } } - + public function testRecordFailedLoginBy() { // Arrange: @@ -146,23 +147,23 @@ public function testRecordFailedLoginBy() $logger = new Psr3EchoLogger(); $expectedPre = count($dbFixture); $expectedPost = $expectedPre + 1; - + // Pre-assert: $this->assertCount( $expectedPre, FailedLoginIpAddress::getFailedLoginsFor($ipAddress) ); - + // Act: FailedLoginIpAddress::recordFailedLoginBy([$ipAddress], $logger); - + // Assert: $this->assertCount( $expectedPost, FailedLoginIpAddress::getFailedLoginsFor($ipAddress) ); } - + public function testResetFailedLoginsBy() { // Arrange: @@ -174,14 +175,14 @@ public function testResetFailedLoginsBy() [$ipAddress, $otherIpAddress], $logger ); - + // Pre-assert: $this->assertCount(1, FailedLoginIpAddress::getFailedLoginsFor($ipAddress)); $this->assertCount(1, FailedLoginIpAddress::getFailedLoginsFor($otherIpAddress)); - + // Act: FailedLoginIpAddress::resetFailedLoginsBy([$ipAddress]); - + // Assert: $this->assertCount(0, FailedLoginIpAddress::getFailedLoginsFor($ipAddress)); $this->assertCount(1, FailedLoginIpAddress::getFailedLoginsFor($otherIpAddress)); diff --git a/modules/silauth/lib/Auth/Source/tests/unit/models/FailedLoginUsernameTest.php b/modules/silauth/src/Auth/Source/tests/unit/models/FailedLoginUsernameTest.php similarity index 98% rename from modules/silauth/lib/Auth/Source/tests/unit/models/FailedLoginUsernameTest.php rename to modules/silauth/src/Auth/Source/tests/unit/models/FailedLoginUsernameTest.php index b5b571c2..9a6ef81f 100644 --- a/modules/silauth/lib/Auth/Source/tests/unit/models/FailedLoginUsernameTest.php +++ b/modules/silauth/src/Auth/Source/tests/unit/models/FailedLoginUsernameTest.php @@ -1,4 +1,5 @@ assertTrue($model->insert(false)); } } - + public function testCountRecentFailedLoginsFor() { // Arrange: @@ -33,7 +34,7 @@ public function testCountRecentFailedLoginsFor() 'occurred_at_utc' => UtcTime::format(), // Now (thus, recent). ]]; $this->setDbFixture($fixtures); - + // Pre-assert: $this->assertCount( count($fixtures), @@ -46,7 +47,7 @@ public function testCountRecentFailedLoginsFor() // Assert: $this->assertEquals(2, $result); } - + public function testGetMostRecentFailedLoginFor() { // Arrange: @@ -63,14 +64,14 @@ public function testGetMostRecentFailedLoginFor() 'occurred_at_utc' => UtcTime::format('-59 minutes'), ]]; $this->setDbFixture($fixtures); - + // Act: $fliaRecord = FailedLoginUsername::getMostRecentFailedLoginFor($username); // Assert: $this->assertSame($nowDateTimeString, $fliaRecord->occurred_at_utc); } - + public function testIsCaptchaRequiredFor() { // Arrange: @@ -102,7 +103,7 @@ public function testIsCaptchaRequiredFor() $this->assertSame($testCase['expected'], $actual); } } - + public function testIsRateLimitBlocking() { // Arrange: @@ -134,7 +135,7 @@ public function testIsRateLimitBlocking() $this->assertSame($testCase['expected'], $actual); } } - + public function testRecordFailedLoginBy() { // Arrange: @@ -146,23 +147,23 @@ public function testRecordFailedLoginBy() $logger = new Psr3EchoLogger(); $expectedPre = count($dbFixture); $expectedPost = $expectedPre + 1; - + // Pre-assert: $this->assertCount( $expectedPre, FailedLoginUsername::getFailedLoginsFor($username) ); - + // Act: FailedLoginUsername::recordFailedLoginBy($username, $logger); - + // Assert: $this->assertCount( $expectedPost, FailedLoginUsername::getFailedLoginsFor($username) ); } - + public function testResetFailedLoginsBy() { // Arrange: @@ -173,14 +174,14 @@ public function testResetFailedLoginsBy() ['username' => $otherUsername, 'occurred_at_utc' => UtcTime::format()], ]; $this->setDbFixture($dbFixture); - + // Pre-assert: $this->assertCount(1, FailedLoginUsername::getFailedLoginsFor($username)); $this->assertCount(1, FailedLoginUsername::getFailedLoginsFor($otherUsername)); - + // Act: FailedLoginUsername::resetFailedLoginsBy($username); - + // Assert: $this->assertCount(0, FailedLoginUsername::getFailedLoginsFor($username)); $this->assertCount(1, FailedLoginUsername::getFailedLoginsFor($otherUsername)); diff --git a/modules/silauth/lib/Auth/Source/tests/unit/text/TextTest.php b/modules/silauth/src/Auth/Source/tests/unit/text/TextTest.php similarity index 98% rename from modules/silauth/lib/Auth/Source/tests/unit/text/TextTest.php rename to modules/silauth/src/Auth/Source/tests/unit/text/TextTest.php index 027cbfc7..1189df12 100644 --- a/modules/silauth/lib/Auth/Source/tests/unit/text/TextTest.php +++ b/modules/silauth/src/Auth/Source/tests/unit/text/TextTest.php @@ -1,4 +1,5 @@ 'with `backticks`', 'expected' => 'with backticks'], ]; foreach ($testCases as $testCase) { - + // Act: $actual = Text::sanitizeString($testCase['input']); - + // Assert: $this->assertSame($testCase['expected'], $actual, sprintf( 'Expected sanitizing %s to result in %s, not %s.', diff --git a/modules/silauth/lib/Auth/Source/tests/unit/time/UtcTimeTest.php b/modules/silauth/src/Auth/Source/tests/unit/time/UtcTimeTest.php similarity index 96% rename from modules/silauth/lib/Auth/Source/tests/unit/time/UtcTimeTest.php rename to modules/silauth/src/Auth/Source/tests/unit/time/UtcTimeTest.php index 5a55c13f..6387d2c4 100644 --- a/modules/silauth/lib/Auth/Source/tests/unit/time/UtcTimeTest.php +++ b/modules/silauth/src/Auth/Source/tests/unit/time/UtcTimeTest.php @@ -1,4 +1,5 @@ assertSame($testCase['expected'], $actual); } } - + public function testGetRemainingSeconds() { // Arrange: @@ -50,15 +51,15 @@ public function testGetRemainingSeconds() $elapsed = $testCase['elapsed']; $expected = $testCase['expected'] ?? null; $expectException = $testCase['expectException'] ?? null; - + // Pre-assert: if ($expectException !== null) { $this->expectException($expectException); } - + // Act: $actual = UtcTime::getRemainingSeconds($total, $elapsed); - + // Assert: if ($expectException !== null) { $this->fail(sprintf( @@ -77,7 +78,7 @@ public function testGetRemainingSeconds() )); } } - + public function testGetSecondsSinceDateTime() { // Arrange: @@ -88,10 +89,10 @@ public function testGetSecondsSinceDateTime() ['value' => UtcTime::format('-2 hours'), 'expected' => 7200], ]; foreach ($testCases as $testCase) { - + // Act: $actual = UtcTime::getSecondsSinceDateTime($testCase['value']); - + // Assert: $this->assertEqualsWithDelta( $testCase['expected'], @@ -105,25 +106,25 @@ public function testGetSecondsSinceDateTime() ); } } - + public function testGetSecondsSinceDateTimeEmptyString() { $this->expectException('\InvalidArgumentException'); UtcTime::getSecondsSinceDateTime(''); } - + public function testGetSecondsSinceDateTimeInvalidDateTimeString() { $this->expectException('\Exception'); UtcTime::getSecondsSinceDateTime('asdf'); } - + public function testGetSecondsSinceDateTimeNull() { $this->expectException('\TypeError'); UtcTime::getSecondsSinceDateTime(null); } - + public function testGetSecondsUntil() { // Arrange: @@ -132,35 +133,35 @@ public function testGetSecondsUntil() $expected = 86400; // 86400 = seconds in a day $dayOneUtcTime = new UtcTime($dayOneString); $dayTwoUtcTime = new UtcTime($dayTwoString); - + // Act: $actual = $dayOneUtcTime->getSecondsUntil($dayTwoUtcTime); - + // Assert: $this->assertSame($expected, $actual); } - + public function testGetTimestamp() { // Arrange: $timestamp = time(); $utcTime = new UtcTime(date('r', $timestamp)); - + // Act: $result = $utcTime->getTimestamp(); - + // Assert: $this->assertSame($timestamp, $result); } - + public function testNow() { // Arrange: $expected = gmdate(UtcTime::DATE_TIME_FORMAT, time()); - + // Act: $actual = UtcTime::now(); - + // Assert: $this->assertSame($expected, $actual); } diff --git a/modules/silauth/lib/Auth/Source/tests/unit/time/WaitTimeTest.php b/modules/silauth/src/Auth/Source/tests/unit/time/WaitTimeTest.php similarity index 98% rename from modules/silauth/lib/Auth/Source/tests/unit/time/WaitTimeTest.php rename to modules/silauth/src/Auth/Source/tests/unit/time/WaitTimeTest.php index b2e5b2c5..32cd0e0c 100644 --- a/modules/silauth/lib/Auth/Source/tests/unit/time/WaitTimeTest.php +++ b/modules/silauth/src/Auth/Source/tests/unit/time/WaitTimeTest.php @@ -1,4 +1,5 @@ assertSame($testCase['expected'], $actual, sprintf( 'Expected %s second(s) to result in %s, not %s.', @@ -37,7 +38,7 @@ public function testGetFriendlyWaitTimeFor() )); } } - + public function testGetLongestWaitTime() { // Arrange: @@ -57,10 +58,10 @@ public function testGetLongestWaitTime() if (array_key_exists('expectException', $testCase)) { $this->expectException($testCase['expectException']); } - + // Act: $actual = WaitTime::getLongestWaitTime($testCase['durations']); - + // Assert: $this->assertEquals($testCase['expected'], $actual, sprintf( 'Expected the longest of %s second(s) to be a wait time of %s, not %s.', diff --git a/modules/silauth/lib/Auth/Source/text/Text.php b/modules/silauth/src/Auth/Source/text/Text.php similarity index 98% rename from modules/silauth/lib/Auth/Source/text/Text.php rename to modules/silauth/src/Auth/Source/text/Text.php index 6649ca65..8b292d59 100644 --- a/modules/silauth/lib/Auth/Source/text/Text.php +++ b/modules/silauth/src/Auth/Source/text/Text.php @@ -1,4 +1,5 @@ . @@ -23,16 +24,16 @@ public function __construct(string $dateTimeString = 'now') $this->utc = new \DateTimeZone('UTC'); $this->dateTime = new \DateTime($dateTimeString, $this->utc); } - + public function __toString() { return $this->dateTime->format(self::DATE_TIME_FORMAT); } - + /** * Convert the given date/time description to a formatted date/time string * in the UTC time zone. - * + * * @param string $dateTimeString (Optional:) The date/time to use. If not * given, 'now' will be used. * @return string @@ -43,7 +44,7 @@ public static function format(string $dateTimeString = 'now'): string { return (string)(new UtcTime($dateTimeString)); } - + /** * Given a total number of seconds and an elapsed number of seconds, get the * remaining seconds until that total has passed. If the total has already @@ -60,7 +61,7 @@ public static function getRemainingSeconds(int $totalSeconds, int $elapsedSecond $remainingSeconds = $totalSeconds - $elapsedSeconds; return max($remainingSeconds, 0); } - + /** * Get the number of seconds we have to go back to get from this UTC time to * the given UTC time. A positive number will be returned if the given UTC @@ -75,7 +76,7 @@ public function getSecondsSince(UtcTime $otherUtcTime): int { return $this->getTimestamp() - $otherUtcTime->getTimestamp(); } - + /** * Get the number of seconds since the given date/time string. * @@ -97,20 +98,20 @@ public static function getSecondsSinceDateTime(string $dateTimeString): int $dateTimeUtc = new UtcTime($dateTimeString); return $nowUtc->getSecondsSince($dateTimeUtc); } - + public function getSecondsUntil(UtcTime $otherUtcTime): int { return $otherUtcTime->getTimestamp() - $this->getTimestamp(); } - + public function getTimestamp(): int { return $this->dateTime->getTimestamp(); } - + /** * Get the current date/time (UTC) as a formatted string - * + * * @return string */ public static function now(): string diff --git a/modules/silauth/lib/Auth/Source/time/WaitTime.php b/modules/silauth/src/Auth/Source/time/WaitTime.php similarity index 98% rename from modules/silauth/lib/Auth/Source/time/WaitTime.php rename to modules/silauth/src/Auth/Source/time/WaitTime.php index 216b46ba..baac8277 100644 --- a/modules/silauth/lib/Auth/Source/time/WaitTime.php +++ b/modules/silauth/src/Auth/Source/time/WaitTime.php @@ -1,4 +1,5 @@ unit = self::UNIT_MINUTE; } } - + public function getFriendlyNumber(): int { return $this->friendlyNumber; } - + /** * Get a WaitTime representing the longest of the given durations. * @@ -55,12 +56,12 @@ public static function getLongestWaitTime(array $durationsInSeconds): WaitTime } return new WaitTime(max($durationsInSeconds)); } - + public function getUnit(): string { return $this->unit; } - + public function __toString() { return sprintf( diff --git a/modules/silauth/lib/Auth/Source/traits/LoggerAwareTrait.php b/modules/silauth/src/Auth/Source/traits/LoggerAwareTrait.php similarity index 98% rename from modules/silauth/lib/Auth/Source/traits/LoggerAwareTrait.php rename to modules/silauth/src/Auth/Source/traits/LoggerAwareTrait.php index c07c72c8..f6b80900 100644 --- a/modules/silauth/lib/Auth/Source/traits/LoggerAwareTrait.php +++ b/modules/silauth/src/Auth/Source/traits/LoggerAwareTrait.php @@ -1,4 +1,5 @@ logger)) { $this->logger = new NullLogger(); } } - + /** * Set a logger for this class instance to use. * diff --git a/modules/silauth/lib/Auth/Source/yii b/modules/silauth/src/Auth/Source/yii similarity index 66% rename from modules/silauth/lib/Auth/Source/yii rename to modules/silauth/src/Auth/Source/yii index a163c10e..736df0ba 100755 --- a/modules/silauth/lib/Auth/Source/yii +++ b/modules/silauth/src/Auth/Source/yii @@ -16,28 +16,28 @@ defined('STDIN') or define('STDIN', fopen('php://stdin', 'r')); defined('STDOUT') or define('STDOUT', fopen('php://stdout', 'w')); $autoloadLocations = [ - __DIR__ . '/../vendor/autoload.php', - '/data/vendor/autoload.php', + __DIR__ . '/../vendor/autoload.php', + '/data/vendor/autoload.php', ]; foreach ($autoloadLocations as $location) { - if (file_exists($location)) { - require_once $location ; - break; - } + if (file_exists($location)) { + require_once $location; + break; + } } use Sil\PhpEnv\Env; use SimpleSAML\Module\silauth\Auth\Source\config\ConfigManager; $application = ConfigManager::getYii2ConsoleApp(['components' => ['db' => [ - 'dsn' => sprintf( - 'mysql:host=%s;dbname=%s', - Env::get('MYSQL_HOST'), - Env::get('MYSQL_DATABASE') - ), - 'username' => Env::get('MYSQL_USER'), - 'password' => Env::get('MYSQL_PASSWORD'), + 'dsn' => sprintf( + 'mysql:host=%s;dbname=%s', + Env::get('MYSQL_HOST'), + Env::get('MYSQL_DATABASE') + ), + 'username' => Env::get('MYSQL_USER'), + 'password' => Env::get('MYSQL_PASSWORD'), ]]]); $exitCode = $application->run(); exit($exitCode); diff --git a/modules/silauth/templates/.gitkeep b/modules/silauth/templates/.gitkeep new file mode 100644 index 00000000..57da54a3 --- /dev/null +++ b/modules/silauth/templates/.gitkeep @@ -0,0 +1 @@ +this directory will be filled in the Docker image with a copy of the material module templates diff --git a/modules/sildisco/www/betatest.php b/modules/sildisco/public/betatest.php similarity index 100% rename from modules/sildisco/www/betatest.php rename to modules/sildisco/public/betatest.php diff --git a/modules/sildisco/www/disco.php b/modules/sildisco/public/disco.php similarity index 90% rename from modules/sildisco/www/disco.php rename to modules/sildisco/public/disco.php index e6b87f69..bc2b8321 100644 --- a/modules/sildisco/www/disco.php +++ b/modules/sildisco/public/disco.php @@ -1,7 +1,7 @@ getBoolean('admin.protectmetadata', false)) { -// Auth::requireAdmin(); +// $authUtils->requireAdmin(); //} try { @@ -32,14 +33,16 @@ $availableCerts = array(); + $cryptoUtils = new Crypto(); + $keys = array(); - $certInfo = Crypto::loadPublicKey($idpmeta, false, 'new_'); + $certInfo = $cryptoUtils->loadPublicKey($idpmeta, false, 'new_'); if ($certInfo !== null) { $availableCerts['new_idp.crt'] = $certInfo; $keys[] = array( - 'type' => 'X509Certificate', - 'signing' => true, - 'encryption' => true, + 'type' => 'X509Certificate', + 'signing' => true, + 'encryption' => true, 'X509Certificate' => $certInfo['certData'], ); $hasNewCert = true; @@ -47,30 +50,30 @@ $hasNewCert = false; } - $certInfo = Crypto::loadPublicKey($idpmeta, true); + $certInfo = $cryptoUtils->loadPublicKey($idpmeta, true); $availableCerts['idp.crt'] = $certInfo; $keys[] = array( - 'type' => 'X509Certificate', - 'signing' => true, - 'encryption' => ($hasNewCert ? false : true), + 'type' => 'X509Certificate', + 'signing' => true, + 'encryption' => ($hasNewCert ? false : true), 'X509Certificate' => $certInfo['certData'], ); if ($idpmeta->hasValue('https.certificate')) { - $httpsCert = Crypto::loadPublicKey($idpmeta, true, 'https.'); + $httpsCert = $cryptoUtils->loadPublicKey($idpmeta, true, 'https.'); assert('isset($httpsCert["certData"])'); $availableCerts['https.crt'] = $httpsCert; $keys[] = array( - 'type' => 'X509Certificate', - 'signing' => true, - 'encryption' => false, + 'type' => 'X509Certificate', + 'signing' => true, + 'encryption' => false, 'X509Certificate' => $httpsCert['certData'], ); } $metaArray = array( 'metadata-set' => 'saml20-idp-remote', - 'entityid' => $idpentityid, + 'entityid' => $idpentityid, ); $ssob = $metadata->getGenerated('SingleSignOnServiceBinding', 'saml20-idp-hosted'); @@ -81,13 +84,13 @@ if (is_array($ssob)) { foreach ($ssob as $binding) { $metaArray['SingleSignOnService'][] = array( - 'Binding' => $binding, + 'Binding' => $binding, 'Location' => $ssol, ); } } else { $metaArray['SingleSignOnService'][] = array( - 'Binding' => $ssob, + 'Binding' => $ssob, 'Location' => $ssol, ); } @@ -95,13 +98,13 @@ if (is_array($slob)) { foreach ($slob as $binding) { $metaArray['SingleLogoutService'][] = array( - 'Binding' => $binding, + 'Binding' => $binding, 'Location' => $slol, ); } } else { $metaArray['SingleLogoutService'][] = array( - 'Binding' => $slob, + 'Binding' => $slob, 'Location' => $slol, ); } @@ -112,12 +115,14 @@ $metaArray['keys'] = $keys; } + $httpUtils = new HTTP(); + if ($idpmeta->getBoolean('saml20.sendartifact', false)) { // Artifact sending enabled $metaArray['ArtifactResolutionService'][] = array( - 'index' => 0, - 'Location' => HTTP::getBaseURL().'saml2/idp/ArtifactResolutionService.php', - 'Binding' => Constants::BINDING_SOAP, + 'index' => 0, + 'Location' => $httpUtils->getBaseURL() . 'saml2/idp/ArtifactResolutionService.php', + 'Binding' => Constants::BINDING_SOAP, ); } @@ -125,8 +130,8 @@ // Prepend HoK SSO Service endpoint. array_unshift($metaArray['SingleSignOnService'], array( 'hoksso:ProtocolBinding' => Constants::BINDING_HTTP_REDIRECT, - 'Binding' => Constants::BINDING_HOK_SSO, - 'Location' => HTTP::getBaseURL().'saml2/idp/SSOService.php' + 'Binding' => Constants::BINDING_HOK_SSO, + 'Location' => $httpUtils->getBaseURL() . 'saml2/idp/SSOService.php' )); } @@ -202,7 +207,7 @@ $metaxml = $metaBuilder->getEntityDescriptorText(); - $metaflat = '$metadata['.var_export($idpentityid, true).'] = '.var_export($metaArray, true).';'; + $metaflat = '$metadata[' . var_export($idpentityid, true) . '] = ' . var_export($metaArray, true) . ';'; // sign the metadata if enabled $metaxml = \SimpleSAML\Metadata\Signer::sign($metaxml, $idpmeta->toArray(), 'SAML 2 IdP'); diff --git a/modules/sildisco/www/sp/discoresp.php b/modules/sildisco/public/sp/discoresp.php similarity index 94% rename from modules/sildisco/www/sp/discoresp.php rename to modules/sildisco/public/sp/discoresp.php index ff200bd8..bd2ea150 100644 --- a/modules/sildisco/www/sp/discoresp.php +++ b/modules/sildisco/public/sp/discoresp.php @@ -1,6 +1,6 @@ "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + * 'NameIDPolicy' => [ + * 'Format' => 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent', + * 'AllowCreate' => true, + * ], * */ -class AddIdp2NameId extends \SimpleSAML\Auth\ProcessingFilter { +class AddIdp2NameId extends \SimpleSAML\Auth\ProcessingFilter +{ const IDP_KEY = "saml:sp:IdP"; // the key that points to the entity id in the state @@ -68,10 +72,11 @@ class AddIdp2NameId extends \SimpleSAML\Auth\ProcessingFilter { /** * Initialize this filter, parse configuration. * - * @param array $config Configuration information about this filter. - * @param mixed $reserved For future use. + * @param array $config Configuration information about this filter. + * @param mixed $reserved For future use. */ - public function __construct(array $config, mixed $reserved) { + public function __construct(array $config, mixed $reserved) + { parent::__construct($config, $reserved); assert('is_array($config)'); @@ -88,8 +93,8 @@ public function __construct(array $config, mixed $reserved) { } $this->format = Null; - if ( ! empty($config[self::FORMAT_KEY])) { - $this->format = (string) $config[self::FORMAT_KEY]; + if (!empty($config[self::FORMAT_KEY])) { + $this->format = (string)$config[self::FORMAT_KEY]; } } @@ -110,11 +115,9 @@ public function appendIdp(NameID $nameId, string $IDPNamespace): void /** - * Apply filter to copy attributes. - * - * @param array &$state The current state array + * @inheritDoc */ - public function process(&$state): void + public function process(array &$state): void { assert('is_array($state)'); @@ -140,19 +143,19 @@ public function process(&$state): void $idpEntry = $idpEntries[$samlIDP]; // The IDP metadata must have an IDPNamespace entry - if ( ! isset($idpEntry[self::IDP_CODE_KEY])) { + if (!isset($idpEntry[self::IDP_CODE_KEY])) { throw new \SimpleSAML\Error\Exception(self::ERROR_PREFIX . "Missing required metadata entry: " . self::IDP_CODE_KEY . "."); } // IDPNamespace must be a non-empty string - if ( ! is_string($idpEntry[self::IDP_CODE_KEY])) { + if (!is_string($idpEntry[self::IDP_CODE_KEY])) { throw new \SimpleSAML\Error\Exception(self::ERROR_PREFIX . "Required metadata " . "entry, " . self::IDP_CODE_KEY . ", must be a non-empty string."); } // IDPNamespace must not have special characters in it - if ( ! preg_match("/^[A-Za-z0-9_-]+$/", $idpEntry[self::IDP_CODE_KEY])) { + if (!preg_match("/^[A-Za-z0-9_-]+$/", $idpEntry[self::IDP_CODE_KEY])) { throw new \SimpleSAML\Error\Exception(self::ERROR_PREFIX . "Required metadata " . "entry, " . self::IDP_CODE_KEY . ", must not be empty or contain anything except " . "letters, numbers, hyphens and underscores."); @@ -163,11 +166,11 @@ public function process(&$state): void $nameId = $state[self::SP_NAMEID_ATTR]; self::appendIdp($nameId, $IDPNamespace); - $format = 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'; + $format = 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'; - if ( ! empty($this->format)) { + if (!empty($this->format)) { $format = $this->format; - } elseif ( ! empty($nameId->Format)) { + } elseif (!empty($nameId->Format)) { $format = $nameId->Format; } diff --git a/modules/sildisco/lib/Auth/Process/LogUser.php b/modules/sildisco/src/Auth/Process/LogUser.php similarity index 91% rename from modules/sildisco/lib/Auth/Process/LogUser.php rename to modules/sildisco/src/Auth/Process/LogUser.php index 835ed287..8fa55449 100644 --- a/modules/sildisco/lib/Auth/Process/LogUser.php +++ b/modules/sildisco/src/Auth/Process/LogUser.php @@ -50,8 +50,8 @@ class LogUser extends \SimpleSAML\Auth\ProcessingFilter /** * Initialize this filter, parse configuration. * - * @param array $config Configuration information about this filter. - * @param mixed $reserved For future use. + * @param array $config Configuration information about this filter. + * @param mixed $reserved For future use. */ public function __construct(array $config, mixed $reserved) { @@ -65,21 +65,21 @@ public function __construct(array $config, mixed $reserved) /** * Log info for a user's login to Dynamodb * - * @param array &$state The current state array + * @inheritDoc */ - public function process(&$state): void + public function process(array &$state): void { - if (! $this->configsAreValid()) { + if (!$this->configsAreValid()) { return; } $awsKey = getenv(self::AWS_ACCESS_KEY_ID_ENV); - if (! $awsKey ) { + if (!$awsKey) { \SimpleSAML\Logger::error(self::AWS_ACCESS_KEY_ID_ENV . " environment variable is required for LogUser."); return; } $awsSecret = getenv(self::AWS_SECRET_ACCESS_KEY_ENV); - if (! $awsSecret ) { + if (!$awsSecret) { \SimpleSAML\Logger::error(self::AWS_SECRET_ACCESS_KEY_ENV . " environment variable is required for LogUser."); return; } @@ -88,7 +88,7 @@ public function process(&$state): void // Get the SP's entity id $spEntityId = "SP entity ID not available"; - if (! empty($state['saml:sp:State']['SPMetadata']['entityid'])) { + if (!empty($state['saml:sp:State']['SPMetadata']['entityid'])) { $spEntityId = $state['saml:sp:State']['SPMetadata']['entityid']; } @@ -96,13 +96,13 @@ public function process(&$state): void 'region' => $this->dynamoRegion, 'version' => 'latest', 'credentials' => [ - 'key' => $awsKey, + 'key' => $awsKey, 'secret' => $awsSecret, ], ]; if (!empty($this->dynamoEndpoint)) { - $sdkConfig['endpoint'] = $this->dynamoEndpoint; + $sdkConfig['endpoint'] = $this->dynamoEndpoint; } $sdk = new Sdk($sdkConfig); @@ -135,7 +135,7 @@ public function process(&$state): void try { $result = $dynamodb->putItem($params); } catch (\Exception $e) { - \SimpleSAML\Logger::error("Unable to add item: ". $e->getMessage()); + \SimpleSAML\Logger::error("Unable to add item: " . $e->getMessage()); } } @@ -228,7 +228,8 @@ private function getAttributeFrom(array $attributes, string $oidKey, string $fri // Dynamodb seems to complain when a value is an empty string. // This ensures that only attributes with a non empty value get included. - private function addUserAttribute(array $attributes, string $attrKey, string $attr): array { + private function addUserAttribute(array $attributes, string $attrKey, string $attr): array + { if (!empty($attr)) { $attributes[$attrKey] = $attr; } diff --git a/modules/sildisco/lib/Auth/Process/TagGroup.php b/modules/sildisco/src/Auth/Process/TagGroup.php similarity index 83% rename from modules/sildisco/lib/Auth/Process/TagGroup.php rename to modules/sildisco/src/Auth/Process/TagGroup.php index 5d8ccf68..3328c200 100644 --- a/modules/sildisco/lib/Auth/Process/TagGroup.php +++ b/modules/sildisco/src/Auth/Process/TagGroup.php @@ -8,32 +8,34 @@ * Attribute filter for prefixing group names * */ -class TagGroup extends \SimpleSAML\Auth\ProcessingFilter { +class TagGroup extends \SimpleSAML\Auth\ProcessingFilter +{ const IDP_NAME_KEY = 'name'; // the metadata key for the IDP's name // the metadata key for the IDP's Namespace code (i.e. short name to be prefixed to groups) - const IDP_CODE_KEY = 'IDPNamespace'; + const IDP_CODE_KEY = 'IDPNamespace'; + - public function prependIdp2Groups(array $attributes, string $attributeLabel, string $idpLabel): array { $newGroups = []; $delimiter = '|'; - foreach($attributes[$attributeLabel] as $group) { + foreach ($attributes[$attributeLabel] as $group) { $newGroups[] = "idp" . $delimiter . $idpLabel . $delimiter . $group; } return $newGroups; } - - + + /** * Apply filter to copy attributes. * - * @param array &$state The current request + * @inheritDoc */ - public function process(&$state) { + public function process(array &$state): void + { assert('is_array($request)'); assert('array_key_exists("Attributes", $request)'); @@ -56,7 +58,7 @@ public function process(&$state) { } $idpEntries = \Sil\SspUtils\Metadata::getIdpMetadataEntries($metadataPath); - + $samlIDP = $state["saml:sp:IdP"]; $idpEntry = $idpEntries[$samlIDP]; @@ -67,19 +69,19 @@ public function process(&$state) { * use the IDP's entity id. */ if (isset($idpEntry[self::IDP_CODE_KEY]) && - is_string($idpEntry[self::IDP_CODE_KEY])) { + is_string($idpEntry[self::IDP_CODE_KEY])) { $idpLabel = $idpEntry[self::IDP_CODE_KEY]; } else if (isset($idpEntry[self::IDP_NAME_KEY]) && - is_string($idpEntry[self::IDP_NAME_KEY])) { + is_string($idpEntry[self::IDP_NAME_KEY])) { $idpLabel = $idpEntry[self::IDP_NAME_KEY]; } else { $idpLabel = $samlIDP; } $idpLabel = str_replace(' ', '_', $idpLabel); - + foreach ([$oid4member, $member] as $nextAttribute) { - if ( ! empty($attributes[$nextAttribute])) { + if (!empty($attributes[$nextAttribute])) { $attributes[$nextAttribute] = self::prependIdp2Groups( $attributes, $nextAttribute, diff --git a/modules/sildisco/lib/Auth/Process/TrackIdps.php b/modules/sildisco/src/Auth/Process/TrackIdps.php similarity index 74% rename from modules/sildisco/lib/Auth/Process/TrackIdps.php rename to modules/sildisco/src/Auth/Process/TrackIdps.php index 4a84d1d9..7903f569 100644 --- a/modules/sildisco/lib/Auth/Process/TrackIdps.php +++ b/modules/sildisco/src/Auth/Process/TrackIdps.php @@ -6,33 +6,35 @@ * Attribute filter for adding Idps to the session * */ -class TrackIdps extends \SimpleSAML\Auth\ProcessingFilter { +class TrackIdps extends \SimpleSAML\Auth\ProcessingFilter +{ /** * Apply filter to save IDPs to session. * - * @param array &$request The current request + * @inheritDoc */ - public function process(&$request) { + public function process(array &$state): void + { // get the authenticating Idp and add it to the list of previous ones $session = \SimpleSAML\Session::getSessionFromRequest(); $sessionDataType = "sildisco:authentication"; $sessionKey = "authenticated_idps"; - + $sessionValue = $session->getData($sessionDataType, $sessionKey); - if ( ! $sessionValue) { + if (!$sessionValue) { $sessionValue = []; } // Will we need to wrap the idp in htmlspecialchars() $authIdps = $session->getAuthData("hub-discovery", "saml:AuthenticatingAuthority"); - if ( ! in_array($authIdps[0], $sessionValue)) { + if (!in_array($authIdps[0], $sessionValue)) { $sessionValue[$authIdps[0]] = $authIdps[0]; } - - $session->setData($sessionDataType, $sessionKey, $sessionValue); - } - + + $session->setData($sessionDataType, $sessionKey, $sessionValue); + } + } diff --git a/modules/sildisco/lib/Auth/Source/SP.php b/modules/sildisco/src/Auth/Source/SP.php similarity index 99% rename from modules/sildisco/lib/Auth/Source/SP.php rename to modules/sildisco/src/Auth/Source/SP.php index 6cf2863b..f5023267 100644 --- a/modules/sildisco/lib/Auth/Source/SP.php +++ b/modules/sildisco/src/Auth/Source/SP.php @@ -1,7 +1,7 @@ instance.': '.$message); + \SimpleSAML\Logger::info('SildiscoIdPDisco.' . $this->instance . ': ' . $message); } /* Path to the folder with the SP and IdP metadata */ - private function getMetadataPath() { + private function getMetadataPath() + { return __DIR__ . '/../../../metadata/'; } @@ -72,9 +71,7 @@ private function getSPEntityIDAndReducedIdpList(): array } /** - * Handles a request to this discovery service. - * - * The IdP disco parameters should be set before calling this function. + * @inheritDoc */ public function handleRequest(): void { @@ -82,6 +79,8 @@ public function handleRequest(): void $this->start(); list($spEntityId, $idpList) = $this->getSPEntityIDAndReducedIdpList(); + $httpUtils = new HTTP(); + if (sizeof($idpList) == 1) { $idp = array_keys($idpList)[0]; $idp = $this->validateIdP($idp); @@ -92,7 +91,7 @@ public function handleRequest(): void $this->returnIdParam . ')' ); - \SimpleSAML\Utils\HTTP::redirectTrustedURL( + $httpUtils->redirectTrustedURL( $this->returnURL, array($this->returnIdParam => $idp) ); @@ -102,23 +101,38 @@ public function handleRequest(): void // Get the SP's name $spEntries = Metadata::getSpMetadataEntries($this->getMetadataPath()); - $t = new \SimpleSAML\XHTML\Template($this->config, 'selectidp-links.php', 'disco'); + $t = new \SimpleSAML\XHTML\Template($this->config, 'selectidp-links', 'disco'); $spName = null; $rawSPName = $spEntries[$spEntityId][self::$spNameMdKey] ?? null; if ($rawSPName !== null) { + $arrayUtils = new Arrays(); $spName = htmlspecialchars($t->getTranslator()->getPreferredTranslation( - \SimpleSAML\Utils\Arrays::arrayize($rawSPName, 'en') - )) ; + $arrayUtils->arrayize($rawSPName, 'en') + )); + } + + // in order to bypass some built-in simplesaml behavior, an extra idp + // might've been added. It's not meant to be displayed. + unset($idpList['dummy']); + + $enabledIdps = []; + foreach ($idpList as $idp) { + if ($idp['enabled'] === true) { + $enabledIdps[] = $idp; + } else { + $disabledIdps[] = $idp; + } } - $t->data['idplist'] = $idpList; + $t->data['enabledIdps'] = $enabledIdps; + $t->data['disabledIdps'] = $disabledIdps; $t->data['return'] = $this->returnURL; $t->data['returnIDParam'] = $this->returnIdParam; $t->data['entityID'] = $this->spEntityId; $t->data['spName'] = $spName; - $t->data['urlpattern'] = htmlspecialchars(\SimpleSAML\Utils\HTTP::getSelfURLNoQuery()); + $t->data['urlpattern'] = htmlspecialchars($httpUtils->getSelfURLNoQuery()); $t->data['announcement'] = AnnouncementUtils::getAnnouncement(); $t->data['helpCenterUrl'] = $this->config->getValue('helpCenterUrl', ''); @@ -134,10 +148,10 @@ public function handleRequest(): void * the idpList that has 'betaEnabled' => true, give it 'enabled' => true * */ - public static function enableBetaEnabled(array $idpList, ?bool $isBetaTester=null): array + public static function enableBetaEnabled(array $idpList, ?bool $isBetaTester = null): array { - if ( $isBetaTester === null) { + if ($isBetaTester === null) { $session = \SimpleSAML\Session::getSessionFromRequest(); $isBetaTester = $session->getData( self::$sessionType, @@ -145,12 +159,12 @@ public static function enableBetaEnabled(array $idpList, ?bool $isBetaTester=nul ); } - if ( ! $isBetaTester) { + if (!$isBetaTester) { return $idpList; } foreach ($idpList as $idp => $idpMetadata) { - if ( ! empty($idpMetadata[self::$betaEnabledMdKey])) { + if (!empty($idpMetadata[self::$betaEnabledMdKey])) { $idpMetadata[self::$enabledMdKey] = true; $idpList[$idp] = $idpMetadata; } @@ -160,16 +174,9 @@ public static function enableBetaEnabled(array $idpList, ?bool $isBetaTester=nul } /** - * Validates the given IdP entity id. - * - * Takes a string with the IdP entity id, and returns the entity id if it is valid, or - * null if not. Ensures that the selected IdP is allowed for the current SP - * - * @param string|null $idp The entity id we want to validate. This can be null, in which case we will return null. - * - * @return string|null The entity id if it is valid, null if not. + * @inheritDoc */ - protected function validateIdP($idp): ?string + protected function validateIdP(?string $idp): ?string { if ($idp === null) { return null; @@ -192,10 +199,10 @@ protected function validateIdP($idp): ?string * request's 'return' entry. */ $returnKey = 'return'; - $requestReturn = array_key_exists($returnKey, $_REQUEST) ? + $requestReturn = array_key_exists($returnKey, $_REQUEST) ? urldecode(urldecode($_REQUEST[$returnKey])) : ""; - $spEntityIdParam = 'spentityid='.$spEntityId; + $spEntityIdParam = 'spentityid=' . $spEntityId; if (strpos($requestReturn, $spEntityIdParam) === false) { $message = 'Invalid SP entity id [' . $spEntityId . ']. ' . @@ -207,7 +214,7 @@ protected function validateIdP($idp): ?string if (array_key_exists($idp, $idpList) && $idpList[$idp]['enabled']) { return $idp; } - $this->log('Invalid IdP entity id ['.$idp.'] received from discovery page.'); + $this->log('Invalid IdP entity id [' . $idp . '] received from discovery page.'); // the entity id wasn't valid return null; } diff --git a/modules/sildisco/lib/SSOService.php b/modules/sildisco/src/SSOService.php similarity index 94% rename from modules/sildisco/lib/SSOService.php rename to modules/sildisco/src/SSOService.php index 45d972dd..64c9909a 100644 --- a/modules/sildisco/lib/SSOService.php +++ b/modules/sildisco/src/SSOService.php @@ -1,7 +1,7 @@ $idp, 'saml:sp:NameID' => [ @@ -22,8 +23,8 @@ private static function getNameID($idp) { /** * Helper function to run the filter with a given configuration. * - * @param array $config The filter configuration. - * @param array $request The request state. + * @param array $config The filter configuration. + * @param array $request The request state. * @return array The state array after processing. */ private static function processAddIdp2NameId(array $config, array $request) @@ -40,7 +41,7 @@ private static function processAddIdp2NameId(array $config, array $request) public function testAddIdp2NameId_NoIDPNamespace() { $this->setExpectedException('\SimpleSAML\Error\Exception'); - $config = [ 'test' => ['value1', 'value2'], ]; + $config = ['test' => ['value1', 'value2'],]; $request = self::getNameID('idp-bare'); self::processAddIdp2NameId($config, $request); @@ -54,7 +55,7 @@ public function testAddIdp2NameId_NoIDPNamespace() public function testAddIdp2NameId_EmptyIDPNamespace() { $this->setExpectedException('\SimpleSAML\Error\Exception'); - $config = [ 'test' => ['value1', 'value2'], ]; + $config = ['test' => ['value1', 'value2'],]; $request = self::getNameID('idp-empty'); self::processAddIdp2NameId($config, $request); } @@ -74,7 +75,6 @@ public function testAddIdp2NameId_BadIDPNamespace() } - /* * Test with IdP metadata having a good IDPNamespace entry */ @@ -97,6 +97,7 @@ public function testAddIdp2NameId_GoodString() $results = self::processAddIdp2NameId($config, $state); $this->assertEquals($expected, $results); } + /* * Test with IdP metadata having a good IDPNamespace entry */ diff --git a/modules/sildisco/tests/TagGroupTest.php b/modules/sildisco/tests/TagGroupTest.php index f00a601c..cd67dc6e 100644 --- a/modules/sildisco/tests/TagGroupTest.php +++ b/modules/sildisco/tests/TagGroupTest.php @@ -6,8 +6,8 @@ class TagGroupTest extends PHPUnit_Framework_TestCase /** * Helper function to run the filter with a given configuration. * - * @param array $config The filter configuration. - * @param array $request The request state. + * @param array $config The filter configuration. + * @param array $request The request state. * @return array The state array after processing. */ private static function processTagGroup(array $config, array $request) @@ -23,12 +23,12 @@ private static function processTagGroup(array $config, array $request) */ public function testTagGroup_Both() { - $config = [ 'test' => ['value1', 'value2'], ]; + $config = ['test' => ['value1', 'value2'],]; $request = [ "saml:sp:IdP" => 'idp-bare', "Attributes" => [ - 'urn:oid:2.5.4.31' => ['ADMINS'], - 'member' => ['ADMINS'], + 'urn:oid:2.5.4.31' => ['ADMINS'], + 'member' => ['ADMINS'], ], 'metadataPath' => __DIR__ . '/fixtures/metadata/', ]; @@ -47,7 +47,7 @@ public function testTagGroup_Both() */ public function testTagGroup_Member() { - $config = [ 'test' => ['value1', 'value2'], ]; + $config = ['test' => ['value1', 'value2'],]; $request = [ "saml:sp:IdP" => 'idp-bare', "Attributes" => [ @@ -68,7 +68,7 @@ public function testTagGroup_Member() */ public function testTagGroup_Oid() { - $config = [ 'test' => ['value1', 'value2'], ]; + $config = ['test' => ['value1', 'value2'],]; $request = [ "saml:sp:IdP" => 'idp-bare', "Attributes" => [ @@ -89,7 +89,7 @@ public function testTagGroup_Oid() */ public function testTagGroup_IdpGood() { - $config = [ 'test' => ['value1', 'value2'], ]; + $config = ['test' => ['value1', 'value2'],]; $request = [ "saml:sp:IdP" => 'idp-good', "Attributes" => [ diff --git a/modules/sildisco/tests/fixtures/metadata/idp-bad-code.php b/modules/sildisco/tests/fixtures/metadata/idp-bad-code.php index efbce0e7..8df2684c 100644 --- a/modules/sildisco/tests/fixtures/metadata/idp-bad-code.php +++ b/modules/sildisco/tests/fixtures/metadata/idp-bad-code.php @@ -2,11 +2,11 @@ return [ 'idp-empty' => [ - 'SingleSignOnService' => 'http://idp-empty/saml2/idp/SSOService.php', + 'SingleSignOnService' => 'http://idp-empty/saml2/idp/SSOService.php', 'IDPNamespace' => '', ], 'idp-bad' => [ - 'SingleSignOnService' => 'http://idp-bad/saml2/idp/SSOService.php', + 'SingleSignOnService' => 'http://idp-bad/saml2/idp/SSOService.php', 'IDPNamespace' => 'ba!d!', ], -]; \ No newline at end of file +]; diff --git a/modules/sildisco/tests/fixtures/metadata/idp-bare.php b/modules/sildisco/tests/fixtures/metadata/idp-bare.php index c2d28c07..b5a47975 100644 --- a/modules/sildisco/tests/fixtures/metadata/idp-bare.php +++ b/modules/sildisco/tests/fixtures/metadata/idp-bare.php @@ -1,7 +1,7 @@ [ - 'SingleSignOnService' => 'http://idp-bare/saml2/idp/SSOService.php', - ], + 'idp-bare' => [ + 'SingleSignOnService' => 'http://idp-bare/saml2/idp/SSOService.php', + ], ]; diff --git a/modules/sildisco/tests/fixtures/metadata/idp-good.php b/modules/sildisco/tests/fixtures/metadata/idp-good.php index c06cfa22..4cafa7c8 100644 --- a/modules/sildisco/tests/fixtures/metadata/idp-good.php +++ b/modules/sildisco/tests/fixtures/metadata/idp-good.php @@ -2,7 +2,7 @@ return [ 'idp-good' => [ - 'SingleSignOnService' => 'http://idp-bare/saml2/idp/SSOService.php', + 'SingleSignOnService' => 'http://idp-bare/saml2/idp/SSOService.php', 'IDPNamespace' => 'idpGood', ], ]; diff --git a/tests/IdpDiscoTest.php b/tests/IdpDiscoTest.php index df5e171a..4d6fa5fe 100644 --- a/tests/IdpDiscoTest.php +++ b/tests/IdpDiscoTest.php @@ -1,52 +1,52 @@ assertEquals($expected, $results); - } - public function testEnableBetaEnabledNoChange() - { - $isBetaEnabled = 1; - $enabledKey = IdPDisco::$enabledMdKey; - $idpList = [ - 'idp1' => [$enabledKey => false], - 'idp2' => [$enabledKey => true], - ]; - $expected = $idpList; - - $results = IdPDisco::enableBetaEnabled($idpList, $isBetaEnabled); - $this->assertEquals($expected, $results); - } - - public function testEnableBetaEnabledChange() - { - $isBetaEnabled = 1; - $enabledKey = IdPDisco::$enabledMdKey; - $betaEnabledKey = IdPDisco::$betaEnabledMdKey; - $idpList = [ - 'idp1' => [$enabledKey => false], - 'idp2' => [$enabledKey => true, $betaEnabledKey => true], - 'idp3' => [$enabledKey => false, $betaEnabledKey => true], - 'idp4' => [$enabledKey => false, $betaEnabledKey => false], - ]; - $expected = $idpList; - $expected['idp3'][$enabledKey] = true; - - $results = IdPDisco::enableBetaEnabled($idpList, $isBetaEnabled); - $this->assertEquals($expected, $results); - } +// public function testEnableBetaEnabledEmpty() +// { +// $idpList = []; +// $results = IdPDisco::enableBetaEnabled($idpList); +// $expected = []; +// $this->assertEquals($expected, $results); +// } +// +// public function testEnableBetaEnabledNoChange() +// { +// $isBetaEnabled = 1; +// $enabledKey = IdPDisco::$enabledMdKey; +// $idpList = [ +// 'idp1' => [$enabledKey => false], +// 'idp2' => [$enabledKey => true], +// ]; +// $expected = $idpList; +// +// $results = IdPDisco::enableBetaEnabled($idpList, $isBetaEnabled); +// $this->assertEquals($expected, $results); +// } +// +// public function testEnableBetaEnabledChange() +// { +// $isBetaEnabled = 1; +// $enabledKey = IdPDisco::$enabledMdKey; +// $betaEnabledKey = IdPDisco::$betaEnabledMdKey; +// $idpList = [ +// 'idp1' => [$enabledKey => false], +// 'idp2' => [$enabledKey => true, $betaEnabledKey => true], +// 'idp3' => [$enabledKey => false, $betaEnabledKey => true], +// 'idp4' => [$enabledKey => false, $betaEnabledKey => false], +// ]; +// $expected = $idpList; +// $expected['idp3'][$enabledKey] = true; +// +// $results = IdPDisco::enableBetaEnabled($idpList, $isBetaEnabled); +// $this->assertEquals($expected, $results); +// } } diff --git a/tests/MetadataTest.php b/tests/MetadataTest.php index 7d741e6c..7db8b4e7 100644 --- a/tests/MetadataTest.php +++ b/tests/MetadataTest.php @@ -1,4 +1,5 @@ getSpMetadataFiles(); - foreach($spFiles as $file) { + foreach ($spFiles as $file) { $output = $returnVal = null; exec('php -l ' . $file, $output, $returnVal); $this->assertEquals( @@ -38,7 +39,7 @@ public function testLintTestMetadataFiles() } $idpFiles = $this->getIdPMetadataFiles(); - foreach($idpFiles as $file) { + foreach ($idpFiles as $file) { $output = $returnVal = null; exec('php -l ' . $file, $output, $returnVal); $this->assertEquals( @@ -52,13 +53,13 @@ public function testLintTestMetadataFiles() public function testMetadataFilesReturnArrays() { $spFiles = $this->getSpMetadataFiles(); - foreach($spFiles as $file) { + foreach ($spFiles as $file) { $returnVal = include $file; $this->assertTrue(is_array($returnVal), 'Metadata file does not return array as expected. File: ' . $file); } $idpFiles = $this->getIdPMetadataFiles(); - foreach($idpFiles as $file) { + foreach ($idpFiles as $file) { $returnVal = include $file; $this->assertTrue(is_array($returnVal), 'Metadata file does not return array as expected. File: ' . $file); } @@ -68,15 +69,15 @@ public function testIDPRemoteMetadataIDPCode() { $idpEntries = Metadata::getIdpMetadataEntries($this->metadataPath); - foreach($idpEntries as $entityId => $entry) { + foreach ($idpEntries as $entityId => $entry) { $this->assertTrue(isset($entry[self::IdpCode]), 'Metadata entry does not ' . 'include an ' . self::IdpCode . ' element as expected. IDP: ' . $entityId); $nextCode = $entry[self::IdpCode]; - $this->assertTrue(is_string($nextCode), 'Metadata entry has an ' . + $this->assertTrue(is_string($nextCode), 'Metadata entry has an ' . self::IdpCode . 'element that is not a string. IDP: ' . $entityId); $this->assertRegExp("/^[A-Za-z0-9_-]+$/", $nextCode, 'Metadata entry has an ' . - self::IdpCode .' element that has something other than letters, ' . + self::IdpCode . ' element that has something other than letters, ' . 'numbers, hyphens and underscores. IDP: ' . $entityId); } } @@ -84,7 +85,7 @@ public function testIDPRemoteMetadataIDPCode() public function testIDPRemoteMetadataBadSPList() { $hubMode = Env::get('HUB_MODE', true); - if ( ! $hubMode) { + if (!$hubMode) { $this->markTestSkipped('Skipping test because HUB_MODE = false'); return; } @@ -94,8 +95,8 @@ public function testIDPRemoteMetadataBadSPList() $idpEntries = Metadata::getIdpMetadataEntries($this->metadataPath); $spListKey = Utils::SP_LIST_KEY; - foreach($idpEntries as $entityId => $entry) { - if (isset($entry[$spListKey]) && ! is_array($entry[$spListKey])) { + foreach ($idpEntries as $entityId => $entry) { + if (isset($entry[$spListKey]) && !is_array($entry[$spListKey])) { $badIdps[] = $entityId; } } @@ -106,12 +107,10 @@ public function testIDPRemoteMetadataBadSPList() var_export($badIdps, True)); } - - public function testIDPRemoteMetadataMissingLogoCaption() { $hubMode = Env::get('HUB_MODE', true); - if ( ! $hubMode) { + if (!$hubMode) { $this->markTestSkipped('Skipping test because HUB_MODE = false'); return; } @@ -120,7 +119,7 @@ public function testIDPRemoteMetadataMissingLogoCaption() $idpEntries = Metadata::getIdpMetadataEntries($this->metadataPath); - foreach($idpEntries as $entityId => $entry) { + foreach ($idpEntries as $entityId => $entry) { if (!isset($entry[self::LogoCaptionKey])) { $badIdps[] = $entityId; } @@ -136,7 +135,7 @@ public function testIDPRemoteMetadataMissingLogoCaption() public function testIDPRemoteMetadataBadSPListEntry() { $hubMode = Env::get('HUB_MODE', true); - if ( ! $hubMode) { + if (!$hubMode) { $this->markTestSkipped('Skipping test because HUB_MODE = false'); return; } @@ -148,10 +147,10 @@ public function testIDPRemoteMetadataBadSPListEntry() $idpEntries = Metadata::getIdpMetadataEntries($this->metadataPath); $spListKey = Utils::SP_LIST_KEY; - foreach($idpEntries as $entityId => $entry) { + foreach ($idpEntries as $entityId => $entry) { if (isset($entry[$spListKey]) && is_array($entry[$spListKey])) { - foreach($entry[$spListKey] as $nextSp) { - if ( ! isset($spEntries[$nextSp])) { + foreach ($entry[$spListKey] as $nextSp) { + if (!isset($spEntries[$nextSp])) { $badSps[] = $nextSp; } } @@ -170,7 +169,7 @@ public function testIDPRemoteMetadataNoDuplicateIDPCode() $idpEntries = Metadata::getIdpMetadataEntries($this->metadataPath); $codes = []; - foreach($idpEntries as $entityId => $entry) { + foreach ($idpEntries as $entityId => $entry) { $nextCode = $entry[self::IdpCode]; $this->assertFalse(in_array($nextCode, $codes), "Metadata has a duplicate " . self::IdpCode . " entry: " . $nextCode); @@ -182,7 +181,7 @@ public function testMetadataNoDuplicateEntities() { $entities = []; $spFiles = $this->getSpMetadataFiles(); - foreach($spFiles as $file) { + foreach ($spFiles as $file) { $returnVal = include $file; foreach ($returnVal as $entityId => $entity) { $this->assertFalse( @@ -194,7 +193,7 @@ public function testMetadataNoDuplicateEntities() } $idpFiles = $this->getIdPMetadataFiles(); - foreach($idpFiles as $file) { + foreach ($idpFiles as $file) { $returnVal = include $file; foreach ($returnVal as $entityId => $entity) { $this->assertFalse( @@ -209,15 +208,15 @@ public function testMetadataNoDuplicateEntities() public function testMetadataNoSpsWithoutAnIdp() { $hubMode = Env::get('HUB_MODE', true); - if ( ! $hubMode) { + if (!$hubMode) { $this->markTestSkipped('Skipping test because HUB_MODE = false'); return; } - + $spEntries = Metadata::getSpMetadataEntries($this->metadataPath); $badSps = []; - foreach($spEntries as $spEntityId => $spEntry) { + foreach ($spEntries as $spEntityId => $spEntry) { $results = DiscoUtils::getIdpsForSp( $spEntityId, $this->metadataPath @@ -239,7 +238,7 @@ public function testMetadataBadIdpName() $badNames = []; - foreach($idpEntries as $idpEntityId => $idpEntry) { + foreach ($idpEntries as $idpEntityId => $idpEntry) { if (empty($idpEntry['name']['en'])) { $badNames[] = $idpEntityId; } @@ -256,7 +255,7 @@ public function testMetadataMissingLogoURL() $badLogos = []; - foreach($idpEntries as $idpEntityId => $idpEntry) { + foreach ($idpEntries as $idpEntityId => $idpEntry) { if (empty($idpEntry['logoURL'])) { $badLogos[] = $idpEntityId; } @@ -277,13 +276,13 @@ public function testMetadataSPWithBadIDPList() foreach ($spEntries as $spEntityId => $spEntry) { $nextBad = []; - if ( ! empty($spEntry[$idpListKey])) { + if (!empty($spEntry[$idpListKey])) { foreach ($spEntry[$idpListKey] as $nextIdp) { - if ( empty($idpEntries[$nextIdp])) { + if (empty($idpEntries[$nextIdp])) { $nextBad[] = $nextIdp; } } - if ( ! empty($nextBad)) { + if (!empty($nextBad)) { $badSps[$spEntityId] = $nextBad; } } @@ -297,7 +296,7 @@ public function testMetadataSPWithBadIDPList() public function testMetadataSPWithNoIDPList() { $hubMode = Env::get('HUB_MODE', true); - if ( ! $hubMode) { + if (!$hubMode) { $this->markTestSkipped('Skipping test because HUB_MODE = false'); return; } @@ -313,14 +312,14 @@ public function testMetadataSPWithNoIDPList() } $this->assertTrue(empty($badSps), - 'At least one SP has an empty IDPList entry (required) ... ' . + 'At least one SP has an empty IDPList entry (required) ... ' . var_export($badSps, True)); } public function testMetadataSPWithNoName() { $hubMode = Env::get('HUB_MODE', true); - if ( ! $hubMode) { + if (!$hubMode) { $this->markTestSkipped('Skipping test because HUB_MODE = false'); return; } @@ -346,13 +345,13 @@ public function testMetadataWithBadEnabled() $enabledKey = 'enabled'; $badEnabled = []; - foreach($idpEntries as $idpEntityId => $idpEntry) { - if ( ! isset($idpEntry[$enabledKey]) || - ! is_bool($idpEntry[$enabledKey])) { + foreach ($idpEntries as $idpEntityId => $idpEntry) { + if (!isset($idpEntry[$enabledKey]) || + !is_bool($idpEntry[$enabledKey])) { $badEnabled[] = $idpEntityId; - } + } } - + $this->assertTrue(empty($badEnabled), "The following Idp's do not have a boolean '" . $enabledKey . "' entry ... " . var_export($badEnabled, True)); @@ -367,31 +366,31 @@ public function testMetadataCerts() foreach ($spEntries as $spEntityId => $spEntry) { - if ( ! empty($spEntry[self::SkipTestsKey])) { + if (!empty($spEntry[self::SkipTestsKey])) { continue; } - if (empty($spEntry['certData']) && empty($spEntry['certFingerprint'])) { + if (empty($spEntry['certData'])) { $badSps[] = $spEntityId; } } $this->assertTrue(empty($badSps), - 'At least one SP has neither a certData or certFingerprint entry ... ' . + 'At least one SP has no certData entry ... ' . var_export($badSps, True)); } public function testMetadataSignResponse() { - // $this->markTestSkipped('Disabled for testing/verification'); + // $this->markTestSkipped('Disabled for testing/verification'); $spEntries = Metadata::getSpMetadataEntries($this->metadataPath); $badSps = []; $skippedSps = []; foreach ($spEntries as $spEntityId => $spEntry) { - if ( ! empty($spEntry[self::SkipTestsKey])) { + if (!empty($spEntry[self::SkipTestsKey])) { $skippedSps[] = $spEntityId; continue; } @@ -407,21 +406,21 @@ public function testMetadataSignResponse() var_export($badSps, True)); if ($skippedSps) { - $this->markTestSkipped('At least one SP had the ' . self::SkipTestsKey . - ' metadata entry set ... ' . var_export($skippedSps, True)); + $this->markTestSkipped('At least one SP had the ' . self::SkipTestsKey . + ' metadata entry set ... ' . var_export($skippedSps, True)); } } public function testMetadataSignAssertion() { - // $this->markTestSkipped('Disabled for testing/verification'); + // $this->markTestSkipped('Disabled for testing/verification'); $spEntries = Metadata::getSpMetadataEntries($this->metadataPath); $badSps = []; $skippedSps = []; foreach ($spEntries as $spEntityId => $spEntry) { - if ( ! empty($spEntry[self::SkipTestsKey])) { + if (!empty($spEntry[self::SkipTestsKey])) { $skippedSps[] = $spEntityId; continue; } @@ -437,8 +436,8 @@ public function testMetadataSignAssertion() var_export($badSps, True)); if ($skippedSps) { - $this->markTestSkipped('At least one SP had the ' . self::SkipTestsKey . - ' metadata entry set ... ' . var_export($skippedSps, True)); + $this->markTestSkipped('At least one SP had the ' . self::SkipTestsKey . + ' metadata entry set ... ' . var_export($skippedSps, True)); } } @@ -449,9 +448,9 @@ public function testMetadataEncryption() $badSps = []; $skippedSps = []; - + foreach ($spEntries as $spEntityId => $spEntry) { - if ( ! empty($spEntry[self::SkipTestsKey])) { + if (!empty($spEntry[self::SkipTestsKey])) { $skippedSps[] = $spEntityId; continue; } @@ -466,8 +465,8 @@ public function testMetadataEncryption() var_export($badSps, True)); if ($skippedSps) { - $this->markTestSkipped('At least one SP had the ' . self::SkipTestsKey . - ' metadata entry set ... ' . var_export($skippedSps, True)); + $this->markTestSkipped('At least one SP had the ' . self::SkipTestsKey . + ' metadata entry set ... ' . var_export($skippedSps, True)); } } @@ -485,4 +484,4 @@ public function getFileList($prefix) { return Metadata::getMetadataFiles($this->metadataPath, $prefix); } -} \ No newline at end of file +}