Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions docs/realm-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,11 @@ These configuration should be set for each UserStorage contained in a Realm :
Those are optional properties to set on a userstorage. If the property is not set at the userstorage level,
the corresponding realm property will be used as default if set.

| Key | Description |
| ---------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
| {name}\_send_login_template with name being a configured external webservice | A template to complete and send to the {name} webservice on /send-login call (see [Notify external webservices](concepts.md#notify-external-webservices) and [Webhooks configuration](configuration.md#webhooks-configuration)) |
| {name}\_reset_template with name being a configured webservice | A template to complete and send to the {name} webservice on /reinit-password call (see [Notify external webservices](concepts.md#notify-external-webservices) and [Webhooks configuration](configuration.md#webhooks-configuration)) |
| {name}\_changepwd_template with name being a configured webservice | A template to complete and send to the {name} webservice on /change-password call (see [Notify external webservices](concepts.md#notify-external-webservices) and [Webhooks configuration](configuration.md#webhooks-configuration)) |
| Key | Description | Example |
| ---------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | -------- |
| send_login_template | The url of each template to complete and send to a webservice on /send-login call (see [Notify external webservices](concepts.md#notify-external-webservices) and [Webhooks configuration](configuration.md#webhooks-configuration)). Each configuration webhook should be prefixed by {name of the webhook}`:` and separated from other webhooks with a `\|` | spoc:https://spoc.insee.fr/template|test:http://test.insee.fr |
| reset_template | The url of each template to complete and send to a webservice on /reinit-password call (see [Notify external webservices](concepts.md#notify-external-webservices) and [Webhooks configuration](configuration.md#webhooks-configuration)). Each configuration webhook should be prefixed by {name of the webhook}`:` and separated from other webhooks with a `\|` | spoc:https://spoc.insee.fr/template|test:http://test.insee.fr |
| changepwd_template | The url of each template to complete and send to a webservice on /change-password call (see [Notify external webservices](concepts.md#notify-external-webservices) and [Webhooks configuration](configuration.md#webhooks-configuration)). Each configuration webhook should be prefixed by {name of the webhook}`:` and separated from other webhooks with a `\|` | spoc:https://spoc.insee.fr/template|test:http://test.insee.fr |

### Userstorage configuration properties on password

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package fr.insee.sugoi.event.listener.webhook.service;

import fr.insee.sugoi.model.RealmConfigKeys;
import java.util.Arrays;
import java.util.Optional;

public enum TemplateConfigKeys implements RealmConfigKeys {
LOGIN_TEMPLATE("send_login_template"),
RESET_TEMPLATE("reset_template"),
CHANGEPWD_TEMPLATE("changepwd_template");

private String name;

TemplateConfigKeys(String name) {
this.name = name;
}

@Override
public String getName() {
return name;
}

private static Optional<TemplateConfigKeys> getTemplateConfigKeys(String name) {
return Arrays.stream(TemplateConfigKeys.values())
.filter(tkc -> tkc.getName().equalsIgnoreCase(name))
.findFirst();
}

public static RealmConfigKeys getRealmConfigKey(String key) {
return getTemplateConfigKeys(key).orElse(null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@

import fr.insee.sugoi.core.event.configuration.EventKeysConfig;
import fr.insee.sugoi.core.realm.RealmProvider;
import fr.insee.sugoi.event.listener.webhook.service.TemplateConfigKeys;
import fr.insee.sugoi.event.listener.webhook.service.WebHookService;
import fr.insee.sugoi.model.exceptions.NoReceiverMailException;
import fr.insee.sugoi.model.exceptions.UserStorageNotFoundException;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
Expand All @@ -25,10 +27,13 @@
import java.io.StringWriter;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
Expand All @@ -50,35 +55,40 @@ public class WebHookServiceImpl implements WebHookService {
public static final Logger logger = LoggerFactory.getLogger(WebHookServiceImpl.class);
private static final String WEBHOOK_PROPERTY_PREFIX = "sugoi.api.event.webhook.";

private static RestTemplate restTemplate = new RestTemplate();

@Autowired private Environment env;

@Autowired private RealmProvider realmProvider;

@Override
public void resetPassword(String webHookName, Map<String, Object> values) {
if (!((List<String>) values.get(EventKeysConfig.MAILS)).isEmpty()) {
if (!((List<?>) values.get(EventKeysConfig.MAILS)).isEmpty()) {
sendRequestToWebhookFromTemplate(
values, webHookName, "_reset_template", ".default.reset.template");
values, webHookName, TemplateConfigKeys.RESET_TEMPLATE, ".default.reset.template");
} else {
throw new NoReceiverMailException("There is no mail address to send the message to");
}
}

@Override
public void changePassword(String webHookName, Map<String, Object> values) {
if (!((List<String>) values.get(EventKeysConfig.MAILS)).isEmpty()) {
if (!((List<?>) values.get(EventKeysConfig.MAILS)).isEmpty()) {
sendRequestToWebhookFromTemplate(
values, webHookName, "_changepwd_template", ".default.changepwd.template");
values,
webHookName,
TemplateConfigKeys.CHANGEPWD_TEMPLATE,
".default.changepwd.template");
} else {
throw new NoReceiverMailException("There is no mail address to send the message to");
}
}

@Override
public void sendLogin(String webHookName, Map<String, Object> values) {
if (!((List<String>) values.get(EventKeysConfig.MAILS)).isEmpty()) {
if (!((List<?>) values.get(EventKeysConfig.MAILS)).isEmpty()) {
sendRequestToWebhookFromTemplate(
values, webHookName, "_send_login_template", ".default.send-login.template");
values, webHookName, TemplateConfigKeys.LOGIN_TEMPLATE, ".default.send-login.template");
} else {
throw new NoReceiverMailException("There is no mail address to send the message to");
}
Expand All @@ -87,11 +97,12 @@ public void sendLogin(String webHookName, Map<String, Object> values) {
private void sendRequestToWebhookFromTemplate(
Map<String, Object> templateProperties,
String webHookName,
String realmTemplateSuffix,
TemplateConfigKeys realmTemplateKey,
String propertyTemplateSuffix) {
String template =
loadTemplate(
webHookName + realmTemplateSuffix,
realmTemplateKey,
webHookName,
WEBHOOK_PROPERTY_PREFIX + webHookName + propertyTemplateSuffix,
(String) templateProperties.get(EventKeysConfig.REALM),
(String) templateProperties.get(EventKeysConfig.USERSTORAGE));
Expand All @@ -112,7 +123,6 @@ public void send(String target, String content, Map<String, String> headers) {
try {
HttpHeaders finalHeaders = new HttpHeaders();
headers.keySet().stream().forEach(header -> finalHeaders.add(header, headers.get(header)));
RestTemplate restTemplate = new RestTemplate();
HttpEntity<String> request = new HttpEntity<>(content, finalHeaders);
restTemplate.postForEntity(target, request, String.class);
logger.info("Sending webHook to {} success", target);
Expand Down Expand Up @@ -169,25 +179,43 @@ private String injectValueInTemplate(String content, Map<String, Object> values)
}

private String loadTemplate(
String realmTemplateConfiguration,
TemplateConfigKeys realmTemplateKey,
String webhookName,
String propertyTemplateConfiguration,
String realmName,
String userStorageName) {
String template = null;
try {
template =
realmProvider.load(realmName).orElseThrow().getUserStorages().stream()
.filter(us -> us.getName().equalsIgnoreCase(userStorageName))
.findFirst()
.orElseThrow()
.getProperties()
.get(realmTemplateConfiguration);
} catch (Exception e) {
// we don't need to manage this exception here
String templateLocation =
createTemplateLocationMapByWebhook(
realmProvider.load(realmName).orElseThrow().getUserStorages().stream()
.filter(us -> us.getName().equalsIgnoreCase(userStorageName))
.findFirst()
.orElseThrow(() -> new UserStorageNotFoundException(realmName, userStorageName))
.getProperties()
.get(realmTemplateKey))
.get(webhookName);
if (templateLocation != null) {
try {
return restTemplate.getForEntity(templateLocation, String.class).getBody();
} catch (Exception e) {
logger.error(
"Could not retrieve template at location {} . Falling back on property. {}",
templateLocation,
e.getLocalizedMessage());
}
}
if (template == null && propertyTemplateConfiguration != null) {
template = loadResource(env.getProperty(propertyTemplateConfiguration));
if (propertyTemplateConfiguration != null) {
return loadResource(env.getProperty(propertyTemplateConfiguration));
}
return template;
return null;
}

private Map<String, String> createTemplateLocationMapByWebhook(String allWebhookConfiguration) {
if (allWebhookConfiguration != null) {
return Arrays.stream(allWebhookConfiguration.split("\\|"))
.collect(
Collectors.toMap(
conf -> StringUtils.substringBefore(conf, ":"),
conf -> StringUtils.substringAfter(conf, ":")));
} else return new HashMap<>();
}
}