first commit

This commit is contained in:
2025-07-18 16:20:14 +07:00
commit 98af45c018
16382 changed files with 3148096 additions and 0 deletions

View File

@@ -0,0 +1,48 @@
`core:AttributeAdd`
===================
Filter that adds attributes to the user.
If the attribute already exists, the values added will be merged into a multi-valued attribute.
If you instead want to replace the existing attribute, you may add the `%replace` option.
Examples
--------
Add a single-valued attributes:
'authproc' => [
50 => [
'class' => 'core:AttributeAdd',
'source' => ['myidp'],
],
],
Add a multi-valued attribute:
'authproc' => [
50 => [
'class' => 'core:AttributeAdd',
'groups' => ['users', 'members'],
],
],
Add multiple attributes:
'authproc' => [
50 => [
'class' => 'core:AttributeAdd',
'eduPersonPrimaryAffiliation' => 'student',
'eduPersonAffiliation' => ['student', 'employee', 'members'],
],
],
Replace an existing attributes:
'authproc' => [
50 => [
'class' => 'core:AttributeAdd',
'%replace',
'uid' => ['guest'],
],
],

View File

@@ -0,0 +1,138 @@
`core:AttributeAlter`
=====================
This filter can be used to substitute and replace different parts of the attribute values based on regular expressions.
It can also be used to create new attributes based on existing values, or even to remove blacklisted values from
attributes.
Parameters
----------
`class`
: This is the name of the filter.
It must be `core:AttributeAlter`.
`subject` (required)
: The attribute in which the search is performed.
The filter will stop quietly if the attribute specified here is empty or not found.
`pattern` (required)
: The pattern to look for inside the subject. Supports full Perl Compatible Regular Expressions (PCRE).
`replacement`
: The value used to replace the match. Back references are not supported.
This parameter is *required*, except when using the `%replace` or `%remove` options. If `%replace` is used and
`replacement` is not set, then the match is used as a replacement.
`target`
: The attribute where the replaced value will be placed.
This parameter is *optional*, and if not set, `subject` is used as `target`.
`%replace`
: Indicates that the whole value of the attribute should be replaced if there is a match,
instead of just the match. If there's no match, the value will not be changed. This parameter is *optional*.
`%remove`
: Indicates that the whole value of the attribute should be removed completely if there is a match.
If no other values exist, the attribute will be removed completely.
This parameter is *optional*.
`%merge`
: Indicates whether the altered values must be merged with the target attribute values. The default
behaviour is to overwrite the target attribute completely.
This parameter is *optional*.
Examples
--------
Change the domain on the `mail` attribute (when both the new and old domain are known):
10 => [
'class' => 'core:AttributeAlter',
'subject' => 'mail',
'pattern' => '/olddomain.com/',
'replacement' => 'newdomain.com',
],
Change the domain on the `mail` attribute (when new domain is known):
10 => [
'class' => 'core:AttributeAlter',
'subject' => 'mail',
'pattern' => '/(?:[A-Za-z0-9-]+\.)+[A-Za-z]{2,6}$/',
'replacement' => 'newdomain.com',
],
Set the eduPersonPrimaryAffiliation based on users' distinguishedName:
10 => [
'class' => 'core:AttributeAlter',
'subject' => 'dn',
'pattern' => '/OU=Staff/',
'replacement' => 'staff',
'target' => 'eduPersonPrimaryAffiliation',
],
Normalize the eduPersonPrimaryAffiliation:
10 => [
'class' => 'core:AttributeAlter',
'subject' => 'eduPersonPrimaryAffiliation',
'pattern' => '/Student in school/',
'replacement' => 'student',
'%replace',
],
Get the domain of the emailaddress and put it in a separate attribute:
10 => [
'class' => 'core:AttributeAlter',
'subject' => 'mail',
'pattern' => '/(?:[A-Za-z0-9-]+\.)+[A-Za-z]{2,6}$/',
'target' => 'domain',
'%replace',
],
Defaulting an attribute to one value (add it with the default before altering)
unless another attribute meets a condition:
10 => [
'class' => 'core:AttributeAdd',
'myAttribute' => 'default-value'
],
11 => [
'class' => 'core:AttributeAlter',
'subject' => 'entitlement',
'pattern' => '/faculty/',
'target' => 'myAttribute',
'%replace',
],
Remove internal, private values from eduPersonEntitlement:
10 => [
'class' => 'core:AttributeAlter',
'subject' => 'eduPersonEntitlement',
'pattern' => '/ldap-admin/',
'%remove',
],
Set a value to be blank (which will be sent as an empty string):
10 => [
'class' => 'core:AttributeAlter',
'subject' => 'cn',
'pattern' => '/No name/',
'replacement' => '',
'%replace',
],
Set a value to be NULL (which will be sent as a NULL value):
10 => [
'class' => 'core:AttributeAlter',
'subject' => 'telephone',
'pattern' => '/NULL/',
'replacement' => null,
'%replace',
],

View File

@@ -0,0 +1,25 @@
`core:AttributeCopy`
====================
Filter that copies attributes.
Examples
--------
Copy a single attribute (user's `uid` will be copied to the user's `username`):
'authproc' => [
50 => [
'class' => 'core:AttributeCopy',
'uid' => 'username',
],
],
Copy a single attribute to more than one attribute (user's `uid` will be copied to the user's `username` and to `urn:mace:dir:attribute-def:uid`)
'authproc' => [
50 => [
'class' => 'core:AttributeCopy',
'uid' => ['username', 'urn:mace:dir:attribute-def:uid'],
],
],

View File

@@ -0,0 +1,137 @@
`core:AttributeLimit`
=====================
A filter that limits the attributes (and their values) sent to a service provider.
If the configuration is empty, the filter will use the attributes configured in the `attributes` option in the SP
metadata. The configuration is a list of attributes that should be allowed. In case you want to limit an attribute to
release some specific values, make the name of the attribute the key of the array, and its value an array with all the
different values allowed for it.
Examples
--------
Here you will find a few examples on how to use this simple module:
Limit to the `cn` and `mail` attribute:
'authproc' => [
50 => [
'class' => 'core:AttributeLimit',
'cn', 'mail'
],
],
Allow `eduPersonTargetedID` and `eduPersonAffiliation` by default, but allow the metadata to override the limitation.
'authproc' => [
50 => [
'class' => 'core:AttributeLimit',
'default' => true,
'eduPersonTargetedID', 'eduPersonAffiliation',
],
],
Only allow specific values for an attribute.
'authproc' => [
50 => [
'class' => 'core:AttributeLimit',
'eduPersonEntitlement' => ['urn:mace:surf.nl:surfdrive:quota:100']
],
],
Only allow specific values for an attribute ignoring case.
'authproc' => [
50 => [
'class' => 'core:AttributeLimit',
'eduPersonEntitlement' => [
'ignoreCase' => true,
'URN:mace:surf.nl:SURFDRIVE:quota:100'
]
],
],
Only allow attributes that match a regex pattern
'authproc' => [
50 => [
'class' => 'core:AttributeLimit',
'/^eduPerson' => [ 'nameIsRegex' => true ]
],
],
Only allow specific values for an attribute that match a regex pattern
'authproc' => [
50 => [
'class' => 'core:AttributeLimit',
'eduPersonEntitlement' => [
'regex' => true,
'/^urn:mace:surf/',
'/^urn:x-IGNORE_Case/i',
]
],
],
Don't allow any attributes by default, but allow the metadata to override it.
'authproc' => [
50 => [
'class' => 'core:AttributeLimit',
'default' => true,
],
],
In order to just use the list of attributes defined in the metadata for each service provider, configure the module
like this:
'authproc' => [
50 => 'core:AttributeLimit',
],
Then, add the allowed attributes to each service provider metadata, in the `attributes` option (for exact matches) or `attributesRegex` (for regular expression matches):
$metadata['https://saml2sp.example.org'] = [
'AssertionConsumerService' => 'https://saml2sp.example.org/simplesaml/module.php/saml/sp/saml2-acs.php/default-sp',
'SingleLogoutService' => 'https://saml2sp.example.org/simplesaml/module.php/saml/sp/saml2-logout.php/default-sp',
...
'attributes' => ['cn', ... ],
'attributesRegex' => [ '/^mail$/', ... ],
...
];
Now, let's look to a couple of examples on how to filter out attribute values. First, allow only the entitlements known
to be used by a service provider (among other attributes):
$metadata['https://saml2sp.example.org'] = [
'AssertionConsumerService' => 'https://saml2sp.example.org/simplesaml/module.php/saml/sp/saml2-acs.php/default-sp',
'SingleLogoutService' => 'https://saml2sp.example.org/simplesaml/module.php/saml/sp/saml2-logout.php/default-sp',
...
'attributes' => [
'uid',
'mail',
'eduPersonEntitlement' => [
'urn:mace:example.org:admin',
'urn:mace:example.org:user',
],
],
...
];
Now, an example on how to normalize the affiliations sent from an identity provider, to make sure that no custom
values ever reach the service providers. Bear in mind that this configuration can be overridden by metadata:
'authproc' => [
50 => 'core:AttributeLimit',
'default' => true,
'eduPersonAffiliation' => [
'student',
'staff',
'member',
'faculty',
'employee',
'affiliate',
],
],

View File

@@ -0,0 +1,57 @@
`core:AttributeMap`
===================
Filter to change attribute names.
This filter can either contain the name of a map file or a set of name => value pairs describing the transformation.
If configuration references a map file, the file must be located in the `attributemap/` directory in the root of
SimpleSAMLphp's installation. Attribute map files located in the `attributemap/` directory in the root of a module can
also be used by specifying the file with the `module:file` syntax.
It can also create multiple attributes from a single attribute by specifying multiple target attributes as an array.
Examples
--------
Attribute maps embedded as parameters:
'authproc' => [
50 => [
'class' => 'core:AttributeMap',
'mail' => 'email',
'uid' => 'user'
'cn' => ['name', 'displayName'],
],
],
Attribute map in separate file:
'authproc' => [
50 => [
'class' => 'core:AttributeMap',
'name2oid',
],
],
This filter will use the map file from `simplesamlphp/attributemap/name2oid.php`.
Attribute map in a file contained in a module:
'authproc' => [
50 => [
'class' => 'core:AttributeMap',
'module:src2dst'
],
],
This filter will use the map file from `simplesamlphp/modules/module/attributemap/src2dst.php`.
Duplicate attributes based on a map file:
'authproc' => [
50 => [
'class' => 'core:AttributeMap',
'name2urn', 'name2oid',
'%duplicate',
],
],

View File

@@ -0,0 +1,86 @@
# `core:AttributeValueMap`
Filter that creates a target attribute based on one or more value(s) in source attribute.
Besides the mapping of source values to target values, the filter has the following options:
* `%replace` can be used to replace all existing values in target with new ones (any existing values will be lost)
* `%keep` can be used to keep the source attribute, otherwise it will be removed.
**Examples**:
## Add student affiliation based on LDAP groupmembership
Will add eduPersonAffiliation containing value `student` if the `memberOf` attribute contains
either `cn=student,o=some,o=organization,dc=org` or `cn=student,o=other,o=organization,dc=org`.
The `memberOf` attribute will be removed (use `%keep`, to keep it) and existing values in
`eduPersonAffiliation` will be merged (use `%replace` to replace them).
'authproc' => [
50 => [
'class' => 'core:AttributeValueMap',
'sourceattribute' => 'memberOf',
'targetattribute' => 'eduPersonAffiliation',
'values' => [
'student' => [
'cn=student,o=some,o=organization,dc=org',
'cn=student,o=other,o=organization,dc=org',
],
],
],
],
## Multiple assignments
Add `student`, `employee` and `both` affiliation based on LDAP groupmembership in the `memberOf` attribute.
'authproc' => [
50 => [
'class' => 'core:AttributeValueMap',
'sourceattribute' => 'memberOf',
'targetattribute' => 'eduPersonAffiliation',
'values' => [
'student' => [
'cn=student,o=some,o=organization,dc=org',
'cn=student,o=other,o=organization,dc=org',
],
'employee' => [
'cn=employees,o=some,o=organization,dc=org',
'cn=employee,o=other,o=organization,dc=org',
'cn=workers,o=any,o=organization,dc=org',
],
'both' => [
'cn=student,o=some,o=organization,dc=org',
'cn=student,o=other,o=organization,dc=org',
'cn=employees,o=some,o=organization,dc=org',
'cn=employee,o=other,o=organization,dc=org',
'cn=workers,o=any,o=organization,dc=org',
],
],
],
],
## Replace and Keep
Replace any existing `affiliation` attribute values and keep the `groups` attribute.
'authproc' => [
50 => [
'class' => 'core:AttributeValueMap',
'sourceattribute' => 'groups',
'targetattribute' => 'affiliation',
'%replace',
'%keep',
'values' => [
'student' => [
'cn=student,o=some,o=organization,dc=org',
'cn=student,o=other,o=organization,dc=org',
],
'employee' => [
'cn=employees,o=some,o=organization,dc=org',
'cn=employee,o=other,o=organization,dc=org',
'cn=workers,o=any,o=organization,dc=org',
],
],
],
],

View File

@@ -0,0 +1,49 @@
`core:Cardinality`
==================
Ensure the number of attribute values is within the specified multiplicity.
This filter should contain a set of attribute name => rule pairs describing the multiplicity rules for an attribute.
The special parameter `%ignoreEntities` can be used to give an array of entity IDs that should be ignored for testing, etc purposes.
A separate [`core:CardinalitySingle`](./core:authproc_cardinalitysingle) authproc filter provides additional functionality for the special case where attributes are single valued.
Specifying Rules
----------------
Multiplicity rules are specified as an associative array containing one or more of the following parameters:
`min`
: The minimum number of values (participation) this attribute should have. Defaults to `zero`.
`max`
: The maximum number of values (cardinality) this attribute should have. Defaults to no upper bound.
`warn`
: Log a warning rather than generating an error. Defaults to `false`.
For convenience, minimum and maximum values can also be specified using a shorthand list notation.
Examples
--------
Require at least one `givenName`, no more than two email addresses, and between two and four values for `eduPersonScopedAffiliation`.
'authproc' => [
50 => [
'class' => 'core:Cardinality',
'givenName' => ['min' => 1],
'mail' => ['max' => 2],
'eduPersonScopedAffiliation' => ['min' => 2, 'max' => 4],
],
],
Use the shorthand notation for min, max:
'authproc' => [
50 => [
'class' => 'core:Cardinality',
'mail' => [0, 2],
],
],

View File

@@ -0,0 +1,88 @@
`core:CardinalitySingle`
========================
Ensure the correct cardinality of single-valued attributes. This filter is a special case
of the more generic [`core:Cardinality`](./core:authproc_cardinality) filter that allows for optional corrective measures
when multi-valued attributes are received where single-valued ones are expected.
Parameters
----------
This filter implements a number of optional parameters:
`singleValued`
: array of attribute names that *must* be single-valued, or a 403 error is generated.
`firstValue`
: array of attribute names where only the first value of a multi-valued assertion should be returned.
`flatten`
: array of attribute names where a multi-valued assertion is flattened into a single delimited string.
`flattenWith`
: the delimiter for `flatten`. Defaults to ";".
`ignoreEntities`
: array of entity IDs that should be ignored for testing, etc purposes.
When the same attribute name appears in multiple stanzas, they are processed in the order above.
Examples
--------
Abort with an error if any attribute defined as single-valued in the eduPerson or SCHAC schemas exists and has more than one value:
'authproc' => [
50 => [
'class' => 'core:CardinalitySingle',
'singleValued' => [
/* from eduPerson (internet2-mace-dir-eduperson-201602) */
'eduPersonOrgDN', 'eduPersonPrimaryAffiliation', 'eduPersonPrimaryOrgUnitDN',
'eduPersonPrincipalName', 'eduPersonUniqueId',
/* from inetOrgPerson (RFC2798), referenced by internet2-mace-dir-eduperson-201602 */
'displayName', 'preferredLanguage',
/* from SCHAC-IAD Version 1.3.0 */
'schacMotherTongue', 'schacGender', 'schacDateOfBirth', 'schacPlaceOfBirth',
'schacPersonalTitle', 'schacHomeOrganization', 'schacHomeOrganizationType',
'schacExpiryDate',
],
],
],
Abort if multiple values are received for `eduPersonPrincipalName`, but take the first value for `eduPersonPrimaryAffiliation`:
'authproc' => [
50 => [
'class' => 'core:CardinalitySingle',
'singleValued' => ['eduPersonPrincipalName'],
'firstValue' => ['eduPersonPrimaryAffiliation'],
],
],
],
Construct `eduPersonPrimaryAffiliation` using the first value in `eduPersonAffiliation`:
'authproc' => [
50 => [
'class' => 'core:AttributeCopy',
'eduPersonAffiliation' => 'eduPersonPrimaryAffiliation',
],
51 => [
'class' => 'core:CardinalitySingle',
'firstValue' => ['eduPersonPrimaryAffiliation'],
],
],
Construct a single, comma-separated value version of `eduPersonAffiliation`:
'authproc' => [
50 => [
'class' => 'core:AttributeCopy',
'eduPersonAffiliation' => 'eduPersonAffiliationWithCommas',
],
51 => [
'class' => 'core:CardinalitySingle',
'flatten' => ['eduPersonAffiliationWithCommas'],
'flattenWith' => ',',
],
],

View File

@@ -0,0 +1,49 @@
`core:GenerateGroups`
=====================
This filter creates a `group` attribute based on the contents of the other attributes of the user.
By default this filter will generate groups from the following set of attributes:
* `eduPersonAffiliation`
* `eduPersonOrgUnitDN`
* `eduPersonEntitlement`
This can be overridden by specifying the names of the attributes in the configuration.
It will attempt to determine a realm the user belongs to based on the `eduPersonPrincipalName`
attribute, if it is present.
The groups this filter generates are on the form `<attribute name>-<attributevalue>` and `<attributename>-<realm>-<attributevalue>`.
For example, if the user has the following attributes:
* `eduPersonPrincipalName`: `user@example.org`
* `eduPersonAffiliation`: `student`, `member`
The following groups will be created:
* `eduPersonAffiliation-student`
* `eduPersonAffiliation-member`
* `eduPersonAffiliation-example.org-student`
* `eduPersonAffiliation-example.org-member`
Examples
--------
Default attributes:
'authproc' => [
50 => [
'class' => 'core:GenerateGroups',
],
],
Custom attributes:
'authproc' => [
50 => [
'class' => 'core:GenerateGroups',
'someAttribute',
'someOtherAttribute',
],
],

View File

@@ -0,0 +1,41 @@
`core:LanguageAdaptor`
======================
SimpleSAMLphp has built in language support, and stores the preferred language in a cookie.
Identity systems also often has a specific attribute that indicates what language is understood by the user.
MACE defines an attribute with preferred language: `preferredLanguage`.
[Read more about the preferredLanguage attribute defined by MACE](https://tools.ietf.org/html/rfc2798#section-2.7).
The LanguageAdaptor brings these two concepts together.
If executed early at the IdP it will check if the `preferredLanguage` attribute is among the user's attributes, and if it is, SimpleSAMLphp will use that language in the user interface.
**Note:** the login page itself is too early to be influenced by the user attributes, because the IdP does not know any user attributes before the user logs in.
In contrast, the consent module will be presented in the correct language based on the user attribute.
The LanguageAdaptor also works the other way around.
If the user does not have the `preferredLanguage` attribute, the user interface for the user will be set to the default for the installation.
If this language is not correct for the user, the user may click to switch language on the login page (or any other UI page in SimpleSAMLphp).
SimpleSAMLphp then stores the preferred language in a cookie.
Now, the LanguageAdaptor will read the preferred language from the cookie and add a user attribute with the preferred language, that is sent to the service provider.
The name of the attribute can be changed from the default by adding the `attributename` option.
Examples
--------
Default attribute (`preferredLanguage`):
'authproc' => [
50 => [
'class' => 'core:LanguageAdaptor',
],
],
Custom attribute:
'authproc' => [
50 => [
'class' => 'core:LanguageAdaptor',
'attributename' => 'lang',
],
],

View File

@@ -0,0 +1,57 @@
`core:PHP`
==========
This is a filter which makes it possible to run arbitrary PHP code to modify the attributes or state of an user.
Parameters
----------
`class`
: This is the name of the filter.
It must be `core:PHP`.
`code`
: The PHP code that should be run. This code will have two variables available:
* `$attributes`.
This is an associative array of attributes, and can be modified to add or remove attributes.
* `$state`.
This is an associative array of request state. It can be modified to adjust data related to the authentication
such as desired NameId, requested Attributes, authnContextRef and many more.
Examples
--------
Add the `mail` attribute based on the user's `uid` attribute:
10 => [
'class' => 'core:PHP',
'code' => '
if (empty($attributes["uid"])) {
throw new Exception("Missing uid attribute.");
}
$uid = $attributes["uid"][0];
$mail = $uid . "@example.net";
$attributes["mail"] = [$mail];
',
],
Create a random number variable:
10 => [
'class' => 'core:PHP',
'code' => '
$attributes["random"] = [
(string)rand(),
];
',
],
Force a specific NameIdFormat. Useful if an SP misbehaves and requests (or publishes) an incorrect NameId
90 => [
'class' => 'core:PHP',
'code' => '$state["saml:NameIDFormat"] = ["Format" => "urn:oasis:names:tc:SAML:2.0:nameid-format:transient", "AllowCreate" => true];'
],

View File

@@ -0,0 +1,49 @@
`core:ScopeAttribute`
=====================
A filter which combines two attributes into a scoped attribute.
That is, the value will be `something@scope`, usually to make it globally unique.
Parameters
----------
`scopeAttribute`
: The attribute that contains the scope.
: If the attribute contains a '@', we will take the scope from the part following the '@'.
Otherwise, we will use the entire value.
: If the attribute is multi-valued, we will add all the scopes to the target.
`sourceAttribute`
: The attribute that contains the values we shall add the scope to.
: This attribute can be multi-valued, in which case we will add all the values.
`targetAttribute`
: The attribute we shall add the scoped attributes to.
: If the attribute already exists, the new values will be merged into the existing attribute.
`onlyIfEmpty`
: Only replace the targetAttribute if it is empty to begin with.
: If `true`, then the targetAttribute will only be created if it didn't already contain values. Defaults to `false`.
: This is useful if, for instance, you want to create eduPersonScopedAffiliation from eduPersonAffiliation _only_ if eduPersonScopedAffiliation was not returned by the authenticaton source.
Example
-------
Add eduPersonScopedAffiliation based on eduPersonAffiliation and eduPersonPrincipalName.
10 => [
'class' => 'core:ScopeAttribute',
'scopeAttribute' => 'eduPersonPrincipalName',
'sourceAttribute' => 'eduPersonAffiliation',
'targetAttribute' => 'eduPersonScopedAffiliation',
],
With values being `eduPersonPrincipalName`: `jdoe@example.edu` and
`eduPersonAffiliation`: `faculty`, this will result in the attribute
`eduPersonScopedAffiliation` with value `faculty@example.edu`.

View File

@@ -0,0 +1,28 @@
`core:ScopeFromAttribute`
=========================
This filter creates a new attribute based on the scope from a different attribute.
Parameters
----------
This filter has two parameters, where both parameters are mandatory.
`sourceAttribute`
: The attribute we should extract the scope from.
`targetAttribute`
: The name of the new attribute.
Example
-------
Set the `scope` attribute to the scope from the `eduPersonPrincipalName` attribute:
'authproc' => [
50 => [
'class' => 'core:ScopeFromAttribute',
'sourceAttribute' => 'eduPersonPrincipalName',
'targetAttribute' => 'scope',
],
],

View File

@@ -0,0 +1,54 @@
`core:TargetedID`
=================
This filter generates the `eduPersonTargetedID` attribute for the user.
This filter will use the contents of the attribute set by the `identifyingAttribute` option as the unique user ID.
Parameters
----------
`identifyingAttribute`
: The name of the attribute we should use for the unique user identifier.
Note: only the first value of the specified attribute is being used for the generation of the identifier.
`nameId`
: Set this option to `true` to generate the attribute as in SAML 2 NameID format.
This can be used to generate an Internet2 compatible `eduPersonTargetedID` attribute.
Optional, defaults to `false`.
Examples
--------
A custom attribute:
'authproc' => [
50 => [
'class' => 'core:TargetedID',
'identifyingAttribute' => 'eduPersonPrincipalName'
],
],
Internet2 compatible `eduPersontargetedID`:
/* In saml20-idp-hosted.php. */
$metadata['urn:x-simplesamlphp:example-idp'] = [
'host' => '__DEFAULT__',
'auth' => 'example-static',
'authproc' => [
60 => [
'class' => 'core:TargetedID',
'nameId' => true,
],
90 => [
'class' => 'core:AttributeMap',
'name2oid',
],
],
'attributes.NameFormat' => 'urn:oasis:names:tc:SAML:2.0:attrname-format:uri',
'attributeencodings' => [
'urn:oid:1.3.6.1.4.1.5923.1.1.1.10' => 'raw', /* eduPersonTargetedID with oid NameFormat. */
],
];

View File

@@ -0,0 +1,14 @@
`core:WarnShortSSOInterval`
===========================
Give a warning to the user when authenticating twice in a short time.
This is mainly intended to prevent redirect loops between the IdP and the SP.
Example
-------
'authproc' => [
50 => [
'class' => 'core:WarnShortSSOInterval',
],
],

View File

@@ -0,0 +1,90 @@
# Authentication source selector
The Authentication source selector is a special kind of Authentication Source
that delegates the actual authentication to a secondary Authentication Source
based on some form of policy decision.
## AbstractSourceSelector
The AbstractSourceSelector extends from `\SimpleSAML\Auth\Source` and as such
act as an Authentication Source. Any derivative classes must implement the
abstract `selectAuthSource` method. This method must return the name of the
Authentication Source to use, based on whatever logic is necessary.
## SourceIPSelector
The SourceIPSelector is an implementation of the `AbstractSourceSelector` that
uses the client IP to decide what Authentication Source is called.
It works by defining zones with corresponding IP-ranges and Authentication
Sources. The 'default' zone is optional and acts as a fallback when none
of the zones match a client's IP-address. When set to `null` a NotFound-
exception will be thrown.
An example configuration would look like this:
```php
'selector' => [
'core:SourceIPSelector',
'zones' => [
'internal' => [
'source' => 'ldap',
'subnet' => [
'10.0.0.0/8',
'2001:0DB8::/108',
],
],
'other' => [
'source' => 'radius',
'subnet' => [
'172.16.0.0/12',
'2002:1234::/108',
],
],
'default' => 'yubikey',
],
],
```
## RequestedAuthnContextSelector
The RequestedAuthnContextSelector is an implementation of the `AbstractSourceSelector` that
uses the RequestedAuthnContext to decide what Authentication Source is called.
It works by defining AuthnContexts with their corresponding Authentication
Sources. The 'default' key will be used as a default when no RequestedAuthnContext
is passed in the request.
An example configuration would look like this:
```php
'selector' => [
'core:RequestedAuthnContextSelector',
'contexts' => [
10 => [
'identifier' => 'urn:x-simplesamlphp:loa1',
'source' => 'ldap',
],
20 => [
'identifier' => 'urn:x-simplesamlphp:loa2',
'source' => 'radius',
],
'default' => [
'identifier' => 'urn:x-simplesamlphp:loa0',
'source' => 'sql',
],
],
],
```
## YourCustomSourceSelector
If you have a use-case for a custom Authentication source selector, all you
have to do is to create your own class, make it extend `AbstractSourceSelector`
and make it implement the abstract `selectAuthSource` method containing
your own logic. The method should return the name of the Authentication
source to use.

View File

@@ -0,0 +1,30 @@
msgid ""
msgstr ""
"X-Domain: core\n"
msgid "If you are a developer who is deploying a single sign-on solution, you have a problem with the metadata configuration. Verify that metadata is configured correctly on both the identity provider and service provider."
msgstr "As jy 'n programmeerder is wat die 'single sign-on' oplossing implementeer, het jy 'n probleem met die metadata opset. Bevestig dat die metadata korrek ingestel is op beide die identiteit verskaffer en diensverskaffer."
msgid "If you are a user who received this error after following a link on a site, you should report this error to the owner of that site."
msgstr "As jy 'n gebruiker is wat na aanleiding van 'n skakel op 'n webwerf hierdie fout ontvang het, moet jy hierdie fout aan die eienaar van die webwerf aan stuur."
msgid "Missing cookie"
msgstr "Verlore cookie"
msgid "Retry"
msgstr "Probeer weer"
msgid "Retry login"
msgstr "Probeer weer aanmeld"
msgid "This is most likely a configuration problem on either the service provider or identity provider."
msgstr "Dié is waarskynlik 'n probleem met die konfigurasie by die diensverskaffer óf die identiteit verskaffer."
msgid "Too short interval between single sign on events."
msgstr "Te kort interval tussen enkel aanmeldings(single sign on) op die gebeure."
msgid "We have detected that there is only a few seconds since you last authenticated with this service provider, and therefore assume that there is a problem with this SP."
msgstr "Ons het ontdek dat daar slegs 'n paar sekondes was sedert jy laas geverifieer het met die diensverskaffer en neem dus aan dat daar 'n probleem is met hierdie SP."
msgid "You appear to have disabled cookies in your browser. Please check the settings in your browser, and try again."
msgstr "Dit blyk dat jy cookies in jou webblaaier af geskakel het. Gaan asseblief die stellings in jou webblaaier na en probeer weer."

View File

@@ -0,0 +1,78 @@
msgid ""
msgstr ""
"X-Domain: core\n"
msgid "Close the web browser, and try again."
msgstr "اغلق الموقع ثم حاول مرة اخري"
msgid "Cookies may be disabled in the web browser."
msgstr "الكوكيز غير منشطة بمتصفحك"
msgid "Go back to the previous page and try again."
msgstr "ارجع للصفحة السابقة و حاول مرة اخري"
msgid "Hosted Shibboleth 1.3 Identity Provider Metadata (automatically generated)"
msgstr "البيانات الوصفية/الميتاداتا لهوية مقدم Shibboleth 1.3 الضيف (تم تجهيزها اتوماتيكياً)"
msgid "Hosted Shibboleth 1.3 Service Provider Metadata (automatically generated)"
msgstr "البيانات الوصفية/الميتاداتا لمقدم Shibboleth 1.3 الضيف (تم تجهيزها اتوماتيكياً)"
msgid "If this problem persists, you can report it to the system administrators."
msgstr "اذا استمرت هذه المشكلة بالحدوث، رجاءا بلغ إدارة الموقع"
msgid "If you are a developer who is deploying a single sign-on solution, you have a problem with the metadata configuration. Verify that metadata is configured correctly on both the identity provider and service provider."
msgstr " و كانت (Single Sign-On) ان كنت مبرمجاً تعمل علي توفير حل لتوثيق دخول لمرة واحدة لديك مشكلة بادخال البيانات الوصفية, تأكد من أن أدخال البيانات الوصفية صحيح بكل من محدد الهوية و المخدم "
msgid "If you are a user who received this error after following a link on a site, you should report this error to the owner of that site."
msgstr "ان تعرضت لهذا الاشكال بعيد اتباعك لرابط بموقع ما, ينبغي عليك الابلاغ عن هذا الاشكال لمالك الموقع المعني"
msgid "Metadata"
msgstr "البيانات الوصفية/الميتاداتا "
msgid "Missing cookie"
msgstr "ألكوكيز المفقودة"
msgid "Opened the web browser with tabs saved from the previous session."
msgstr "فتح متصفحك مستخدما معلومات محفوظة من المرة السابقة"
msgid "Report this error"
msgstr "بلغ عن هذا الخطأ "
msgid "Retry"
msgstr "اعد المحاولة"
msgid "Retry login"
msgstr "اعد تسجيل الدخول"
msgid "Shibboleth 1.3 SP example - test logging in through your Shib IdP"
msgstr "مثال Shibboleth 1.3 SP- اختبر تسجيل الدخول مستخدماً هوية Shib IdP"
msgid "State information lost"
msgstr "حدد المعلومات المفقودة"
msgid "Suggestions for resolving this problem:"
msgstr "اقتراحات لحل المشكلة "
msgid "This error may be caused by:"
msgstr "سبب حدوث هذا الخطأ قد يكون:"
msgid "This is most likely a configuration problem on either the service provider or identity provider."
msgstr "من الارجح ان هذا الاشكال نابع اما من مشكلة بالمخدم أو مشكلة بمحدد الهوية"
msgid "Too short interval between single sign on events."
msgstr "فترات قصيرة جداً بين محاولات تسجيل الدخول الموحد "
msgid "Using the back and forward buttons in the web browser."
msgstr "استخدام أزرار الرجوع للخلف و الامام بمتصفحك"
msgid "We have detected that there is only a few seconds since you last authenticated with this service provider, and therefore assume that there is a problem with this SP."
msgstr "يبدو انك قد قمت بتصديق الدخول عدة مرات لمقدم هذه الخدمة خلال الثواني القليلة الماضية مما يقودنا للاعتقاد بوجود مشكلة ما بهذا ال SP "
msgid "We were unable to locate the state information for the current request."
msgstr "لم نستطع تحديد المعلومات المفقودة للطلب الحالي"
msgid "Welcome"
msgstr "مرحباً"
msgid "You appear to have disabled cookies in your browser. Please check the settings in your browser, and try again."
msgstr "يبدو انك قد عطلت الكوكيز بمتصفحك. قم رجاءا بمراجعة إعدادات متصفحك ثم حاول مرة اخري"

View File

@@ -0,0 +1,75 @@
msgid ""
msgstr ""
"X-Domain: core\n"
msgid "Close the web browser, and try again."
msgstr "Zavřít webový prohlížeč a zkusit znovu."
msgid "Cookies may be disabled in the web browser."
msgstr "Ve webovém prohlížeči mohou být zakázány cookies."
msgid "Go back to the previous page and try again."
msgstr "Jít zpět na předchozí stránku a zkusit znovu."
msgid "Hosted Shibboleth 1.3 Identity Provider Metadata (automatically generated)"
msgstr "Metada lookálního (hosted) Shibboleth 1.3 poskytovatele služby (IdP) (automaticky generované)"
msgid "Hosted Shibboleth 1.3 Service Provider Metadata (automatically generated)"
msgstr "Metada lookálního (hosted) Shibboleth 1.3 poskytovatele služby (SP) (automaticky generované)"
msgid "If this problem persists, you can report it to the system administrators."
msgstr "Pokud problém přetrvává, můžete ho nahlásit správci."
msgid "If you are a developer who is deploying a single sign-on solution, you have a problem with the metadata configuration. Verify that metadata is configured correctly on both the identity provider and service provider."
msgstr "Pokud jste vývojář nasazující řešení jednotného přihlašování, máte problém s konfigurací metadat. Ověřte, zda jsou metadata nakonfigurována správně jak u poskytovatele identity tak u poskytovatele služby."
msgid "If you are a user who received this error after following a link on a site, you should report this error to the owner of that site."
msgstr "Pokud jste uživatel, který obdržel chybu po následování odkazu na webové stránce, měli byste o této chybě informovat vlastníka této stránky. "
msgid "Missing cookie"
msgstr "Chybějící cookie"
msgid "Opened the web browser with tabs saved from the previous session."
msgstr "Otevřením webového prohlížeče se záložkami z předchozího sezení."
msgid "Report this error"
msgstr "Nahlásit tuto chybu"
msgid "Retry"
msgstr "Opakujte"
msgid "Retry login"
msgstr "Přihlašte se znovu."
msgid "Shibboleth 1.3 SP example - test logging in through your Shib IdP"
msgstr "Shibboleth 1.3 SP ukázka - testovací přihlášení pomocí vaší Shib IdP"
msgid "State information lost"
msgstr "Stavová informace ztracena"
msgid "Suggestions for resolving this problem:"
msgstr "Návrhy pro vyřešení tohoto problému:"
msgid "This error may be caused by:"
msgstr "Tato chyba může být způsobená:"
msgid "This is most likely a configuration problem on either the service provider or identity provider."
msgstr "Toto je pravděpodobně konfigurační problém na straně poskytovatele služby nebo poskytovatele identity."
msgid "Too short interval between single sign on events."
msgstr "Příliš krátký interval mezi událostmi jednoho prihlášení."
msgid "Using the back and forward buttons in the web browser."
msgstr "Použitím tlačítek zpět a vpřed ve webvém prohlížeči."
msgid "We have detected that there is only a few seconds since you last authenticated with this service provider, and therefore assume that there is a problem with this SP."
msgstr "Zjistili jsme, že uběhlo pouze pár sekund od Vašeho minulého priřhlášení pomocí service providera a proto předpokládáme, že nastala chyba v tom SP."
msgid "We were unable to locate the state information for the current request."
msgstr "Nebylo možné najít stavovou informaci pro současný požadavek."
msgid "Welcome"
msgstr "Vítejte"
msgid "You appear to have disabled cookies in your browser. Please check the settings in your browser, and try again."
msgstr "Váš internetový prohlížeč má zřejmě vypnutou podporu cookies. Prosíme, zkontrolujte nastavení cookies ve vašem prohlížeči a zkuste znovu."

View File

@@ -0,0 +1,75 @@
msgid ""
msgstr ""
"X-Domain: core\n"
msgid "Close the web browser, and try again."
msgstr "Luk din browser og prøv igen."
msgid "Cookies may be disabled in the web browser."
msgstr "Cookies kan være deaktiveret i browseren."
msgid "Go back to the previous page and try again."
msgstr "Gå tilbage til forrige side og prøv igen."
msgid "Hosted Shibboleth 1.3 Identity Provider Metadata (automatically generated)"
msgstr "Hosted Shibboleth 1.3 identitetsudbyder metadata (automatisk genereret)"
msgid "Hosted Shibboleth 1.3 Service Provider Metadata (automatically generated)"
msgstr "Hosted Shibboleth 1.3 tjenesteudbyder metadata (automatisk genereret)"
msgid "If this problem persists, you can report it to the system administrators."
msgstr "Hvis dette problem fortsætter, kan du rapportere det til systemadministratoren."
msgid "If you are a developer who is deploying a single sign-on solution, you have a problem with the metadata configuration. Verify that metadata is configured correctly on both the identity provider and service provider."
msgstr "Hvis du er udvikler, så har du et metadata-konfigurationsproblem. Tjek at metadata er konfigurerede korrekt både på service-siden og identitetsudbyder-siden."
msgid "If you are a user who received this error after following a link on a site, you should report this error to the owner of that site."
msgstr "Hvis du har modtaget denne fejlbesked efter at have klikket på et lilnk, skal du rappoterer fejlen til ejeren af siden. "
msgid "Missing cookie"
msgstr "Mangler cookie"
msgid "Opened the web browser with tabs saved from the previous session."
msgstr "Åben browseren med faner fra sidste session."
msgid "Report this error"
msgstr "Rapporter denne fejl"
msgid "Retry"
msgstr "Forsøg igen"
msgid "Retry login"
msgstr "Login igen"
msgid "Shibboleth 1.3 SP example - test logging in through your Shib IdP"
msgstr "Shibboleth 1.3 SP eksempel - test indlogning med Shibboleth 1.3 via din IdP"
msgid "State information lost"
msgstr "Tilstandsinformation forsvundet"
msgid "Suggestions for resolving this problem:"
msgstr "Løsningsforslag til problemet:"
msgid "This error may be caused by:"
msgstr "Fejlen kan være forårsaget af:"
msgid "This is most likely a configuration problem on either the service provider or identity provider."
msgstr "Der er sandsynligvis en konfigurationsfejl hos enten servicen eller identitetsudbyderen."
msgid "Too short interval between single sign on events."
msgstr "For kort interval mellem single sign on hændelse."
msgid "Using the back and forward buttons in the web browser."
msgstr "Brug frem- og tilbage-knappen i browseren."
msgid "We have detected that there is only a few seconds since you last authenticated with this service provider, and therefore assume that there is a problem with this SP."
msgstr "Vi har opdaget at det kun er få sekunder siden du sidst autentificerede dig op mod denne service. Vi antager derfor at der er et problem med services."
msgid "We were unable to locate the state information for the current request."
msgstr "Tilstandsinformation for igangværende request kan ikke findes"
msgid "Welcome"
msgstr "Velkommen"
msgid "You appear to have disabled cookies in your browser. Please check the settings in your browser, and try again."
msgstr "Det ser ud til at du har slået cookies fra i din browser. Tjek dine browserindstillinger og prøv igen."

View File

@@ -0,0 +1,75 @@
msgid ""
msgstr ""
"X-Domain: core\n"
msgid "Close the web browser, and try again."
msgstr "Schließe den Web-Browser und versuche es erneut."
msgid "Cookies may be disabled in the web browser."
msgstr "Cookies könnten im Web-Browser deaktiviert sein."
msgid "Go back to the previous page and try again."
msgstr "Kehre zur letzen Seite zurück und versuche es erneut."
msgid "Hosted Shibboleth 1.3 Identity Provider Metadata (automatically generated)"
msgstr "Hosted Shibboleth 1.3 Identity Provider Metadaten (automatisch generiert)"
msgid "Hosted Shibboleth 1.3 Service Provider Metadata (automatically generated)"
msgstr "Hosted Shibboleth 1.3 Service Provider Metadaten (automatisch generiert)"
msgid "If this problem persists, you can report it to the system administrators."
msgstr "Wenn das Problem weiter besteht, kannst du diesen Fehler den Systemadministratoren melden."
msgid "If you are a developer who is deploying a single sign-on solution, you have a problem with the metadata configuration. Verify that metadata is configured correctly on both the identity provider and service provider."
msgstr "Arbeiten Sie selbst an einem Web Single Sign-On System, stimmt mit den benutzten Metadaten etwas nicht. Überprüfen Sie die Metadaten des Identity Providers und des Service Providers."
msgid "If you are a user who received this error after following a link on a site, you should report this error to the owner of that site."
msgstr "Sind Sie lediglich einem Verweis einer anderen Website hierher gefolgt, sollten Sie diesen Fehler den Betreibern der Website melden."
msgid "Missing cookie"
msgstr "Cookie fehlt"
msgid "Opened the web browser with tabs saved from the previous session."
msgstr "Das Öffnen des Web-Browser mit gespeicherten Tabs aus der letzten Sitzung."
msgid "Report this error"
msgstr "Diesen Fehler melden"
msgid "Retry"
msgstr "Erneut versuchen"
msgid "Retry login"
msgstr "Versuche Anmeldung erneut"
msgid "Shibboleth 1.3 SP example - test logging in through your Shib IdP"
msgstr "Shibboleth 1.3 SP Beispiel - Anmelden über ihren Shibboleth IdP testen"
msgid "State information lost"
msgstr "Statusinformationen verloren"
msgid "Suggestions for resolving this problem:"
msgstr "Empfehlungen um dieses Problem zu lösen:"
msgid "This error may be caused by:"
msgstr "Dieser Fehler könnte durch folgendes verursacht werden:"
msgid "This is most likely a configuration problem on either the service provider or identity provider."
msgstr "Ursache ist wahrscheinlich eine Fehlkonfiguration auf Seiten des Service Providers oder des Identity Providers."
msgid "Too short interval between single sign on events."
msgstr "Zu kurzes Intervall zwischen generellen Anmeldeereignissen."
msgid "Using the back and forward buttons in the web browser."
msgstr "Das Benutzen der Zurück- und Vorwärts-Schaltflächen im Web-Browser."
msgid "We have detected that there is only a few seconds since you last authenticated with this service provider, and therefore assume that there is a problem with this SP."
msgstr "Wir haben festgestellt, dass seit Ihrer letzten Anmeldung bei diesem Diensteanbieter nur wenige Sekunden vergangen sind. Deswegen gehen wir davon aus, dass es ein Problem mit diesem Anbieter gibt."
msgid "We were unable to locate the state information for the current request."
msgstr "Wir konnten die Statusinformationen für die aktuelle Anfrage nicht lokalisieren."
msgid "Welcome"
msgstr "Willkommen"
msgid "You appear to have disabled cookies in your browser. Please check the settings in your browser, and try again."
msgstr "Sie scheinen Cookies in Ihrem Browser deaktiviert zu haben. Bitte überprüfen Sie die Einstellungen in Ihrem Browser und versuchen Sie es erneut."

View File

@@ -0,0 +1,75 @@
msgid ""
msgstr ""
"X-Domain: core\n"
msgid "Close the web browser, and try again."
msgstr "Κλείστε το πρόγραμμα περιήγησης ιστού (web browser) και προσπαθήστε ξανά"
msgid "Cookies may be disabled in the web browser."
msgstr "Η λειτουργία cookie είναι απενεργοποιημένη στο πρόγραμμα περιήγησης ιστού."
msgid "Go back to the previous page and try again."
msgstr "Επιστρέψτε στην προηγούμενη σελίδα και προσπαθήστε ξανά."
msgid "Hosted Shibboleth 1.3 Identity Provider Metadata (automatically generated)"
msgstr "Μεταδεδομένα φιλοξενούμενου Παρόχου Ταυτότητας Shibboleth 1.3 (παράγονται αυτόματα)"
msgid "Hosted Shibboleth 1.3 Service Provider Metadata (automatically generated)"
msgstr "Μεταδεδομένα φιλοξενούμενου Παρόχου Υπηρεσιών Shibboleth 1.3 (παράγονται αυτόματα)"
msgid "If this problem persists, you can report it to the system administrators."
msgstr "Αν το πρόβλημα εξακολουθεί να υφίσταται, μπορείτε να το αναφέρετε στους διαχειριστές του συστήματος."
msgid "If you are a developer who is deploying a single sign-on solution, you have a problem with the metadata configuration. Verify that metadata is configured correctly on both the identity provider and service provider."
msgstr "Εάν είστε διαχειριστής της υπηρεσίας ταυτοποίησης και εξουσιοδότησης, τότε αντιμετωπίζετε κάποιο πρόβλημα με τη διαμόρφωση των μεταδεδομένων. Βεβαιωθείτε ότι τα μεταδεδομένα έχουν ρυθμιστεί σωστά τόσο στον πάροχο ταυτότητας όσο και στον πάροχο υπηρεσιών."
msgid "If you are a user who received this error after following a link on a site, you should report this error to the owner of that site."
msgstr "Αν λάβατε αυτό το σφάλμα ακολουθώντας έναν σύνδεσμο σε κάποιον ιστότοπο, θα πρέπει να το αναφέρετε στον ιδιοκτήτη του εν λόγω ιστότοπου."
msgid "Missing cookie"
msgstr "Πρόβλημα λειτουργίας cookie"
msgid "Opened the web browser with tabs saved from the previous session."
msgstr "Ανοίξατε το πρόγραμμα περιήγησης ιστού και επαναφέρατε καρτέλες προηγούμενης συνεδρίας."
msgid "Report this error"
msgstr "Αναφορά σφάλματος"
msgid "Retry"
msgstr "Δοκιμάστε ξανά"
msgid "Retry login"
msgstr "Επανάληψη σύνδεσης"
msgid "Shibboleth 1.3 SP example - test logging in through your Shib IdP"
msgstr "Παράδειγμα Παρόχου Υπηρεσιών Shibboleth 1.3 - δοκιμή εισόδου μέσω Παρόχου Ταυτότητας Shibboleth 1.3"
msgid "State information lost"
msgstr "Δεν βρέθηκαν πληροφορίες κατάστασης"
msgid "Suggestions for resolving this problem:"
msgstr "Προτάσεις για την επίλυση αυτού του προβλήματος:"
msgid "This error may be caused by:"
msgstr "Αυτό το σφάλμα μπορεί να προκύψει, εάν:"
msgid "This is most likely a configuration problem on either the service provider or identity provider."
msgstr "Αυτό υποδεικνύει πρόβλημα με τις ρυθμίσεις είτε του παρόχου υπηρεσιών είτε του παρόχου ταυτότητας."
msgid "Too short interval between single sign on events."
msgstr "Σύντομο χρονικό διάστημα μεταξύ διαδοχικών συνδέσεων."
msgid "Using the back and forward buttons in the web browser."
msgstr "Μεταβήκατε πίσω και εμπρός στο ιστορικό του προγράμματος περιήγησης ιστού."
msgid "We have detected that there is only a few seconds since you last authenticated with this service provider, and therefore assume that there is a problem with this SP."
msgstr "Έχουν περάσει μόλις λίγα δευτερόλεπτα από την τελευταία φορά που συνδεθήκατε σε αυτόν τον πάροχο υπηρεσιών, γεγονός που μπορεί να υποδηλώνει πρόβλημα με τον συγκεκριμένο πάροχο."
msgid "We were unable to locate the state information for the current request."
msgstr "Δεν ήταν δυνατό να εντοπιστούν πληροφορίες κατάστασης για το τρέχον αίτημα."
msgid "Welcome"
msgstr "Καλώς ορίσατε"
msgid "You appear to have disabled cookies in your browser. Please check the settings in your browser, and try again."
msgstr "Ενδέχεται τα cookie του προγράμματος περιήγησής σας να έχουν απενεργοποιηθεί. Παρακαλούμε ελέγξτε τις σχετικές ρυθμίσεις και και δοκιμάστε ξανά."

View File

@@ -0,0 +1,180 @@
msgid ""
msgstr ""
"X-Domain: core\n"
msgid "A service has requested you to authenticate yourself. Please enter your username and password in the form below."
msgstr ""
msgid "Check that the link you used to access the web site is correct."
msgstr ""
msgid "Close the web browser, and try again."
msgstr "Close the web browser, and try again."
msgid "Continue"
msgstr ""
msgid "Cookies may be disabled in the web browser."
msgstr "Cookies may be disabled in the web browser."
msgid "Do you want to logout from all the services above?"
msgstr ""
msgid "Enter your username and password"
msgstr ""
msgid "Error report sent"
msgstr ""
msgid "Go back to the previous page and try again."
msgstr "Go back to the previous page and try again."
msgid "Help! I don't remember my password."
msgstr ""
msgid "Hosted Shibboleth 1.3 Identity Provider Metadata (automatically generated)"
msgstr "Hosted Shibboleth 1.3 Identity Provider Metadata (automatically generated)"
msgid "Hosted Shibboleth 1.3 Service Provider Metadata (automatically generated)"
msgstr "Hosted Shibboleth 1.3 Service Provider Metadata (automatically generated)"
msgid "If this problem persists, you can report it to the system administrators."
msgstr "If this problem persists, you can report it to the system administrators."
msgid "If you are a developer who is deploying a single sign-on solution, you have a problem with the metadata configuration. Verify that metadata is configured correctly on both the identity provider and service provider."
msgstr "If you are a developer who is deploying a single sign-on solution, you have a problem with the metadata configuration. Verify that metadata is configured correctly on both the identity provider and service provider."
msgid "If you are a user who received this error after following a link on a site, you should report this error to the owner of that site."
msgstr "If you are a user who received this error after following a link on a site, you should report this error to the owner of that site."
msgid "If you report this error, please also report this tracking number which makes it possible to locate your session in the logs available to the system administrator:"
msgstr ""
msgid "Incorrect Attributes"
msgstr ""
msgid "Logging out..."
msgstr ""
msgid "Login"
msgstr ""
msgid "Logout"
msgstr ""
msgid "Missing cookie"
msgstr "Missing cookie"
msgid "No"
msgstr ""
msgid "No, only %SP%"
msgstr ""
msgid "One or more of the attributes supplied by your identity provider did not contain the expected number of values."
msgstr ""
msgid "Opened the web browser with tabs saved from the previous session."
msgstr "Opened the web browser with tabs saved from the previous session."
msgid "Organization"
msgstr ""
msgid "Password"
msgstr ""
msgid "Processing..."
msgstr ""
msgid "Remember me"
msgstr ""
msgid "Remember my organization"
msgstr ""
msgid "Remember my username"
msgstr ""
msgid "Report this error"
msgstr "Report this error"
msgid "Retry"
msgstr "Retry"
msgid "Retry login"
msgstr "Retry login"
msgid "Shibboleth 1.3 SP example - test logging in through your Shib IdP"
msgstr "Shibboleth 1.3 SP example - test logging in through your Shib IdP"
msgid "SimpleSAMLphp"
msgstr ""
msgid "State information lost"
msgstr "State information lost"
msgid "Suggestions for resolving this problem:"
msgstr "Suggestions for resolving this problem:"
msgid "The error report has been sent to the administrators."
msgstr ""
msgid "The link used to get here was bad, perhaps a bookmark."
msgstr ""
msgid "The problematic attribute(s) are:"
msgstr ""
msgid "This error may be caused by:"
msgstr "This error may be caused by:"
msgid "This is most likely a configuration problem on either the service provider or identity provider."
msgstr "This is most likely a configuration problem on either the service provider or identity provider."
msgid "Too short interval between single sign on events."
msgstr "Too short interval between single sign on events."
msgid "Unable to log out of one or more services. To ensure that all your sessions are closed, you are encouraged to <i>close your webbrowser</i>."
msgstr ""
msgid "Username"
msgstr ""
msgid "Using the back and forward buttons in the web browser."
msgstr "Using the back and forward buttons in the web browser."
msgid "We have detected that there is only a few seconds since you last authenticated with this service provider, and therefore assume that there is a problem with this SP."
msgstr "We have detected that there is only a few seconds since you last authenticated with this service provider, and therefore assume that there is a problem with this SP."
msgid "We were unable to locate the state information for the current request."
msgstr "We were unable to locate the state information for the current request."
msgid "Welcome"
msgstr "Welcome"
msgid "Without your username and password you cannot authenticate yourself for access to the service. There may be someone that can help you. Consult the help desk at your organization!"
msgstr ""
msgid "Yes, all services"
msgstr ""
msgid "You appear to have disabled cookies in your browser. Please check the settings in your browser, and try again."
msgstr "You appear to have disabled cookies in your browser. Please check the settings in your browser, and try again."
msgid "You are also logged in on these services:"
msgstr ""
msgid "You are now accessing a pre-production system. This authentication setup is for testing and pre-production verification only. If someone sent you a link that pointed you here, and you are not <i>a tester</i> you probably got the wrong link, and should <b>not be here</b>."
msgstr ""
msgid "You are now successfully logged out from %SP%."
msgstr ""
msgid "You are running an outdated version of SimpleSAMLphp. Please update to <a href=\"https://simplesamlphp.org/download\">the latest version</a> as soon as possible."
msgstr "You are running an outdated version of SimpleSAMLphp. Please update to <a href=\"https://simplesamlphp.org/download\">the latest version</a> as soon as possible."
msgid "got %got% values, want %want%"
msgstr ""
msgid "logout is not supported"
msgstr ""

View File

@@ -0,0 +1,67 @@
msgid ""
msgstr ""
"X-Domain: core\n"
msgid "Close the web browser, and try again."
msgstr "Kwala sebadi sa webe, ebe o leka hape."
msgid "Cookies may be disabled in the web browser."
msgstr "Dikhuki di ka nna tsa kwalwa sebading sa webe."
msgid "Go back to the previous page and try again."
msgstr "Kgutlela leqepheng le fetileng ebe o leka hape."
msgid "If this problem persists, you can report it to the system administrators."
msgstr "Haeba bothata bona bo phehella, o ka bo tlaleha ho batsamaisi ba sistimi."
msgid "If you are a developer who is deploying a single sign-on solution, you have a problem with the metadata configuration. Verify that metadata is configured correctly on both the identity provider and service provider."
msgstr "Haeba o mohlahisi ya sebedisang tharollo ya ho saena hang, o na le bothata ka phetolo ya metadata. Netefatsa hore metadata e hlophiswe ka ho nepahala ho bobedi mofani wa boitsebiso le mofani wa tshebeletso."
msgid "If you are a user who received this error after following a link on a site, you should report this error to the owner of that site."
msgstr "Haeba o le mosebedisi ya fumaneng phoso ena kamora ho latela lehokela le setsing, o tlameha ho tlaleha phoso ena ho monga setsi."
msgid "Incorrect Attributes"
msgstr "Makgabane a Fosahetseng"
msgid "Missing cookie"
msgstr "Khukhi e siyo"
msgid "One or more of the attributes supplied by your identity provider did not contain the expected number of values."
msgstr "E le nngwe kapa ho feta ya makgabane a fanweng ke wena ke mofani wa boitsebiso wa hao ha e na lenane le nepahetseng la dipalo."
msgid "Opened the web browser with tabs saved from the previous session."
msgstr "O butse sebadi sa webe ka di-tab tse bolokilweng sesheneng e fetileng."
msgid "Report this error"
msgstr "Tlaleha phoso ena"
msgid "Retry"
msgstr "Khukhi e siyo"
msgid "State information lost"
msgstr "Tlhahisoleseding ya provense e lahlehile"
msgid "Suggestions for resolving this problem:"
msgstr "Ditlhahiso bakeng sa ho rarolla bothata bona:"
msgid "The problematic attribute(s) are:"
msgstr "Makgabane a nang le mathata ke:"
msgid "This error may be caused by:"
msgstr "Phoso ena e ka bakwa ke:"
msgid "This is most likely a configuration problem on either the service provider or identity provider."
msgstr "Bona ke bothata bo ka kgonahalang ka ho fetisisa ho mofani wa tshebeletso kapa mofani wa tshebeletso."
msgid "Using the back and forward buttons in the web browser."
msgstr "Ho sebedisa dikonopo tsa pele le morao sebading sa webo."
msgid "We were unable to locate the state information for the current request."
msgstr "Ha re kgone ho fumana tlhahisoleseding ka provenseng bakeng sa kopo ya ha jwale."
msgid "You appear to have disabled cookies in your browser. Please check the settings in your browser, and try again."
msgstr "O bonahala o kwetse dikhukhi sebading sa hao. Ka kopo hlahloba disetting sebading sa hao."
#, python-format
msgid "got %GOT% values, want %WANT%"
msgstr "o fumane dipalo tse %GOT%, o batla tse %WANT%"

View File

@@ -0,0 +1,78 @@
msgid ""
msgstr ""
"X-Domain: core\n"
msgid "Close the web browser, and try again."
msgstr "Cierre el navegador y pruebe de nuevo"
msgid "Cookies may be disabled in the web browser."
msgstr "Las cookies pueden estar deshabilitadas en el navegador"
msgid "Go back to the previous page and try again."
msgstr "Regrese a la página anterior y pruebe de nuevo"
msgid "Hosted Shibboleth 1.3 Identity Provider Metadata (automatically generated)"
msgstr "Metadatos alojados del IdP Shibooleth 1.3 (generados automáticamente)"
msgid "Hosted Shibboleth 1.3 Service Provider Metadata (automatically generated)"
msgstr "Metadatos alojados del SP Shibooleth 1.3 (generados automáticamente)"
msgid "If this problem persists, you can report it to the system administrators."
msgstr "Si el problema persiste, puede reportarlo a los administradores del sistema"
msgid "If you are a developer who is deploying a single sign-on solution, you have a problem with the metadata configuration. Verify that metadata is configured correctly on both the identity provider and service provider."
msgstr "Si usted es un desarrollador que está desplegando una solución de inicio único, tiene un problema con la configuración de sus metadatos. Verifique que los metadatos están configurados correctamente en el proveedor de identidad y en el proveedor de servicios"
msgid "If you are a user who received this error after following a link on a site, you should report this error to the owner of that site."
msgstr "Si usted es un usuario que recibe este error luego de seguir un vínculo en un sitio, debe reportar el error al dueño del sitio."
msgid "Missing cookie"
msgstr "No se encuentra cookie"
msgid "Opened the web browser with tabs saved from the previous session."
msgstr "Abrió su navegador web con pestañas guardadas de la sesión previa."
msgid "Report this error"
msgstr "Informar de este error"
msgid "Retry"
msgstr "Reintentar"
msgid "Retry login"
msgstr "Reintente autenticación"
msgid "Shibboleth 1.3 SP example - test logging in through your Shib IdP"
msgstr "Ejemplo de SP empleando Shibboleth 1.3 - Prueba a acceder empleando tu IdP Shibboleth"
msgid "State information lost"
msgstr "Información de estado perdida"
msgid "Suggestions for resolving this problem:"
msgstr "Sugerencias para resolver este problema"
msgid "This error may be caused by:"
msgstr "Este error puede ser causado por"
msgid "This is most likely a configuration problem on either the service provider or identity provider."
msgstr "Esto es posiblemente un problema de configuración en el proveedor de servicios o en el proveedor de identidad."
msgid "Too short interval between single sign on events."
msgstr "Intervalo de tiempo muy corto entre eventos de sesión única."
msgid "Using the back and forward buttons in the web browser."
msgstr "Usando los botones atrás y adelante de su navegador web."
msgid "We have detected that there is only a few seconds since you last authenticated with this service provider, and therefore assume that there is a problem with this SP."
msgstr "Se ha detectado que han transcurrido solo unos segundos desde que fue autenticado por última vez en este servicio, por lo que se asumirá que existe un problema con este SP."
msgid "We were unable to locate the state information for the current request."
msgstr "No podemos encontrar la información de estado para la solicitud actual"
msgid "Welcome"
msgstr "Bienvenido"
msgid "You appear to have disabled cookies in your browser. Please check the settings in your browser, and try again."
msgstr "Al parecer ha deshabilitado las cookies de su navegador. Por favor revise las preferencias de su navegador y reintente."
msgid "You are running an outdated version of SimpleSAMLphp. Please update to <a href=\"https://simplesamlphp.org/download\">the latest version</a> as soon as possible."
msgstr "Su instalaci&oacute;n de SimpleSAMLphp est&aacute; desactualizada. Por favor, actualice a la <a href=\"https://simplesamlphp.org/download\">&uacute;ltima versi&oacute;n</a> lo antes posible."

View File

@@ -0,0 +1,75 @@
msgid ""
msgstr ""
"X-Domain: core\n"
msgid "Close the web browser, and try again."
msgstr "Sulge brauser ja proovi uuesti."
msgid "Cookies may be disabled in the web browser."
msgstr "küpsiste keelamisest brauseris"
msgid "Go back to the previous page and try again."
msgstr "Mine tagasi eelmisele leheküljele ja proovi uuesti."
msgid "Hosted Shibboleth 1.3 Identity Provider Metadata (automatically generated)"
msgstr "Hostitud Shibboleth 2.0 identiteedipakkuja metaandmed (automaatselt genereeritud) "
msgid "Hosted Shibboleth 1.3 Service Provider Metadata (automatically generated)"
msgstr "Hostitud Shibboleth 1.3 identiteedipakkuja metaandmed (automaatselt genereeritud) "
msgid "If this problem persists, you can report it to the system administrators."
msgstr "Kui probleem ei kao, siis teavita sellest süsteemi administraatoreid."
msgid "If you are a developer who is deploying a single sign-on solution, you have a problem with the metadata configuration. Verify that metadata is configured correctly on both the identity provider and service provider."
msgstr "Kui sa oled arendaja, kes juurutab ühekordse sisselogimise lahendust, siis on probleemi põhjuseks metaandmete seadistused. Kontrolli, et metaandmed oleks seadistatud korrektselt nii identiteedipakkuja kui teenusepakkuja poolel."
msgid "If you are a user who received this error after following a link on a site, you should report this error to the owner of that site."
msgstr "Kui sa oled kasutaja, kes sai selle veateate veebilehel linki klõpsates, siis peaksid sellest tõrkest veebilehe omanikku teavitama."
msgid "Missing cookie"
msgstr "Küpsis puudub"
msgid "Opened the web browser with tabs saved from the previous session."
msgstr "brauseri avamisest eelmisel kasutuskorral salvestatud kaartidega"
msgid "Report this error"
msgstr "Teavita sellest tõrkest"
msgid "Retry"
msgstr "Proovi uuesti"
msgid "Retry login"
msgstr "Proovi uuesti logida"
msgid "Shibboleth 1.3 SP example - test logging in through your Shib IdP"
msgstr "Shibboleth 1.3 SP näide - sisselogimine sinu Shib IdP kaudu"
msgid "State information lost"
msgstr "Olekuinfo on kadunud"
msgid "Suggestions for resolving this problem:"
msgstr "Nõuanded selle probleemi lahendamiseks:"
msgid "This error may be caused by:"
msgstr "See tõrge võib olla põhjustatud:"
msgid "This is most likely a configuration problem on either the service provider or identity provider."
msgstr "Tõenäoliselt on tegemist probleemiga kas teenusepakkuja või identiteedipakkuja seadistustes."
msgid "Too short interval between single sign on events."
msgstr "Liiga lühike intervall ühekordse sisselogimise sündmuste vahel."
msgid "Using the back and forward buttons in the web browser."
msgstr "brauseri edasi-tagasi nuppude kasutamisest"
msgid "We have detected that there is only a few seconds since you last authenticated with this service provider, and therefore assume that there is a problem with this SP."
msgstr "Tuvastasime, et sinu viimasest autentimisest selle teenusepakkujaga on möödunud ainult mõned sekundid ja seepärast arvame, et sellega teenusepakkujaga on probleeme."
msgid "We were unable to locate the state information for the current request."
msgstr "Aktiivse päringu olekuinfo leidmine ei õnnestunud."
msgid "Welcome"
msgstr "Tere tulemast"
msgid "You appear to have disabled cookies in your browser. Please check the settings in your browser, and try again."
msgstr "Paistab, et sinu brauseris on küpsised keelatud. Palun kontrolli brauseri seadistusi ja proovi seejärel uuesti."

View File

@@ -0,0 +1,75 @@
msgid ""
msgstr ""
"X-Domain: core\n"
msgid "Close the web browser, and try again."
msgstr "Nabigatzailea itxi eta saiatu berriro"
msgid "Cookies may be disabled in the web browser."
msgstr "Cookie-ak desgaituta egon litezke nabigatzailean."
msgid "Go back to the previous page and try again."
msgstr "Itzul zaitez aurreko orrira eta saiatu berriro"
msgid "Hosted Shibboleth 1.3 Identity Provider Metadata (automatically generated)"
msgstr "IdP Shibooleth 1.3ren ostatatutako metadatuak (automatikoki sortuak)"
msgid "Hosted Shibboleth 1.3 Service Provider Metadata (automatically generated)"
msgstr "SP Shibooleth 1.3ren ostatatutako metadatuak (automatikoki sortuak)"
msgid "If this problem persists, you can report it to the system administrators."
msgstr "Arazoak bere horretan badirau, sistemaren administratzaileei berri eman diezaiekezu."
msgid "If you are a developer who is deploying a single sign-on solution, you have a problem with the metadata configuration. Verify that metadata is configured correctly on both the identity provider and service provider."
msgstr "Hasiera-bakarreko sistema bat zabaltzen ari zaren garatzaile bat bazara, arazo bat duzu zure metadatuen kongigurazioarekin. Egiazta ezazu metadatuak zuzen konfiguratuak daudela identitate hornitzailean eta zerbitzu hornitzailean."
msgid "If you are a user who received this error after following a link on a site, you should report this error to the owner of that site."
msgstr "Gune bateko lotura bat jarraituz errore hau jasotzen duen erabiltzaile bat bazara, guneko jabeari eman behar diozu errorearen berri."
msgid "Missing cookie"
msgstr "Cookie-a falta da"
msgid "Opened the web browser with tabs saved from the previous session."
msgstr "Zure web nabigatzailea aurreko saiotik gordeta zeuden fitxekin ireki duzu."
msgid "Report this error"
msgstr "Errore honen berri eman"
msgid "Retry"
msgstr "Saiatu berriro"
msgid "Retry login"
msgstr "Saiatu berriro kautotzen"
msgid "Shibboleth 1.3 SP example - test logging in through your Shib IdP"
msgstr "SPren adibidea Shibboleth 1.3 erabiliz - saikera zure IdP Shibboleth erabiliz sartzen"
msgid "State information lost"
msgstr "Egoeraren informazioa galdu da"
msgid "Suggestions for resolving this problem:"
msgstr "Arazo hau konpontzeko iradokizunak:"
msgid "This error may be caused by:"
msgstr "Errore hau honek eragin dezake:"
msgid "This is most likely a configuration problem on either the service provider or identity provider."
msgstr "Hau ziurrenik konfigurazio arazo bat izango da zerbitzu hornitzailean edota identitate hornitzailean. "
msgid "Too short interval between single sign on events."
msgstr "Denbora tarte oso motza saio bakarreko gertaeren artean."
msgid "Using the back and forward buttons in the web browser."
msgstr "Zure web nabigatzaileko atzera eta aurrera botoiak erabiltzen."
msgid "We have detected that there is only a few seconds since you last authenticated with this service provider, and therefore assume that there is a problem with this SP."
msgstr "Azken aldiz zerbitzu honetan kautotu zinenetik segundu gutxi batzu besterik ez direla igaro antzeman dugu, beraz ZH honekin arazoren bat dagoela hartuko dugu. "
msgid "We were unable to locate the state information for the current request."
msgstr "Ez dugu aurkitu egoeraren informaziorik eskaera honentzat."
msgid "Welcome"
msgstr "Ongi etorri"
msgid "You appear to have disabled cookies in your browser. Please check the settings in your browser, and try again."
msgstr "Badirudi zure nabigatzaileko cookie-ak desgaitu dituzula. Mesedez, berrikusi zure nabigatzaileko lehentasunak eta saiatu berriro."

View File

@@ -0,0 +1,24 @@
msgid ""
msgstr ""
"X-Domain: core\n"
msgid "Hosted Shibboleth 1.3 Identity Provider Metadata (automatically generated)"
msgstr "Isännöidyn Shibboleth 1.3 identiteetintarjoajan Metadata (automaattisesti luotu)"
msgid "Hosted Shibboleth 1.3 Service Provider Metadata (automatically generated)"
msgstr "Isännöidyn Shibboleth 1.3 palveluntarjoajan Metadata (automaattisesti luotu)"
msgid "Missing cookie"
msgstr "Puuttuva eväste"
msgid "Retry"
msgstr "Uudestaan"
msgid "Shibboleth 1.3 SP example - test logging in through your Shib IdP"
msgstr "Shibboleth 1.3 SP esimerkki - testikirjautuminen Shib IdP:si kautta"
msgid "Welcome"
msgstr "Tervetuloa"
msgid "You appear to have disabled cookies in your browser. Please check the settings in your browser, and try again."
msgstr "Näyttää, että olet kieltänyt evästeiden käytön selaimessasi. Ole hyvä ja salli evästeet selaimestasi ja yritä uudelleen."

View File

@@ -0,0 +1,75 @@
msgid ""
msgstr ""
"X-Domain: core\n"
msgid "Close the web browser, and try again."
msgstr "Fermez le navigateur, essayez à nouveau."
msgid "Cookies may be disabled in the web browser."
msgstr "Les cookies sont peut-être déactivés dans le navigateur."
msgid "Go back to the previous page and try again."
msgstr "Retournez à la page précédente et réessayez."
msgid "Hosted Shibboleth 1.3 Identity Provider Metadata (automatically generated)"
msgstr "Métadonnées du fournisseur d'identités Shibboleth 1.3 (générées automatiquement)"
msgid "Hosted Shibboleth 1.3 Service Provider Metadata (automatically generated)"
msgstr "Métadonnées du fournisseur de service Shibboleth 1.3 (générées automatiquement)"
msgid "If this problem persists, you can report it to the system administrators."
msgstr "Si ce problème persiste, vous pouvez le remonter vers l'administrateur système."
msgid "If you are a developer who is deploying a single sign-on solution, you have a problem with the metadata configuration. Verify that metadata is configured correctly on both the identity provider and service provider."
msgstr "Si vous êtes un développeur qui déploie une solution de single sign-on, vous avez un problème avec la configuration des métadonnées. Vérifiez que ces métadonnées sont correctement configurées sur le fournisseur d'identité et le fournisseur de service "
msgid "If you are a user who received this error after following a link on a site, you should report this error to the owner of that site."
msgstr "Si vous êtes un usager qui reçoit cette erreur après avoir suivi un lien sur un site, vous devriez remonter cette erreur au propriétaire de ce site."
msgid "Missing cookie"
msgstr "Cookie introuvable"
msgid "Opened the web browser with tabs saved from the previous session."
msgstr "Ouvert le navigateur avec des onglets sauvegardés lors de la session précédente."
msgid "Report this error"
msgstr "Remontez cette erreur"
msgid "Retry"
msgstr "Ré-essayer"
msgid "Retry login"
msgstr "Ré-essayez de vous connecter"
msgid "Shibboleth 1.3 SP example - test logging in through your Shib IdP"
msgstr "SP Shibboleth 1.3 d'exemple - tester l'identification via votre IdP"
msgid "State information lost"
msgstr "Information d'état perdue"
msgid "Suggestions for resolving this problem:"
msgstr "Suggestions pour résoudre ce problème :"
msgid "This error may be caused by:"
msgstr "Cette erreur peut être causée par :"
msgid "This is most likely a configuration problem on either the service provider or identity provider."
msgstr "Cela ressemble à un problème de configuration soit du fournisseur de service ou du fournisseur d'identité."
msgid "Too short interval between single sign on events."
msgstr "Connexions uniques trop proches dans le temps."
msgid "Using the back and forward buttons in the web browser."
msgstr "Utilisation des boutons avance et retour dans le navigateur."
msgid "We have detected that there is only a few seconds since you last authenticated with this service provider, and therefore assume that there is a problem with this SP."
msgstr "Il ne s'est écoulé que quelques secondes depuis votre authentification précédente, ce qui est la marque d'un dysfonctionnement de ce SP."
msgid "We were unable to locate the state information for the current request."
msgstr "Nous ne pouvons pas trouver l'information d'état pour la demande courante."
msgid "Welcome"
msgstr "Bienvenue"
msgid "You appear to have disabled cookies in your browser. Please check the settings in your browser, and try again."
msgstr "Il semble que votre navigateur refuse les cookies. Merci de vérifier les réglages de votre navigateur, puis de ré-essayer."

View File

@@ -0,0 +1,75 @@
msgid ""
msgstr ""
"X-Domain: core\n"
msgid "Close the web browser, and try again."
msgstr "סגור את הדפדפן, ונסה שוב."
msgid "Cookies may be disabled in the web browser."
msgstr "תמיכה בעוגיות מבוטלת בדפדפן"
msgid "Go back to the previous page and try again."
msgstr "חזור לדף הקודם ונסה שוב."
msgid "Hosted Shibboleth 1.3 Identity Provider Metadata (automatically generated)"
msgstr "מטא-הנתונים של ספק השזהויות מסוג Shibboleth 1.3 המאורח (נוצר אוטומטית)"
msgid "Hosted Shibboleth 1.3 Service Provider Metadata (automatically generated)"
msgstr "מטא-הנתונים של ספק השירותים מסוג Shibboleth 1.3 המאורח (נוצר אוטומטית)"
msgid "If this problem persists, you can report it to the system administrators."
msgstr "אם הבעייה ממשיכה, אתה יכול לדווח עליה למנהל המערכת."
msgid "If you are a developer who is deploying a single sign-on solution, you have a problem with the metadata configuration. Verify that metadata is configured correctly on both the identity provider and service provider."
msgstr "אם אתה מפתח שפורש פיתרון התחברות יחידה, יש לך בעייה עם הגדרות המטא-מידע. בדוק שהמטא-מידע מוגדר נכון בספקי הזהות והשרות."
msgid "If you are a user who received this error after following a link on a site, you should report this error to the owner of that site."
msgstr "אם אתה משתמש שקיבל שגיאה זו לאחר לחיצה על קישור באתר, כדי שתדווח על השגיאה לבעלי האתר."
msgid "Missing cookie"
msgstr "חסרה עוגייה"
msgid "Opened the web browser with tabs saved from the previous session."
msgstr "פתיחת הדפדפן עם לשוניות שנשמרו משימוש הקודם."
msgid "Report this error"
msgstr "דווח על השגיאה הנוכחית"
msgid "Retry"
msgstr "נסה שנית"
msgid "Retry login"
msgstr "נסה שוב להתחבר"
msgid "Shibboleth 1.3 SP example - test logging in through your Shib IdP"
msgstr "דוגמא לס\"ש מסוג Shibboleth 1.3 - בוחן כניסה למערכת דרך ס\"ז מסוג - Shibboleth"
msgid "State information lost"
msgstr "מידע המצב אבד"
msgid "Suggestions for resolving this problem:"
msgstr "הצעות לפתרון הבעייה הנוכחית:"
msgid "This error may be caused by:"
msgstr "יכול להיות שהשגיאה נגרמה על-ידי:"
msgid "This is most likely a configuration problem on either the service provider or identity provider."
msgstr "זו, ככל הנראה, בעייה בהגדרות של ספק הזהות או ספק השירות."
msgid "Too short interval between single sign on events."
msgstr "פרק זמן קצר מידי בין ארועי כניסה יחידה."
msgid "Using the back and forward buttons in the web browser."
msgstr "שימוש בכפתורי הבא והקודם בדפדפן."
msgid "We have detected that there is only a few seconds since you last authenticated with this service provider, and therefore assume that there is a problem with this SP."
msgstr "גילינו שעברו רק מספר שניות מאז שהיזדהת בפעם האחרונה עם ספק השרות הזה, ולכן אנחנו מניחים שישנה בעייה עם ס\"הש."
msgid "We were unable to locate the state information for the current request."
msgstr "לא הצלחנו לאתר את מידע המצב לבקשה הנוכחית."
msgid "Welcome"
msgstr "ברוך-הבא"
msgid "You appear to have disabled cookies in your browser. Please check the settings in your browser, and try again."
msgstr "נראה שכיבית את העוגיות בדפדפן שלךץ אנא בדוק את ההגדרות בדפדפן שלך, ונסה שנית. "

View File

@@ -0,0 +1,75 @@
msgid ""
msgstr ""
"X-Domain: core\n"
msgid "Close the web browser, and try again."
msgstr "Zatvorite web preglednik i pokušajte ponovno."
msgid "Cookies may be disabled in the web browser."
msgstr "Moguće da je podrška za kolačiće (\"cookies\") isključena u web pregledniku."
msgid "Go back to the previous page and try again."
msgstr "Vratite se na prethodnu stranicu i pokušajte ponovno."
msgid "Hosted Shibboleth 1.3 Identity Provider Metadata (automatically generated)"
msgstr "Metapodaci za lokalni Shibboleth 1.3 IdP (automatski generirani)"
msgid "Hosted Shibboleth 1.3 Service Provider Metadata (automatically generated)"
msgstr "Metapodaci za lokalni Shibboleth 1.3 SP (automatski generirani)"
msgid "If this problem persists, you can report it to the system administrators."
msgstr "Ako se ova greška bude i dalje pojavljivala, možete ju prijaviti administratorima."
msgid "If you are a developer who is deploying a single sign-on solution, you have a problem with the metadata configuration. Verify that metadata is configured correctly on both the identity provider and service provider."
msgstr "Ako ste programer koji postavlja sustav jedinstvene autentifikacije (Single Sign-On sustav), tada imate problema s konfiguracijom metapodataka. Provjerite jesu li metapodaci ispravno uneseni i na strani davatelja usluge i u konfiguraciji autentifikacijskog servisa."
msgid "If you are a user who received this error after following a link on a site, you should report this error to the owner of that site."
msgstr "Ako se ova greška pojavila nakon što ste slijedili poveznicu na nekoj web stranici, onda biste grešku trebali prijaviti vlasniku navedene stranice."
msgid "Missing cookie"
msgstr "Nedostaje kolačić (cookie)"
msgid "Opened the web browser with tabs saved from the previous session."
msgstr "Otvaranjem web preglednika sa spremljenim stranicama od prethodne sjednice."
msgid "Report this error"
msgstr "Prijavite ovu grešku"
msgid "Retry"
msgstr "Pokušaj ponovo"
msgid "Retry login"
msgstr "Pokušaj se prijaviti ponovo"
msgid "Shibboleth 1.3 SP example - test logging in through your Shib IdP"
msgstr "Shibboleth 1.3 SP primjer - isprobajte autentifikaciju kroz vaš Shib IdP"
msgid "State information lost"
msgstr "Podatak o stanju je izgubljen"
msgid "Suggestions for resolving this problem:"
msgstr "Preporuke za rješavanje ovog problema:"
msgid "This error may be caused by:"
msgstr "Ova greška može biti uzrokovana:"
msgid "This is most likely a configuration problem on either the service provider or identity provider."
msgstr "Najvjerojatnije je problem u konfiguraciji na strani davatelja usluge ili u konfiguraciji autentifikacijskog servisa."
msgid "Too short interval between single sign on events."
msgstr "Prekratak interval između uzastopnih SSO prijava."
msgid "Using the back and forward buttons in the web browser."
msgstr "Korištenjem gumba za prethodnu (back) i sljedeću (forward) stranicu u web pregledniku."
msgid "We have detected that there is only a few seconds since you last authenticated with this service provider, and therefore assume that there is a problem with this SP."
msgstr "Sustav je utvrdio da je prošlo tek nekoliko sekundi otkad ste se zadnji put autentificirali za pristup ovoj aplikaciji te stoga pretpostavljamo da se javio problem kod davatelja usluge."
msgid "We were unable to locate the state information for the current request."
msgstr "Ne možemo pronaći podatak o stanju aktualnog zahtjeva."
msgid "Welcome"
msgstr "Dobrodošli"
msgid "You appear to have disabled cookies in your browser. Please check the settings in your browser, and try again."
msgstr "Izgleda da ste onemogućili kolačiće (cookies) u vašem web pregledniku. Molimo provjerite postavke vašeg web preglednika i pokušajte ponovo."

View File

@@ -0,0 +1,75 @@
msgid ""
msgstr ""
"X-Domain: core\n"
msgid "Close the web browser, and try again."
msgstr "Zárja be böngészőjét, majd próbálja újra."
msgid "Cookies may be disabled in the web browser."
msgstr "Talán a böngészőben nincsenek engedélyezve a sütik (cookie)."
msgid "Go back to the previous page and try again."
msgstr "Menjen vissza az előző oldalra, majd próbálja ismét."
msgid "Hosted Shibboleth 1.3 Identity Provider Metadata (automatically generated)"
msgstr "Ezen a gépen futó (hosted) Shibboleth 1.3 személyazonosság-szolgáltató (IdP) metaadat (automatikusan generált)"
msgid "Hosted Shibboleth 1.3 Service Provider Metadata (automatically generated)"
msgstr "Ezen a gépen futó (hosted) Shibboleth 1.3 alkalmazásszolgáltató (SP) metaadat (automatikusan generált)"
msgid "If this problem persists, you can report it to the system administrators."
msgstr "Ha a probléma állandónak tűnik, kérjük, jelezze ezt az oldal adminisztrátorának."
msgid "If you are a developer who is deploying a single sign-on solution, you have a problem with the metadata configuration. Verify that metadata is configured correctly on both the identity provider and service provider."
msgstr "Ha ön az oldal üzemeltetője, úgy javasoljuk, ellenőrizze a metaadat beállításokat mint IdP-, mind SP oldalon."
msgid "If you are a user who received this error after following a link on a site, you should report this error to the owner of that site."
msgstr "Amennyiben ön, mint felhasználó keveredett erre az oldalra, úgy kérjük, a hibával keresse az oldal adminisztrátorát."
msgid "Missing cookie"
msgstr "Hiányzó süti (cookie)"
msgid "Opened the web browser with tabs saved from the previous session."
msgstr "A böngésző a legutóbb bezárt füleket újranyitva indult."
msgid "Report this error"
msgstr "A hiba jelentése"
msgid "Retry"
msgstr "Újra"
msgid "Retry login"
msgstr "Újbóli belépés"
msgid "Shibboleth 1.3 SP example - test logging in through your Shib IdP"
msgstr "Shibboleth 1.3 SP példa - teszt bejelentkezés saját Shibboleth 1.3 IdP keresztül"
msgid "State information lost"
msgstr "Elvezett az állapotinformácó"
msgid "Suggestions for resolving this problem:"
msgstr "Javaslat a probléma elhárítására:"
msgid "This error may be caused by:"
msgstr "Az alábbi hibát okozhatta:"
msgid "This is most likely a configuration problem on either the service provider or identity provider."
msgstr "Valószínűleg valamilyen konfigurációs probléma okozta hiba, amely lehet akár IdP-, akár SP-oldalon."
msgid "Too short interval between single sign on events."
msgstr "Túl kevés idő telt el a belépési kísérletek között."
msgid "Using the back and forward buttons in the web browser."
msgstr "Használja a böngésző előre, ill. vissza gombjait"
msgid "We have detected that there is only a few seconds since you last authenticated with this service provider, and therefore assume that there is a problem with this SP."
msgstr "Mindössze néhány másodperc telt el az SP-hez történő, legutóbbi azonosítás óta. Ez nem normális működés, úgy tűnik, valami probléma lépett fel az SP-nél."
msgid "We were unable to locate the state information for the current request."
msgstr "Nem lehet beazonosítani a kéréshez tartozó állapotinformációt."
msgid "Welcome"
msgstr "Üdvözöljük"
msgid "You appear to have disabled cookies in your browser. Please check the settings in your browser, and try again."
msgstr "Úgy tűnik, az ön böngészőjében nincsenek engedélyezve a sütik (cookie) használata. Kérjük ellenőrizze beállításait, majd próbálja újra."

View File

@@ -0,0 +1,75 @@
msgid ""
msgstr ""
"X-Domain: core\n"
msgid "Close the web browser, and try again."
msgstr "Tutup browser, dan coba lagi."
msgid "Cookies may be disabled in the web browser."
msgstr "Cookie mungkin dinonaktifkan pada web browser ini."
msgid "Go back to the previous page and try again."
msgstr "Kembali ke halaman sebelumnya dan coba lagi."
msgid "Hosted Shibboleth 1.3 Identity Provider Metadata (automatically generated)"
msgstr "Metadata Identity Provider Shibboleth 1.3 Hosted (secara otomatis digenerate)"
msgid "Hosted Shibboleth 1.3 Service Provider Metadata (automatically generated)"
msgstr "Metadata Service Provider Shibboleth 1.3 Hosted (secara otomatis digenerate)"
msgid "If this problem persists, you can report it to the system administrators."
msgstr "Jika masalah ini tetap terjadi, anda dapat melaporkannnya ke system administrator."
msgid "If you are a developer who is deploying a single sign-on solution, you have a problem with the metadata configuration. Verify that metadata is configured correctly on both the identity provider and service provider."
msgstr "Jika anda adalah pengembang yang mendeploy solusi sing-on, anda memiliki masalah dengan konfigurasi metadata. Periksalah kalau metadata telah dikonfigurasi dengan benar baik pada sisi identity provider dan pada sisi service provider."
msgid "If you are a user who received this error after following a link on a site, you should report this error to the owner of that site."
msgstr "Jika adalah user yang menerika error ini setelah mengklik link pada sebuah situs, anda harus melaporkan error ini kepada pemilik situs tersebut"
msgid "Missing cookie"
msgstr "Cookie hilang"
msgid "Opened the web browser with tabs saved from the previous session."
msgstr "Membuka web browser dengan tab-tab yang telah disimpan dari session sebelumnya."
msgid "Report this error"
msgstr "Laporkan error ini"
msgid "Retry"
msgstr "Coba lagi"
msgid "Retry login"
msgstr "Coba login kembali"
msgid "Shibboleth 1.3 SP example - test logging in through your Shib IdP"
msgstr "Contoh Shibboleth 1.3 SP - Tes login melalui IdP Shib Anda"
msgid "State information lost"
msgstr "Informasi kondisi/state hilang"
msgid "Suggestions for resolving this problem:"
msgstr "Saran untuk memperbaiki masalah ini:"
msgid "This error may be caused by:"
msgstr "Error ini mungkin disebabkan oleh:"
msgid "This is most likely a configuration problem on either the service provider or identity provider."
msgstr "Sepertinya ini terjadi karena ada kesalahan konfigurasi baik pada service provider maupun pada identity provider"
msgid "Too short interval between single sign on events."
msgstr "Interval yang terlalu pendek antara event single sign on."
msgid "Using the back and forward buttons in the web browser."
msgstr "Menggunakan tombol back dan forward pada browser web."
msgid "We have detected that there is only a few seconds since you last authenticated with this service provider, and therefore assume that there is a problem with this SP."
msgstr "Kami telah mendeteksi kalau beberapa detik yang lalu sejak autentifikasi yang anda lakukan pada service provider ini, dan oleh karena itu diasumsikan ada masalah dengan SP ini"
msgid "We were unable to locate the state information for the current request."
msgstr "Kita tidak dapat menemukan informasi kondisi/state dari request saat ini."
msgid "Welcome"
msgstr "Selamat Datang"
msgid "You appear to have disabled cookies in your browser. Please check the settings in your browser, and try again."
msgstr "Anda sepertinya menonaktifkan cookie di browser anda. Silahkan periksa pengaturan pada browser anda, dan coba lagi."

View File

@@ -0,0 +1,75 @@
msgid ""
msgstr ""
"X-Domain: core\n"
msgid "Close the web browser, and try again."
msgstr "Chiudere il browser web e quindi provare di nuovo."
msgid "Cookies may be disabled in the web browser."
msgstr "I cookies potrebbe essere disabilitati."
msgid "Go back to the previous page and try again."
msgstr "Tornare alla pagina precedente e provare di nuovo."
msgid "Hosted Shibboleth 1.3 Identity Provider Metadata (automatically generated)"
msgstr "Metadati dell'Identity Provider Shibboleth 1.3 Locale (generati automaticamente)"
msgid "Hosted Shibboleth 1.3 Service Provider Metadata (automatically generated)"
msgstr "Metadati del Service Provider Shibboleth 1.3 Locale (generati automaticamente)"
msgid "If this problem persists, you can report it to the system administrators."
msgstr "Se questo problema persiste, è possibile segnalarlo agli amministratori di sistema."
msgid "If you are a developer who is deploying a single sign-on solution, you have a problem with the metadata configuration. Verify that metadata is configured correctly on both the identity provider and service provider."
msgstr "Se sei uno sviluppatore che sta sviluppando una soluzione di single sign-on, hai un problema con la configurazione dei metadati. Verifica che siano correttamente configurati sia sull'identity provider che sul service provider."
msgid "If you are a user who received this error after following a link on a site, you should report this error to the owner of that site."
msgstr "Se sei un utente che ha ricevuto questo errore dopo aver cliccato un link su un sito, dovresti riportare questo errore al gestore di quel sito."
msgid "Missing cookie"
msgstr "Cookie mancante"
msgid "Opened the web browser with tabs saved from the previous session."
msgstr "Il browser web è stato aperto e le finestre (tab) sono state ripristinate dalla sessione precedente."
msgid "Report this error"
msgstr "Riportare questo errore."
msgid "Retry"
msgstr "Riprovare"
msgid "Retry login"
msgstr "Riprovare a connettersi"
msgid "Shibboleth 1.3 SP example - test logging in through your Shib IdP"
msgstr "Esempio di Shibboleth 1.3 SP - prova l'autenticazione tramite il tuo IdP Shibboleth"
msgid "State information lost"
msgstr "Informazioni di stato perse"
msgid "Suggestions for resolving this problem:"
msgstr "Suggerimenti per risolvere questo problema:"
msgid "This error may be caused by:"
msgstr "Questo errore potrebbe essere causato da:"
msgid "This is most likely a configuration problem on either the service provider or identity provider."
msgstr "Questo è probabilmente un problema di configurazione del service provider o dell'identity provider."
msgid "Too short interval between single sign on events."
msgstr "L'intervallo tra le autenticazioni è troppo breve."
msgid "Using the back and forward buttons in the web browser."
msgstr "Utilizzo i pulsanti avanti ed indietro del browser web."
msgid "We have detected that there is only a few seconds since you last authenticated with this service provider, and therefore assume that there is a problem with this SP."
msgstr "E' stato rilevato che sono passati solo alcuni secondi dalla tua ultima autenticazione con questo fornitore di servizio, quindi si può assumere che ci sia un problema con il Service Provider."
msgid "We were unable to locate the state information for the current request."
msgstr "Non è stato possibile localizzare le informazioni di stato per la richiesta corrente."
msgid "Welcome"
msgstr "Benvenuto"
msgid "You appear to have disabled cookies in your browser. Please check the settings in your browser, and try again."
msgstr "Sembra che i cookie siano disabilitati nel browser. Si prega di verificare e quindi riprovare."

View File

@@ -0,0 +1,75 @@
msgid ""
msgstr ""
"X-Domain: core\n"
msgid "Close the web browser, and try again."
msgstr "WEBブラウザを閉じて、再度試してください。"
msgid "Cookies may be disabled in the web browser."
msgstr "このWEBブラウザではクッキーが無効化されています。"
msgid "Go back to the previous page and try again."
msgstr "前のページに戻り、再度試してください。"
msgid "Hosted Shibboleth 1.3 Identity Provider Metadata (automatically generated)"
msgstr "ホスト Shibboleth 1.3 アイデンティティプロバイダメタデータ (自動生成)"
msgid "Hosted Shibboleth 1.3 Service Provider Metadata (automatically generated)"
msgstr "ホスト Shibboleth 1.3 サービスプロバイダメタデータ(自動生成)"
msgid "If this problem persists, you can report it to the system administrators."
msgstr "この問題が継続して起こる場合、システム管理者に報告してください。"
msgid "If you are a developer who is deploying a single sign-on solution, you have a problem with the metadata configuration. Verify that metadata is configured correctly on both the identity provider and service provider."
msgstr "もしあなたが開発者でシングルサインオンシステムの構築者である場合、メタデータの設定に問題があります。アイデンティティプロバイダとサービスプロバイダの両方にメタデータが正しく設定されているか確認してください。"
msgid "If you are a user who received this error after following a link on a site, you should report this error to the owner of that site."
msgstr "もしあなたがユーザーで以下のリンクのサイトでこのエラーを受け取ったのであれば、このエラーをサイトの管理者に報告してください。"
msgid "Missing cookie"
msgstr "クッキーが見つかりません"
msgid "Opened the web browser with tabs saved from the previous session."
msgstr "ブラウザに保存されたタブにより、以前のセッションが開かれました。"
msgid "Report this error"
msgstr "このエラーをレポート"
msgid "Retry"
msgstr "再試行"
msgid "Retry login"
msgstr "ログインを再試行"
msgid "Shibboleth 1.3 SP example - test logging in through your Shib IdP"
msgstr "Shibboleth 1.3 SP example - Shib IdP経由でテストログイン"
msgid "State information lost"
msgstr "状態情報が無くなりました"
msgid "Suggestions for resolving this problem:"
msgstr "この問題を解決する為の提案:"
msgid "This error may be caused by:"
msgstr "このエラーの原因:"
msgid "This is most likely a configuration problem on either the service provider or identity provider."
msgstr "これは恐らくサービスプロバイダかアイデンティティプロバイダの設定の問題です。"
msgid "Too short interval between single sign on events."
msgstr "シングルサインオンイベントの間隔が短すぎます。"
msgid "Using the back and forward buttons in the web browser."
msgstr "WEBブラウザの戻るや次へのボタンを使用します。"
msgid "We have detected that there is only a few seconds since you last authenticated with this service provider, and therefore assume that there is a problem with this SP."
msgstr "このサービスプロバイダで最後に認証されてから数秒しか経過していないことが検出されたため、このSPに問題があると思われます。"
msgid "We were unable to locate the state information for the current request."
msgstr "現在のリクエストから状態情報を特定することが出来ませんでした。"
msgid "Welcome"
msgstr "ようこそ"
msgid "You appear to have disabled cookies in your browser. Please check the settings in your browser, and try again."
msgstr "ブラウザのクッキーが無効化されている可能性があります。ブラウザの設定を確認し、再度試してください。"

View File

@@ -0,0 +1,12 @@
msgid ""
msgstr ""
"X-Domain: core\n"
msgid "Hosted Shibboleth 1.3 Identity Provider Metadata (automatically generated)"
msgstr "Hosted Shibboleth 1.3 Identity Provider Meta Données (automatesch erstallt)"
msgid "Hosted Shibboleth 1.3 Service Provider Metadata (automatically generated)"
msgstr "Hosted Shibboleth 1.3 Service Provider Meta Données (automatesch erstallt)"
msgid "Shibboleth 1.3 SP example - test logging in through your Shib IdP"
msgstr "Shibboleth 1.3 SP Beispill - probeier dech iwer dain Shib IdP anzeloggen"

View File

@@ -0,0 +1,75 @@
msgid ""
msgstr ""
"X-Domain: core\n"
msgid "Close the web browser, and try again."
msgstr "Uždarykite interneto naršyklę ir pabandykite dar kartą."
msgid "Cookies may be disabled in the web browser."
msgstr "Interneto naršyklėje gali būti išjungti slapukai (cookies)."
msgid "Go back to the previous page and try again."
msgstr "Grįžkite į ankstesnį puslapį ir pabandykite dar kartą."
msgid "Hosted Shibboleth 1.3 Identity Provider Metadata (automatically generated)"
msgstr "Vietinio Shibboleth 1.3 tapatybės teikėjo (IdP) metaduomenys (sugeneruoti automatiškai)"
msgid "Hosted Shibboleth 1.3 Service Provider Metadata (automatically generated)"
msgstr "Vietinio Shibboleth 1.3 paslaugos teikėjo (SP) metaduomenys (sugeneruoti automatiškai)"
msgid "If this problem persists, you can report it to the system administrators."
msgstr "Jei ši problema išliks, galite pranešti apie tai sistemos administratoriui."
msgid "If you are a developer who is deploying a single sign-on solution, you have a problem with the metadata configuration. Verify that metadata is configured correctly on both the identity provider and service provider."
msgstr "Jei Jūs esate kūrėjas, kuris diegiate SSO sprendimą, Jums iškilo problema susijusi su metaduomenų konfigūracija. Patikrinkite, ar metaduomenys teisingai sukonfigūruoti tiek tapatybių teikėjo, tiek paslaugos teikėjo pusėse."
msgid "If you are a user who received this error after following a link on a site, you should report this error to the owner of that site."
msgstr "Jei Jūs esate naudotojas, kuris gavote šią klaidą spragtelėjęs nuorodą tinklapyje, Jūs turėtumėte informuoti tinklapio administratorių apie šią klaidą."
msgid "Missing cookie"
msgstr "Slapukas nerastas"
msgid "Opened the web browser with tabs saved from the previous session."
msgstr "Atidaryta interneto naršyklė su kortelėmis, išsaugotomis iš ankstesnės sesijos."
msgid "Report this error"
msgstr "Pranešti apie šią klaidą"
msgid "Retry"
msgstr "Bandyti dar kartą"
msgid "Retry login"
msgstr "Prisijunkite iš naujo"
msgid "Shibboleth 1.3 SP example - test logging in through your Shib IdP"
msgstr "Shibboleth 1.3 SP pavyzdys - istorinių duomenų testavimas kartu su Jūsų Shib IdP"
msgid "State information lost"
msgstr "Būsenos informacia prarasta"
msgid "Suggestions for resolving this problem:"
msgstr "Pasiūlymai spręsti šią problemą:"
msgid "This error may be caused by:"
msgstr "Šią klaidą galėjo sukelti:"
msgid "This is most likely a configuration problem on either the service provider or identity provider."
msgstr "Tai greičiausiai konfigūracijos problema paslaugos teikėjo arba tapatybių teikėjo pusėje."
msgid "Too short interval between single sign on events."
msgstr "Per trumpas intervalas tarp prisijungimų prie paslaugų."
msgid "Using the back and forward buttons in the web browser."
msgstr "Back (Atgal) ir Forward (Pirmyn) mygtukų naudojimas interneto naršyklėje"
msgid "We have detected that there is only a few seconds since you last authenticated with this service provider, and therefore assume that there is a problem with this SP."
msgstr "Mes nustatėme, kad praėjo tik kelios sekundės nuo Jūsų autentiškumo patvirtimo šiam paslaugos teikėjui, dėl to manome, kad yra nesklandumų su SP."
msgid "We were unable to locate the state information for the current request."
msgstr "Nepavyko nustatyti būsenos informacijos šiai užklausai."
msgid "Welcome"
msgstr "Sveiki atvykę"
msgid "You appear to have disabled cookies in your browser. Please check the settings in your browser, and try again."
msgstr "Atrodo Jūsų naršyklė nepalaiko slapukų. Patikrinkite naršyklės nustatymus ir bandykite dar kartą."

View File

@@ -0,0 +1,75 @@
msgid ""
msgstr ""
"X-Domain: core\n"
msgid "Close the web browser, and try again."
msgstr "Aizveriet interneta pārlūku un mēģiniet vēlreiz."
msgid "Cookies may be disabled in the web browser."
msgstr "Iespējams, interneta pārlūkā ir aizliegtas sīkdatnes."
msgid "Go back to the previous page and try again."
msgstr "Ejiet atpakaļ uz iepriekšējo lapu un mēģiniet vēlreiz."
msgid "Hosted Shibboleth 1.3 Identity Provider Metadata (automatically generated)"
msgstr "Hostēta Shibboleth 1.3 identitātes piegādātāja metadati (ģenerēti automātiski)"
msgid "Hosted Shibboleth 1.3 Service Provider Metadata (automatically generated)"
msgstr "Hostēta Shibboleth 1.3 servisa piegādātāja metadati (ģenerēti automātiski)"
msgid "If this problem persists, you can report it to the system administrators."
msgstr "Ja problēma atkārtojas, varat ziņot sistēmas administratoriem."
msgid "If you are a developer who is deploying a single sign-on solution, you have a problem with the metadata configuration. Verify that metadata is configured correctly on both the identity provider and service provider."
msgstr "Ja Jūs esat vienotas pieslēgšanās risinājuma izstrādātājs, Jūsu metadatu konfigurācijā ir kļūda. Pārbaudiet tos gan pie identitātes piegādātāja, gan pie servisa piegādātāja."
msgid "If you are a user who received this error after following a link on a site, you should report this error to the owner of that site."
msgstr "Ja Jūs esat lietotājs un saņemat šo kļūdu, sekojot saitei kādā interneta lapā, Jums jāziņo par šo kļūdu lapas īpašniekam."
msgid "Missing cookie"
msgstr "Trūkst sīkdatnes"
msgid "Opened the web browser with tabs saved from the previous session."
msgstr "Interneta pārlūka atvēršana ar saglabātām cilnēm no iepriekšējās sesijas."
msgid "Report this error"
msgstr "Ziņojiet par šo kļūdu"
msgid "Retry"
msgstr "Mēģināt vēlreiz"
msgid "Retry login"
msgstr "Mēģināt pieslēgties vēlreiz"
msgid "Shibboleth 1.3 SP example - test logging in through your Shib IdP"
msgstr "Shibboleth 1.3 SP piemērs - testa pieslēgšanās caur Jūsu Shib IDP"
msgid "State information lost"
msgstr "Stāvokļa informācija ir pazaudēta"
msgid "Suggestions for resolving this problem:"
msgstr "Ieteikumi problēmas atrisināšanai:"
msgid "This error may be caused by:"
msgstr "Kļūdu radījis:"
msgid "This is most likely a configuration problem on either the service provider or identity provider."
msgstr "Visticamāk šī ir konfigurācijas problēma pie servisa piegādātāja vai identitātes piegādātāja."
msgid "Too short interval between single sign on events."
msgstr "Pārāk mazs intervāls starp pieslēgšanās notikumiem."
msgid "Using the back and forward buttons in the web browser."
msgstr "Interneta pārlūka pogu Uz priekšu un Atpakaļ lietošana."
msgid "We have detected that there is only a few seconds since you last authenticated with this service provider, and therefore assume that there is a problem with this SP."
msgstr "Pēc pēdējās autentifikācijas ir pagājušas tikai dažas sekundes, tādēļ, iespējams, ir problēma ar servisa piegādātāju."
msgid "We were unable to locate the state information for the current request."
msgstr "Nav iespējams atrast stāvokļa informāciju šim pieprasījumam."
msgid "Welcome"
msgstr "Laipni lūdzam"
msgid "You appear to have disabled cookies in your browser. Please check the settings in your browser, and try again."
msgstr "Izskatās, ka Jūsu interneta pārlūkā ir aizliegtas sīkdatnes. Lūdzu pārbaudiet sava pārlūka uzstādījumus un mēģiniet vēlreiz."

View File

@@ -0,0 +1,75 @@
msgid ""
msgstr ""
"X-Domain: core\n"
msgid "Close the web browser, and try again."
msgstr "Lukk nettleseren, og prøv på nytt."
msgid "Cookies may be disabled in the web browser."
msgstr "At informasjonskapsler ikke er aktivert i nettleseren."
msgid "Go back to the previous page and try again."
msgstr "Gå tilbake til forrige side og prøv på nytt."
msgid "Hosted Shibboleth 1.3 Identity Provider Metadata (automatically generated)"
msgstr "Hosted Shibboleth 1.3 Identity Provider Metadata (automatisk generert)"
msgid "Hosted Shibboleth 1.3 Service Provider Metadata (automatically generated)"
msgstr "Hosted Shibboleth 1.3 Service Provider Metadata (automatisk generert)"
msgid "If this problem persists, you can report it to the system administrators."
msgstr "Hvis problemet vedvarer, kan du rapportere det til systemadministratorene."
msgid "If you are a developer who is deploying a single sign-on solution, you have a problem with the metadata configuration. Verify that metadata is configured correctly on both the identity provider and service provider."
msgstr "Hvis du er en utvikler som setter opp en \"single sign-on\" løsning, så har du et problem med metadataoppsettet. Kontroller at metadata er riktig konfigurert hos både identitetsleverandøren og tjenesteleverandøren."
msgid "If you are a user who received this error after following a link on a site, you should report this error to the owner of that site."
msgstr "Hvis du er en bruker som fikk denne feilen etter at du fulgte en link på en nettside, så bør du rapportere denne feilen til eieren av den nettsiden."
msgid "Missing cookie"
msgstr "Mangler informasjonskapsel"
msgid "Opened the web browser with tabs saved from the previous session."
msgstr "Starte nettleseren med faner lagret fra forrige gang."
msgid "Report this error"
msgstr "Rapporter denne feilen"
msgid "Retry"
msgstr "Prøv igjen"
msgid "Retry login"
msgstr "Forsøk å logge inn på nytt"
msgid "Shibboleth 1.3 SP example - test logging in through your Shib IdP"
msgstr "Shibboleth 1.3 SP eksempel - test innlogging med Shibboleth 1.3 via din IdP"
msgid "State information lost"
msgstr "Tilstandsinformasjon tapt"
msgid "Suggestions for resolving this problem:"
msgstr "Forslag for å løse dette problemet:"
msgid "This error may be caused by:"
msgstr "Denne feilen kan være forårsaket av:"
msgid "This is most likely a configuration problem on either the service provider or identity provider."
msgstr "Dette er sannsynligvis et konfigurasjonsproblem hos enten tjenesteleverandøren eller identitetsleverandøren."
msgid "Too short interval between single sign on events."
msgstr "For kort intervall imellom innloggingsforespørsler"
msgid "Using the back and forward buttons in the web browser."
msgstr "Bruk av \"frem\"- og \"tilbake\"-knappene i nettleseren."
msgid "We have detected that there is only a few seconds since you last authenticated with this service provider, and therefore assume that there is a problem with this SP."
msgstr "Vi har detektert at det er bare noen få sekunder siden du sist ble autentisert på denne tjenesten, og derfor antar vi at det er et problem med oppsettet av denne tjenesten."
msgid "We were unable to locate the state information for the current request."
msgstr "Vi kunne ikke finne tilstandsinformasjonen for denne forespørselen."
msgid "Welcome"
msgstr "Velkommen"
msgid "You appear to have disabled cookies in your browser. Please check the settings in your browser, and try again."
msgstr "Du ser ut til å ha deaktivert informasjonskapsler. Kontroller innstillingene i nettleseren din og prøv igjen."

View File

@@ -0,0 +1,81 @@
msgid ""
msgstr ""
"X-Domain: core\n"
msgid "Close the web browser, and try again."
msgstr "Sluit de web browser, en probeer opnieuw."
msgid "Cookies may be disabled in the web browser."
msgstr "Cookies kunnen uitgeschakeld zijn in de web browser."
msgid "Go back to the previous page and try again."
msgstr "Ga terug naar de vorige pagina, en probeer opnieuw."
msgid "Hosted Shibboleth 1.3 Identity Provider Metadata (automatically generated)"
msgstr "Lokale Shibboleth 1.3 Identity Provider Metadata (automatisch gegenereerd)"
msgid "Hosted Shibboleth 1.3 Service Provider Metadata (automatically generated)"
msgstr "Lokale Shibboleth 1.3 Service Provider Metadata (automatisch gegenereerd)"
msgid "If this problem persists, you can report it to the system administrators."
msgstr "If dit probleem behoud, dan kun je het melden aan de systeem beheerders."
msgid "If you are a developer who is deploying a single sign-on solution, you have a problem with the metadata configuration. Verify that metadata is configured correctly on both the identity provider and service provider."
msgstr "Als u een ontwikkelaar bent die een single sign-on oplossing aan het implementeren is, heeft u een probleem met de metadataconfiguratie. Controleer of de metadata correct is geconfigureerd zowel bij de identiteitsverstrekker als bij de service provider."
msgid "If you are a user who received this error after following a link on a site, you should report this error to the owner of that site."
msgstr "Als u een eindgebruiker bent die deze foutmelding kreeg na het volgen van een link op een site, dan kunt u deze fout melden bij de eigenaar van die site."
msgid "Missing cookie"
msgstr "Cookie ontbreekt"
msgid "Opened the web browser with tabs saved from the previous session."
msgstr "Web browser geopend met tabs opgeslagen van de vorige sessie."
msgid "Report this error"
msgstr "Meld deze error"
msgid "Retry"
msgstr "Opnieuw"
msgid "Retry login"
msgstr "Inloggen opnieuw proberen"
msgid "Shibboleth 1.3 SP example - test logging in through your Shib IdP"
msgstr "Shibboleth 1.3 SP voorbeeld - test inloggen via je Shibboleth 1.3 IdP"
msgid "State information lost"
msgstr "Toestand informatie verloren"
msgid "Suggestions for resolving this problem:"
msgstr "Suggesties om dit probleem op te lossen:"
msgid "This error may be caused by:"
msgstr "Deze error is waarschijnlijk veroorzaakt door:"
msgid "This is most likely a configuration problem on either the service provider or identity provider."
msgstr "Dit is waarschijnlijk een configuratieprobleem bij ofwel de serviceprovider ofwel de identiteitsverstrekker."
msgid "Too short interval between single sign on events."
msgstr "Te kort interval tussen single sign on pogingen"
msgid "Using the back and forward buttons in the web browser."
msgstr "Gebruik van de 'Volgende'- en 'Terug'-knoppen in de web browser."
msgid "Warnings"
msgstr "Waarschuwingen"
msgid "We have detected that there is only a few seconds since you last authenticated with this service provider, and therefore assume that there is a problem with this SP."
msgstr "We hebben waargenomen dat u slechts een paar seconden geleden al aangemeld bent bij deze serviceprovider, daarom nemen we aan dat er een probleem is met deze SP."
msgid "We were unable to locate the state information for the current request."
msgstr "Wij waren niet in staat om de toestand informatie te vinden voor het huidige verzoek."
msgid "Welcome"
msgstr "Welkom"
msgid "You appear to have disabled cookies in your browser. Please check the settings in your browser, and try again."
msgstr "Het ziet er naaruit dat cookies zijn uitgeschakeld in uw browser. Controleer de browserinstellingen en probeer het opnieuw."
msgid "You are running an outdated version of SimpleSAMLphp. Please update to <a href=\"https://simplesamlphp.org/download\">the latest version</a> as soon as possible."
msgstr "Deze installatie van SimpleSAMLphp is verouderd. Het is aan te raden zo snel mogelijk te upgraden naar <a href=\"https://simplesamlphp.org/download\">de meest recente versie</a>."

View File

@@ -0,0 +1,75 @@
msgid ""
msgstr ""
"X-Domain: core\n"
msgid "Close the web browser, and try again."
msgstr "Lukk nettlesaren, og prøv på nytt."
msgid "Cookies may be disabled in the web browser."
msgstr "At informasjonskapsler ikkje er aktivert i nettlesaren."
msgid "Go back to the previous page and try again."
msgstr "Gå tilbake til forrige side og prøv på nytt."
msgid "Hosted Shibboleth 1.3 Identity Provider Metadata (automatically generated)"
msgstr "Hosted Shibboleth 1.3 Identity Provider Metadata (automatisk generert)"
msgid "Hosted Shibboleth 1.3 Service Provider Metadata (automatically generated)"
msgstr "Hosted Shibboleth 1.3 Service Provider Metadata (automatisk generert)"
msgid "If this problem persists, you can report it to the system administrators."
msgstr "Om problemet vedvarar, kan du rapportere det til systemadministratorane."
msgid "If you are a developer who is deploying a single sign-on solution, you have a problem with the metadata configuration. Verify that metadata is configured correctly on both the identity provider and service provider."
msgstr "Om du er ein utviklar som set opp ei \"single sign-on\" løysing, så har du eit problem med metadataoppsettet. Kontroller at metadata er rett satt opp hjå både identitetsleverandøren og tenesteleverandøren."
msgid "If you are a user who received this error after following a link on a site, you should report this error to the owner of that site."
msgstr "Om du er ein brukar som mottok denne feilen etter at du følgde ei lenke på ei nettside, så bør du melde denne feilen til eigaren av den nettsida."
msgid "Missing cookie"
msgstr "Manglar informasjonskapsel"
msgid "Opened the web browser with tabs saved from the previous session."
msgstr "Starte nettlesaren med faner lagret fra forrige gong."
msgid "Report this error"
msgstr "Rapporter denne feilen"
msgid "Retry"
msgstr "Prøv på nytt"
msgid "Retry login"
msgstr "Prøv å logge inn på nytt"
msgid "Shibboleth 1.3 SP example - test logging in through your Shib IdP"
msgstr "Shibboleth 1.3 SP eksempel - testinnlogging med Shibboleth 1.3 via din IdP"
msgid "State information lost"
msgstr "Tilstandsinformasjon tapt"
msgid "Suggestions for resolving this problem:"
msgstr "Forslag for å løyse dette problemet:"
msgid "This error may be caused by:"
msgstr "Denne feilen kan være forårsaket av:"
msgid "This is most likely a configuration problem on either the service provider or identity provider."
msgstr "Dette er sannsynlegvis eit problem med oppsettet hjå anten tenesteleverandøren eller identitetsleverandøren."
msgid "Too short interval between single sign on events."
msgstr "For kort intervall mellom innloggingsforespørslar"
msgid "Using the back and forward buttons in the web browser."
msgstr "Bruk av \"fram\"- og \"attende\"-knappane i nettlesaren."
msgid "We have detected that there is only a few seconds since you last authenticated with this service provider, and therefore assume that there is a problem with this SP."
msgstr "Vi har merka at det kun er nokon få sekund sidan du sist vart logga inn på denne tenesta, og derfor trur vi at det er eit problem med oppsettet av denne tjenesta."
msgid "We were unable to locate the state information for the current request."
msgstr "Vi kunne ikkje finne tilstandsinformasjonen for denne forespørselen."
msgid "Welcome"
msgstr "Velkomen"
msgid "You appear to have disabled cookies in your browser. Please check the settings in your browser, and try again."
msgstr "Det ser ut til at informasjonskapslar er avslått i nettlesaren din. Vær vennleg og sjekk instillingane i nettlesaren din, og prøv på nytt."

View File

@@ -0,0 +1,15 @@
msgid ""
msgstr ""
"X-Domain: core\n"
msgid "Hosted Shibboleth 1.3 Identity Provider Metadata (automatically generated)"
msgstr "Metadane - Lokalny Shibboleth 1.3 Dostawca Tożsamości (generowane automatycznie)"
msgid "Hosted Shibboleth 1.3 Service Provider Metadata (automatically generated)"
msgstr "Metadane - Lokalny Shibboleth 1.3 Dostawca Serwisu (generowane automatycznie)"
msgid "Shibboleth 1.3 SP example - test logging in through your Shib IdP"
msgstr "Shibboleth 1.3 SP - przykład - test logowania przez Twoje Shib IdP"
msgid "Welcome"
msgstr "Witaj"

View File

@@ -0,0 +1,36 @@
msgid ""
msgstr ""
"X-Domain: core\n"
msgid "Hosted Shibboleth 1.3 Identity Provider Metadata (automatically generated)"
msgstr "Metadados do fornecedor de identidade (IdP) Shibboleth 1.3 local (gerado automaticamente)"
msgid "Hosted Shibboleth 1.3 Service Provider Metadata (automatically generated)"
msgstr "Metadados do fornecedor de serviço (SP) Shibboleth 1.3 local (gerado automaticamente)"
msgid "Missing cookie"
msgstr "Cookie não encontrado"
msgid "Retry"
msgstr "Tentar de novo"
msgid "Retry login"
msgstr "Tentar de novo"
msgid "Shibboleth 1.3 SP example - test logging in through your Shib IdP"
msgstr "Exemplo de um SP Shibboleth 1.3 - Para testes de login pelo seu IdP Shib"
msgid "SimpleSAMLphp Advanced Features"
msgstr "Funcionalidades avançadas do SimpleSAMLphp"
msgid "Too short interval between single sign on events."
msgstr "Intervalo entre eventos de single sign on demasiado curto."
msgid "We have detected that there is only a few seconds since you last authenticated with this service provider, and therefore assume that there is a problem with this SP."
msgstr "Foi detectada uma repetição de autenticação neste serviço em poucos segundos. Este SP pode ter um problema."
msgid "Welcome"
msgstr "Bem vindo"
msgid "You appear to have disabled cookies in your browser. Please check the settings in your browser, and try again."
msgstr "Provavelmente desligou o suporte de cookies no seu browser. Por favor verifique se tem o suporte de cookies ligado e tente de novo."

View File

@@ -0,0 +1,24 @@
msgid ""
msgstr ""
"X-Domain: core\n"
msgid "Hosted Shibboleth 1.3 Identity Provider Metadata (automatically generated)"
msgstr "Hospedado Shibboleth 1.3 Identity Provider Metadata (gerado automaticamente)"
msgid "Hosted Shibboleth 1.3 Service Provider Metadata (automatically generated)"
msgstr "Hospedado Shibboleth 1.3 Service Provider Metadata (gerado automaticamente)"
msgid "If you are a developer who is deploying a single sign-on solution, you have a problem with the metadata configuration. Verify that metadata is configured correctly on both the identity provider and service provider."
msgstr "Se você é um desenvolvedor que está implantando uma solução SSO, você tem um problema com a configuração de metadados. Verifique se os metadados estão configurados corretamente no provedor de identidade e no provedor de serviços."
msgid "If you are a user who received this error after following a link on a site, you should report this error to the owner of that site."
msgstr "Se você é um usuário que recebeu esse erro depois de seguir um link em um site, você deve relatar esse erro para o proprietário do site."
msgid "Shibboleth 1.3 SP example - test logging in through your Shib IdP"
msgstr "Shibboleth 1.3 SP exemplo - efetuar login na sua Shib IDP"
msgid "This is most likely a configuration problem on either the service provider or identity provider."
msgstr "Isso é possivelmente um problema de configuração do provedor de serviços ou do provedor de identidade."
msgid "Welcome"
msgstr "Seja bem-vindo(a)"

View File

@@ -0,0 +1,75 @@
msgid ""
msgstr ""
"X-Domain: core\n"
msgid "Close the web browser, and try again."
msgstr "Închideți browser-ul și încercați din nou."
msgid "Cookies may be disabled in the web browser."
msgstr "Browser-ul are deactivate <i>cookies</i>."
msgid "Go back to the previous page and try again."
msgstr "Accesați pagina anterioară și încercați din nou."
msgid "Hosted Shibboleth 1.3 Identity Provider Metadata (automatically generated)"
msgstr "Metadate pentru furnizorul de identitate Shibboleth 1.3 găzduit (generate automat)"
msgid "Hosted Shibboleth 1.3 Service Provider Metadata (automatically generated)"
msgstr "Metadate pentru furnizorul de servicii Shibboleth 1.3 găzduit (generate automat)"
msgid "If this problem persists, you can report it to the system administrators."
msgstr "Dacă problema persistă, anunțați administratorii de sistem."
msgid "If you are a developer who is deploying a single sign-on solution, you have a problem with the metadata configuration. Verify that metadata is configured correctly on both the identity provider and service provider."
msgstr "Dacă sunteți dezvoltator care implementează o soluție <i>single sign-on</i>, aveți o problemă la configurarea metadatelor. Vă rugăm să verificați configurarea corectă a metadatelor, atât la furnizorul de identitate cât și la furnizorul de servicii."
msgid "If you are a user who received this error after following a link on a site, you should report this error to the owner of that site."
msgstr "Dacă sunteți un utilizator care a primit acest mesaj de eroare în urma utilizării unui link din alt sit, vă rugăm să anunțați această eroare deținătorului sitului respectiv."
msgid "Missing cookie"
msgstr "<i>Cookie</i> lipsă"
msgid "Opened the web browser with tabs saved from the previous session."
msgstr "Pornirea browser-ului cu file salvate într-o sesiune anterioară."
msgid "Report this error"
msgstr "Vă rugăm să anunțați această eroare"
msgid "Retry"
msgstr "Încearcă din nou"
msgid "Retry login"
msgstr "Încercați din nou"
msgid "Shibboleth 1.3 SP example - test logging in through your Shib IdP"
msgstr "Exemplu furnizor de servicii Shibboleth 1.3 - testarea autentificării prin furnizorul dumneavoastră de identitate Shib"
msgid "State information lost"
msgstr "Informațiile de stare au fost pierdute"
msgid "Suggestions for resolving this problem:"
msgstr "Sugestii pentru rezolvarea acestei probleme:"
msgid "This error may be caused by:"
msgstr "Această eroare poate fi cauzată de:"
msgid "This is most likely a configuration problem on either the service provider or identity provider."
msgstr "Probabil există o problemă de configurare, fie la furnizorul de servicii fie la furnizorul de identitate."
msgid "Too short interval between single sign on events."
msgstr "Interval prea scurt între evenimentele <i>single sign-on</i>."
msgid "Using the back and forward buttons in the web browser."
msgstr "Utilizarea butoanelor \"înainte\" sau \"înapoi\" din browser."
msgid "We have detected that there is only a few seconds since you last authenticated with this service provider, and therefore assume that there is a problem with this SP."
msgstr "A fost detectat faptul că v-ați autentificat în urmă cu doar câteva secunde cu acest furnizor de servicii, se va considera că există o problemă cu acest furnizor de servicii."
msgid "We were unable to locate the state information for the current request."
msgstr "Nu a fost posibilă localizarea informațiilor de stare pentru cererea curentă."
msgid "Welcome"
msgstr "Bine ați venit"
msgid "You appear to have disabled cookies in your browser. Please check the settings in your browser, and try again."
msgstr "<i>Cookies</i> au fost dezactivate în browser-ul dumneavoastră. Vă rugăm să verificați configurarea browser-ului după care încercați din nou."

View File

@@ -0,0 +1,75 @@
msgid ""
msgstr ""
"X-Domain: core\n"
msgid "Close the web browser, and try again."
msgstr "Закрыть веб браузер и попробовать снова."
msgid "Cookies may be disabled in the web browser."
msgstr "Возможно, в браузере отключены Cookies."
msgid "Go back to the previous page and try again."
msgstr "Вернуться к предыдущей странице и попробовать снова."
msgid "Hosted Shibboleth 1.3 Identity Provider Metadata (automatically generated)"
msgstr "Метаданные Shibboleth 1.3 Провайдера подлинности (IdP) (генерируются автоматически)"
msgid "Hosted Shibboleth 1.3 Service Provider Metadata (automatically generated)"
msgstr "Метаданные Shibboleth 1.3 Поставщика Услуг (SP) (генерируются автоматически)"
msgid "If this problem persists, you can report it to the system administrators."
msgstr "Если проблема остается, сообщить об этом администратору."
msgid "If you are a developer who is deploying a single sign-on solution, you have a problem with the metadata configuration. Verify that metadata is configured correctly on both the identity provider and service provider."
msgstr "Если вы разработчик внедряющий Технологию единого вход (SSO), у вас есть проблемы с метаданными конфигурации. Убедитесь, что метаданные настроены правильно на Провайдере подлинности и Поставщике услуг."
msgid "If you are a user who received this error after following a link on a site, you should report this error to the owner of that site."
msgstr "Если, перейдя по ссылке на сайт, вы увидели эту ошибку, вы должны сообщить об этом владелецу этого сайта."
msgid "Missing cookie"
msgstr "Отсутствует cookie-файл"
msgid "Opened the web browser with tabs saved from the previous session."
msgstr "Открыт браузер с сохраненными закладками от предыдущей сессии."
msgid "Report this error"
msgstr "Сообщить о данной ошибке"
msgid "Retry"
msgstr "Повторить"
msgid "Retry login"
msgstr "Повторить попытку входа"
msgid "Shibboleth 1.3 SP example - test logging in through your Shib IdP"
msgstr "Пример Shibboleth 1.3 SP - тестовый вход в систему через ваш Shib IdP"
msgid "State information lost"
msgstr "Информация о состоянии утеряна"
msgid "Suggestions for resolving this problem:"
msgstr "Варианты решения проблемы:"
msgid "This error may be caused by:"
msgstr "Эта ошибка может быть вызвана:"
msgid "This is most likely a configuration problem on either the service provider or identity provider."
msgstr "Скорее всего, это проблема конфигурации поставщика услуг или провайдера подлинности."
msgid "Too short interval between single sign on events."
msgstr "Очень короткий промежуток времени между единым входом в событиях."
msgid "Using the back and forward buttons in the web browser."
msgstr "Используйте клавиши \"Вперед\" \"Назад\" в броузере."
msgid "We have detected that there is only a few seconds since you last authenticated with this service provider, and therefore assume that there is a problem with this SP."
msgstr "Мы обнаружили, что прошло только несколько секунд с момента последней аутентификации с этим поставщиком услуг, и, следовательно, предположили, что существует проблема с этим поставщиком услуг."
msgid "We were unable to locate the state information for the current request."
msgstr "Не удалось определить информацию о состоянии для данного запроса."
msgid "Welcome"
msgstr "Добро пожаловать"
msgid "You appear to have disabled cookies in your browser. Please check the settings in your browser, and try again."
msgstr "Видимо, вы отключили поддержку cookies в вашем браузере. Пожалуйста, проверьте настройки вашего браузера и повторите попытку."

View File

@@ -0,0 +1,180 @@
msgid ""
msgstr ""
"X-Domain: core\n"
msgid "A service has requested you to authenticate yourself. Please enter your username and password in the form below."
msgstr "Služba požaduje Vašu autentifikáciu. Zadajte, prosím, Vaše prihlasovacie meno a heslo do formulára nižšie."
msgid "Check that the link you used to access the web site is correct."
msgstr "Skontrolujte, či je odkaz na prístup k webovej stránke správny."
msgid "Close the web browser, and try again."
msgstr "Zatvorte prehliadač a skúste to znovu."
msgid "Continue"
msgstr "Pokračovať"
msgid "Cookies may be disabled in the web browser."
msgstr "Súbory cookies môžu byť vypnuté v prehliadači."
msgid "Do you want to logout from all the services above?"
msgstr "Chcete sa odhlásiť zo všetkých služieb vyššie?"
msgid "Enter your username and password"
msgstr "Zadajte Vaše prihlasovacie meno a heslo"
msgid "Error report sent"
msgstr "Chybová správa odoslaná"
msgid "Go back to the previous page and try again."
msgstr "Choďte späť na predchádzajúcu stránku a skúste to znovu."
msgid "Help! I don't remember my password."
msgstr ""
msgid "Hosted Shibboleth 1.3 Identity Provider Metadata (automatically generated)"
msgstr "Hosted Shibboleth 1.3 Identity Provider Metadata (automatically generated)"
msgid "Hosted Shibboleth 1.3 Service Provider Metadata (automatically generated)"
msgstr "Metadáta lokálne prevádzkovaného Shibboleth 1.3 Service Provider (automaticky generované)"
msgid "If this problem persists, you can report it to the system administrators."
msgstr "Ak tento problém pretrváva, môžete odoslať hlásenie systémovým administrátorom."
msgid "If you are a developer who is deploying a single sign-on solution, you have a problem with the metadata configuration. Verify that metadata is configured correctly on both the identity provider and service provider."
msgstr "Ak ste vývojár a nastavujete systém jednotného prihlásenia, máte problém s konfiguráciou metadát. Skontrolujte, či sú metadáta nakonfigurované správne na oboch stranách - poskytovateľa služby a poskytovateľa identity"
msgid "If you are a user who received this error after following a link on a site, you should report this error to the owner of that site."
msgstr "Ak ste dostali túto chybu po kliknutí na odkaz na nejakej stránky, mali by ste túto chybu nahlásiť vlastníkovi tejto stránky."
msgid "If you report this error, please also report this tracking number which makes it possible to locate your session in the logs available to the system administrator:"
msgstr "Ak nahlasujete túto chybu, nahláste prosím aj toto sledovacie číslo, ktoré umožní administrátorovi nájsť Vašu reláciu v logoch:"
msgid "Incorrect Attributes"
msgstr "Nesprávne atribúty"
msgid "Logging out..."
msgstr "Odhlasuje sa..."
msgid "Login"
msgstr ""
msgid "Logout"
msgstr "Odhlásenie"
msgid "Missing cookie"
msgstr "Chýba cookie"
msgid "No"
msgstr "Nie"
msgid "No, only %SP%"
msgstr "Nie, iba %SP%"
msgid "One or more of the attributes supplied by your identity provider did not contain the expected number of values."
msgstr "Jedna alebo viacero atribútov poskytnutých od poskytovateľa identity nespĺňa očakávané množstvo hodnôt."
msgid "Opened the web browser with tabs saved from the previous session."
msgstr "Otvorený prehliadač s kartami z predchádzajúcej relácie."
msgid "Organization"
msgstr ""
msgid "Password"
msgstr ""
msgid "Processing..."
msgstr ""
msgid "Remember me"
msgstr ""
msgid "Remember my organization"
msgstr ""
msgid "Remember my username"
msgstr ""
msgid "Report this error"
msgstr "Nahlásiť túto chybu"
msgid "Retry"
msgstr "Opakovať"
msgid "Retry login"
msgstr "Znovu skúsiť prihlásenie"
msgid "Shibboleth 1.3 SP example - test logging in through your Shib IdP"
msgstr "Shibboleth 1.3 SP - testovanie prihlasovania cez Shib IdP"
msgid "SimpleSAMLphp"
msgstr ""
msgid "State information lost"
msgstr "Stavová informácia stratená"
msgid "Suggestions for resolving this problem:"
msgstr "Návrhy na vyriešenie tohto problému:"
msgid "The error report has been sent to the administrators."
msgstr "Chybová správa bola odoslaná administrátorom."
msgid "The link used to get here was bad, perhaps a bookmark."
msgstr "Odkaz smerujúci sem je zlý, napríklad zo záložky."
msgid "The problematic attribute(s) are:"
msgstr "Problémové atribúty sú:"
msgid "This error may be caused by:"
msgstr "Možné dôvody tejto chyby:"
msgid "This is most likely a configuration problem on either the service provider or identity provider."
msgstr "Toto je najpravdepodobnejšie problém konfigurácie buď na strane poskytovateľa služby alebo identity."
msgid "Too short interval between single sign on events."
msgstr "Moc krátky interval medzi akciami jednotného prihlásenia."
msgid "Unable to log out of one or more services. To ensure that all your sessions are closed, you are encouraged to <i>close your webbrowser</i>."
msgstr "Nepodarilo sa odhlásiť z jednej alebo viacerých služieb. Aby ste uistili, že sú všetky relácie zatvorené, je odporúčané <i>zatvoriť Váš prehliadač</i>."
msgid "Username"
msgstr ""
msgid "Using the back and forward buttons in the web browser."
msgstr "Použitie tlačidla späť a vpred v prehliadači."
msgid "We have detected that there is only a few seconds since you last authenticated with this service provider, and therefore assume that there is a problem with this SP."
msgstr "Detekovali sme, že prebehlo iba pár sekúnd od poslednej autentifikácie s týmto poskytovateľom služby, a preto predpokladáme, že je s týmto poskytovateľom služby problém."
msgid "We were unable to locate the state information for the current request."
msgstr "Nepodarilo sa nám nájsť informáciu o stave pre aktuálnu požiadavku."
msgid "Welcome"
msgstr "Vitajte"
msgid "Without your username and password you cannot authenticate yourself for access to the service. There may be someone that can help you. Consult the help desk at your organization!"
msgstr "Bez prihlasovacieho mena a hesla sa nemôžete autentifikovať pre prístup do služby. Kontaktujte podporu Vašej organizácie."
msgid "Yes, all services"
msgstr "Áno, všetky služby"
msgid "You appear to have disabled cookies in your browser. Please check the settings in your browser, and try again."
msgstr "Vyzerá to tak, že ste zablokovali súbory cookies vo Vašom prehliadači. Prosím, skontrolujte nastavenia vo Vašom prehliadači a skúste to znovu."
msgid "You are also logged in on these services:"
msgstr "Ste tiež prihlásený na týchto službách:"
msgid "You are now accessing a pre-production system. This authentication setup is for testing and pre-production verification only. If someone sent you a link that pointed you here, and you are not <i>a tester</i> you probably got the wrong link, and should <b>not be here</b>."
msgstr ""
msgid "You are now successfully logged out from %SP%."
msgstr "Teraz ste úspešne odhlásený z %SP%."
msgid "You are running an outdated version of SimpleSAMLphp. Please update to <a href=\"https://simplesamlphp.org/download\">the latest version</a> as soon as possible."
msgstr "Máte zastaralú verziu SimpleSAMLphp. Aktualizujte prosím čo najskôr na <a href=\"https://simplesamlphp.org/download\">najnovšiu verziu</a>."
msgid "got %got% values, want %want%"
msgstr "dostané %got% hodnoty, očakávané %want%"
msgid "logout is not supported"
msgstr "Odhlásenie sa nie je podporované"

View File

@@ -0,0 +1,75 @@
msgid ""
msgstr ""
"X-Domain: core\n"
msgid "Close the web browser, and try again."
msgstr "Zaprite spletni brskalnik in poskusite znova."
msgid "Cookies may be disabled in the web browser."
msgstr "Spletni brskalnik ima izklopjeno podporo za piškotke."
msgid "Go back to the previous page and try again."
msgstr "Pojdite nazaj na prejšnjo stran in poskusite znova."
msgid "Hosted Shibboleth 1.3 Identity Provider Metadata (automatically generated)"
msgstr "Metapodatki za Shibboleth 1.3 IdP (samodejno generirani)"
msgid "Hosted Shibboleth 1.3 Service Provider Metadata (automatically generated)"
msgstr "Metapodatki za Shibboleth 1.3 SP (samodejno generirani)"
msgid "If this problem persists, you can report it to the system administrators."
msgstr "Če se ta napaka ponavlja, jo lahko prijavite za skrbniku sistema."
msgid "If you are a developer who is deploying a single sign-on solution, you have a problem with the metadata configuration. Verify that metadata is configured correctly on both the identity provider and service provider."
msgstr "Če ste razvijalec, ki razvija SSO rešitev preverite, ali so nastavitve metapodatkov ustrezne, tako na stani ponudnika identitete (IdP), kot na strani ponudnika storitve (SP)."
msgid "If you are a user who received this error after following a link on a site, you should report this error to the owner of that site."
msgstr "Če ste na to težavo naleteli po kliku povezave te spletne strani, prijavite težavo skrbniku te spletne strani."
msgid "Missing cookie"
msgstr "Piškotek (\"cookie\") ne obstaja!"
msgid "Opened the web browser with tabs saved from the previous session."
msgstr "Spletni brskalnik je odprl spletno stan s (poteklimi) podatki iz prejšnje seje."
msgid "Report this error"
msgstr "Prijavite to napako"
msgid "Retry"
msgstr "Poskusi ponovno"
msgid "Retry login"
msgstr "Ponovna prijava"
msgid "Shibboleth 1.3 SP example - test logging in through your Shib IdP"
msgstr "Shibboleth 1.3 SP primer - preveri prijavo preko svojega Shib IdP"
msgid "State information lost"
msgstr "Informacije o stanju zahtevka niso na voljo."
msgid "Suggestions for resolving this problem:"
msgstr "Predloga za razrešitev nastale težave:"
msgid "This error may be caused by:"
msgstr "Vzrok za to napako je lahko:"
msgid "This is most likely a configuration problem on either the service provider or identity provider."
msgstr "Najverjetneje gre za težavo z nastavitvami bodisi ponudnika storitve (SP) bodisi ponudnika identitet (IdP)."
msgid "Too short interval between single sign on events."
msgstr "Prekratek interval med dogodki enotne prijave."
msgid "Using the back and forward buttons in the web browser."
msgstr "Uporaba gumbov \"nazaj\" ali \"naprej\" v spletnem brskalniku."
msgid "We have detected that there is only a few seconds since you last authenticated with this service provider, and therefore assume that there is a problem with this SP."
msgstr "Sistem je zaznal naslednje, od predhodnje in te prijave je poteklo le nekaj sekund, zato sklepa na težave ponudnika storitve (SP)."
msgid "We were unable to locate the state information for the current request."
msgstr "Informacije o stanju trenutne zahteve ni bilo moč najti."
msgid "Welcome"
msgstr "Dobrodošli"
msgid "You appear to have disabled cookies in your browser. Please check the settings in your browser, and try again."
msgstr "Vaš spletni brskalnik ima onemogočene piškotke (\"cookies\"). Omogočite to nastavitev in poskusite ponovno."

View File

@@ -0,0 +1,75 @@
msgid ""
msgstr ""
"X-Domain: core\n"
msgid "Close the web browser, and try again."
msgstr "Zatvorite web pretraživač i pokušajte ponovo."
msgid "Cookies may be disabled in the web browser."
msgstr "Moguće da je podrška za kolačiće (\"cookies\") isključena u web pretraživaču."
msgid "Go back to the previous page and try again."
msgstr "Vratite se na prethodnu stranicu i pokušajte ponovo."
msgid "Hosted Shibboleth 1.3 Identity Provider Metadata (automatically generated)"
msgstr "Metapodaci za lokalni Shibboleth 1.3 Davalac Identiteta (automatski generisani)"
msgid "Hosted Shibboleth 1.3 Service Provider Metadata (automatically generated)"
msgstr "Metapodaci za lokalni Shibboleth 1.3 Davalac Servisa (automatski generisani)"
msgid "If this problem persists, you can report it to the system administrators."
msgstr "Ako se ova greška bude i dalje pojavljivala, možete je prijaviti administratorima."
msgid "If you are a developer who is deploying a single sign-on solution, you have a problem with the metadata configuration. Verify that metadata is configured correctly on both the identity provider and service provider."
msgstr "Postoji greška sa podešavanjima metapodataka. Ukoliko ste administrator sistema, proverite da li metapodaci ispravno uneseni na strani davaoca servisa i davaoca identiteta."
msgid "If you are a user who received this error after following a link on a site, you should report this error to the owner of that site."
msgstr "Ukoliko se ova greška pojavila nakon što ste sledili link na nekoj web stranici, onda biste grešku trebali prijaviti vlasniku navedene stranice."
msgid "Missing cookie"
msgstr "Nedostaje kolačić (cookie)"
msgid "Opened the web browser with tabs saved from the previous session."
msgstr "Otvaranjem web pretraživača sa stranicama sačuvanim iz prethodne sesije."
msgid "Report this error"
msgstr "Prijavite ovu grešku"
msgid "Retry"
msgstr "Pokušaj ponovo"
msgid "Retry login"
msgstr "Pokušaj se prijaviti ponovo"
msgid "Shibboleth 1.3 SP example - test logging in through your Shib IdP"
msgstr "Shibboleth 1.3 SP primer - testirajte autentifikaciju kroz vaš Shib Davalac Servisa"
msgid "State information lost"
msgstr "Informacije o stanju su izgubljene"
msgid "Suggestions for resolving this problem:"
msgstr "Preporuke za rešavanje ovog problema:"
msgid "This error may be caused by:"
msgstr "Ova greška može biti uzrokovana:"
msgid "This is most likely a configuration problem on either the service provider or identity provider."
msgstr "Najverojatnije je problem u podešavanjima davaoca servisa ili davaoca identiteta."
msgid "Too short interval between single sign on events."
msgstr "Prekratak interval između uzastopnih SSO prijava."
msgid "Using the back and forward buttons in the web browser."
msgstr "Korišćenjem tastera za prethodnu (back) i sledeću (forward) stranicu u web pretraživaču."
msgid "We have detected that there is only a few seconds since you last authenticated with this service provider, and therefore assume that there is a problem with this SP."
msgstr "Prošlo tek nekoliko sekundi otkad ste se zadnji put autentifikovali za pristup ovoj aplikaciji te stoga pretpostavljamo da se javio problem kod davaoca servisa."
msgid "We were unable to locate the state information for the current request."
msgstr "Ne možemo pronaći informacije o stanju aktuelnog zahteva."
msgid "Welcome"
msgstr "Dobrodošli"
msgid "You appear to have disabled cookies in your browser. Please check the settings in your browser, and try again."
msgstr "Izgleda da ste onemogućili kolačiće (cookies) u vašem web pretraživaču. Molimo proverite podešavanja vašeg web pretraživača i pokušajte ponovo."

View File

@@ -0,0 +1,75 @@
msgid ""
msgstr ""
"X-Domain: core\n"
msgid "Close the web browser, and try again."
msgstr "Stäng din webbläsare och försök igen."
msgid "Cookies may be disabled in the web browser."
msgstr "Webbkakor (Cookies) är avstängt i webbläsaren."
msgid "Go back to the previous page and try again."
msgstr "Gå tillbaka till föregående sida och försök igen."
msgid "Hosted Shibboleth 1.3 Identity Provider Metadata (automatically generated)"
msgstr "Lokala Shibboleth 1.3 Identity Provider Metadata (automatiskt genererat)"
msgid "Hosted Shibboleth 1.3 Service Provider Metadata (automatically generated)"
msgstr "Lokala Shibboleth 1.3 Service Provider Metadata (automatiskt genererat)"
msgid "If this problem persists, you can report it to the system administrators."
msgstr "Om problemet kvarstår kan du rapportera det till systemadministratörerna."
msgid "If you are a developer who is deploying a single sign-on solution, you have a problem with the metadata configuration. Verify that metadata is configured correctly on both the identity provider and service provider."
msgstr "Om du är en utvecklare som driftsätter en lösning med single-on har du problem med metadatakonfigurationen. Kontrollera att metadata är korrekt konfigurerade både i identitetsutgivare och tjänsteleverantören."
msgid "If you are a user who received this error after following a link on a site, you should report this error to the owner of that site."
msgstr "Om du är en användare och fick detta fel när du klickade på en länk bör du rapportera felet till den som hanterar webbplatsen med länken."
msgid "Missing cookie"
msgstr "Saknar webbläsarkaka (cookie)"
msgid "Opened the web browser with tabs saved from the previous session."
msgstr "Öppnande av webbläsaren med sparade flikar från tidigare användning."
msgid "Report this error"
msgstr "Rapportera detta fel"
msgid "Retry"
msgstr "Försök igen"
msgid "Retry login"
msgstr "Försök med inloggningen igen"
msgid "Shibboleth 1.3 SP example - test logging in through your Shib IdP"
msgstr "Shibboleth 1.3 SP exempel - testinloggning med SAML 2.0 via din IdP"
msgid "State information lost"
msgstr "Tillståndsinformation är förlorad"
msgid "Suggestions for resolving this problem:"
msgstr "Förslag för att åtgärda detta problem:"
msgid "This error may be caused by:"
msgstr "Detta fel kan bero på:"
msgid "This is most likely a configuration problem on either the service provider or identity provider."
msgstr "Detta beror oftast på ett konfigurationsfel antingen i tjänsteleverantören eller identitetsutgivaren."
msgid "Too short interval between single sign on events."
msgstr "För kort intervall mellan inloggningar."
msgid "Using the back and forward buttons in the web browser."
msgstr "Användning av framåt- och bakåtknappar i webbläsaren."
msgid "We have detected that there is only a few seconds since you last authenticated with this service provider, and therefore assume that there is a problem with this SP."
msgstr "Vi har upptäckt att det bara vara några få sekunder sedan du senast loggade in mot denna tjänst (service provider) och därför antar vi att det är ett problem med denna tjänst."
msgid "We were unable to locate the state information for the current request."
msgstr "Hittar inte tillståndsinformationen för aktuell förfrågan."
msgid "Welcome"
msgstr "Välkommen"
msgid "You appear to have disabled cookies in your browser. Please check the settings in your browser, and try again."
msgstr "Det verkar som om du har stängt av möjligheten till kakor (cookies) i din webbläsare. Kontrollera inställningarna i webbläsaren och försök igen."

View File

@@ -0,0 +1,15 @@
msgid ""
msgstr ""
"X-Domain: core\n"
msgid "Hosted Shibboleth 1.3 Identity Provider Metadata (automatically generated)"
msgstr "Sunulan Shibboleth 1.3 Kimlik Sağlayıcı Üstverisi (metadata) (otomatik olarak üretilmiştir)"
msgid "Hosted Shibboleth 1.3 Service Provider Metadata (automatically generated)"
msgstr "Sunulan Shibboleth 1.3 Servis Sağlayıcı Üstverisi (metadata) (otomatik olarak üretilmiştir)"
msgid "Shibboleth 1.3 SP example - test logging in through your Shib IdP"
msgstr "Shibboleth 1.3 SP örneği - Shib IdP'nizden giriş yaparak test edin"
msgid "Welcome"
msgstr "Hoşgeldiniz"

View File

@@ -0,0 +1,21 @@
msgid ""
msgstr ""
"X-Domain: core\n"
msgid "Cookies may be disabled in the web browser."
msgstr "Iikhuki zisenokwenziwa zingasebenzi kwibhrawuza yewebhu."
msgid "One or more of the attributes supplied by your identity provider did not contain the expected number of values."
msgstr "Uphawu olunye okanye olungakumbi olunikelwe ngumboonelei wesazisi sakho aluqulethanga inani lamaxabiso alindelekileyo."
msgid "Opened the web browser with tabs saved from the previous session."
msgstr "Kuvulwe ibhrawuza yewebhu ngeethebhu eziseyivwe kwiseshoni edlulileyo."
msgid "Retry"
msgstr "Zama kwakhona"
msgid "This error may be caused by:"
msgstr "Le mpazamo isenokuba ibangelwe:"
msgid "Using the back and forward buttons in the web browser."
msgstr "Ukusebenzisa amaqhosha okuya emva naphambili kwibhrawuza yewebhu."

View File

@@ -0,0 +1,75 @@
msgid ""
msgstr ""
"X-Domain: core\n"
msgid "Close the web browser, and try again."
msgstr "关闭浏览器并重试"
msgid "Cookies may be disabled in the web browser."
msgstr "该浏览器上的cookie可能遭禁止"
msgid "Go back to the previous page and try again."
msgstr "返回上一页并重新尝试"
msgid "Hosted Shibboleth 1.3 Identity Provider Metadata (automatically generated)"
msgstr "存储的 Shibboleth 1.3 Identity Provider Metadata自动生成"
msgid "Hosted Shibboleth 1.3 Service Provider Metadata (automatically generated)"
msgstr "存储的 Shibboleth 1.3 Service Provider Metadata自动生成"
msgid "If this problem persists, you can report it to the system administrators."
msgstr "如果这个错误再次出现,你可以向你的系统管理员报告"
msgid "If you are a developer who is deploying a single sign-on solution, you have a problem with the metadata configuration. Verify that metadata is configured correctly on both the identity provider and service provider."
msgstr "如果你是部署这个单点登录系统的开发人员,那么你的配置文件存在问题,验证服务提供者和身份提供者是否配置正确"
msgid "If you are a user who received this error after following a link on a site, you should report this error to the owner of that site."
msgstr "如果你是点击一个网站上的链接后收到该错误的用户,你应该报告这个错误给站点所有人"
msgid "Missing cookie"
msgstr "cookie丢失"
msgid "Opened the web browser with tabs saved from the previous session."
msgstr "从先前的session保存的选项卡打开Web浏览器"
msgid "Report this error"
msgstr "报告这个错误"
msgid "Retry"
msgstr "重试"
msgid "Retry login"
msgstr "重新尝试登陆"
msgid "Shibboleth 1.3 SP example - test logging in through your Shib IdP"
msgstr "Shibboleth 1.3SP样例-测试从你的Shib idP登录"
msgid "State information lost"
msgstr "状态信息丢失"
msgid "Suggestions for resolving this problem:"
msgstr "关于解决该问题的建议"
msgid "This error may be caused by:"
msgstr "该错误可能是以下原因导致的:"
msgid "This is most likely a configuration problem on either the service provider or identity provider."
msgstr "这可能是服务提供者或者身份提供者的配置问题"
msgid "Too short interval between single sign on events."
msgstr "单点登录事件之间间隔太短了"
msgid "Using the back and forward buttons in the web browser."
msgstr "使用浏览器中的前进后退按钮"
msgid "We have detected that there is only a few seconds since you last authenticated with this service provider, and therefore assume that there is a problem with this SP."
msgstr "我们检测到从你上一次连接到该服务提供者到本次连接中间间隔仅仅数秒的时间我们猜测该SP可能有问题"
msgid "We were unable to locate the state information for the current request."
msgstr "我们无法定位当前请求的状态信息"
msgid "Welcome"
msgstr "欢迎"
msgid "You appear to have disabled cookies in your browser. Please check the settings in your browser, and try again."
msgstr "你似乎禁止了你浏览器的cookie功能请检查设置然后重新尝试"

View File

@@ -0,0 +1,75 @@
msgid ""
msgstr ""
"X-Domain: core\n"
msgid "Close the web browser, and try again."
msgstr "關閉網頁瀏覽器,並再試一次。"
msgid "Cookies may be disabled in the web browser."
msgstr "網頁瀏覽器的 Cookies 可能被關閉。"
msgid "Go back to the previous page and try again."
msgstr "回到上一頁並再試一次。"
msgid "Hosted Shibboleth 1.3 Identity Provider Metadata (automatically generated)"
msgstr "託管Shibboleth 1.3 驗證提供者詮釋資料(自動產生)"
msgid "Hosted Shibboleth 1.3 Service Provider Metadata (automatically generated)"
msgstr "託管 Shibboleth 1.3 服務提供者詮釋資料(自動產生)"
msgid "If this problem persists, you can report it to the system administrators."
msgstr "如果這個錯誤持續存在,您可以將它回報系統管理者。"
msgid "If you are a developer who is deploying a single sign-on solution, you have a problem with the metadata configuration. Verify that metadata is configured correctly on both the identity provider and service provider."
msgstr "若您是單一簽入程式開發人員,您的詮釋資料設定可能有問題。請確認服務提供者或驗證提供者之詮釋資料設定檔是否正確。"
msgid "If you are a user who received this error after following a link on a site, you should report this error to the owner of that site."
msgstr "若您是個使用者,而您於此網站收到下列連結,請反映此錯誤給此站管理員。"
msgid "Missing cookie"
msgstr "遺失 cookie"
msgid "Opened the web browser with tabs saved from the previous session."
msgstr "您使用網頁瀏覽器儲存標籤開啟了上一次的連線。"
msgid "Report this error"
msgstr "回報這個錯誤"
msgid "Retry"
msgstr "重試"
msgid "Retry login"
msgstr "重試登入"
msgid "Shibboleth 1.3 SP example - test logging in through your Shib IdP"
msgstr "Shibboleth 1.3 SP 範本 - 測試使用您的 Shib IdP 登入"
msgid "State information lost"
msgstr "遺失狀態資訊"
msgid "Suggestions for resolving this problem:"
msgstr "建議解決這個問題:"
msgid "This error may be caused by:"
msgstr "這個錯誤可能是因為:"
msgid "This is most likely a configuration problem on either the service provider or identity provider."
msgstr "服務提供者或驗證提供者之設定檔可能有問題。"
msgid "Too short interval between single sign on events."
msgstr "單一簽入事件間隔過短。"
msgid "Using the back and forward buttons in the web browser."
msgstr "於網頁瀏覽器使用上一頁及下一頁。"
msgid "We have detected that there is only a few seconds since you last authenticated with this service provider, and therefore assume that there is a problem with this SP."
msgstr "我們偵測到距離您最後一次驗證於這個服務提供者只有短短幾秒,而這可能是 SP 有點問題。"
msgid "We were unable to locate the state information for the current request."
msgstr "我們無法找到關於這個請求的狀態資訊。"
msgid "Welcome"
msgstr "歡迎"
msgid "You appear to have disabled cookies in your browser. Please check the settings in your browser, and try again."
msgstr "您可能關閉了瀏覽器 cookie 支援,請檢查瀏覽器設定,然後再試一次。"

View File

@@ -0,0 +1,21 @@
msgid ""
msgstr ""
"X-Domain: core\n"
msgid "Cookies may be disabled in the web browser."
msgstr "Amakhukhi kungenzeka ukuthi ayekisiwe kusiphequluli sewebhu."
msgid "One or more of the attributes supplied by your identity provider did not contain the expected number of values."
msgstr "Isici esisodwa noma ngaphezulu esinikezwe umhlinzeki wakho kamazisi asizange siqukathe inani lezinombolo ezilindelwe."
msgid "Opened the web browser with tabs saved from the previous session."
msgstr "Kuvulwe isiphequluli sewebhu ngamathebhu alondolozwe kuseshini yangaphambilini."
msgid "Retry"
msgstr "Zama futhi"
msgid "This error may be caused by:"
msgstr "Leli phutha kungenzeka libangelwa ukuthi:"
msgid "Using the back and forward buttons in the web browser."
msgstr "Ukusebenzisa izinkinobho ezithi emuva naphambili kusiphequluli sewebhu."

View File

@@ -0,0 +1,17 @@
ready(function () {
window.onpageshow = function () {
var button = document.getElementById("submit_button");
var replacement = document.createTextNode(button.getAttribute("data-default"));
button.replaceChild(replacement, button.childNodes[0]);
button.disabled = false;
}
var form = document.getElementById("f");
form.onsubmit = function () {
var button = document.getElementById("submit_button");
var replacement = document.createTextNode(button.getAttribute("data-processing"));
button.replaceChild(replacement, button.childNodes[0]);
button.disabled = true;
}
});

View File

@@ -0,0 +1,146 @@
---
core-welcome:
path: /welcome
defaults: {
_controller: 'SimpleSAML\Module\core\Controller\Login::welcome'
}
methods: [GET]
core-account-disco-clearchoices:
path: /account/disco/clearchoices
defaults: {
_controller: 'SimpleSAML\Module\core\Controller\Login::cleardiscochoices'
}
methods: [GET]
core-legacy-login:
path: /login/{as}
defaults: {
_controller: 'Symfony\Bundle\FrameworkBundle\Controller\RedirectController::urlRedirectAction',
path: /module.php/saml/sp/login/, permanent: true
}
methods: [GET]
core-loginuserpass:
path: /loginuserpass
defaults: {
_controller: 'SimpleSAML\Module\core\Controller\Login::loginuserpass'
}
methods: [GET, POST]
core-loginuserpassorg:
path: /loginuserpassorg
defaults: {
_controller: 'SimpleSAML\Module\core\Controller\Login::loginuserpassorg'
}
methods: [GET, POST]
core-error-nocookie:
path: /error/nocookie
defaults: {
_controller: 'SimpleSAML\Module\core\Controller\Exception::nocookie'
}
methods: [GET]
core-cardinality:
path: /error/cardinality
defaults: {
_controller: 'SimpleSAML\Module\core\Controller\Exception::cardinality'
}
methods: [GET]
core-error:
path: /error/{code}
defaults: {
_controller: 'SimpleSAML\Module\core\Controller\Exception::error'
}
methods: [GET]
core-warning-shortssointerval:
path: /warning/short_sso_interval
defaults: {
_controller: 'SimpleSAML\Module\core\Controller\Exception::shortSsoInterval'
}
methods: [GET]
core-post-redirect:
path: /postredirect
defaults: {
_controller: 'SimpleSAML\Module\core\Controller\Redirection::postredirect'
}
methods: [GET]
core-legacy-welcome:
path: /frontpage_welcome.php
defaults: {
_controller: 'Symfony\Bundle\FrameworkBundle\Controller\RedirectController::urlRedirectAction',
path: /admin/, permanent: true
}
methods: [GET]
core-legacy-config:
path: /frontpage_config.php
defaults: {
_controller: 'Symfony\Bundle\FrameworkBundle\Controller\RedirectController::urlRedirectAction',
path: /admin/, permanent: true
}
methods: [GET]
core-legacy-auth:
path: /frontpage_auth.php
defaults: {
_controller: 'Symfony\Bundle\FrameworkBundle\Controller\RedirectController::urlRedirectAction',
path: /admin/test, permanent: true
}
methods: [GET]
core-legacy-federation:
path: /frontpage_federation.php
defaults: {
_controller: 'Symfony\Bundle\FrameworkBundle\Controller\RedirectController::urlRedirectAction',
path: /admin/federation, permanent: true
}
methods: [GET]
core-logout:
path: /logout/{as}
defaults: {
_controller: 'SimpleSAML\Module\core\Controller\Logout::logout'
}
methods: [GET]
core-logout-resume:
path: /logout-resume
defaults: {
_controller: 'SimpleSAML\Module\core\Controller\Logout::resumeLogout'
}
methods: [GET]
core-logout-iframe:
path: /logout-iframe
defaults: {
_controller: 'SimpleSAML\Module\core\Controller\Logout::logoutIframe'
}
methods: [GET]
core-logout-iframe-done:
path: /logout-iframe-done
defaults: {
_controller: 'SimpleSAML\Module\core\Controller\Logout::logoutIframeDone'
}
methods: [GET]
core-logout-iframe-post:
path: /logout-iframe-post
defaults: {
_controller: 'SimpleSAML\Module\core\Controller\Logout::logoutIframePost'
}
methods: [GET]
core-error-report:
path: /errorReport
defaults: {
_controller: '\SimpleSAML\Module\core\Controller\ErrorReport::main'
}
methods: [GET, POST]

View File

@@ -0,0 +1,92 @@
<?php
declare(strict_types=1);
namespace SimpleSAML\Module\core\Auth\Process;
use Exception;
use SimpleSAML\Assert\Assert;
use SimpleSAML\Auth;
/**
* Filter to add attributes.
*
* This filter allows you to add attributes to the attribute set being processed.
*
* @package SimpleSAMLphp
*/
class AttributeAdd extends Auth\ProcessingFilter
{
/**
* Flag which indicates whether this filter should append new values or replace old values.
* @var bool
*/
private bool $replace = false;
/**
* Attributes which should be added/appended.
*
* Associative array of arrays.
* @var array
*/
private array $attributes = [];
/**
* Initialize this filter.
*
* @param array &$config Configuration information about this filter.
* @param mixed $reserved For future use.
*/
public function __construct(array &$config, $reserved)
{
parent::__construct($config, $reserved);
foreach ($config as $name => $values) {
if (is_int($name)) {
if ($values === '%replace') {
$this->replace = true;
} else {
throw new Exception('Unknown flag: ' . var_export($values, true));
}
continue;
}
if (!is_array($values)) {
$values = [$values];
}
foreach ($values as $value) {
if (!is_string($value)) {
throw new Exception(
'Invalid value for attribute ' . $name . ': ' . var_export($values, true),
);
}
}
$this->attributes[$name] = $values;
}
}
/**
* Apply filter to add or replace attributes.
*
* Add or replace existing attributes with the configured values.
*
* @param array &$state The current request
*/
public function process(array &$state): void
{
Assert::keyExists($state, 'Attributes');
$attributes = &$state['Attributes'];
foreach ($this->attributes as $name => $values) {
if ($this->replace === true || !array_key_exists($name, $attributes)) {
$attributes[$name] = $values;
} else {
$attributes[$name] = array_merge($attributes[$name], $values);
}
}
}
}

View File

@@ -0,0 +1,218 @@
<?php
declare(strict_types=1);
namespace SimpleSAML\Module\core\Auth\Process;
use SimpleSAML\Assert\Assert;
use SimpleSAML\Auth;
use SimpleSAML\Error;
/**
* Filter to modify attributes using regular expressions
*
* This filter can modify or replace attributes given a regular expression.
*
* @package SimpleSAMLphp
*/
class AttributeAlter extends Auth\ProcessingFilter
{
/**
* Should the pattern found be replaced?
* @var bool
*/
private bool $replace = false;
/**
* Should the value found be removed?
* @var bool
*/
private bool $remove = false;
/**
* Pattern to search for.
* @var string
*/
private string $pattern = '';
/**
* String to replace the pattern found with.
* @var string|false|null
*/
private string|bool|null $replacement = false;
/**
* Attribute to search in
* @var string
*/
private string $subject = '';
/**
* Attribute to place the result in.
* @var string
*/
private string $target = '';
/**
* Should the altered value be merged with target values
* @var bool
*/
private bool $merge = false;
/**
* Initialize this filter.
*
* @param array &$config Configuration information about this filter.
* @param mixed $reserved For future use.
* @throws \SimpleSAML\Error\Exception In case of invalid configuration.
*/
public function __construct(array &$config, $reserved)
{
parent::__construct($config, $reserved);
// parse filter configuration
foreach ($config as $name => $value) {
if (is_int($name)) {
// check if this is an option
if ($value === '%replace') {
$this->replace = true;
} elseif ($value === '%remove') {
$this->remove = true;
} elseif ($value === '%merge') {
$this->merge = true;
} else {
throw new Error\Exception('Unknown flag : ' . var_export($value, true));
}
continue;
} elseif ($name === 'pattern') {
// Set pattern
$this->pattern = $value;
} elseif ($name === 'replacement') {
// Set replacement
$this->replacement = $value;
} elseif ($name === 'subject') {
// Set subject
$this->subject = $value;
} elseif ($name === 'target') {
// Set target
$this->target = $value;
}
}
}
/**
* Apply the filter to modify attributes.
*
* Modify existing attributes with the configured values.
*
* @param array &$state The current request.
* @throws \SimpleSAML\Error\Exception In case of invalid configuration.
*/
public function process(array &$state): void
{
Assert::keyExists($state, 'Attributes');
// get attributes from request
$attributes = &$state['Attributes'];
// check that all required params are set in config
if (empty($this->pattern) || empty($this->subject)) {
throw new Error\Exception("Not all params set in config.");
}
if (!$this->replace && !$this->remove && $this->replacement === false) {
throw new Error\Exception(
"'replacement' must be set if neither '%replace' nor " . "'%remove' are set.",
);
}
if (!$this->replace && $this->replacement === null) {
throw new Error\Exception("'%replace' must be set if 'replacement' is null.");
}
if ($this->replace && $this->remove) {
throw new Error\Exception("'%replace' and '%remove' cannot be used together.");
}
if (empty($this->target)) {
// use subject as target if target is not set
$this->target = $this->subject;
}
if ($this->subject !== $this->target && $this->remove) {
throw new Error\Exception("Cannot use '%remove' when 'target' is different than 'subject'.");
}
if (!array_key_exists($this->subject, $attributes)) {
// if no such subject, stop gracefully
return;
}
if ($this->replace) {
// replace the whole value
foreach ($attributes[$this->subject] as &$value) {
$matches = [];
if (preg_match($this->pattern, $value, $matches) > 0) {
$new_value = $matches[0];
if (is_string($this->replacement)) {
$new_value = $this->replacement;
}
if ($this->subject === $this->target) {
$value = $new_value;
} elseif ($this->merge === true) {
$attributes[$this->target] = array_values(
array_diff($attributes[$this->target], [$value]),
);
$attributes[$this->target][] = $new_value;
} else {
$attributes[$this->target] = [$new_value];
}
}
}
} elseif ($this->remove) {
// remove the whole value
$removedAttrs = [];
foreach ($attributes[$this->subject] as $value) {
$matches = [];
if (preg_match($this->pattern, $value, $matches) > 0) {
$removedAttrs[] = $value;
}
}
$attributes[$this->target] = array_diff($attributes[$this->subject], $removedAttrs);
if (empty($attributes[$this->target])) {
unset($attributes[$this->target]);
}
} else {
// replace only the part that matches
if ($this->subject === $this->target) {
$attributes[$this->target] = preg_replace(
$this->pattern,
$this->replacement,
$attributes[$this->subject],
);
} else {
$diff = array_diff(
preg_replace(
$this->pattern,
$this->replacement,
$attributes[$this->subject],
),
$attributes[$this->subject],
);
if ($this->merge === true) {
/** @psalm-suppress InvalidArgument */
$attributes[$this->target] = array_merge($diff, $attributes[$this->target] ?? []);
} else {
/** @psalm-suppress InvalidArgument */
$attributes[$this->target] = $diff;
}
}
}
}
}

View File

@@ -0,0 +1,81 @@
<?php
declare(strict_types=1);
namespace SimpleSAML\Module\core\Auth\Process;
use Exception;
use SimpleSAML\Assert\Assert;
use SimpleSAML\Auth;
/**
* Attribute filter for renaming attributes.
*
* @package SimpleSAMLphp
*
* You just follow the 'source' => 'destination' schema. In this example user's * cn will be the user's displayName.
*
* 5 => [
* 'class' => 'core:AttributeCopy',
* 'cn' => 'displayName',
* 'uid' => 'username',
* ],
*
*/
class AttributeCopy extends Auth\ProcessingFilter
{
/**
* Assosiative array with the mappings of attribute names.
* @var array
*/
private array $map = [];
/**
* Initialize this filter, parse configuration
*
* @param array &$config Configuration information about this filter.
* @param mixed $reserved For future use.
*/
public function __construct(array &$config, $reserved)
{
parent::__construct($config, $reserved);
foreach ($config as $source => $destination) {
if (!is_string($source)) {
throw new Exception('Invalid source attribute name: ' . var_export($source, true));
}
if (!is_string($destination) && !is_array($destination)) {
throw new Exception('Invalid destination attribute name: ' . var_export($destination, true));
}
$this->map[$source] = $destination;
}
}
/**
* Apply filter to rename attributes.
*
* @param array &$state The current request
*/
public function process(array &$state): void
{
Assert::keyExists($state, 'Attributes');
$attributes = &$state['Attributes'];
foreach ($attributes as $name => $values) {
if (array_key_exists($name, $this->map)) {
if (!is_array($this->map[$name])) {
$attributes[$this->map[$name]] = $values;
} else {
foreach ($this->map[$name] as $to_map) {
$attributes[$to_map] = $values;
}
}
}
}
}
}

View File

@@ -0,0 +1,262 @@
<?php
declare(strict_types=1);
namespace SimpleSAML\Module\core\Auth\Process;
use SimpleSAML\Assert\Assert;
use SimpleSAML\Auth;
use SimpleSAML\Error;
use SimpleSAML\Logger;
use function array_intersect;
use function array_key_exists;
use function array_uintersect;
use function in_array;
use function is_array;
use function is_int;
use function is_string;
use function preg_match;
use function sprintf;
use function var_export;
/**
* A filter for limiting which attributes are passed on.
*
* @package SimpleSAMLphp
*/
class AttributeLimit extends Auth\ProcessingFilter
{
/**
* List of attributes which this filter will allow through.
* @var array
*/
private array $allowedAttributes = [];
/**
* List of regular expressions for attributes which this filter will allow through.
* @var array
*/
private array $allowedAttributeRegex = [];
/**
* Whether the 'attributes' option in the metadata takes precedence.
*
* @var bool
*/
private bool $isDefault = false;
/**
* Initialize this filter.
*
* @param array &$config Configuration information about this filter.
* @param mixed $reserved For future use
* @throws \SimpleSAML\Error\Exception If invalid configuration is found.
*/
public function __construct(array &$config, $reserved)
{
parent::__construct($config, $reserved);
foreach ($config as $index => $value) {
if ($index === 'default') {
$this->isDefault = (bool) $value;
} elseif (is_int($index)) {
if (!is_string($value)) {
throw new Error\Exception(sprintf(
'AttributeLimit: Invalid attribute name: %s',
var_export($value, true),
));
}
$this->allowedAttributes[] = $value;
} elseif (!is_array($value)) {
throw new Error\Exception(sprintf(
'AttributeLimit: Values for %s must be specified in an array.',
var_export($index, true),
));
} elseif (array_key_exists('nameIsRegex', $value) && (true === (bool) $value['nameIsRegex'])) {
$this->allowedAttributeRegex[$index] = $value;
unset($this->allowedAttributeRegex[$index]['nameIsRegex']);
} else {
$this->allowedAttributes[$index] = $value;
// In case user sets nameIsRegex=false
unset($this->allowedAttributes[$index]['nameIsRegex']);
}
}
}
/**
* Get list of allowed from the SP/IdP config.
*
* @param array &$state The current request.
* @return array|null Array with attribute names, or null if no limit is placed.
*/
private static function getSPIdPAllowed(array &$state): ?array
{
if (array_key_exists('attributes', $state['Destination'])) {
// SP Config
return $state['Destination']['attributes'];
}
if (array_key_exists('attributes', $state['Source'])) {
// IdP Config
return $state['Source']['attributes'];
}
return null;
}
/**
* Get list of regular expressions of attribute names allowed from the SP/IdP config.
*
* @param array &$state The current request.
* @return array|null Array with attribute names, or null if no limit is placed.
*/
private static function getSPIdPAllowedRegex(array &$state): ?array
{
if (array_key_exists('Destination', $state) && array_key_exists('attributesRegex', $state['Destination'])) {
// SP Config
return $state['Destination']['attributesRegex'];
}
if (array_key_exists('Source', $state) && array_key_exists('attributesRegex', $state['Source'])) {
// IdP Config
return $state['Source']['attributesRegex'];
}
return null;
}
/**
* Apply filter to remove attributes.
*
* Removes all attributes which aren't one of the allowed attributes.
*
* @param array &$state The current request
* @throws \SimpleSAML\Error\Exception If invalid configuration is found.
*/
public function process(array &$state): void
{
assert::keyExists($state, 'Attributes');
if ($this->isDefault) {
$allowedAttributes = self::getSPIdPAllowed($state) ?? [];
$allowedAttributeRegex = self::getSPIdPAllowedRegex($state) ?? [];
if (empty($allowedAttributes) && empty($allowedAttributeRegex)) {
$allowedAttributes = $this->allowedAttributes ?? [];
$allowedAttributeRegex = $this->allowedAttributeRegex ?? [];
}
} elseif (!(empty($this->allowedAttributes) && empty($this->allowedAttributeRegex))) {
$allowedAttributes = $this->allowedAttributes ?? [];
$allowedAttributeRegex = $this->allowedAttributeRegex ?? [];
} else {
$allowedAttributes = self::getSPIdPAllowed($state) ?? [];
$allowedAttributeRegex = self::getSPIdPAllowedRegex($state) ?? [];
}
if (empty($allowedAttributes) && empty($allowedAttributeRegex)) {
// No limit on attributes
return;
}
$attributes = &$state['Attributes'];
foreach ($attributes as $name => $values) {
if (!in_array($name, $allowedAttributes, true)) {
// the attribute name is not in the array of allowed attributes
if (array_key_exists($name, $allowedAttributes)) {
// but it is an index of the array
if (!is_array($allowedAttributes[$name])) {
throw new Error\Exception(sprintf(
'AttributeLimit: Values for %s must be specified in an array.',
var_export($name, true),
));
}
$attributes[$name] = $this->filterAttributeValues($attributes[$name], $allowedAttributes[$name]);
if (!empty($attributes[$name])) {
continue;
}
} elseif (($regexpMatch = self::matchAnyRegex($name, $allowedAttributeRegex)) !== null) {
if (array_key_exists($regexpMatch, $allowedAttributeRegex)) {
$attributes[$name] = $this->filterAttributeValues(
$attributes[$name],
$allowedAttributeRegex[$regexpMatch],
);
}
if (!empty($attributes[$name])) {
continue;
}
}
unset($attributes[$name]);
}
}
}
/**
* Perform the filtering of attributes
* @param array $values The current values for a given attribute
* @param array $allowedConfigValues The allowed values, and possibly configuration options.
* @return array The filtered values
*/
private function filterAttributeValues(array $values, ?array $allowedConfigValues): array
{
if (($allowedConfigValues === null) || empty($allowedConfigValues)) {
return $values;
}
if (array_key_exists('regex', $allowedConfigValues) && $allowedConfigValues['regex'] === true) {
$matchedValues = [];
foreach ($allowedConfigValues as $option => $pattern) {
if (!is_int($option)) {
// Ignore any configuration options in $allowedConfig. e.g. regex=>true
continue;
}
foreach ($values as $index => $attributeValue) {
/* Suppress errors in preg_match since phpunit is set to fail on warnings, which
* prevents us from testing with invalid regex.
*/
$regexResult = @preg_match($pattern, $attributeValue);
if ($regexResult === false) {
Logger::warning("Error processing regex '$pattern' on value '$attributeValue'");
break;
} elseif ($regexResult === 1) {
$matchedValues[] = $attributeValue;
// Remove matched value in case a subsequent regex also matches it.
unset($values[$index]);
}
}
}
return $matchedValues;
} elseif (array_key_exists('ignoreCase', $allowedConfigValues) && $allowedConfigValues['ignoreCase'] === true) {
unset($allowedConfigValues['ignoreCase']);
return array_uintersect($values, $allowedConfigValues, "strcasecmp");
}
// The not true values for these options shouldn't leak through to array_intersect
unset($allowedConfigValues['ignoreCase']);
unset($allowedConfigValues['regex']);
return array_intersect($values, $allowedConfigValues);
}
/**
* Check if a string matches any of the regular expressions in the array of regexps
*
* @param string $needle The string we're searching on
* @param array|null Array with regular expressions to test against. null is equivalent to an empty array.
* @return string|null Regular expression that matched, or null if no match.
*/
private static function matchAnyRegex(string $needle, ?array $regexps = null): string | null
{
if ($regexps !== null) {
foreach ($regexps as $x => $y) {
$regexp = is_int($x) ? $y : $x;
if (preg_match($regexp, $needle)) {
return $regexp;
}
}
}
return null;
}
}

View File

@@ -0,0 +1,153 @@
<?php
declare(strict_types=1);
namespace SimpleSAML\Module\core\Auth\Process;
use Exception;
use SimpleSAML\Assert\Assert;
use SimpleSAML\Auth;
use SimpleSAML\Configuration;
use SimpleSAML\Module;
use Symfony\Component\Filesystem\Filesystem;
/**
* Attribute filter for renaming attributes.
*
* @package SimpleSAMLphp
*/
class AttributeMap extends Auth\ProcessingFilter
{
/**
* Associative array with the mappings of attribute names.
* @var array
*/
private array $map = [];
/**
* Should attributes be duplicated or renamed.
* @var bool
*/
private bool $duplicate = false;
/**
* Initialize this filter, parse configuration
*
* @param array &$config Configuration information about this filter.
* @param mixed $reserved For future use.
*
* @throws \Exception If the configuration of the filter is wrong.
*/
public function __construct(array &$config, $reserved)
{
parent::__construct($config, $reserved);
$mapFiles = [];
foreach ($config as $origName => $newName) {
if (is_int($origName)) {
if ($newName === '%duplicate') {
$this->duplicate = true;
} else {
// no index given, this is a map file
$mapFiles[] = $newName;
}
continue;
}
if (!is_string($newName) && !is_array($newName)) {
throw new Exception('Invalid attribute name: ' . var_export($newName, true));
}
$this->map[$origName] = $newName;
}
// load map files after we determine duplicate or rename
foreach ($mapFiles as &$file) {
$this->loadMapFile($file);
}
}
/**
* Loads and merges in a file with a attribute map.
*
* @param string $fileName Name of attribute map file. Expected to be in the attributemap directory in the root
* of the SimpleSAMLphp installation, or in the root of a module.
*
* @throws \Exception If the filter could not load the requested attribute map file.
*/
private function loadMapFile(string $fileName): void
{
$config = Configuration::getInstance();
$m = explode(':', $fileName);
if (count($m) === 2) {
// we are asked for a file in a module
if (!Module::isModuleEnabled($m[0])) {
throw new Exception("Module '$m[0]' is not enabled.");
}
$filePath = Module::getModuleDir($m[0]) . '/attributemap/' . $m[1] . '.php';
} else {
$attributenamemapdir = $config->getPathValue('attributenamemapdir', 'attributemap/') ?: 'attributemap/';
$filePath = $attributenamemapdir . $fileName . '.php';
}
$fileSystem = new Filesystem();
if (!$fileSystem->exists($filePath)) {
throw new Exception('Could not find attribute map file: ' . $filePath);
}
/** @psalm-var mixed|null $attributemap */
$attributemap = null;
include($filePath);
if (!is_array($attributemap)) {
throw new Exception('Attribute map file "' . $filePath . '" didn\'t define an attribute map.');
}
if ($this->duplicate) {
$this->map = array_merge_recursive($this->map, $attributemap);
} else {
$this->map = array_merge($this->map, $attributemap);
}
}
/**
* Apply filter to rename attributes.
*
* @param array &$state The current request.
*/
public function process(array &$state): void
{
Assert::keyExists($state, 'Attributes');
$mapped_attributes = [];
foreach ($state['Attributes'] as $name => $values) {
if (array_key_exists($name, $this->map)) {
if (!is_array($this->map[$name])) {
if ($this->duplicate) {
$mapped_attributes[$name] = $values;
}
$mapped_attributes[$this->map[$name]] = $values;
} else {
foreach ($this->map[$name] as $to_map) {
$mapped_attributes[$to_map] = $values;
}
if ($this->duplicate && !in_array($name, $this->map[$name], true)) {
$mapped_attributes[$name] = $values;
}
}
} else {
if (array_key_exists($name, $mapped_attributes)) {
continue;
}
$mapped_attributes[$name] = $values;
}
}
$state['Attributes'] = $mapped_attributes;
}
}

View File

@@ -0,0 +1,155 @@
<?php
declare(strict_types=1);
namespace SimpleSAML\Module\core\Auth\Process;
use SimpleSAML\Assert\Assert;
use SimpleSAML\Auth;
use SimpleSAML\Error;
use SimpleSAML\Logger;
/**
* Filter to create target attribute based on value(s) in source attribute
*
* @package SimpleSAMLphp
*/
class AttributeValueMap extends Auth\ProcessingFilter
{
/**
* The name of the attribute we should assign values to (ie: the target attribute).
* @var string
*/
private string $targetattribute = '';
/**
* The name of the attribute we should create values from.
* @var string
*/
private string $sourceattribute = '';
/**
* The required $sourceattribute values and target affiliations.
* @var array
*/
private array $values = [];
/**
* Whether $sourceattribute should be kept or not.
* @var bool
*/
private bool $keep = false;
/**
* Whether $target attribute values should be replaced by new values or not.
* @var bool
*/
private bool $replace = false;
/**
* Initialize the filter.
*
* @param array &$config Configuration information about this filter.
* @param mixed $reserved For future use.
* @throws \SimpleSAML\Error\Exception If the configuration is not valid.
*/
public function __construct(array &$config, $reserved)
{
parent::__construct($config, $reserved);
// parse configuration
foreach ($config as $name => $value) {
if (is_int($name)) {
// check if this is an option
if ($value === '%replace') {
$this->replace = true;
} elseif ($value === '%keep') {
$this->keep = true;
} else {
// unknown configuration option, log it and ignore the error
Logger::warning(
"AttributeValueMap: unknown configuration flag '" . var_export($value, true) . "'",
);
}
continue;
}
// set the target attribute
if ($name === 'targetattribute') {
$this->targetattribute = $value;
}
// set the source attribute
if ($name === 'sourceattribute') {
$this->sourceattribute = $value;
}
// set the values
if ($name === 'values') {
$this->values = $value;
}
}
// now validate it
if (empty($this->sourceattribute)) {
throw new Error\Exception("AttributeValueMap: 'sourceattribute' configuration option not set.");
}
if (empty($this->targetattribute)) {
throw new Error\Exception("AttributeValueMap: 'targetattribute' configuration option not set.");
}
if (!is_array($this->values)) {
throw new Error\Exception("AttributeValueMap: 'values' configuration option is not an array.");
}
}
/**
* Apply filter.
*
* @param array &$state The current request
*/
public function process(array &$state): void
{
Logger::debug('Processing the AttributeValueMap filter.');
Assert::keyExists($state, 'Attributes');
$attributes = &$state['Attributes'];
if (!array_key_exists($this->sourceattribute, $attributes)) {
// the source attribute does not exist, nothing to do here
return;
}
$sourceattribute = $attributes[$this->sourceattribute];
$targetvalues = [];
if (is_array($sourceattribute)) {
foreach ($this->values as $value => $values) {
if (!is_array($values)) {
$values = [$values];
}
if (count(array_intersect($values, $sourceattribute)) > 0) {
Logger::debug("AttributeValueMap: intersect match for '$value'");
$targetvalues[] = $value;
}
}
}
if (count($targetvalues) > 0) {
if ($this->replace || !array_key_exists($this->targetattribute, $attributes)) {
$attributes[$this->targetattribute] = $targetvalues;
} else {
$attributes[$this->targetattribute] = array_unique(array_merge(
$attributes[$this->targetattribute],
$targetvalues,
));
}
}
if (!$this->keep) {
// no need to keep the source attribute
unset($attributes[$this->sourceattribute]);
}
}
}

View File

@@ -0,0 +1,202 @@
<?php
declare(strict_types=1);
namespace SimpleSAML\Module\core\Auth\Process;
use SimpleSAML\Assert\Assert;
use SimpleSAML\Auth;
use SimpleSAML\Error;
use SimpleSAML\Logger;
use SimpleSAML\Module;
use SimpleSAML\Utils;
/**
* Filter to ensure correct cardinality of attributes
*
* @package SimpleSAMLphp
*/
class Cardinality extends Auth\ProcessingFilter
{
/** @var array Associative array with the mappings of attribute names. */
private array $cardinality = [];
/** @var array Entities that should be ignored */
private array $ignoreEntities = [];
/** @var \SimpleSAML\Utils\HTTP */
private Utils\HTTP $httpUtils;
/**
* Initialize this filter, parse configuration.
*
* @param array &$config Configuration information about this filter.
* @param mixed $reserved For future use.
* @param \SimpleSAML\Utils\HTTP $httpUtils HTTP utility service (handles redirects).
* @throws \SimpleSAML\Error\Exception
*/
public function __construct(array &$config, $reserved, Utils\HTTP $httpUtils = null)
{
parent::__construct($config, $reserved);
$this->httpUtils = $httpUtils ?: new Utils\HTTP();
foreach ($config as $attribute => $rules) {
if ($attribute === '%ignoreEntities') {
$this->ignoreEntities = $config['%ignoreEntities'];
continue;
}
if (!is_string($attribute)) {
throw new Error\Exception('Invalid attribute name: ' . var_export($attribute, true));
}
$this->cardinality[$attribute] = ['warn' => false];
/* allow either positional or name-based parameters */
if (isset($rules[0])) {
$this->cardinality[$attribute]['min'] = $rules[0];
} elseif (isset($rules['min'])) {
$this->cardinality[$attribute]['min'] = $rules['min'];
}
if (isset($rules[1])) {
$this->cardinality[$attribute]['max'] = $rules[1];
} elseif (isset($rules['max'])) {
$this->cardinality[$attribute]['max'] = $rules['max'];
}
if (array_key_exists('warn', $rules)) {
$this->cardinality[$attribute]['warn'] = (bool) $rules['warn'];
}
/* sanity check the rules */
if (!array_key_exists('min', $this->cardinality[$attribute])) {
$this->cardinality[$attribute]['min'] = 0;
} elseif (
!is_int($this->cardinality[$attribute]['min'])
|| $this->cardinality[$attribute]['min'] < 0
) {
throw new Error\Exception('Minimum cardinality must be a positive integer: ' .
var_export($attribute, true));
}
if (
array_key_exists('max', $this->cardinality[$attribute])
&& !is_int($this->cardinality[$attribute]['max'])
) {
throw new Error\Exception('Maximum cardinality must be a positive integer: ' .
var_export($attribute, true));
}
if (
array_key_exists('min', $this->cardinality[$attribute])
&& array_key_exists('max', $this->cardinality[$attribute])
&& $this->cardinality[$attribute]['min'] > $this->cardinality[$attribute]['max']
) {
throw new Error\Exception('Minimum cardinality must be less than maximum: ' .
var_export($attribute, true));
}
/* generate a display expression */
$this->cardinality[$attribute]['_expr'] = sprintf('%d ≤ n', $this->cardinality[$attribute]['min']);
if (array_key_exists('max', $this->cardinality[$attribute])) {
$this->cardinality[$attribute]['_expr'] .= sprintf(' ≤ %d', $this->cardinality[$attribute]['max']);
}
}
}
/**
* Process this filter
*
* @param array &$state The current request
*/
public function process(array &$state): void
{
Assert::keyExists($state, 'Attributes');
$entityid = false;
if (array_key_exists('Source', $state) && array_key_exists('entityid', $state['Source'])) {
$entityid = $state['Source']['entityid'];
}
if (in_array($entityid, $this->ignoreEntities, true)) {
Logger::debug('Cardinality: Ignoring assertions from ' . $entityid);
return;
}
foreach ($state['Attributes'] as $k => $v) {
if (!array_key_exists($k, $this->cardinality)) {
continue;
}
if (!is_array($v)) {
$v = [$v];
}
/* minimum cardinality */
if (count($v) < $this->cardinality[$k]['min']) {
if ($this->cardinality[$k]['warn']) {
Logger::warning(
sprintf(
'Cardinality: attribute %s from %s does not meet minimum cardinality of %d (%d)',
$k,
$entityid,
$this->cardinality[$k]['min'],
count($v),
),
);
} else {
$state['core:cardinality:errorAttributes'][$k] = [
count($v),
$this->cardinality[$k]['_expr'],
];
}
continue;
}
/* maximum cardinality */
if (array_key_exists('max', $this->cardinality[$k]) && count($v) > $this->cardinality[$k]['max']) {
if ($this->cardinality[$k]['warn']) {
Logger::warning(
sprintf(
'Cardinality: attribute %s from %s does not meet maximum cardinality of %d (%d)',
$k,
$entityid,
$this->cardinality[$k]['max'],
count($v),
),
);
} else {
$state['core:cardinality:errorAttributes'][$k] = [
count($v),
$this->cardinality[$k]['_expr'],
];
}
continue;
}
}
/* check for missing attributes with a minimum cardinality */
foreach ($this->cardinality as $k => $v) {
if (!$this->cardinality[$k]['min'] || array_key_exists($k, $state['Attributes'])) {
continue;
}
if ($this->cardinality[$k]['warn']) {
Logger::warning(sprintf(
'Cardinality: attribute %s from %s is missing',
$k,
$entityid,
));
} else {
$state['core:cardinality:errorAttributes'][$k] = [
0,
$this->cardinality[$k]['_expr'],
];
}
}
/* abort if we found a problematic attribute */
if (array_key_exists('core:cardinality:errorAttributes', $state)) {
$id = Auth\State::saveState($state, 'core:cardinality');
$url = Module::getModuleURL('core/error/cardinality');
$this->httpUtils->redirectTrustedURL($url, ['StateId' => $id]);
return;
}
}
}

View File

@@ -0,0 +1,129 @@
<?php
declare(strict_types=1);
namespace SimpleSAML\Module\core\Auth\Process;
use SimpleSAML\Assert\Assert;
use SimpleSAML\Auth;
use SimpleSAML\Logger;
use SimpleSAML\Module;
use SimpleSAML\Utils;
/**
* Filter to ensure correct cardinality of single-valued attributes
*
* This filter implements a special case of the core:Cardinality filter, and
* allows for optional corrections to be made when cardinality errors are encountered.
*
* @package SimpleSAMLphp
*/
class CardinalitySingle extends Auth\ProcessingFilter
{
/** @var array Attributes that should be single-valued or we generate an error */
private array $singleValued = [];
/** @var array Attributes for which the first value should be taken */
private array $firstValue = [];
/** @var array Attributes that can be flattened to a single value */
private array $flatten = [];
/** @var string Separator for flattened value */
private string $flattenWith = ';';
/** @var array Entities that should be ignored */
private array $ignoreEntities = [];
/** @var \SimpleSAML\Utils\HTTP */
private Utils\HTTP $httpUtils;
/**
* Initialize this filter, parse configuration.
*
* @param array &$config Configuration information about this filter.
* @param mixed $reserved For future use.
* @param \SimpleSAML\Utils\HTTP $httpUtils HTTP utility service (handles redirects).
*/
public function __construct(array &$config, $reserved, Utils\HTTP $httpUtils = null)
{
parent::__construct($config, $reserved);
$this->httpUtils = $httpUtils ?: new Utils\HTTP();
if (array_key_exists('singleValued', $config)) {
$this->singleValued = $config['singleValued'];
}
if (array_key_exists('firstValue', $config)) {
$this->firstValue = $config['firstValue'];
}
if (array_key_exists('flattenWith', $config)) {
if (is_array($config['flattenWith'])) {
$this->flattenWith = array_shift($config['flattenWith']);
} else {
$this->flattenWith = $config['flattenWith'];
}
}
if (array_key_exists('flatten', $config)) {
$this->flatten = $config['flatten'];
}
if (array_key_exists('ignoreEntities', $config)) {
$this->ignoreEntities = $config['ignoreEntities'];
}
/* for consistency with core:Cardinality */
if (array_key_exists('%ignoreEntities', $config)) {
$this->ignoreEntities = $config['%ignoreEntities'];
}
}
/**
* Process this filter
*
* @param array &$state The current request
*/
public function process(array &$state): void
{
Assert::keyExists($state, 'Attributes');
if (
array_key_exists('Source', $state)
&& array_key_exists('entityid', $state['Source'])
&& in_array($state['Source']['entityid'], $this->ignoreEntities, true)
) {
Logger::debug('CardinalitySingle: Ignoring assertions from ' . $state['Source']['entityid']);
return;
}
foreach ($state['Attributes'] as $k => $v) {
if (!is_array($v)) {
continue;
}
if (count($v) <= 1) {
continue;
}
if (in_array($k, $this->singleValued)) {
$state['core:cardinality:errorAttributes'][$k] = [count($v), '0 ≤ n ≤ 1'];
continue;
}
if (in_array($k, $this->firstValue)) {
$state['Attributes'][$k] = [array_shift($v)];
continue;
}
if (in_array($k, $this->flatten)) {
$state['Attributes'][$k] = [implode($this->flattenWith, $v)];
continue;
}
}
/* abort if we found a problematic attribute */
if (array_key_exists('core:cardinality:errorAttributes', $state)) {
$id = Auth\State::saveState($state, 'core:cardinality');
$url = Module::getModuleURL('core/error/cardinality');
$this->httpUtils->redirectTrustedURL($url, ['StateId' => $id]);
return;
}
}
}

View File

@@ -0,0 +1,61 @@
<?php
declare(strict_types=1);
namespace SimpleSAML\Module\core\Auth\Process;
use SimpleSAML\Auth;
use SimpleSAML\Configuration;
use SimpleSAML\Session;
use SimpleSAML\SessionHandler;
/**
* Extend IdP session and cookies.
*/
class ExtendIdPSession extends Auth\ProcessingFilter
{
/**
* @param array &$state
*/
public function process(array &$state): void
{
if (empty($state['Expire']) || empty($state['Authority'])) {
return;
}
$now = time();
$delta = $state['Expire'] - $now;
$globalConfig = Configuration::getInstance();
$sessionDuration = $globalConfig->getOptionalInteger('session.duration', 28800); // 8*60*60
// Extend only if half of session duration already passed
if ($delta >= ($sessionDuration * 0.5)) {
return;
}
// Update authority expire time
$session = Session::getSessionFromRequest();
$session->setAuthorityExpire($state['Authority']);
// Update session cookies duration
// If remember me is active
$rememberMeExpire = $session->getRememberMeExpire();
if (
!empty($state['RememberMe'])
&& $rememberMeExpire !== null
&& $globalConfig->getOptionalBoolean('session.rememberme.enable', false)
) {
$session->setRememberMeExpire();
return;
}
// Or if session lifetime is more than zero
$sessionHandler = SessionHandler::getSessionHandler();
$cookieParams = $sessionHandler->getCookieParams();
if ($cookieParams['lifetime'] > 0) {
$session->updateSessionCookies();
}
}
}

View File

@@ -0,0 +1,151 @@
<?php
declare(strict_types=1);
namespace SimpleSAML\Module\core\Auth\Process;
use Exception;
use SimpleSAML\Assert\Assert;
use SimpleSAML\Auth;
use SimpleSAML\Logger;
/**
* Filter to generate a groups attribute based on many of the attributes of the user.
*
* @package SimpleSAMLphp
*/
class GenerateGroups extends Auth\ProcessingFilter
{
/**
* The attributes we should generate groups from.
* @var array
*/
private array $generateGroupsFrom;
/**
* Initialize this filter.
*
* @param array &$config Configuration information about this filter.
* @param mixed $reserved For future use.
*/
public function __construct(array &$config, $reserved)
{
parent::__construct($config, $reserved);
if (count($config) === 0) {
// Use default groups
$this->generateGroupsFrom = [
'eduPersonAffiliation',
'eduPersonOrgUnitDN',
'eduPersonEntitlement',
];
} else {
// Validate configuration
foreach ($config as $attributeName) {
if (!is_string($attributeName)) {
throw new Exception('Invalid attribute name for core:GenerateGroups filter: ' .
var_export($attributeName, true));
}
}
$this->generateGroupsFrom = $config;
}
}
/**
* Apply filter to add groups attribute.
*
* @param array &$state The current request
*/
public function process(array &$state): void
{
Assert::keyExists($state, 'Attributes');
$groups = [];
$attributes = &$state['Attributes'];
$realm = self::getRealm($attributes);
if ($realm !== null) {
$groups[] = 'realm-' . $realm;
}
foreach ($this->generateGroupsFrom as $name) {
if (!array_key_exists($name, $attributes)) {
Logger::debug('GenerateGroups - attribute \'' . $name . '\' not found.');
// Attribute not present
continue;
}
foreach ($attributes[$name] as $value) {
$value = self::escapeIllegalChars($value);
$groups[] = $name . '-' . $value;
if ($realm !== null) {
$groups[] = $name . '-' . $realm . '-' . $value;
}
}
}
if (count($groups) > 0) {
$attributes['groups'] = $groups;
}
}
/**
* Determine which realm the user belongs to.
*
* This function will attempt to determine the realm a user belongs to based on the
* eduPersonPrincipalName attribute if it is present. If it isn't, or if it doesn't contain
* a realm, NULL will be returned.
*
* @param array $attributes The attributes of the user.
* @return string|null The realm of the user, or NULL if we are unable to determine the realm.
*/
private static function getRealm(array $attributes): ?string
{
if (!array_key_exists('eduPersonPrincipalName', $attributes)) {
return null;
}
$eppn = $attributes['eduPersonPrincipalName'];
if (count($eppn) < 1) {
return null;
}
$eppn = $eppn[0];
$realm = explode('@', $eppn, 2);
if (count($realm) < 2) {
return null;
}
$realm = $realm[1];
return self::escapeIllegalChars($realm);
}
/**
* Escape special characters in a string.
*
* This function is similar to urlencode, but encodes many more characters.
* This function takes any characters not in [a-zA-Z0-9_@=.] and encodes them with as
* %<hex version>. For example, it will encode '+' as '%2b' and '%' as '%25'.
*
* @param string $string The string which should be escaped.
* @return string The escaped string.
*/
private static function escapeIllegalChars(string $string): string
{
return preg_replace_callback(
'/([^a-zA-Z0-9_@=.])/',
/**
* @param array $m
* @return string
*/
function ($m) {
return sprintf("%%%02x", ord($m[1]));
},
$string,
);
}
}

View File

@@ -0,0 +1,74 @@
<?php
declare(strict_types=1);
namespace SimpleSAML\Module\core\Auth\Process;
use SimpleSAML\Assert\Assert;
use SimpleSAML\Auth;
use SimpleSAML\Locale\Language;
use SimpleSAML\Logger;
/**
* Filter to set and get language settings from attributes.
*
* @package SimpleSAMLphp
*/
class LanguageAdaptor extends Auth\ProcessingFilter
{
/** @var string */
private string $langattr = 'preferredLanguage';
/**
* Initialize this filter.
*
* @param array &$config Configuration information about this filter.
* @param mixed $reserved For future use.
*/
public function __construct(array &$config, $reserved)
{
parent::__construct($config, $reserved);
if (array_key_exists('attributename', $config)) {
$this->langattr = $config['attributename'];
}
}
/**
* Apply filter to add or replace attributes.
*
* Add or replace existing attributes with the configured values.
*
* @param array &$state The current request
*/
public function process(array &$state): void
{
Assert::keyExists($state, 'Attributes');
$attributes = &$state['Attributes'];
$attrlang = null;
if (array_key_exists($this->langattr, $attributes)) {
$attrlang = $attributes[$this->langattr][0];
}
$lang = Language::getLanguageCookie();
if (isset($attrlang)) {
Logger::debug('LanguageAdaptor: Language in attribute was set [' . $attrlang . ']');
}
if (isset($lang)) {
Logger::debug('LanguageAdaptor: Language in session was set [' . $lang . ']');
}
if (isset($attrlang) && !isset($lang)) {
// Language set in attribute but not in cookie - update cookie
Language::setLanguageCookie($attrlang);
} elseif (!isset($attrlang) && isset($lang)) {
// Language set in cookie, but not in attribute. Update attribute
$state['Attributes'][$this->langattr] = [$lang];
}
}
}

View File

@@ -0,0 +1,67 @@
<?php
declare(strict_types=1);
namespace SimpleSAML\Module\core\Auth\Process;
use SimpleSAML\Assert\Assert;
use SimpleSAML\Auth;
use SimpleSAML\Error;
/**
* Attribute filter for running arbitrary PHP code.
*
* @package SimpleSAMLphp
*/
class PHP extends Auth\ProcessingFilter
{
/**
* The PHP code that should be run.
*
* @var string
*/
private string $code;
/**
* Initialize this filter, parse configuration
*
* @param array &$config Configuration information about this filter.
* @param mixed $reserved For future use.
*
* @throws \SimpleSAML\Error\Exception if the 'code' option is not defined.
*/
public function __construct(array &$config, $reserved)
{
parent::__construct($config, $reserved);
if (!isset($config['code'])) {
throw new Error\Exception("core:PHP: missing mandatory configuration option 'code'.");
}
$this->code = strval($config['code']);
}
/**
* Apply the PHP code to the attributes.
*
* @param array &$state The current request
*/
public function process(array &$state): void
{
Assert::keyExists($state, 'Attributes');
/**
* @param array &$attributes
* @param array &$state
*/
$function = function (
/** @scrutinizer ignore-unused */ array &$attributes,
/** @scrutinizer ignore-unused */ array &$state,
): void {
eval($this->code);
};
$function($state['Attributes'], $state);
}
}

View File

@@ -0,0 +1,112 @@
<?php
declare(strict_types=1);
namespace SimpleSAML\Module\core\Auth\Process;
use SimpleSAML\Assert\Assert;
use SimpleSAML\Auth;
use SimpleSAML\Configuration;
/**
* Add a scoped variant of an attribute.
*
* @package SimpleSAMLphp
*/
class ScopeAttribute extends Auth\ProcessingFilter
{
/**
* The attribute we extract the scope from.
*
* @var string
*/
private string $scopeAttribute;
/**
* The attribute we want to add scope to.
*
* @var string
*/
private string $sourceAttribute;
/**
* The attribute we want to add the scoped attributes to.
*
* @var string
*/
private string $targetAttribute;
/**
* Only modify targetAttribute if it doesn't already exist.
*
* @var bool
*/
private bool $onlyIfEmpty = false;
/**
* Initialize this filter, parse configuration
*
* @param array &$config Configuration information about this filter.
* @param mixed $reserved For future use.
*/
public function __construct(array &$config, $reserved)
{
parent::__construct($config, $reserved);
$cfg = Configuration::loadFromArray($config, 'ScopeAttribute');
$this->scopeAttribute = $cfg->getString('scopeAttribute');
$this->sourceAttribute = $cfg->getString('sourceAttribute');
$this->targetAttribute = $cfg->getString('targetAttribute');
$this->onlyIfEmpty = $cfg->getOptionalBoolean('onlyIfEmpty', false);
}
/**
* Apply this filter to the request.
*
* @param array &$state The current request
*/
public function process(array &$state): void
{
Assert::keyExists($state, 'Attributes');
$attributes = &$state['Attributes'];
if (!isset($attributes[$this->scopeAttribute])) {
return;
}
if (!isset($attributes[$this->sourceAttribute])) {
return;
}
if (!isset($attributes[$this->targetAttribute])) {
$attributes[$this->targetAttribute] = [];
}
if ($this->onlyIfEmpty && count($attributes[$this->targetAttribute]) > 0) {
return;
}
foreach ($attributes[$this->scopeAttribute] as $scope) {
if (strpos($scope, '@') !== false) {
$scope = explode('@', $scope, 2);
$scope = $scope[1];
}
foreach ($attributes[$this->sourceAttribute] as $value) {
$value = $value . '@' . $scope;
if (in_array($value, $attributes[$this->targetAttribute], true)) {
// Already present
continue;
}
$attributes[$this->targetAttribute][] = $value;
}
}
}
}

View File

@@ -0,0 +1,99 @@
<?php
declare(strict_types=1);
namespace SimpleSAML\Module\core\Auth\Process;
use SimpleSAML\Assert\Assert;
use SimpleSAML\Auth;
use SimpleSAML\Configuration;
use SimpleSAML\Logger;
/**
* Retrieve a scope from a source attribute and add it as a virtual target
* attribute.
*
* For instance, add the following to $simplesamldir/config.php, entry
* authproc.sp
*
* 51 => array(
* 'class' => 'core:ScopeFromAttribute',
* 'sourceAttribute' => 'eduPersonPrincipalName',
* 'targetAttribute' => 'scope',
* ),
*
* to add a virtual 'scope' attribute from the eduPersonPrincipalName
* attribute.
*/
class ScopeFromAttribute extends Auth\ProcessingFilter
{
/**
* The attribute where the scope is taken from
*
* @var string
*/
private string $sourceAttribute;
/**
* The name of the attribute which includes the scope
*
* @var string
*/
private string $targetAttribute;
/**
* Initialize this filter, parse configuration
*
* @param array &$config Configuration information about this filter.
* @param mixed $reserved For future use.
*/
public function __construct(array &$config, $reserved)
{
parent::__construct($config, $reserved);
$cfg = Configuration::loadFromArray($config, 'ScopeFromAttribute');
$this->targetAttribute = $cfg->getString('targetAttribute');
$this->sourceAttribute = $cfg->getString('sourceAttribute');
}
/**
* Apply this filter.
*
* @param array &$state The current request
*/
public function process(array &$state): void
{
Assert::keyExists($state, 'Attributes');
$attributes = &$state['Attributes'];
if (!isset($attributes[$this->sourceAttribute])) {
return;
}
// will not overwrite existing attribute
if (isset($attributes[$this->targetAttribute])) {
return;
}
$sourceAttrVal = $attributes[$this->sourceAttribute][0];
/* Treat the first @ as usually the beginning of the scope
* string, as per eduPerson recommendation. */
$scopeIndex = strpos($sourceAttrVal, '@');
if ($scopeIndex !== false) {
$attributes[$this->targetAttribute] = [];
$scope = substr($sourceAttrVal, $scopeIndex + 1);
$attributes[$this->targetAttribute][] = $scope;
Logger::debug(
'ScopeFromAttribute: Inserted new attribute ' . $this->targetAttribute . ', with scope ' . $scope,
);
} else {
Logger::warning('ScopeFromAttribute: The configured source attribute ' . $this->sourceAttribute
. ' does not have a scope. Did not add attribute ' . $this->targetAttribute . '.');
}
}
}

View File

@@ -0,0 +1,184 @@
<?php
declare(strict_types=1);
namespace SimpleSAML\Module\core\Auth\Process;
use Exception;
use SAML2\Constants;
use SAML2\XML\saml\NameID;
use SimpleSAML\Assert\Assert;
use SimpleSAML\Auth;
use SimpleSAML\Logger;
use SimpleSAML\Utils;
/**
* Filter to generate the eduPersonTargetedID attribute.
*
* By default, this filter will generate the ID based on the UserID of the current user.
* This is generated from the attribute configured in 'identifyingAttribute' in the
* authproc-configuration.
*
* Example - generate from attribute:
* <code>
* 'authproc' => [
* 50 => [
* 'core:TargetedID',
* 'identifyingAttribute' => 'mail',
* ]
* ]
* </code>
*
* @package SimpleSAMLphp
*/
class TargetedID extends Auth\ProcessingFilter
{
/**
* The attribute we should generate the targeted id from.
*
* @var string
*/
private string $identifyingAttribute;
/**
* Whether the attribute should be generated as a NameID value, or as a simple string.
*
* @var boolean
*/
private bool $generateNameId = false;
/**
* @var \SimpleSAML\Utils\Config
*/
protected Utils\Config $configUtils;
/**
* Initialize this filter.
*
* @param array &$config Configuration information about this filter.
* @param mixed $reserved For future use.
*/
public function __construct(array &$config, $reserved)
{
parent::__construct($config, $reserved);
Assert::keyExists($config, 'identifyingAttribute', "Missing mandatory 'identifyingAttribute' config setting.");
Assert::stringNotEmpty(
$config['identifyingAttribute'],
"TargetedID: 'identifyingAttribute' must be a non-empty string.",
);
$this->identifyingAttribute = $config['identifyingAttribute'];
if (array_key_exists('nameId', $config)) {
if (!is_bool($config['nameId'])) {
throw new Exception('Invalid value of \'nameId\'-option to core:TargetedID filter.');
}
$this->generateNameId = $config['nameId'];
}
$this->configUtils = new Utils\Config();
}
/**
* Inject the \SimpleSAML\Utils\Config dependency.
*
* @param \SimpleSAML\Utils\Config $configUtils
*/
public function setConfigUtils(Utils\Config $configUtils): void
{
$this->configUtils = $configUtils;
}
/**
* Apply filter to add the targeted ID.
*
* @param array &$state The current state.
*/
public function process(array &$state): void
{
Assert::keyExists($state, 'Attributes');
if (!array_key_exists($this->identifyingAttribute, $state['Attributes'])) {
Logger::warning(
sprintf(
"core:TargetedID: Missing attribute '%s', which is needed to generate the TargetedID.",
$this->identifyingAttribute,
),
);
return;
}
$userID = $state['Attributes'][$this->identifyingAttribute][0];
Assert::stringNotEmpty($userID);
if (array_key_exists('Source', $state)) {
$srcID = self::getEntityId($state['Source']);
} else {
$srcID = '';
}
if (array_key_exists('Destination', $state)) {
$dstID = self::getEntityId($state['Destination']);
} else {
$dstID = '';
}
$secretSalt = $this->configUtils->getSecretSalt();
$uidData = 'uidhashbase' . $secretSalt;
$uidData .= strlen($srcID) . ':' . $srcID;
$uidData .= strlen($dstID) . ':' . $dstID;
$uidData .= strlen($userID) . ':' . $userID;
$uidData .= $secretSalt;
$uid = hash('sha1', $uidData);
if ($this->generateNameId) {
// Convert the targeted ID to a SAML 2.0 name identifier element
$nameId = new NameID();
$nameId->setValue($uid);
$nameId->setFormat(Constants::NAMEID_PERSISTENT);
if (isset($state['Source']['entityid'])) {
$nameId->setNameQualifier($state['Source']['entityid']);
}
if (isset($state['Destination']['entityid'])) {
$nameId->setSPNameQualifier($state['Destination']['entityid']);
}
} else {
$nameId = $uid;
}
$state['Attributes']['eduPersonTargetedID'] = [$nameId];
}
/**
* Generate ID from entity metadata.
*
* This function takes in the metadata of an entity, and attempts to generate
* an unique identifier based on that.
*
* @param array $metadata The metadata of the entity.
* @return string The unique identifier for the entity.
*/
private static function getEntityId(array $metadata): string
{
$id = '';
if (array_key_exists('metadata-set', $metadata)) {
$set = $metadata['metadata-set'];
$id .= 'set' . strlen($set) . ':' . $set;
}
if (array_key_exists('entityid', $metadata)) {
$entityid = $metadata['entityid'];
$id .= 'set' . strlen($entityid) . ':' . $entityid;
}
return $id;
}
}

View File

@@ -0,0 +1,58 @@
<?php
declare(strict_types=1);
namespace SimpleSAML\Module\core\Auth\Process;
use SimpleSAML\Auth;
use SimpleSAML\Logger;
use SimpleSAML\Module;
use SimpleSAML\Utils;
/**
* Give a warning to the user if we receive multiple requests in a short time.
*
* @package SimpleSAMLphp
*/
class WarnShortSSOInterval extends Auth\ProcessingFilter
{
/**
* Process a authentication response.
*
* This function checks how long it is since the last time the user was authenticated.
* If it is to short a while since, we will show a warning to the user.
*
* @param array $state The state of the response.
*/
public function process(array &$state): void
{
if (!array_key_exists('PreviousSSOTimestamp', $state)) {
/*
* No timestamp from the previous SSO to this SP. This is the first
* time during this session.
*/
return;
}
$timeDelta = time() - $state['PreviousSSOTimestamp'];
if ($timeDelta >= 10) {
// At least 10 seconds since last attempt
return;
}
if (array_key_exists('Destination', $state) && array_key_exists('entityid', $state['Destination'])) {
$entityId = $state['Destination']['entityid'];
} else {
$entityId = 'UNKNOWN';
}
Logger::warning('WarnShortSSOInterval: Only ' . $timeDelta .
' seconds since last SSO for this user from the SP ' . var_export($entityId, true));
// Save state and redirect
$id = Auth\State::saveState($state, 'core:short_sso_interval');
$url = Module::getModuleURL('core/short_sso_interval');
$httpUtils = new Utils\HTTP();
$httpUtils->redirectTrustedURL($url, ['StateId' => $id]);
}
}

View File

@@ -0,0 +1,96 @@
<?php
declare(strict_types=1);
namespace SimpleSAML\Module\core\Auth\Source;
use Exception;
use SimpleSAML\Auth;
use SimpleSAML\Configuration;
use SimpleSAML\Error;
/**
* Authentication source which delegates authentication to secondary
* authentication sources based on policy decision
*
* @package SimpleSAMLphp
*/
abstract class AbstractSourceSelector extends Auth\Source
{
/**
* @var array The names of all the configured auth sources
*/
protected array $validSources;
/**
* Constructor for this authentication source.
*
* @param array $info Information about this authentication source.
* @param array $config Configuration.
*/
public function __construct(array $info, array $config)
{
// Call the parent constructor first, as required by the interface
parent::__construct($info, $config);
$authsources = Configuration::getConfig('authsources.php');
$this->validSources = array_keys($authsources->toArray());
}
/**
* Process a request.
*
* If an authentication source returns from this function, it is assumed to have
* authenticated the user, and should have set elements in $state with the attributes
* of the user.
*
* If the authentication process requires additional steps which make it impossible to
* complete before returning from this function, the authentication source should
* save the state, and at a later stage, load the state, update it with the authentication
* information about the user, and call completeAuth with the state array.
*
* @param array &$state Information about the current authentication.
*/
public function authenticate(array &$state): void
{
$source = $this->selectAuthSource($state);
$as = Auth\Source::getById($source);
if ($as === null || !in_array($source, $this->validSources, true)) {
throw new Exception('Invalid authentication source: ' . $source);
}
$state['sourceSelector:selected'] = $source;
static::doAuthentication($as, $state);
}
/**
* @param \SimpleSAML\Auth\Source $as
* @param array $state
* @return void
*/
public static function doAuthentication(Auth\Source $as, array $state): void
{
try {
$as->authenticate($state);
} catch (Error\Exception $e) {
Auth\State::throwException($state, $e);
} catch (Exception $e) {
$e = new Error\UnserializableException($e);
Auth\State::throwException($state, $e);
}
Auth\Source::completeAuth($state);
}
/**
* Decide what authsource to use.
*
* @param array &$state Information about the current authentication.
* @return string
*/
abstract protected function selectAuthSource(array &$state): string;
}

View File

@@ -0,0 +1,83 @@
<?php
declare(strict_types=1);
namespace SimpleSAML\Module\core\Auth\Source;
use SimpleSAML\Configuration;
use SimpleSAML\Error;
use SimpleSAML\Logger;
use SimpleSAML\Module\core\Auth\UserPassBase;
use Symfony\Component\PasswordHasher\Hasher\NativePasswordHasher;
/**
* Authentication source which verifies the password against
* the 'auth.adminpassword' configuration option.
*
* @package SimpleSAMLphp
*/
class AdminPassword extends UserPassBase
{
/**
* Constructor for this authentication source.
*
* @param array $info Information about this authentication source.
* @param array $config Configuration.
*/
public function __construct(array $info, array $config)
{
// Call the parent constructor first, as required by the interface
parent::__construct($info, $config);
$this->setForcedUsername("admin");
}
/**
* 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(\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.
* @return array Associative array with the users attributes.
*/
protected function login(string $username, string $password): array
{
$config = Configuration::getInstance();
$adminPassword = $config->getString('auth.adminpassword');
if ($adminPassword === '123') {
// We require that the user changes the password
throw new Error\Error(Error\ErrorCodes::NOTSET);
}
if ($username !== "admin") {
throw new Error\Error(Error\ErrorCodes::WRONGUSERPASS);
}
$pwinfo = password_get_info($adminPassword);
if ($pwinfo['algo'] === null) {
// @deprecated: remove this in the future.
// Continue to allow admin login when the config contains
// a password that is not hashed
if ($adminPassword === $password) {
Logger::deprecated('Please consider hashing the admin password stored in auth.adminpassword'
. ' in config.php. Using a plain text password in that config setting'
. ' will be removed in the future.');
return ['user' => ['admin']];
}
throw new Error\Error(Error\ErrorCodes::ADMINNOTHASHED);
}
$hasher = new NativePasswordHasher();
if (!$hasher->verify($adminPassword, $password)) {
throw new Error\Error(Error\ErrorCodes::WRONGUSERPASS);
}
return ['user' => ['admin']];
}
}

View File

@@ -0,0 +1,155 @@
<?php
declare(strict_types=1);
namespace SimpleSAML\Module\core\Auth\Source;
use SAML2\Exception\Protocol\NoAuthnContextException;
use SimpleSAML\Assert\Assert;
use SimpleSAML\Error\Exception;
use SimpleSAML\Logger;
use function array_key_exists;
use function sprintf;
/**
* Authentication source which delegates authentication to secondary
* authentication sources based on the RequestedAuthnContext
*
* @package simplesamlphp/simplesamlphp
*/
class RequestedAuthnContextSelector extends AbstractSourceSelector
{
/**
* The key of the AuthId field in the state.
*/
public const AUTHID = '\SimpleSAML\Module\core\Auth\Source\RequestedAuthnContextSelector.AuthId';
/**
* The string used to identify our states.
*/
public const STAGEID = '\SimpleSAML\Module\core\Auth\Source\RequestedAuthnContextSelector.StageId';
/**
* The key where the sources is saved in the state.
*/
public const SOURCESID = '\SimpleSAML\Module\core\Auth\Source\RequestedAuthnContextSelector.SourceId';
/**
* @var string The default authentication source to use when no RequestedAuthnContext is passed
* @psalm-suppress PropertyNotSetInConstructor
*/
protected string $defaultSource;
/**
* @var array<int, array> An array of AuthnContexts, indexed by a numeric key.
* Each entry is in the format of:
* `loa` => [`identifier` => 'identifier', `source` => 'source']
*
* i.e.:
*
* 10 => [
* 'identifier' => 'urn:x-simplesamlphp:loa1',
* 'source' => 'exampleauth',
* ],
*
* 20 => [
* 'identifier' => 'urn:x-simplesamlphp:loa2',
* 'source' => 'exampleauth-mfa',
* ]
*/
protected array $contexts = [];
/**
* Constructor for this authentication source.
*
* @param array $info Information about this authentication source.
* @param array $config Configuration.
*/
public function __construct(array $info, array $config)
{
// Call the parent constructor first, as required by the interface
parent::__construct($info, $config);
Assert::keyExists($config, 'contexts');
Assert::keyExists($config['contexts'], 'default');
if (!is_array($config['contexts']['default'])) {
Assert::stringNotEmpty($config['contexts']['default']);
$this->defaultSource = $config['contexts']['default'];
unset($config['contexts']['default']);
}
foreach ($config['contexts'] as $key => $context) {
($key !== 'default') && Assert::natural($key);
if (!array_key_exists('identifier', $context)) {
throw new Exception(sprintf("Incomplete context '%d' due to missing `identifier` key.", $key));
} elseif (!array_key_exists('source', $context)) {
throw new Exception(sprintf("Incomplete context '%d' due to missing `source` key.", $key));
}
Assert::stringNotEmpty($context['identifier']);
Assert::stringNotEmpty($context['source']);
$this->contexts[$key] = $context;
}
}
/**
* Decide what authsource to use.
*
* @param array &$state Information about the current authentication.
* @return string
*/
protected function selectAuthSource(array &$state): string
{
$requestedContexts = $state['saml:RequestedAuthnContext'] ?? null;
if (
$requestedContexts === null
|| !array_key_exists('AuthnContextClassRef', $requestedContexts)
|| $requestedContexts['AuthnContextClassRef'] === null
) {
Logger::info(
"core:RequestedAuthnContextSelector: no RequestedAuthnContext provided; selecting default authsource",
);
if (array_key_exists('default', $this->contexts)) {
$state['saml:AuthnContextClassRef'] = $this->contexts['default']['identifier'];
return $this->contexts['default']['source'];
}
return $this->defaultSource;
}
Assert::isArray($requestedContexts['AuthnContextClassRef']);
$comparison = $requestedContexts['Comparison'] ?? 'exact';
Assert::oneOf($comparison, ['exact', 'minimum', 'maximum', 'better']);
/**
* The set of supplied references MUST be evaluated as an ordered set, where the first element
* is the most preferred authentication context class or declaration.
*/
foreach ($requestedContexts['AuthnContextClassRef'] as $requestedContext) {
switch ($comparison) {
case 'exact':
foreach ($this->contexts as $index => $context) {
if ($context['identifier'] === $requestedContext) {
$state['saml:AuthnContextClassRef'] = $context['identifier'];
return $context['source'];
}
}
break 1;
case 'minimum':
case 'maximum':
case 'better':
// Not implemented
throw new Exception('Not implemented.');
}
}
throw new NoAuthnContextException();
}
}

View File

@@ -0,0 +1,122 @@
<?php
declare(strict_types=1);
namespace SimpleSAML\Module\core\Auth\Source;
use SimpleSAML\{Error, Logger};
use SimpleSAML\Assert\Assert;
use Symfony\Component\HttpFoundation\{IpUtils, Request};
use function array_key_exists;
use function sprintf;
/**
* Authentication source which delegates authentication to secondary
* authentication sources based on the client's source IP
*
* @package simplesamlphp/simplesamlphp
*/
class SourceIPSelector extends AbstractSourceSelector
{
/**
* The key of the AuthId field in the state.
*/
public const AUTHID = '\SimpleSAML\Module\core\Auth\Source\SourceIPSelector.AuthId';
/**
* The string used to identify our states.
*/
public const STAGEID = '\SimpleSAML\Module\core\Auth\Source\SourceIPSelector.StageId';
/**
* The key where the sources is saved in the state.
*/
public const SOURCESID = '\SimpleSAML\Module\core\Auth\Source\SourceIPSelector.SourceId';
/**
* @param string|null The default authentication source to use when none of the zones match
*/
protected ?string $defaultSource;
/**
* @param array An array of zones. Each zone requires two keys;
* 'source' containing the authsource for the zone,
* 'subnet' containing an array of IP-ranges (CIDR notation).
*/
protected array $zones = [];
/**
* Constructor for this authentication source.
*
* @param array $info Information about this authentication source.
* @param array $config Configuration.
*/
public function __construct(array $info, array $config)
{
// Call the parent constructor first, as required by the interface
parent::__construct($info, $config);
Assert::keyExists($config, 'zones');
Assert::keyExists($config['zones'], 'default');
Assert::nullOrStringNotEmpty($config['zones']['default']);
$this->defaultSource = $config['zones']['default'];
unset($config['zones']['default']);
$zones = $config['zones'];
foreach ($zones as $key => $zone) {
if (!array_key_exists('source', $zone)) {
throw new Error\Exception(
sprintf("Incomplete zone-configuration '%s' due to missing `source` key.", $key),
);
} elseif (!array_key_exists('subnet', $zone)) {
throw new Error\Exception(
sprintf("Incomplete zone-configuration '%s' due to missing `subnet` key.", $key),
);
} else {
$this->zones[$key] = $zone;
}
}
}
/**
* Decide what authsource to use.
*
* @param array &$state Information about the current authentication.
* @return string
*/
protected function selectAuthSource(/** @scrutinizer ignore-unused */ array &$state): string
{
$ip = Request::createFromGlobals()->getClientIp();
Assert::notNull($ip, "Unable to determine client IP.");
$source = $this->defaultSource;
foreach ($this->zones as $name => $zone) {
foreach ($zone['subnet'] as $subnet) {
if (IpUtils::checkIp($ip, $subnet)) {
// Client's IP is in one of the ranges for the secondary auth source
Logger::info(sprintf(
"core:SourceIPSelector: Selecting zone `%s` based on client IP %s",
$name,
$ip,
));
$source = $zone['source'];
break;
}
}
}
if ($source === null) {
throw new Error\NotFound();
}
if ($source === $this->defaultSource) {
Logger::info("core:SourceIPSelector: no match on client IP; selecting default zone");
}
return $source;
}
}

View File

@@ -0,0 +1,319 @@
<?php
declare(strict_types=1);
namespace SimpleSAML\Module\core\Auth;
use SAML2\Constants;
use SimpleSAML\Assert\Assert;
use SimpleSAML\Auth;
use SimpleSAML\Configuration;
use SimpleSAML\Error;
use SimpleSAML\Logger;
use SimpleSAML\Module;
use SimpleSAML\Utils;
/**
* Helper class for username/password authentication.
*
* This helper class allows for implementations of username/password authentication by
* implementing a single function: login($username, $password)
*
* @package SimpleSAMLphp
*/
abstract class UserPassBase extends Auth\Source
{
/**
* The string used to identify our states.
*/
public const STAGEID = '\SimpleSAML\Module\core\Auth\UserPassBase.state';
/**
* The key of the AuthId field in the state.
*/
public const AUTHID = '\SimpleSAML\Module\core\Auth\UserPassBase.AuthId';
/**
* Username we should force.
*
* A forced username cannot be changed by the user.
* If this is NULL, we won't force any username.
*
* @var string|null
*/
private ?string $forcedUsername = null;
/**
* Links to pages from login page.
* From configuration
*
* @var array
*/
protected array $loginLinks = [];
/**
* Storage for authsource config option remember.username.enabled
* /loginuserpass and /loginuserpassorg pages/templates use this option to
* present users with a checkbox to save their username for the next login request.
*
* @var bool
*/
protected bool $rememberUsernameEnabled = false;
/**
* Storage for authsource config option remember.username.checked
* /loginuserpass and /loginuserpassorg pages/templates use this option
* to default the remember username checkbox to checked or not.
*
* @var bool
*/
protected bool $rememberUsernameChecked = false;
/**
* Storage for general config option session.rememberme.enable.
* /loginuserpass page/template uses this option to present
* users with a checkbox to keep their session alive across
* different browser sessions (that is, closing and opening the
* browser again).
*
* @var bool
*/
protected bool $rememberMeEnabled = false;
/**
* Storage for general config option session.rememberme.checked.
* /loginuserpass page/template uses this option to default
* the "remember me" checkbox to checked or not.
*
* @var bool
*/
protected bool $rememberMeChecked = false;
/**
* Constructor for this authentication source.
*
* All subclasses who implement their own constructor must call this constructor before
* using $config for anything.
*
* @param array $info Information about this authentication source.
* @param array &$config Configuration for this authentication source.
*/
public function __construct(array $info, array &$config)
{
if (isset($config['core:loginpage_links'])) {
$this->loginLinks = $config['core:loginpage_links'];
}
// Call the parent constructor first, as required by the interface
parent::__construct($info, $config);
// Get the remember username config options
if (isset($config['remember.username.enabled'])) {
$this->rememberUsernameEnabled = (bool) $config['remember.username.enabled'];
unset($config['remember.username.enabled']);
}
if (isset($config['remember.username.checked'])) {
$this->rememberUsernameChecked = (bool) $config['remember.username.checked'];
unset($config['remember.username.checked']);
}
// get the "remember me" config options
$sspcnf = Configuration::getInstance();
$this->rememberMeEnabled = $sspcnf->getOptionalBoolean('session.rememberme.enable', false);
$this->rememberMeChecked = $sspcnf->getOptionalBoolean('session.rememberme.checked', false);
}
/**
* Set forced username.
*
* @param string|null $forcedUsername The forced username.
*/
public function setForcedUsername(?string $forcedUsername): void
{
Assert::nullOrString($forcedUsername);
$this->forcedUsername = $forcedUsername;
}
/**
* Return login links from configuration
* @return string[]
*/
public function getLoginLinks(): array
{
return $this->loginLinks;
}
/**
* Getter for the authsource config option remember.username.enabled
* @return bool
*/
public function getRememberUsernameEnabled(): bool
{
return $this->rememberUsernameEnabled;
}
/**
* Getter for the authsource config option remember.username.checked
* @return bool
*/
public function getRememberUsernameChecked(): bool
{
return $this->rememberUsernameChecked;
}
/**
* Check if the "remember me" feature is enabled.
* @return bool TRUE if enabled, FALSE otherwise.
*/
public function isRememberMeEnabled(): bool
{
return $this->rememberMeEnabled;
}
/**
* Check if the "remember me" checkbox should be checked.
* @return bool TRUE if enabled, FALSE otherwise.
*/
public function isRememberMeChecked(): bool
{
return $this->rememberMeChecked;
}
/**
* 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(array &$state): void
{
/*
* Save the identifier of this authentication source, so that we can
* retrieve it later. This allows us to call the login()-function on
* the current object.
*/
$state[self::AUTHID] = $this->authId;
// What username we should force, if any
if ($this->forcedUsername !== null) {
/*
* This is accessed by the login form, to determine if the user
* is allowed to change the username.
*/
$state['forcedUsername'] = $this->forcedUsername;
}
// ECP requests supply authentication credentials with the AuthnRequest
// so we validate them now rather than redirecting. The SAML spec
// doesn't define how the credentials are transferred, but Office 365
// uses the Authorization header, so we will just use that in lieu of
// other use cases.
if (isset($state['saml:Binding']) && $state['saml:Binding'] === Constants::BINDING_PAOS) {
if (!isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW'])) {
Logger::error("ECP AuthnRequest did not contain Basic Authentication header");
// TODO Return a SOAP fault instead of using the current binding?
throw new Error\Error(Error\ErrorCodes::WRONGUSERPASS);
}
$username = $_SERVER['PHP_AUTH_USER'];
$password = $_SERVER['PHP_AUTH_PW'];
if (isset($state['forcedUsername'])) {
$username = $state['forcedUsername'];
}
$attributes = $this->login($username, $password);
$state['Attributes'] = $attributes;
return;
}
// Save the $state-array, so that we can restore it after a redirect
$id = Auth\State::saveState($state, self::STAGEID);
/*
* Redirect to the login form. We include the identifier of the saved
* state array as a parameter to the login form.
*/
$url = Module::getModuleURL('core/loginuserpass');
$params = ['AuthState' => $id];
$httpUtils = new Utils\HTTP();
$httpUtils->redirectTrustedURL($url, $params);
// The previous function never returns, so this code is never executed.
assert::true(false);
}
/**
* 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/error. If the error was caused by the user entering the wrong
* 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.
* @return array Associative array with the user's attributes.
*/
abstract protected function login(string $username, string $password): array;
/**
* Handle login request.
*
* This function is used by the login form (core/loginuserpass) when the user
* enters a username and password. On success, it will not return. On wrong
* username/password failure, and other errors, it will throw an exception.
*
* @param string $authStateId The identifier of the authentication state.
* @param string $username The username the user wrote.
* @param string $password The password the user wrote.
*/
public static function handleLogin(string $authStateId, string $username, string $password): void
{
// Here we retrieve the state array we saved in the authenticate-function.
$state = Auth\State::loadState($authStateId, self::STAGEID);
// Retrieve the authentication source we are executing.
Assert::keyExists($state, self::AUTHID);
/** @var \SimpleSAML\Module\core\Auth\UserPassBase|null $source */
$source = Auth\Source::getById($state[self::AUTHID]);
if ($source === null) {
throw new \Exception('Could not find authentication source with id ' . $state[self::AUTHID]);
}
/*
* $source now contains the authentication source on which authenticate()
* was called. We should call login() on the same authentication source.
*/
// Attempt to log in
try {
$attributes = $source->login($username, $password);
} catch (\Exception $e) {
Logger::stats('Unsuccessful login attempt from ' . $_SERVER['REMOTE_ADDR'] . '.');
throw $e;
}
Logger::stats('User \'' . $username . '\' successfully authenticated from ' . $_SERVER['REMOTE_ADDR']);
// Save the attributes we received from the login-function in the $state-array
$state['Attributes'] = $attributes;
// Return control to SimpleSAMLphp after successful authentication.
Auth\Source::completeAuth($state);
}
}

View File

@@ -0,0 +1,350 @@
<?php
declare(strict_types=1);
namespace SimpleSAML\Module\core\Auth;
use SimpleSAML\Assert\Assert;
use SimpleSAML\Auth;
use SimpleSAML\Error;
use SimpleSAML\Logger;
use SimpleSAML\Module;
use SimpleSAML\Utils;
/**
* Helper class for username/password/organization authentication.
*
* This helper class allows for implementations of username/password/organization
* authentication by implementing two functions:
* - login($username, $password, $organization)
* - getOrganizations()
*
* @package SimpleSAMLphp
*/
abstract class UserPassOrgBase extends Auth\Source
{
/**
* The string used to identify our states.
*/
public const STAGEID = '\SimpleSAML\Module\core\Auth\UserPassOrgBase.state';
/**
* The key of the AuthId field in the state.
*/
public const AUTHID = '\SimpleSAML\Module\core\Auth\UserPassOrgBase.AuthId';
/**
* The key of the OrgId field in the state, identifies which org was selected.
*/
public const ORGID = '\SimpleSAML\Module\core\Auth\UserPassOrgBase.SelectedOrg';
/**
* What way do we handle the organization as part of the username.
* Three values:
* 'none': Force the user to select the correct organization from the dropdown box.
* 'allow': Allow the user to enter the organization as part of the username.
* 'force': Remove the dropdown box.
*
* @var string
*/
private string $usernameOrgMethod;
/**
* Storage for authsource config option remember.username.enabled
* /loginuserpass and /loginuserpassorg pages/templates use this option to
* present users with a checkbox to save their username for the next login request.
*
* @var bool
*/
protected bool $rememberUsernameEnabled = false;
/**
* Storage for authsource config option remember.username.checked
* /loginuserpass and /loginuserpassorg pages/templates use this option
* to default the remember username checkbox to checked or not.
*
* @var bool
*/
protected bool $rememberUsernameChecked = false;
/**
* Storage for authsource config option remember.organization.enabled
* /loginuserpassorg page/template use this option to present users
* with a checkbox to save their organization choice for the next login request.
*
* @var bool
*/
protected bool $rememberOrganizationEnabled = false;
/**
* Storage for authsource config option remember.organization.checked
* /loginuserpassorg page/template use this option to
* default the remember organization checkbox to checked or not.
*
* @var bool
*/
protected bool $rememberOrganizationChecked = false;
/**
* Constructor for this authentication source.
*
* All subclasses who implement their own constructor must call this constructor before
* using $config for anything.
*
* @param array $info Information about this authentication source.
* @param array &$config Configuration for this authentication source.
*/
public function __construct(array $info, array &$config)
{
// Call the parent constructor first, as required by the interface
parent::__construct($info, $config);
// Get the remember username config options
if (isset($config['remember.username.enabled'])) {
$this->rememberUsernameEnabled = (bool) $config['remember.username.enabled'];
unset($config['remember.username.enabled']);
}
if (isset($config['remember.username.checked'])) {
$this->rememberUsernameChecked = (bool) $config['remember.username.checked'];
unset($config['remember.username.checked']);
}
// Get the remember organization config options
if (isset($config['remember.organization.enabled'])) {
$this->rememberOrganizationEnabled = (bool) $config['remember.organization.enabled'];
unset($config['remember.organization.enabled']);
}
if (isset($config['remember.organization.checked'])) {
$this->rememberOrganizationChecked = (bool) $config['remember.organization.checked'];
unset($config['remember.organization.checked']);
}
$this->usernameOrgMethod = 'none';
}
/**
* Configure the way organizations as part of the username is handled.
*
* There are three possible values:
* - 'none': Force the user to select the correct organization from the dropdown box.
* - 'allow': Allow the user to enter the organization as part of the username.
* - 'force': Remove the dropdown box.
*
* If unconfigured, the default is 'none'.
*
* @param string $usernameOrgMethod The method which should be used.
*/
protected function setUsernameOrgMethod(string $usernameOrgMethod): void
{
Assert::oneOf($usernameOrgMethod, ['none', 'allow', 'force']);
$this->usernameOrgMethod = $usernameOrgMethod;
}
/**
* Retrieve the way organizations as part of the username should be handled.
*
* There are three possible values:
* - 'none': Force the user to select the correct organization from the dropdown box.
* - 'allow': Allow the user to enter the organization as part of the username.
* - 'force': Remove the dropdown box.
*
* @return string The method which should be used.
*/
public function getUsernameOrgMethod(): string
{
return $this->usernameOrgMethod;
}
/**
* Getter for the authsource config option remember.username.enabled
* @return bool
*/
public function getRememberUsernameEnabled(): bool
{
return $this->rememberUsernameEnabled;
}
/**
* Getter for the authsource config option remember.username.checked
* @return bool
*/
public function getRememberUsernameChecked(): bool
{
return $this->rememberUsernameChecked;
}
/**
* Getter for the authsource config option remember.organization.enabled
* @return bool
*/
public function getRememberOrganizationEnabled(): bool
{
return $this->rememberOrganizationEnabled;
}
/**
* Getter for the authsource config option remember.organization.checked
* @return bool
*/
public function getRememberOrganizationChecked(): bool
{
return $this->rememberOrganizationChecked;
}
/**
* 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(array &$state): void
{
// We are going to need the authId in order to retrieve this authentication source later
$state[self::AUTHID] = $this->authId;
$id = Auth\State::saveState($state, self::STAGEID);
$url = Module::getModuleURL('core/loginuserpassorg');
$params = ['AuthState' => $id];
$httpUtils = new Utils\HTTP();
$httpUtils->redirectTrustedURL($url, $params);
}
/**
* Attempt to log in using the given username, password and organization.
*
* On a successful login, this function should return the users attributes. On failure,
* it should throw an exception/error. If the error was caused by the user entering the wrong
* 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 $organization The id of the organization the user chose.
* @return array Associative array with the user's attributes.
*/
abstract protected function login(string $username, string $password, string $organization): array;
/**
* Retrieve list of organizations.
*
* The list of organizations is an associative array. The key of the array is the
* id of the organization, and the value is the description. The value can be another
* array, in which case that array is expected to contain language-code to
* description mappings.
*
* @return array Associative array with the organizations.
*/
abstract protected function getOrganizations(): array;
/**
* Handle login request.
*
* This function is used by the login form (core/loginuserpassorg) when the user
* enters a username and password. On success, it will not return. On wrong
* username/password failure, and other errors, it will throw an exception.
*
* @param string $authStateId The identifier of the authentication state.
* @param string $username The username the user wrote.
* @param string $password The password the user wrote.
* @param string $organization The id of the organization the user chose.
*/
public static function handleLogin(
string $authStateId,
string $username,
string $password,
string $organization,
): void {
/* Retrieve the authentication state. */
$state = Auth\State::loadState($authStateId, self::STAGEID);
/* Find authentication source. */
Assert::keyExists($state, self::AUTHID);
/** @var \SimpleSAML\Module\core\Auth\UserPassOrgBase|null $source */
$source = Auth\Source::getById($state[self::AUTHID]);
if ($source === null) {
throw new \Exception('Could not find authentication source with id ' . $state[self::AUTHID]);
}
$orgMethod = $source->getUsernameOrgMethod();
if ($orgMethod !== 'none') {
$tmp = explode('@', $username, 2);
if (count($tmp) === 2) {
$username = $tmp[0];
$organization = $tmp[1];
} else {
if ($orgMethod === 'force') {
/* The organization should be a part of the username, but isn't. */
throw new Error\Error(Error\ErrorCodes::WRONGUSERPASS);
}
}
}
/* Attempt to log in. */
try {
$attributes = $source->login($username, $password, $organization);
} catch (\Exception $e) {
Logger::stats('Unsuccessful login attempt from ' . $_SERVER['REMOTE_ADDR'] . '.');
throw $e;
}
Logger::stats(
'User \'' . $username . '\' at \'' . $organization
. '\' successfully authenticated from ' . $_SERVER['REMOTE_ADDR'],
);
// Add the selected Org to the state
$state[self::ORGID] = $organization;
$state['PersistentAuthData'][] = self::ORGID;
$state['Attributes'] = $attributes;
Auth\Source::completeAuth($state);
}
/**
* Get available organizations.
*
* This function is used by the login form to get the available organizations.
*
* @param string $authStateId The identifier of the authentication state.
* @return array|null Array of organizations. NULL if the user must enter the
* organization as part of the username.
*/
public static function listOrganizations(string $authStateId): ?array
{
/* Retrieve the authentication state. */
$state = Auth\State::loadState($authStateId, self::STAGEID);
/* Find authentication source. */
Assert::keyExists($state, self::AUTHID);
/** @var \SimpleSAML\Module\core\Auth\UserPassOrgBase|null $source */
$source = Auth\Source::getById($state[self::AUTHID]);
if ($source === null) {
throw new \Exception('Could not find authentication source with id ' . $state[self::AUTHID]);
}
$orgMethod = $source->getUsernameOrgMethod();
if ($orgMethod === 'force') {
return null;
}
return $source->getOrganizations();
}
}

View File

@@ -0,0 +1,104 @@
<?php
declare(strict_types=1);
namespace SimpleSAML\Module\core\Controller;
use Exception as BuiltinException;
use SimpleSAML\{Configuration, Error, Logger, Session, Utils};
use SimpleSAML\HTTP\RunnableResponse;
use SimpleSAML\XHTML\Template;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use function dirname;
use function php_uname;
use function var_export;
/**
* Controller class for the core module.
*
* This class serves the different views available in the module.
*
* @package SimpleSAML\Module\core
*/
class ErrorReport
{
/**
* Controller constructor.
*
* It initializes the global configuration for the controllers implemented here.
*
* @param \SimpleSAML\Configuration $config The configuration to use by the controllers.
* @param \SimpleSAML\Session $config The session to use by the controllers.
*/
public function __construct(
protected Configuration $config,
protected Session $session,
) {
}
/**
* @param \Symfony\Component\HttpFoundation\Request $request
* @return \SimpleSAML\XHTML\Template|\SimpleSAML\HTTP\RunnableResponse
*/
public function main(Request $request): Response
{
// this page will redirect to itself after processing a POST request and sending the email
if ($request->server->get('REQUEST_METHOD') !== 'POST') {
// the message has been sent. Show error report page
return new Template($this->config, 'core:errorreport.twig');
}
$reportId = $request->request->get('reportId');
$email = $request->request->get('email');
$text = $request->request->get('text');
if (!preg_match('/^[0-9a-f]{8}$/', $reportId)) {
throw new Error\Exception('Invalid reportID');
}
try {
$data = $this->session->getData('core:errorreport', $reportId);
} catch (BuiltinException $e) {
$data = null;
Logger::error('Error loading error report data: ' . var_export($e->getMessage(), true));
}
if ($data === null) {
$data = [
'exceptionMsg' => 'not set',
'exceptionTrace' => 'not set',
'trackId' => 'not set',
'url' => 'not set',
'referer' => 'not set',
];
if (isset($this->session)) {
$data['trackId'] = $this->session->getTrackID();
}
}
$data['reportId'] = $reportId;
$data['version'] = $this->config->getVersion();
$data['hostname'] = php_uname('n');
$data['directory'] = dirname(__FILE__, 2);
if ($this->config->getOptionalBoolean('errorreporting', true)) {
$mail = new Utils\EMail('SimpleSAMLphp error report from ' . $email);
$mail->setData($data);
if (filter_var($email, FILTER_VALIDATE_EMAIL, FILTER_REQUIRE_SCALAR)) {
$mail->addReplyTo($email);
}
$mail->setText($text);
$mail->send();
Logger::error('Report with id ' . $reportId . ' sent');
}
// redirect the user back to this page to clear the POST request
$httpUtils = new Utils\HTTP();
return new RunnableResponse([$httpUtils, 'redirectTrustedURL'], [$httpUtils->getSelfURLNoQuery()]);
}
}

View File

@@ -0,0 +1,197 @@
<?php
declare(strict_types=1);
namespace SimpleSAML\Module\core\Controller;
use DateTimeInterface;
use SimpleSAML\Assert\Assert;
use SimpleSAML\{Auth, Configuration, Error, Logger, Module, Session, Utils};
use SimpleSAML\XHTML\Template;
use Symfony\Component\HttpFoundation\{Request, Response};
use function array_keys;
use function date;
use function implode;
use function intval;
use function strval;
use function urlencode;
/**
* Controller class for the core module.
*
* This class serves the different views available in the module.
*
* @package SimpleSAML\Module\core
*/
class Exception
{
public const CODES = ['IDENTIFICATION_FAILURE', 'AUTHENTICATION_FAILURE', 'AUTHORIZATION_FAILURE', 'OTHER_ERROR'];
/**
* Controller constructor.
*
* It initializes the global configuration and auth source configuration for the controllers implemented here.
*
* @param \SimpleSAML\Configuration $config The configuration to use by the controllers.
* @param \SimpleSAML\Session $session The session to use by the controllers.
*
* @throws \Exception
*/
public function __construct(
protected Configuration $config,
protected Session $session,
) {
}
/**
* Show Service Provider error.
*
* @param Request $request The request that lead to this login operation.
* @param string $code The error code
* @return \SimpleSAML\XHTML\Template An HTML template
*/
public function error(Request $request, string $code): Response
{
if ($code !== 'ERRORURL_CODE') {
Assert::oneOf($code, self::CODES);
}
$ts = $request->query->get('ts');
$rp = $request->query->get('rp');
$tid = $request->query->get('tid');
$ctx = $request->query->get('ctx');
if ($ts !== 'ERRORURL_TS') {
Assert::integerish($ts);
$ts = date(DateTimeInterface::W3C, intval($ts));
} else {
$ts = null;
}
if ($rp === 'ERRORURL_RP') {
$rp = null;
}
if ($tid === 'ERRORURL_TID') {
$tid = null;
}
if ($ctx === 'ERRORURL_CTX') {
$ctx = null;
}
Logger::notice(sprintf(
"A Service Provider reported the following error during authentication: "
. "Code: %s; Timestamp: %s; Relying party: %s; Transaction ID: %s; Context: [%s]",
$code,
$ts ?? 'null',
$rp ?? 'null',
$tid ?? 'null',
$ctx,
));
$t = new Template($this->config, 'core:error.twig');
$t->data['code'] = $code;
$t->data['ts'] = $ts;
$t->data['rp'] = $rp;
$t->data['tid'] = $tid;
$t->data['ctx'] = $ctx;
return $t;
}
/**
* Show cardinality error.
*
* @param Request $request The request that lead to this login operation.
* @throws \SimpleSAML\Error\BadRequest
* @return \SimpleSAML\XHTML\Template|\Symfony\Component\HttpFoundation\RedirectResponse
* An HTML template or a redirection if we are not authenticated.
*/
public function cardinality(Request $request): Response
{
$stateId = $request->query->get('StateId', false);
if ($stateId === false) {
throw new Error\BadRequest('Missing required StateId query parameter.');
}
$state = Auth\State::loadState($stateId, 'core:cardinality');
Logger::stats(
'core:cardinality:error ' . $state['Destination']['entityid'] . ' ' . $state['saml:sp:IdP'] .
' ' . implode(',', array_keys($state['core:cardinality:errorAttributes'])),
);
$t = new Template($this->config, 'core:cardinality_error.twig');
$t->data['cardinalityErrorAttributes'] = $state['core:cardinality:errorAttributes'];
if (isset($state['Source']['auth'])) {
$t->data['LogoutURL'] = Module::getModuleURL(
'saml/sp/login/' . urlencode($state['Source']['auth']),
);
}
$t->setStatusCode(403);
return $t;
}
/**
* Show missing cookie error.
*
* @param Request $request The request that lead to this login operation.
* @return \SimpleSAML\XHTML\Template|\Symfony\Component\HttpFoundation\RedirectResponse
* An HTML template or a redirection if we are not authenticated.
*/
public function nocookie(Request $request): Response
{
$retryURL = $request->query->get('retryURL', null);
if ($retryURL !== null) {
$httpUtils = new Utils\HTTP();
$retryURL = $httpUtils->checkURLAllowed(strval($retryURL));
}
$t = new Template($this->config, 'core:no_cookie.twig');
$t->data['retryURL'] = $retryURL;
return $t;
}
/**
* Show a warning to an user about the SP requesting SSO a short time after
* doing it previously.
*
* @param Request $request The request that lead to this login operation.
*
* @return \SimpleSAML\XHTML\Template|\SimpleSAML\HTTP\RunnableResponse|\Symfony\Component\HttpFoundation\RedirectResponse
* An HTML template, a redirect or a "runnable" response.
*
* @throws \SimpleSAML\Error\BadRequest
*/
public function shortSsoInterval(Request $request): Response
{
$stateId = $request->query->get('StateId', false);
if ($stateId === false) {
throw new Error\BadRequest('Missing required StateId query parameter.');
}
$state = Auth\State::loadState($stateId, 'core:short_sso_interval');
$continue = $request->query->get('continue', false);
if ($continue !== false) {
// The user has pressed the continue/retry-button
Auth\ProcessingChain::resumeProcessing($state);
}
$t = new Template($this->config, 'core:short_sso_interval.twig');
$t->data['params'] = ['StateId' => $stateId];
$t->data['trackId'] = $this->session->getTrackID();
$t->data['autofocus'] = 'contbutton';
return $t;
}
}

View File

@@ -0,0 +1,527 @@
<?php
declare(strict_types=1);
namespace SimpleSAML\Module\core\Controller;
use SimpleSAML\{Auth, Configuration, Error, Module, Utils};
use SimpleSAML\Module\core\Auth\{UserPassBase, UserPassOrgBase};
use SimpleSAML\XHTML\Template;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use SimpleSAML\Error\ErrorCodes;
use function array_key_exists;
use function substr;
use function time;
use function trim;
/**
* Controller class for the core module.
*
* This class serves the different views available in the module.
*
* @package SimpleSAML\Module\core
*/
class Login
{
/**
* @var \SimpleSAML\Auth\Source|string
* @psalm-var \SimpleSAML\Auth\Source|class-string
*/
protected $authSource = Auth\Source::class;
/**
* @var \SimpleSAML\Auth\State|string
* @psalm-var \SimpleSAML\Auth\State|class-string
*/
protected $authState = Auth\State::class;
/**
* These are all the subclass instances of ErrorCodes which have been created
*/
protected static array $registeredErrorCodeClasses = [];
/**
* Controller constructor.
*
* It initializes the global configuration for the controllers implemented here.
*
* @param \SimpleSAML\Configuration $config The configuration to use by the controllers.
*
* @throws \Exception
*/
public function __construct(
protected Configuration $config,
) {
}
/**
* Inject the \SimpleSAML\Auth\Source dependency.
*
* @param \SimpleSAML\Auth\Source $authSource
*/
public function setAuthSource(Auth\Source $authSource): void
{
$this->authSource = $authSource;
}
/**
* Inject the \SimpleSAML\Auth\State dependency.
*
* @param \SimpleSAML\Auth\State $authState
*/
public function setAuthState(Auth\State $authState): void
{
$this->authState = $authState;
}
/**
* @return \SimpleSAML\XHTML\Template
*/
public function welcome(): Template
{
return new Template($this->config, 'core:welcome.twig');
}
/**
* This page shows a username/password login form, and passes information from it
* to the \SimpleSAML\Module\core\Auth\UserPassBase class, which is a generic class for
* username/password authentication.
*
* @param \Symfony\Component\HttpFoundation\Request $request
*/
public function loginuserpass(Request $request): Response
{
// Retrieve the authentication state
if (!$request->query->has('AuthState')) {
throw new Error\BadRequest('Missing AuthState parameter.');
}
$authStateId = $request->query->get('AuthState');
$this->authState::validateStateId($authStateId);
$state = $this->authState::loadState($authStateId, UserPassBase::STAGEID);
/** @var \SimpleSAML\Module\core\Auth\UserPassBase|null $source */
$source = $this->authSource::getById($state[UserPassBase::AUTHID]);
if ($source === null) {
throw new Error\Exception(
'Could not find authentication source with id ' . $state[UserPassBase::AUTHID],
);
}
return $this->handleLogin($request, $source, $state);
}
/**
* Called by the constructor in ErrorCode to register subclasses with us
* so we can track which subclasses are valid names in order to limit
* which classes we might recreate
*
* @para object ecc an instance of an ErrorCode or subclass
*/
public static function registerErrorCodeClass(ErrorCodes $ecc): void
{
if (is_subclass_of($ecc, ErrorCodes::class, false)) {
$className = get_class($ecc);
self::$registeredErrorCodeClasses[] = $className;
}
}
/**
* This method handles the generic part for both loginuserpass and loginuserpassorg
*
* @param \Symfony\Component\HttpFoundation\Request $request
* @param \SimpleSAML\Module\core\Auth\UserPassBase|\SimpleSAML\Module\core\Auth\UserPassOrgBase $source
* @param array $state
*/
private function handleLogin(Request $request, UserPassBase|UserPassOrgBase $source, array $state): Response
{
$authStateId = $request->query->get('AuthState');
$this->authState::validateStateId($authStateId);
$organizations = $organization = null;
if ($source instanceof UserPassOrgBase) {
$organizations = UserPassOrgBase::listOrganizations($authStateId);
$organization = $this->getOrganizationFromRequest($request, $source, $state);
}
$username = $this->getUsernameFromRequest($request, $source, $state);
$password = $this->getPasswordFromRequest($request);
$errorCode = null;
$errorParams = null;
$codeClass = '';
if (isset($state['error'])) {
$errorCode = $state['error']['code'];
$errorParams = $state['error']['params'];
$codeClass = $state['error']['codeclass'];
}
$cookies = [];
if ($organizations === null || $organization !== '') {
if (!empty($username) || !empty($password)) {
$httpUtils = new Utils\HTTP();
$sameSiteNone = $httpUtils->canSetSamesiteNone() ? Cookie::SAMESITE_NONE : null;
// Either username or password set - attempt to log in
if (array_key_exists('forcedUsername', $state) && ($state['forcedUsername'] !== false)) {
$username = $state['forcedUsername'];
}
if ($source->getRememberUsernameEnabled()) {
if (
$request->request->has('remember_username')
&& ($request->request->get('remember_username') === 'Yes')
) {
$expire = time() + 3153600;
} else {
$expire = time() - 300;
}
$cookies[] = $this->renderCookie(
$source->getAuthId() . '-username',
$username,
$expire,
'/', // path
null, // domain
null, // secure
true, // httponly
false, // raw
$sameSiteNone,
);
}
if (($source instanceof UserPassBase) && $source->isRememberMeEnabled()) {
if ($request->request->has('remember_me') && ($request->request->get('remember_me') === 'Yes')) {
$state['RememberMe'] = true;
$authStateId = Auth\State::saveState($state, UserPassBase::STAGEID);
}
}
if (($source instanceof UserPassOrgBase) && $source->getRememberOrganizationEnabled()) {
if (
$request->request->has('remember_organization')
&& ($request->request->get('remember_organization') === 'Yes')
) {
$expire = time() + 3153600;
} else {
$expire = time() - 300;
}
$cookies[] = $this->renderCookie(
$source->getAuthId() . '-organization',
$organization,
$expire,
'/', // path
null, // domain
null, // secure
true, // httponly
false, // raw
$sameSiteNone,
);
}
try {
if ($source instanceof UserPassOrgBase) {
UserPassOrgBase::handleLogin($authStateId, $username, $password, $organization);
} else {
UserPassBase::handleLogin($authStateId, $username, $password);
}
} catch (Error\Error $e) {
// Login failed. Extract error code and parameters, to display the error
$errorCode = $e->getErrorCode();
$errorParams = $e->getParameters();
$codeClass = get_class($e->getErrorCodes());
$state['error'] = [
'code' => $errorCode,
'params' => $errorParams,
'codeclass' => $codeClass,
];
$authStateId = Auth\State::saveState($state, $source::STAGEID);
}
if (isset($state['error'])) {
unset($state['error']);
}
}
}
$t = new Template($this->config, 'core:loginuserpass.twig');
if ($source instanceof UserPassOrgBase) {
$t->data['username'] = $state['core:username'] ?? '';
$t->data['forceUsername'] = false;
$t->data['rememberUsernameEnabled'] = $source->getRememberUsernameEnabled();
$t->data['rememberUsernameChecked'] = $source->getRememberUsernameChecked();
$t->data['rememberMeEnabled'] = false;
$t->data['rememberMeChecked'] = false;
} elseif (array_key_exists('forcedUsername', $state)) {
$t->data['username'] = $state['forcedUsername'];
$t->data['forceUsername'] = true;
$t->data['rememberUsernameEnabled'] = false;
$t->data['rememberUsernameChecked'] = false;
$t->data['rememberMeEnabled'] = $source->isRememberMeEnabled();
$t->data['rememberMeChecked'] = $source->isRememberMeChecked();
} else {
$t->data['username'] = $state['core:username'] ?? '';
$t->data['forceUsername'] = false;
$t->data['rememberUsernameEnabled'] = $source->getRememberUsernameEnabled();
$t->data['rememberUsernameChecked'] = $source->getRememberUsernameChecked();
$t->data['rememberMeEnabled'] = $source->isRememberMeEnabled();
$t->data['rememberMeChecked'] = $source->isRememberMeChecked();
if ($request->cookies->has($source->getAuthId() . '-username')) {
$t->data['rememberUsernameChecked'] = true;
}
}
if ($source instanceof UserPassOrgBase) {
$t->data['formURL'] = Module::getModuleURL('core/loginuserpassorg', ['AuthState' => $authStateId]);
if ($request->request->has($source->getAuthId() . '-username')) {
$t->data['rememberUsernameChecked'] = true;
}
$t->data['rememberOrganizationEnabled'] = $source->getRememberOrganizationEnabled();
$t->data['rememberOrganizationChecked'] = $source->getRememberOrganizationChecked();
if ($request->request->has($source->getAuthId() . '-organization')) {
$t->data['rememberOrganizationChecked'] = true;
}
if ($organizations !== null) {
$t->data['selectedOrg'] = $organization;
$t->data['organizations'] = $organizations;
}
} else {
$t->data['formURL'] = Module::getModuleURL('core/loginuserpass', ['AuthState' => $authStateId]);
$t->data['loginpage_links'] = $source->getLoginLinks();
}
$t->data['errorcode'] = $errorCode;
$t->data['errorcodes'] = ErrorCodes::getAllErrorCodeMessages();
$t->data['errorparams'] = $errorParams;
$className = $codeClass;
if ($className) {
if (in_array($className, self::$registeredErrorCodeClasses)) {
if (!class_exists($className)) {
throw new Error\Exception("Could not resolve error class. no class named '$className'.");
}
if (!is_subclass_of($className, ErrorCodes::class)) {
throw new Error\Exception(
'Could not resolve error class: The class \'' . $className
. '\' isn\'t a subclass of \'' . ErrorCodes::class . '\'.',
);
}
$obj = Module::createObject($className, ErrorCodes::class);
$t->data['errorcodes'] = $obj->getAllErrorCodeMessages();
} else {
if ($className != ErrorCodes::class) {
throw new Error\Exception(
'The desired error code class is not found or of the wrong type ' . $className,
);
}
}
}
if (isset($state['SPMetadata'])) {
$t->data['SPMetadata'] = $state['SPMetadata'];
} else {
$t->data['SPMetadata'] = null;
}
foreach ($cookies as $cookie) {
$t->headers->setCookie($cookie);
}
return $t;
}
/**
* This page shows a username/password/organization login form, and passes information from
* into the \SimpleSAML\Module\core\Auth\UserPassBase class, which is a generic class for
* username/password/organization authentication.
*
* @param \Symfony\Component\HttpFoundation\Request $request
*/
public function loginuserpassorg(Request $request): Response
{
// Retrieve the authentication state
if (!$request->query->has('AuthState')) {
throw new Error\BadRequest('Missing AuthState parameter.');
}
$authStateId = $request->query->get('AuthState');
$this->authState::validateStateId($authStateId);
$state = $this->authState::loadState($authStateId, UserPassOrgBase::STAGEID);
/** @var \SimpleSAML\Module\core\Auth\UserPassOrgBase $source */
$source = $this->authSource::getById($state[UserPassOrgBase::AUTHID]);
if ($source === null) {
throw new Error\Exception(
'Could not find authentication source with id ' . $state[UserPassOrgBase::AUTHID],
);
}
return $this->handleLogin($request, $source, $state);
}
/**
* @param string $name The name for the cookie
* @param string $value The value for the cookie
* @param int $expire The expiration in seconds
* @param string $path The path for the cookie
* @param string $domain The domain for the cookie
* @param bool $secure Whether this cookie must have the secure-flag
* @param bool $httponly Whether this cookie must have the httponly-flag
* @param bool $raw Whether this cookie must be sent without urlencoding
* @param string $sameSite The value for the sameSite-flag
* @return \Symfony\Component\HttpFoundation\Cookie
*/
private function renderCookie(
string $name,
?string $value,
int $expire = 0,
string $path = '/',
?string $domain = null,
?bool $secure = null,
bool $httponly = true,
bool $raw = false,
?string $sameSite = 'none',
): Cookie {
return new Cookie($name, $value, $expire, $path, $domain, $secure, $httponly, $raw, $sameSite);
}
/**
* Retrieve the username from the request, a cookie or the state
*
* @param \Symfony\Component\HttpFoundation\Request $request
* @param \SimpleSAML\Auth\Source $source
* @param array $state
* @return string
*/
private function getUsernameFromRequest(Request $request, Auth\Source $source, array $state): string
{
$username = '';
if ($request->request->has('username')) {
$username = trim($request->request->get('username'));
} elseif (
$source->getRememberUsernameEnabled()
&& $request->cookies->has($source->getAuthId() . '-username')
) {
$username = $request->cookies->get($source->getAuthId() . '-username');
}
return $username;
}
/**
* Retrieve the password from the request
*
* @param \Symfony\Component\HttpFoundation\Request $request
* @return string
*/
private function getPasswordFromRequest(Request $request): string
{
$password = '';
if ($request->request->has('password')) {
$password = $request->request->get('password');
}
return $password;
}
/**
* Retrieve the organization from the request, a cookie or the state
*
* @param \Symfony\Component\HttpFoundation\Request $request
* @param \SimpleSAML\Auth\Source $source
* @param array $state
* @return string
*/
private function getOrganizationFromRequest(Request $request, Auth\Source $source, array $state): string
{
$organization = '';
if ($request->request->has('organization')) {
$organization = $request->request->get('organization');
} elseif (
$source->getRememberOrganizationEnabled()
&& $request->cookies->has($source->getAuthId() . '-organization')
) {
$organization = $request->cookies->get($source->getAuthId() . '-organization');
} elseif (isset($state['core:organization'])) {
$organization = strval($state['core:organization']);
}
return $organization;
}
/**
* Searches for a valid and allowed ReturnTo URL parameter,
* otherwise give the base installation page as a return point.
*/
private function getReturnPath(Request $request): string
{
$httpUtils = new Utils\HTTP();
$returnTo = $request->query->get('ReturnTo', false);
if ($returnTo !== false) {
$returnTo = $httpUtils->checkURLAllowed($returnTo);
}
if (empty($returnTo)) {
return $this->config->getBasePath();
}
return $returnTo;
}
/**
* This clears the user's IdP discovery choices.
*
* @param Request $request The request that lead to this login operation.
*/
public function cleardiscochoices(Request $request): void
{
$httpUtils = new Utils\HTTP();
// The base path for cookies. This should be the installation directory for SimpleSAMLphp.
$cookiePath = $this->config->getBasePath();
// We delete all cookies which starts with 'idpdisco_'
foreach ($request->cookies->all() as $cookieName => $value) {
if (substr($cookieName, 0, 9) !== 'idpdisco_') {
// Not a idpdisco cookie.
continue;
}
$httpUtils->setCookie($cookieName, null, ['path' => $cookiePath, 'httponly' => false], false);
}
$returnTo = $this->getReturnPath($request);
// Redirect to destination.
$httpUtils->redirectTrustedURL($returnTo);
}
}

View File

@@ -0,0 +1,404 @@
<?php
declare(strict_types=1);
namespace SimpleSAML\Module\core\Controller;
use Exception as BuiltinException;
use SAML2\Binding;
use SAML2\Constants;
use SimpleSAML\{Auth, Configuration, Error, IdP, Logger, Stats, Utils};
use SimpleSAML\HTTP\RunnableResponse;
use SimpleSAML\Metadata\MetaDataStorageHandler;
use SimpleSAML\Module\saml\Message;
use SimpleSAML\XHTML\Template;
use Symfony\Component\HttpFoundation\Request;
use function call_user_func;
use function in_array;
use function method_exists;
use function sha1;
use function substr;
use function time;
use function urldecode;
use function var_export;
/**
* Controller class for the core module.
*
* This class serves the different views available in the module.
*
* @package simplesamlphp/simplesamlphp
*/
class Logout
{
/**
* @var \SimpleSAML\Auth\State|string
* @psalm-var \SimpleSAML\Auth\State|class-string
*/
protected $authState = Auth\State::class;
/**
* Controller constructor.
*
* It initializes the global configuration for the controllers implemented here.
*
* @param \SimpleSAML\Configuration $config The configuration to use by the controllers.
*/
public function __construct(
protected Configuration $config,
) {
}
/**
* Inject the \SimpleSAML\Auth\State dependency.
*
* @param \SimpleSAML\Auth\State $authState
*/
public function setAuthState(Auth\State $authState): void
{
$this->authState = $authState;
}
/**
* Log the user out of a given authentication source.
*
* @param Request $request The request that lead to this logout operation.
* @param string $as The name of the auth source.
*
* @return \SimpleSAML\HTTP\RunnableResponse A runnable response which will actually perform logout.
*
* @throws \SimpleSAML\Error\CriticalConfigurationError
*/
public function logout(Request $request, string $as): RunnableResponse
{
$auth = new Auth\Simple($as);
$returnTo = $this->getReturnPath($request);
return new RunnableResponse(
[$auth, 'logout'],
[$returnTo],
);
}
/**
* Searches for a valid and allowed ReturnTo URL parameter,
* otherwise give the base installation page as a return point.
*/
private function getReturnPath(Request $request): string
{
$httpUtils = new Utils\HTTP();
$returnTo = $request->query->get('ReturnTo', false);
if ($returnTo !== false) {
$returnTo = $httpUtils->checkURLAllowed($returnTo);
}
if (empty($returnTo)) {
return $this->config->getBasePath();
}
return $returnTo;
}
/**
* @param Request $request The request that lead to this logout operation.
* @return \SimpleSAML\HTTP\RunnableResponse
*/
public function logoutIframeDone(Request $request): RunnableResponse
{
if (!$request->query->has('id')) {
throw new Error\BadRequest('Missing required parameter: id');
}
$id = $request->query->get('id');
$state = $this->authState::loadState($id, 'core:Logout-IFrame');
$idp = IdP::getByState($state);
$associations = $idp->getAssociations();
if (!$request->query->has('cancel')) {
Logger::stats('slo-iframe done');
Stats::log('core:idp:logout-iframe:page', ['type' => 'done']);
$SPs = $state['core:Logout-IFrame:Associations'];
} else {
// user skipped global logout
Logger::stats('slo-iframe skip');
Stats::log('core:idp:logout-iframe:page', ['type' => 'skip']);
$SPs = []; // no SPs should have been logged out
$state['core:Failed'] = true; // mark as partial logout
}
// find the status of all SPs
foreach ($SPs as $assocId => &$sp) {
$spId = 'logout-iframe-' . sha1($assocId);
if ($request->query->has($spId)) {
$spStatus = $request->query->get($spId);
if ($spStatus === 'completed' || $spStatus === 'failed') {
$sp['core:Logout-IFrame:State'] = $spStatus;
}
}
if (!isset($associations[$assocId])) {
$sp['core:Logout-IFrame:State'] = 'completed';
}
}
// terminate the associations
foreach ($SPs as $assocId => $sp) {
if ($sp['core:Logout-IFrame:State'] === 'completed') {
$idp->terminateAssociation($assocId);
} else {
Logger::warning('Unable to terminate association with ' . var_export($assocId, true) . '.');
if (isset($sp['saml:entityID'])) {
$spId = $sp['saml:entityID'];
} else {
$spId = $assocId;
}
Logger::stats('slo-iframe-fail ' . $spId);
Stats::log('core:idp:logout-iframe:spfail', ['sp' => $spId]);
$state['core:Failed'] = true;
}
}
// we are done
return new RunnableResponse([$idp, 'finishLogout'], [$state]);
}
/**
* @param Request $request The request that lead to this logout operation.
* @return \SimpleSAML\HTTP\RunnableResponse
*/
public function logoutIframePost(Request $request): RunnableResponse
{
if (!$request->query->has('idp')) {
throw new Error\BadRequest('Missing required parameter: idp');
}
$idp = IdP::getById($request->query->get('idp'));
if (!$request->query->has('association')) {
throw new Error\BadRequest('Missing required parameter: association');
}
$assocId = urldecode($request->query->get('association'));
$relayState = null;
if ($request->query->has('RelayState')) {
$relayState = $request->query->get('RelayState');
}
$associations = $idp->getAssociations();
if (!isset($associations[$assocId])) {
throw new Error\BadRequest('Invalid association id.');
}
$association = $associations[$assocId];
$metadata = MetaDataStorageHandler::getMetadataHandler();
$idpMetadata = $idp->getConfig();
$spMetadata = $metadata->getMetaDataConfig($association['saml:entityID'], 'saml20-sp-remote');
$lr = Message::buildLogoutRequest($idpMetadata, $spMetadata);
$lr->setSessionIndex($association['saml:SessionIndex']);
$lr->setNameId($association['saml:NameID']);
$assertionLifetime = $spMetadata->getOptionalInteger('assertion.lifetime', null);
if ($assertionLifetime === null) {
$assertionLifetime = $idpMetadata->getOptionalInteger('assertion.lifetime', 300);
}
$lr->setNotOnOrAfter(time() + $assertionLifetime);
$encryptNameId = $spMetadata->getOptionalBoolean('nameid.encryption', null);
if ($encryptNameId === null) {
$encryptNameId = $idpMetadata->getOptionalBoolean('nameid.encryption', false);
}
if ($encryptNameId) {
$lr->encryptNameId(Message::getEncryptionKey($spMetadata));
}
Stats::log('saml:idp:LogoutRequest:sent', [
'spEntityID' => $association['saml:entityID'],
'idpEntityID' => $idpMetadata->getString('entityid'),
]);
$bindings = [Constants::BINDING_HTTP_POST];
$dst = $spMetadata->getDefaultEndpoint('SingleLogoutService', $bindings);
$binding = Binding::getBinding($dst['Binding']);
$lr->setDestination($dst['Location']);
$lr->setRelayState($relayState);
return new RunnableResponse([$binding, 'send'], [$lr]);
}
/**
* @param Request $request The request that lead to this logout operation.
* @return \SimpleSAML\XHTML\Template
*/
public function logoutIframe(Request $request): Template
{
if (!$request->query->has('id')) {
throw new Error\BadRequest('Missing required parameter: id');
}
$id = $request->query->get('id');
$type = 'init';
if ($request->query->has('type')) {
$type = $request->query->get('type');
if (!in_array($type, ['init', 'js', 'nojs', 'embed'], true)) {
throw new Error\BadRequest('Invalid value for type.');
}
}
if ($type !== 'embed') {
Logger::stats('slo-iframe ' . $type);
Stats::log('core:idp:logout-iframe:page', ['type' => $type]);
}
$state = $this->authState::loadState($id, 'core:Logout-IFrame');
$idp = IdP::getByState($state);
$mdh = MetaDataStorageHandler::getMetadataHandler();
if ($type !== 'init') {
// update association state
foreach ($state['core:Logout-IFrame:Associations'] as $assocId => &$sp) {
$spId = sha1($assocId);
// move SPs from 'onhold' to 'inprogress'
if ($sp['core:Logout-IFrame:State'] === 'onhold') {
$sp['core:Logout-IFrame:State'] = 'inprogress';
}
// check for update through request
if ($request->query->has($spId)) {
$s = $request->query->get($spId);
if ($s == 'completed' || $s == 'failed') {
$sp['core:Logout-IFrame:State'] = $s;
}
}
// check for timeout
if (isset($sp['core:Logout-IFrame:Timeout']) && $sp['core:Logout-IFrame:Timeout'] < time()) {
if ($sp['core:Logout-IFrame:State'] === 'inprogress') {
$sp['core:Logout-IFrame:State'] = 'failed';
}
}
// update the IdP
if ($sp['core:Logout-IFrame:State'] === 'completed') {
$idp->terminateAssociation($assocId);
}
if (!isset($sp['core:Logout-IFrame:Timeout'])) {
if (method_exists($sp['Handler'], 'getAssociationConfig')) {
$assocIdP = IdP::getByState($sp);
$assocConfig = call_user_func([$sp['Handler'], 'getAssociationConfig'], $assocIdP, $sp);
$timeout = $assocConfig->getOptionalInteger('core:logout-timeout', 5);
$sp['core:Logout-IFrame:Timeout'] = $timeout + time();
} else {
$sp['core:Logout-IFrame:Timeout'] = time() + 5;
}
}
}
}
$associations = $idp->getAssociations();
foreach ($state['core:Logout-IFrame:Associations'] as $assocId => &$sp) {
// in case we are refreshing a page
if (!isset($associations[$assocId])) {
$sp['core:Logout-IFrame:State'] = 'completed';
}
try {
$assocIdP = IdP::getByState($sp);
$url = call_user_func([$sp['Handler'], 'getLogoutURL'], $assocIdP, $sp, null);
$sp['core:Logout-IFrame:URL'] = $url;
} catch (BuiltinException $e) {
$sp['core:Logout-IFrame:State'] = 'failed';
}
}
// get the metadata of the service that initiated logout, if any
$terminated = null;
if ($state['core:TerminatedAssocId'] !== null) {
$mdset = 'saml20-sp-remote';
if (substr($state['core:TerminatedAssocId'], 0, 4) === 'adfs') {
$mdset = 'adfs-sp-remote';
}
$terminated = $mdh->getMetaDataConfig($state['saml:SPEntityId'], $mdset)->toArray();
}
// build an array with information about all services currently logged in
$remaining = [];
foreach ($state['core:Logout-IFrame:Associations'] as $association) {
$key = sha1($association['id']);
$mdset = 'saml20-sp-remote';
if (substr($association['id'], 0, 4) === 'adfs') {
$mdset = 'adfs-sp-remote';
}
if ($association['core:Logout-IFrame:State'] === 'completed') {
continue;
}
$remaining[$key] = [
'id' => $association['id'],
'expires_on' => $association['Expires'],
'entityID' => $association['saml:entityID'],
'subject' => $association['saml:NameID'],
'status' => $association['core:Logout-IFrame:State'],
'metadata' => $mdh->getMetaDataConfig($association['saml:entityID'], $mdset)->toArray(),
];
if (isset($association['core:Logout-IFrame:URL'])) {
$remaining[$key]['logoutURL'] = $association['core:Logout-IFrame:URL'];
}
if (isset($association['core:Logout-IFrame:Timeout'])) {
$remaining[$key]['timeout'] = $association['core:Logout-IFrame:Timeout'];
}
}
if ($type === 'nojs') {
$t = new Template($this->config, 'core:logout-iframe-wrapper.twig');
} else {
$t = new Template($this->config, 'core:logout-iframe.twig');
}
$t->data['auth_state'] = Auth\State::saveState($state, 'core:Logout-IFrame');
$t->data['type'] = $type;
$t->data['terminated_service'] = $terminated;
$t->data['remaining_services'] = $remaining;
return $t;
}
/**
* @param Request $request The request that lead to this logout operation.
* @return \SimpleSAML\HTTP\RunnableResponse
*/
public function resumeLogout(Request $request): RunnableResponse
{
if (!$request->query->has('id')) {
throw new Error\BadRequest('Missing required parameter: id');
}
$id = $request->query->get('id');
$state = $this->authState::loadState($id, 'core:Logout:afterbridge');
$idp = IdP::getByState($state);
$assocId = $state['core:TerminatedAssocId'];
return new RunnableResponse([$idp->getLogoutHandler(), 'startLogout'], [&$state, $assocId]);
}
}

View File

@@ -0,0 +1,105 @@
<?php
declare(strict_types=1);
namespace SimpleSAML\Module\core\Controller;
use SimpleSAML\Assert\Assert;
use SimpleSAML\Configuration;
use SimpleSAML\Error;
use SimpleSAML\Session;
use SimpleSAML\Utils;
use SimpleSAML\XHTML\Template;
use SimpleSAML\XMLSecurity\Alg\Encryption\AES;
use SimpleSAML\XMLSecurity\Constants as C;
use SimpleSAML\XMLSecurity\Key\SymmetricKey;
use Symfony\Component\HttpFoundation\{Request, Response};
/**
* Controller class for the core module.
*
* This class serves the different views available in the module.
*
* @package SimpleSAML\Module\core
*/
class Redirection
{
/**
* Controller constructor.
*
* It initializes the global configuration and auth source configuration for the controllers implemented here.
*
* @param \SimpleSAML\Configuration $config The configuration to use by the controllers.
* @param \SimpleSAML\Session $session The session to use by the controllers.
*
* @throws \Exception
*/
public function __construct(
protected Configuration $config,
protected Session $session,
) {
}
/**
* This controller provides a way to create a redirect to a POST request
*
* @param Request $request The request that lead to this login operation.
* @throws \SimpleSAML\Error\BadRequest
* @return \SimpleSAML\XHTML\Template|\Symfony\Component\HttpFoundation\RedirectResponse
* An HTML template or a redirection if we are not authenticated.
*/
public function postredirect(Request $request): Response
{
$redirId = $request->query->get('RedirId', false);
$redirInfo = $request->query->get('RedirInfo', false);
if ($redirId !== false) {
$postId = $redirId;
} elseif ($redirInfo !== false) {
$encData = base64_decode($redirInfo, true);
if (empty($encData)) {
throw new Error\BadRequest('Invalid RedirInfo data.');
}
$key = new SymmetricKey((new Utils\Config())->getSecretSalt());
$decryptor = new AES($key, C::BLOCK_ENC_AES256_GCM);
list($sessionId, $postId) = explode(':', $decryptor->decrypt($encData));
if (empty($sessionId) || empty($postId)) {
throw new Error\BadRequest('Invalid session info data.');
}
} else {
throw new Error\BadRequest('Missing redirection info parameter.');
}
$session = $this->session;
if ($session === null) {
throw new \Exception('Unable to load session.');
}
$postData = $session->getData('core_postdatalink', $postId);
if ($postData === null) {
// The post data is missing, probably because it timed out
throw new \Exception('The POST data we should restore was lost.');
}
$session->deleteData('core_postdatalink', $postId);
Assert::isArray($postData);
Assert::keyExists($postData, 'url');
Assert::keyExists($postData, 'post');
$httpUtils = new Utils\HTTP();
if (!$httpUtils->isValidURL($postData['url'])) {
throw new Error\Exception('Invalid destination URL.');
}
$t = new Template($this->config, 'post.twig');
$t->data['destination'] = $postData['url'];
$t->data['post'] = $postData['post'];
return $t;
}
}

View File

@@ -0,0 +1,106 @@
<?php
declare(strict_types=1);
namespace SimpleSAML\Module\core\Stats\Output;
use Exception;
use SimpleSAML\Assert\Assert;
use SimpleSAML\Configuration;
use SimpleSAML\Error;
/**
* Statistics logger that writes to a set of log files
*
* @package SimpleSAMLphp
*/
class File extends \SimpleSAML\Stats\Output
{
/**
* The log directory.
* @var string
*/
private string $logDir;
/**
* The file handle for the current file.
* @var resource|null
*/
private $file = null;
/**
* The current file date.
* @var string|null
*/
private ?string $fileDate = null;
/**
* Initialize the output.
*
* @param \SimpleSAML\Configuration $config The configuration for this output.
*/
public function __construct(Configuration $config)
{
$logDir = $config->getPathValue('directory');
if ($logDir === null) {
throw new Exception('Missing "directory" option for core:File');
}
if (!is_dir($logDir)) {
throw new Exception('Could not find log directory: ' . var_export($logDir, true));
}
$this->logDir = $logDir;
}
/**
* Open a log file.
*
* @param string $date The date for the log file.
*/
private function openLog(string $date): void
{
if ($this->file !== null && $this->file !== false) {
fclose($this->file);
$this->file = null;
}
$fileName = $this->logDir . '/' . $date . '.log';
$fh = @fopen($fileName, 'a');
if ($fh === false) {
throw new Error\Exception('Error opening log file: ' . var_export($fileName, true));
}
// Disable output buffering
stream_set_write_buffer($fh, 0);
$this->file = $fh;
$this->fileDate = $date;
}
/**
* Write a stats event.
*
* @param array $data The event.
*/
public function emit(array $data): void
{
Assert::notNull($data['time']);
$time = $data['time'];
$milliseconds = intval((($time - intval($time)) * 1000));
$timestamp = gmdate('Y-m-d\TH:i:s', intval($time)) . sprintf('.%03dZ', $milliseconds);
$outDate = substr($timestamp, 0, 10); // The date-part of the timstamp
if ($outDate !== $this->fileDate) {
$this->openLog($outDate);
}
$line = $timestamp . ' ' . json_encode($data) . "\n";
/** @psalm-suppress PossiblyNullArgument */
fwrite($this->file, $line);
}
}

View File

@@ -0,0 +1,50 @@
<?php
declare(strict_types=1);
namespace SimpleSAML\Module\core\Stats\Output;
use SimpleSAML\Configuration;
use SimpleSAML\Logger;
/**
* Statistics logger that writes to the default logging handler.
*
* @package SimpleSAMLphp
*/
class Log extends \SimpleSAML\Stats\Output
{
/**
* The logging function we should call.
* @var callable
*/
private $logger;
/**
* Initialize the output.
*
* @param \SimpleSAML\Configuration $config The configuration for this output.
* @throws \Exception
*/
public function __construct(Configuration $config)
{
$logLevel = $config->getOptionalString('level', 'notice');
$this->logger = [Logger::class, $logLevel];
if (!is_callable($this->logger)) {
throw new \Exception('Invalid log level: ' . var_export($logLevel, true));
}
}
/**
* Write a stats event.
*
* @param array $data The event
*/
public function emit(array $data): void
{
$str_data = json_encode($data);
call_user_func($this->logger, 'EVENT ' . $str_data);
}
}

View File

@@ -0,0 +1,318 @@
<?php
declare(strict_types=1);
namespace SimpleSAML\Module\core\Storage;
use PDO;
use SimpleSAML\Assert\Assert;
use SimpleSAML\Configuration;
use SimpleSAML\Error\CriticalConfigurationError;
/**
* SQLPermanentStorage
*
* Generic SQL Store to store key value pairs. To be used in several other modules that needs
* to store data permanently.
*
* @package SimpleSAMLphp
*/
class SQLPermanentStorage
{
/** @var \PDO */
private PDO $db;
/**
* @param string $name
* @param \SimpleSAML\Configuration|null $config
* @throws \Exception
*/
public function __construct(string $name, Configuration $config = null)
{
if (is_null($config)) {
$config = Configuration::getInstance();
}
$datadir = $config->getPathValue('datadir', null);
Assert::notNull($datadir, "Missing 'datadir' in configuration.", CriticalConfigurationError::class);
if (!is_dir($datadir)) {
throw new \Exception('Data directory [' . $datadir . '] does not exist');
} elseif (!is_writable($datadir)) {
throw new \Exception('Data directory [' . $datadir . '] is not writable');
}
$sqllitedir = $datadir . 'sqllite/';
if (!is_dir($sqllitedir)) {
mkdir($sqllitedir);
}
$dbfile = 'sqlite:' . $sqllitedir . $name . '.sqlite';
$this->db = new PDO($dbfile);
if ($this->db) {
$this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
$q = @$this->db->query('SELECT key1 FROM data LIMIT 1');
if ($q === false) {
$this->db->exec('
CREATE TABLE data (
key1 text,
key2 text,
type text,
value text,
created timestamp,
updated timestamp,
expire timestamp,
PRIMARY KEY (key1,key2,type)
);
');
}
} else {
throw new \Exception('Error creating SQL lite database [' . $dbfile . '].');
}
}
/**
* @param string $type
* @param string $key1
* @param string $key2
* @param string $value
* @param int|null $duration
*/
public function set(string $type, string $key1, string $key2, string $value, int $duration = null): void
{
if ($this->exists($type, $key1, $key2)) {
$this->update($type, $key1, $key2, $value, $duration);
} else {
$this->insert($type, $key1, $key2, $value, $duration);
}
}
/**
* @param string $type
* @param string $key1
* @param string $key2
* @param string $value
* @param int|null $duration
* @return array
*/
private function insert(string $type, string $key1, string $key2, string $value, int $duration = null): array
{
$expire = is_null($duration) ? null : (time() + $duration);
$query = "INSERT INTO data (key1, key2, type, created, updated, expire, value)" .
" VALUES(:key1, :key2, :type, :created, :updated, :expire, :value)";
$prepared = $this->db->prepare($query);
$data = [':key1' => $key1, ':key2' => $key2,
':type' => $type, ':created' => time(),
':updated' => time(), ':expire' => $expire,
':value' => serialize($value),
];
$prepared->execute($data);
$results = $prepared->fetchAll(PDO::FETCH_ASSOC);
return $results;
}
/**
* @param string $type
* @param string $key1
* @param string $key2
* @param string $value
* @param int|null $duration
* @return array
*/
private function update(string $type, string $key1, string $key2, string $value, int $duration = null): array
{
$expire = is_null($duration) ? null : (time() + $duration);
$query = "UPDATE data SET updated = :updated, value = :value, " .
"expire = :expire WHERE key1 = :key1 AND key2 = :key2 AND type = :type";
$prepared = $this->db->prepare($query);
$data = [':key1' => $key1, ':key2' => $key2,
':type' => $type, ':updated' => time(),
':expire' => $expire, ':value' => serialize($value),
];
$prepared->execute($data);
$results = $prepared->fetchAll(PDO::FETCH_ASSOC);
return $results;
}
/**
* @param string|null $type
* @param string|null $key1
* @param string|null $key2
* @return array|null
*/
public function get(string $type = null, string $key1 = null, string $key2 = null): ?array
{
$conditions = $this->getCondition($type, $key1, $key2);
$query = 'SELECT * FROM data WHERE ' . $conditions;
$prepared = $this->db->prepare($query);
$prepared->execute();
$results = $prepared->fetchAll(PDO::FETCH_ASSOC);
if (count($results) !== 1) {
return null;
}
$res = $results[0];
$res['value'] = unserialize($res['value']);
return $res;
}
/**
* Return the value directly (not in a container)
*
* @param string|null $type
* @param string|null $key1
* @param string|null $key2
* @return string|null
*/
public function getValue(string $type = null, string $key1 = null, string $key2 = null): ?string
{
$res = $this->get($type, $key1, $key2);
if ($res === null) {
return null;
}
return $res['value'];
}
/**
* @param string $type
* @param string $key1
* @param string $key2
* @return bool
*/
public function exists(string $type, string $key1, string $key2): bool
{
$query = 'SELECT * FROM data WHERE type = :type AND key1 = :key1 AND key2 = :key2 LIMIT 1';
$prepared = $this->db->prepare($query);
$data = [':type' => $type, ':key1' => $key1, ':key2' => $key2];
$prepared->execute($data);
$results = $prepared->fetchAll(PDO::FETCH_ASSOC);
return (count($results) == 1);
}
/**
* @param string|null $type
* @param string|null $key1
* @param string|null $key2
* @return array|false
*/
public function getList(string $type = null, string $key1 = null, string $key2 = null)
{
$conditions = $this->getCondition($type, $key1, $key2);
$query = 'SELECT * FROM data WHERE ' . $conditions;
$prepared = $this->db->prepare($query);
$prepared->execute();
$results = $prepared->fetchAll(PDO::FETCH_ASSOC);
if ($results === false) {
return false;
}
foreach ($results as $key => $value) {
$results[$key]['value'] = unserialize($results[$key]['value']);
}
return $results;
}
/**
* @param string|null $type
* @param string|null $key1
* @param string|null $key2
* @param string $whichKey
* @throws \Exception
* @return array|null
*/
public function getKeys(
string $type = null,
string $key1 = null,
string $key2 = null,
string $whichKey = 'type',
): ?array {
if (!in_array($whichKey, ['key1', 'key2', 'type'], true)) {
throw new \Exception('Invalid key type');
}
$conditions = $this->getCondition($type, $key1, $key2);
$query = 'SELECT DISTINCT :whichKey FROM data WHERE ' . $conditions;
$prepared = $this->db->prepare($query);
$data = ['whichKey' => $whichKey];
$prepared->execute($data);
$results = $prepared->fetchAll(PDO::FETCH_ASSOC);
if (count($results) == 0) {
return null;
}
$resarray = [];
foreach ($results as $key => $value) {
$resarray[] = $value[$whichKey];
}
return $resarray;
}
/**
* @param string $type
* @param string $key1
* @param string $key2
* @return bool
*/
public function remove(string $type, string $key1, string $key2): bool
{
$query = 'DELETE FROM data WHERE type = :type AND key1 = :key1 AND key2 = :key2';
$prepared = $this->db->prepare($query);
$data = [':type' => $type, ':key1' => $key1, ':key2' => $key2];
$prepared->execute($data);
$results = $prepared->fetchAll(PDO::FETCH_ASSOC);
return (count($results) == 1);
}
/**
* @return int
*/
public function removeExpired(): int
{
$query = "DELETE FROM data WHERE expire IS NOT NULL AND expire < :expire";
$prepared = $this->db->prepare($query);
$data = [':expire' => time()];
$prepared->execute($data);
return $prepared->rowCount();
}
/**
* Create a SQL condition statement based on parameters
*
* @param string|null $type
* @param string|null $key1
* @param string|null $key2
* @return string
*/
private function getCondition(string $type = null, string $key1 = null, string $key2 = null): string
{
$conditions = [];
if (!is_null($type)) {
$conditions[] = "type = " . $this->db->quote($type);
}
if (!is_null($key1)) {
$conditions[] = "key1 = " . $this->db->quote($key1);
}
if (!is_null($key2)) {
$conditions[] = "key2 = " . $this->db->quote($key2);
}
$conditions[] = "(expire IS NULL OR expire >= " . time() . ")";
return join(' AND ', $conditions);
}
}

View File

@@ -0,0 +1,12 @@
{% extends "base.twig" %}
{% block contentwrapper %}
<div id="portalmenu" class="ui-tabs ui-widget ui-widget-content ui-corner-all">
<div id="portalcontent" class="ui-tabs-panel ui-widget-content ui-corner-bottom">
{{ block('content') }}
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,28 @@
{% set pagetitle = 'Incorrect Attributes' | trans %}
{% extends "base.twig" %}
{% block content %}
<h1>{{ pagetitle }}</h1>
<p>{{ 'One or more of the attributes supplied by your identity provider did not contain the expected number of values.'|trans }}</p>
<h3>{{ 'The problematic attribute(s) are:'|trans }}</h3>
<dl class="cardinalityErrorAttributes">
{% for attr,issues in cardinalityErrorAttributes %}
{% set got = issues[0] %}
{% set want = issues[1] %}
<dt>{{ attr }}</dt>
<dd>{% trans with {
'%got%': got,
'%want%': want
} %}got %got% values, want %want%{% endtrans %}</dd>
{% endfor %}
</dl>
{% if LogoutURL is defined %}
<p><a href="{{ LogoutURL }}">{{ 'Logout'|trans }}</a></p>
{% endif %}
{% endblock %}

View File

@@ -0,0 +1,33 @@
{% set pagetitle = 'An error has occurred'|trans %}
{% extends "base.twig" %}
{% block content %}
<h2>{{ pagetitle }}</h2>
{% if code is same as ('IDENTIFICATION_FAILURE') %}
<p>{{ 'The identification procesd has failed.' |trans }}</p>
{% elseif code is same as ('AUTHENTICATION_FAILURE') %}
<p>{{ 'The authentication procesd has failed.' |trans }}</p>
{% elseif code is same as ('AUTHORIZATION_FAILURE') %}
<p>{{ 'The authorization procesd has failed.' |trans }}</p>
{% else %}
<p>{{ 'There was an issue while signing you in.' |trans }}</p>
{% endif %}
{% if ts is defined or rp is defined or tid is defined or ctx is defined %}
<table id="table_with_attributes" class="attributes pure-table pure-table-striped pure-table-attributes" summary="attribute overview">
{% if ts is defined %}
<tr><td>Timestamp</td><td>{{ ts }}</td></tr>
{% endif %}
{% if rp is defined %}
<tr><td>Service Provider</td><td>{{ rp }}</td></tr>
{% endif %}
{% if tid is defined %}
<tr><td>Reference code</td><td>{{ tid }}</td></tr>
{% endif %}
{% if ctx is defined %}
<tr><td>Context</td><td>{{ ctx }}</td></tr>
{% endif %}
</table>
{% endif %}
{% endblock %}

View File

@@ -0,0 +1,8 @@
{% set pagetitle = 'Error report sent'|trans %}
{% extends "base.twig" %}
{% block content %}
<h2>{{ pagetitle }}</h2>
<p>{{ 'The error report has been sent to the administrators.' |trans }}</p>
{% endblock %}

View File

@@ -0,0 +1,126 @@
{% set pagetitle = 'Enter your username and password'|trans %}
{% extends "@core/base.twig" %}
{% block postload %}
<script src="{{ asset('js/loginuserpass.js', 'core') }}"></script>
{% endblock %}
{% block content %}
{%- if not isProduction %}
<div class="message-box warning">
{% trans %}You are now accessing a pre-production system. This authentication setup is for testing and pre-production verification only. If someone sent you a link that pointed you here, and you are not <i>a tester</i> you probably got the wrong link, and should <b>not be here</b>.{% endtrans %}
</div>
{% endif -%}
{% if errorcode -%}
<div class="pure-g">
<div class="pure-u-1">
<div class="message-box error">
{% set errtitles = errorcodes['title'] %}
{% set errtitle = errtitles[errorcode] %}
<h3>{{ errtitle|trans(errorparams) }}</h3>
{% set errdescs = errorcodes['descr'] %}
{% set errdesc = errdescs[errorcode] %}
<p>{{ errdesc|trans(errorparams) }}</p>
</div>
</div>
</div>
{%- endif %}
<h1>{{ 'Enter your username and password'|trans }}</h1>
<p>{{ 'A service has requested you to authenticate yourself. Please enter your username and password in the form below.'|trans }}</p>
<div class="center-form login-form-start">
<form id="f" class="pure-form pure-form-aligned" action="{{ formURL }}" method="post" name="f" spellcheck="false">
<div class="pure-control-group">
<label for="username">{{ 'Username'|trans }}</label>
<input id="username" {{ forceUsername ? 'disabled autocomplete="off"' }} placeholder="{{ username }}" type="text" name="username" class="edge"
{%- if not forceUsername %} tabindex="1" value="{{ username }}" autocomplete="username" {% endif %}
{%- if not forceUsername and not username %} autofocus {% endif %} >
{% if rememberUsernameEnabled and not forceUsername -%}
</div>
<div class="pure-controls">
<label for="remember_username" class="pure-checkbox">
<input id="remember_username" type="checkbox" tabindex="4"
{{ rememberUsernameChecked ? 'checked' }} name="remember_username" value="Yes">
<small>{{ 'Remember my username'|trans }}</small>
</label>
{%- endif %}
</div>
<div class="pure-control-group">
<label for="password">{{ 'Password'|trans}}</label>
<input id="password" type="password" tabindex="2" name="password" class="edge" autocomplete="current-password"
{%- if forceUsername or username %} autofocus {% endif %} >
</div>
{% if rememberMeEnabled -%}
<div class="pure-controls">
<label for="remember_me" class="pure-checkbox">
<input id="remember_me" type="checkbox" tabindex="5"
{{ rememberMeChecked ? 'checked="checked"' }} name="remember_me" value="Yes">
<small>{{ 'Remember me'|trans }}</small>
</label>
</div>
{%- endif %}
{% if organizations is defined -%}
<div class="pure-control-group">
<label for="organization">{{ 'Organization'|trans }}</label>
<div class="pure-select right pure-input-1-2 pure-input-sm-1-1">
<select name="organization" id="organization" tabindex="3">
{{ selectedOrg ?: null }}
{%- for id, orgDesc in organizations -%}
{% if id == selectedOrg -%}
{%- set selected = 'selected="selected"' %}
{%- else -%}
{% set selected = '' -%}
{% endif -%}
{% if orgDesc -%}
<option value="{{ id }}" {{ selected }}>{{ orgDesc|trans }}</option>
{% endif -%}
{% endfor %}
</select>
</div>
{% if rememberOrganizationEnabled is defined -%}
<div class="pure-controls">
<label for="remember_organization" class="pure-checkbox">
<input type="checkbox" id="remember_organization" tabindex="5" name="remember_organization"
value="Yes" {{ rememberOrganizationChecked ? 'checked="checked"' }} >
<small>{{ 'Remember my organization'|trans }}</small>
</label>
</div>
{%- endif %}
</div> <!--pure-control-group-->
{%- endif %}
<div class="pure-control-group center login-form-submit">
<button class="pure-button pure-button-red pure-input-1-2 pure-input-sm-1-1 right" id="submit_button"
type="submit" tabindex="6" data-default="{% trans %}Login{% endtrans %}"
data-processing="{% trans %}Processing...{% endtrans %}">
{% trans %}Login{% endtrans %}
</button>
</div>
</form>
</div>
{% if loginpage_links is defined -%}
<ul>
{% for link in loginpage_links -%}
<li><a href="{{ link.href }}">{{ link['text']|trans }}</a></li>
{% endfor %}
</ul>
{%- endif %}
<br><br>
<div class="pure-form-message">
<strong>{{ 'Help! I don\'t remember my password.'|trans }}</strong>
<p>{{ 'Without your username and password you cannot authenticate yourself for access to the service. There may be someone that can help you. Consult the help desk at your organization!'|trans }}</p>
</div>
{% endblock %}

View File

@@ -0,0 +1,2 @@
{% set pagetitle = 'Logging out...'|trans %}
{% extends "@core/logout-iframe.twig" %}

View File

@@ -0,0 +1,126 @@
{% set pagetitle = 'Logging out...'|trans %}
{% extends "base.twig" %}
{% block preload %}
<link rel="preload" href="{{ asset('js/logout.js') }}" as="script">
{%- if type != "init" %}
{%- set content = '2' %}
{%- if remaining_services|length == 0 %}
{%- set content = '0; url=' ~ moduleURL('core/logout-iframe-done', {'id': auth_state }) %}
{%- endif %}
<meta http-equiv="refresh" content="{{ content }}">
{% endif %}
{% endblock preload %}
{% block content %}
<h1>{{ pagetitle }}</h1>
{%- if terminated_service %}
{%- set SP = terminated_service|entityDisplayName %}
<p>{% trans with {
'%SP%': SP
} %}You are now successfully logged out from %SP%.{% endtrans %}</p>
{%- endif %}
{%- if remaining_services %}
{%- set failed = false %}
{%- set remaining = 0 %}
{%- if remaining_services|length > 0 %}
<p>{% trans %}You are also logged in on these services:{% endtrans %}</p>
{%- endif %}
<div class="custom-restricted-width">
<ul class="fa-ul">
{%- for key, sp in remaining_services %}
{%- set timeout = 5 %}
{%- set name = sp['metadata']|entityDisplayName %}
{%- set icon = 'circle-o-notch' %}
{%- if sp['status'] == 'completed' %}
{%- set icon = 'check-circle' %}
{%- elseif sp['status'] == 'failed' %}
{%- set icon = 'exclamation-circle' %}
{%- set failed = true %}
{%- elseif (sp['status'] == 'onhold' or sp['status'] == 'inprogress') %}
{%- set remaining = remaining + 1 %}
{%- endif %}
{%- if type == 'nojs' and sp['status'] == 'inprogress' %}
{%- set icon = icon ~ ' fa-spin' %}
{%- endif %}
<li id="sp-{{ key }}" data-id="{{ key }}" data-status="{{ sp['status'] }}"
{#- #} data-timeout="{{ timeout }}">
<span class="fa-li"><i id="icon-{{ key }}" class="fa fa-{{ icon }}"></i></span>
{{ name }}
{%- if sp['status'] != 'completed' and sp['status'] != 'failed' %}
{%- if type == 'nojs' %}
<iframe id="iframe-{{ key }}" class="hidden" src="{{ sp['logoutURL'] }}"></iframe>
{%- else %}
<iframe id="iframe-{{ key }}" class="hidden" data-url="{{ sp['logoutURL'] }}"></iframe>
{%- endif %}
{%- else %}
{%- if sp['status'] == 'failed' %}
({% trans %}logout is not supported{% endtrans %})
{%- endif %}
{%- endif %}
</li>
{%- endfor %}
</ul>
</div>
<br>
<div id="error-message"{% if not failed or type == 'init' %} class="hidden"{% endif %}>
<div class="message-box error">
{% trans %}Unable to log out of one or more services. To ensure that all your sessions are closed, you are encouraged to <i>close your webbrowser</i>.{% endtrans %}
</div>
</div>
<form id="error-form" action="{{ moduleURL('core/logout-iframe-done') }}"
{%- if (not failed or type == 'init') and remaining %} class="hidden"{% endif %}>
<input type="hidden" name="id" value="{{ auth_state }}">
<button type="submit" id="btn-continue" name="ok" class="pure-button pure-button-red">
{%- trans %}Continue{% endtrans -%}
</button>
</form>
<div id="original-actions"{% if type != 'init' %} class="hidden"{% endif %}>
<p>{% trans %}Do you want to logout from all the services above?{% endtrans %}</p>
<div class="pure-button-group two-elements">
<form id="startform" action="{{ moduleURL('core/logout-iframe') }}">
<input type="hidden" name="id" value="{{ auth_state }}">
<noscript>
<input type="hidden" name="type" value="nojs" id="logout-type-selector">
</noscript>
<button type="submit" id="btn-all" name="ok" class="pure-button pure-button-red">
{%- trans %}Yes, all services{% endtrans -%}
</button>
</form>
<form action="{{ moduleURL('core/logout-iframe-done') }}">
<input type="hidden" name="id" value="{{ auth_state }}">
<input type="hidden" name="cancel" value="">
<button id="btn-cancel" class="pure-button" type="submit">
{%- if terminated_service %}{% trans with {
'%SP%': SP
} %}No, only %SP%{% endtrans %}
{%- else %}{% trans %}No{% endtrans %}{% endif -%}
</button>
</form>
</div>
</div>
{%- else %}
<form id="error-form" action="{{ moduleURL('core/logout-iframe-done') }}">
<input type="hidden" name="id" value="{{ auth_state }}">
<button type="submit" id="btn-continue" name="ok" class="pure-button pure-button-red">
{%- trans %}Continue{% endtrans -%}
</button>
</form>
{% endif %}
{% endblock %}
{% block postload %}
<script src="{{ asset('js/logout.js') }}"></script>
{% endblock postload %}

View File

@@ -0,0 +1,6 @@
<p>{{ 'This is most likely a configuration problem on either the service provider or identity provider.'|trans }}</p>
<ul>
<li>{{ 'If you are a user who received this error after following a link on a site, you should report this error to the owner of that site.'|trans }}</li>
<li>{{ 'If you are a developer who is deploying a single sign-on solution, you have are trying to reach an endpoint using the wrong HTTP-method.'|trans }}</li>
</ul>

View File

@@ -0,0 +1,10 @@
{% set pagetitle = 'Missing cookie'|trans %}
{% extends "base.twig" %}
{% block content %}
<h2>{{ 'Missing cookie'|trans }}</h2>
<p>{{ 'You appear to have disabled cookies in your browser. Please check the settings in your browser, and try again.'|trans }}</p>
{% if retryURL is not null %}
<p><a href="{{ retryURL|escape('html') }}" class="pure-button pure-button-red" id="retry">{{ 'Retry'|trans }}</a></p>
{% endif %}
{% endblock %}

View File

@@ -0,0 +1,7 @@
<p>{{ 'This is most likely a configuration problem on either the service provider or identity provider.'|trans }}</p>
<ul>
<li>{{ 'If you are a user who received this error after following a link on a site, you should report this error to the owner of that site.'|trans }}</li>
<li>{{ 'If you are a developer who is deploying a single sign-on solution, you have a problem with the metadata configuration. Verify that metadata is configured correctly on both the identity provider and service provider.'|trans }}</li>
</ul>

View File

@@ -0,0 +1,14 @@
<h3>{{ 'Suggestions for resolving this problem:'|trans }}</h3>
<ul>
<li>{{ 'Check that the link you used to access the web site is correct.'|trans }}</li>
<li>{{ 'Go back to the previous page and try again.'|trans }}</li>
<li>{{ 'Close the web browser, and try again.'|trans }}</li>
</ul>
<h3>{{ 'This error may be caused by:'|trans }}</h3>
<ul>
<li>{{ 'The link used to get here was bad, perhaps a bookmark.'|trans }}</li>
<li>{{ 'Using the back and forward buttons in the web browser.'|trans }}</li>
<li>{{ 'Opened the web browser with tabs saved from the previous session.'|trans }}</li>
<li>{{ 'Cookies may be disabled in the web browser.'|trans }}</li>
</ul>

View File

@@ -0,0 +1,16 @@
{% set pagetitle = 'SimpleSAMLphp'|trans %}
{% extends "base.twig" %}
{% block content %}
<h1>{{ 'Too short interval between single sign on events.'|trans }}</h1>
<form style="display: inline; margin: 0px; padding: 0px" action="{{ moduleURL('core/short_sso_interval') }}">
{% for name, value in params %}
<input type="hidden" name="{{ name|escape('html') }}" value="{{ value|escape('html') }}">
{% endfor %}
<p>{{ 'We have detected that there is only a few seconds since you last authenticated with this service provider, and therefore assume that there is a problem with this SP.'|trans }}</p>
<div class="trackidtext">
<p>{{ 'If you report this error, please also report this tracking number which makes it possible to locate your session in the logs available to the system administrator:'|trans }}<span class="trackid">{{ trackId }}</span></p>
</div>
<input type="submit" name="continue" id="contbutton" value="{{ 'Retry login'|trans|escape('html') }}" autofocus>
</form>
{% endblock %}

View File

@@ -0,0 +1,12 @@
{% set pagetitle = 'Welcome'|trans %}
{% extends "@core/base.twig" %}
{% block content %}
<h1>{{ 'Welcome'|trans }}</h1>
<p>{{ 'This is the front page of the SimpleSAMLphp authentication software. There\'s not much to see here.'|trans }}</p>
<p>{% trans %}If you are the administrator of this installation, please refer to the <a href="https://simplesamlphp.org/docs/">SimpleSAMLphp documentation</a> for how to configure and interact with the software.{% endtrans %}</p>
{% endblock %}