Skip to content
Merged
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## [Unreleased]

* [PR-20](https://github.com/itk-dev/os2forms_nemlogin_openid_connect/pull/20)
Added support for Key
Added support for Key.

## [2.2.1]

Expand Down
33 changes: 20 additions & 13 deletions src/Controller/OpenIDConnectController.php
Original file line number Diff line number Diff line change
Expand Up @@ -147,20 +147,27 @@ public function main(string $id) {
private function getOpenIdConfigurationProvider(): OpenIdConfigurationProvider {
$pluginConfiguration = $this->plugin->getConfiguration();

try {
$keyId = $pluginConfiguration[OpenIDConnect::KEY] ?? '';
$key = $this->keyRepository->getKey($keyId);
if (NULL === $key) {
throw new \RuntimeException(sprintf('Cannot get key %s', $keyId));
}
[
OidcKeyType::DISCOVERY_URL => $discoveryUrl,
OidcKeyType::CLIENT_ID => $clientId,
OidcKeyType::CLIENT_SECRET => $clientSecret,
] = $this->keyHelper->getOidcValues($key);
if (OpenIDConnect::PROVIDER_TYPE_KEY === $pluginConfiguration[OpenIDConnect::PROVIDER_TYPE_KEY]) {
$discoveryUrl = $pluginConfiguration[OpenIDConnect::DISCOVERY_URL];
$clientId = $pluginConfiguration[OpenIDConnect::CLIENT_ID];
$clientSecret = $pluginConfiguration[OpenIDConnect::CLIENT_SECRET];
}
catch (\Exception $e) {
throw new AuthenticationException('Cannot get client id and secret', $e->getCode(), $e);
else {
try {
$keyId = $pluginConfiguration[OpenIDConnect::KEY] ?? '';
$key = $this->keyRepository->getKey($keyId);
if (NULL === $key) {
throw new \RuntimeException(sprintf('Cannot get key %s', $keyId));
}
[
OidcKeyType::DISCOVERY_URL => $discoveryUrl,
OidcKeyType::CLIENT_ID => $clientId,
OidcKeyType::CLIENT_SECRET => $clientSecret,
] = $this->keyHelper->getOidcValues($key);
}
catch (\Exception $e) {
throw new AuthenticationException('Cannot get client id and secret', $e->getCode(), $e);
}
}

$providerOptions = [
Expand Down
114 changes: 100 additions & 14 deletions src/Plugin/os2web/NemloginAuthProvider/OpenIDConnect.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,18 @@ class OpenIDConnect extends AuthProviderBase {
use LoggerTrait;
use LoggerAwareTrait;

/**
* Session name for storing OIDC user token.
*/
private const SESSION_TOKEN = 'os2forms_nemlogin_openid_connect.user_token';
public const SESSION_TOKEN = 'os2forms_nemlogin_openid_connect.user_token';
public const KEY = 'nemlogin_openid_connect_key';
public const SECRET_PROVIDER = 'secret_provider';
public const PROVIDER_TYPE_FORM = 'form';
public const PROVIDER_TYPE_KEY = 'key';
public const FETCH_ONCE = 'nemlogin_openid_connect_fetch_once';
public const POST_LOGOUT_REDIRECT_URI = 'nemlogin_openid_connect_post_logout_redirect_uri';
public const USER_CLAIMS = 'nemlogin_openid_connect_user_claims';
public const DISCOVERY_URL = 'nemlogin_openid_connect_discovery_url';
public const CLIENT_ID = 'nemlogin_openid_connect_client_id';
public const CLIENT_SECRET = 'nemlogin_openid_connect_client_secret';


/**
* Fetch only mode flag.
Expand Down Expand Up @@ -115,8 +123,8 @@ public static function create(ContainerInterface $container, array $configuratio
* {@inheritdoc}
*/
public function isInitialized() {
$configuration = $configuration = $this->getConfiguration();
if (!empty($configuration['nemlogin_openid_connect_discovery_url'])) {
$configuration = $this->getConfiguration();
if (!empty($configuration[self::DISCOVERY_URL])) {
return TRUE;
}

Expand Down Expand Up @@ -265,11 +273,6 @@ public function fetchValue($key) {
return $value;
}

public const KEY = 'nemlogin_openid_connect_key';
public const FETCH_ONCE = 'nemlogin_openid_connect_fetch_once';
public const POST_LOGOUT_REDIRECT_URI = 'nemlogin_openid_connect_post_logout_redirect_uri';
public const USER_CLAIMS = 'nemlogin_openid_connect_user_claims';

/**
* {@inheritdoc}
*
Expand All @@ -280,6 +283,10 @@ public function fetchValue($key) {
*/
public function defaultConfiguration() {
return parent::defaultConfiguration() + [
self::SECRET_PROVIDER => self::PROVIDER_TYPE_FORM,
self::DISCOVERY_URL => '',
self::CLIENT_ID => '',
self::CLIENT_SECRET => '',
self::KEY => '',
self::FETCH_ONCE => '',
self::POST_LOGOUT_REDIRECT_URI => '',
Expand All @@ -294,15 +301,79 @@ public function defaultConfiguration() {
* @phpstan-return array<string, mixed>
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state): array {

$form[self::SECRET_PROVIDER] = [
'#type' => 'select',
'#title' => $this->t('Provider'),
'#options' => [
self::PROVIDER_TYPE_FORM => $this->t('Form'),
self::PROVIDER_TYPE_KEY => $this->t('Key'),
],
'#default_value' => $this->configuration[self::SECRET_PROVIDER] ?? self::PROVIDER_TYPE_FORM,
];

$form[self::DISCOVERY_URL] = [
'#type' => 'textfield',
'#title' => $this->t('OpenID Connect Discovery url'),
// Our urls are very long.
'#maxlength' => 256,
'#default_value' => $this->configuration[self::DISCOVERY_URL] ?? NULL,
'#description' => $this->t('OpenID Connect Discovery url (cf. <a href="https://swagger.io/docs/specification/authentication/openid-connect-discovery/">https://swagger.io/docs/specification/authentication/openid-connect-discovery/</a>)'),
'#states' => [
'visible' => [
[':input[name="secret_provider"]' => ['value' => self::PROVIDER_TYPE_FORM]],
],
'required' => [
[':input[name="secret_provider"]' => ['value' => self::PROVIDER_TYPE_FORM]],
],
],
];

$form[self::CLIENT_ID] = [
'#type' => 'textfield',
'#title' => $this->t('Client id'),
'#default_value' => $this->configuration[self::CLIENT_ID] ?? NULL,
'#states' => [
'visible' => [
[':input[name="secret_provider"]' => ['value' => self::PROVIDER_TYPE_FORM]],
],
'required' => [
[':input[name="secret_provider"]' => ['value' => self::PROVIDER_TYPE_FORM]],
],
],
];

$form[self::CLIENT_SECRET] = [
'#type' => 'textfield',
'#title' => $this->t('Client secret'),
'#default_value' => $this->configuration[self::CLIENT_SECRET] ?? NULL,
'#states' => [
'visible' => [
[':input[name="secret_provider"]' => ['value' => self::PROVIDER_TYPE_FORM]],
],
'required' => [
[':input[name="secret_provider"]' => ['value' => self::PROVIDER_TYPE_FORM]],
],
],
];

$form[self::KEY] = [
'#type' => 'key_select',
'#key_filters' => [
'type' => 'os2web_key_oidc',
],
'#title' => $this->t('Key'),
'#required' => TRUE,
'#default_value' => $this->configuration[self::KEY] ?? NULL,
'#states' => [
'visible' => [
[':input[name="secret_provider"]' => ['value' => self::PROVIDER_TYPE_KEY]],
],
'required' => [
[':input[name="secret_provider"]' => ['value' => self::PROVIDER_TYPE_KEY]],
],
],
];

$form[self::FETCH_ONCE] = [
'#type' => 'checkbox',
'#title' => $this->t('Use fetch only mode.'),
Expand Down Expand Up @@ -334,9 +405,20 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
* @phpstan-param array<string, mixed> $form
*/
public function validateConfigurationForm(array &$form, FormStateInterface $form_state): void {
$url = $form_state->getValue(self::POST_LOGOUT_REDIRECT_URI);

if (self::PROVIDER_TYPE_FORM === $form_state->getValue(self::SECRET_PROVIDER)) {

$discoveryUrl = $form_state->getValue(self::DISCOVERY_URL);

if (!UrlHelper::isValid($discoveryUrl, TRUE)) {
$form_state->setErrorByName(self::DISCOVERY_URL, $this->t('Discovery url is not valid'));
}
}

$redirectUrl = $form_state->getValue(self::POST_LOGOUT_REDIRECT_URI);

try {
UrlHelper::isExternal($url) ? Url::fromUri($url) : Url::fromUserInput($url);
UrlHelper::isExternal($redirectUrl) ? Url::fromUri($redirectUrl) : Url::fromUserInput($redirectUrl);
}
catch (\Exception $exception) {
$form_state->setErrorByName(self::POST_LOGOUT_REDIRECT_URI, $this->t('Post logout redirect url is not valid (@message)', ['@message' => $exception->getMessage()]));
Expand Down Expand Up @@ -381,6 +463,10 @@ public function validateConfigurationForm(array &$form, FormStateInterface $form
public function submitConfigurationForm(array &$form, FormStateInterface $form_state): void {
$configuration = $this->getConfiguration();

$configuration[self::SECRET_PROVIDER] = $form_state->getValue(self::SECRET_PROVIDER);
$configuration[self::DISCOVERY_URL] = $form_state->getValue(self::DISCOVERY_URL);
$configuration[self::CLIENT_ID] = $form_state->getValue(self::CLIENT_ID);
$configuration[self::CLIENT_SECRET] = $form_state->getValue(self::CLIENT_SECRET);
$configuration[self::KEY] = $form_state->getValue(self::KEY);
$configuration[self::FETCH_ONCE] = $form_state->getValue(self::FETCH_ONCE);
$configuration[self::POST_LOGOUT_REDIRECT_URI] = $form_state->getValue(self::POST_LOGOUT_REDIRECT_URI);
Expand Down