Show a message when confirming an invitation link
Closes #29794 Signed-off-by: Pedro Igor <pigor.craveiro@gmail.com>
This commit is contained in:
parent
4c8abfb61f
commit
2d4d32764c
7 changed files with 32 additions and 6 deletions
|
@ -25,6 +25,7 @@ import java.util.stream.Stream;
|
|||
public interface OrganizationModel {
|
||||
|
||||
String ORGANIZATION_ATTRIBUTE = "kc.org";
|
||||
String ORGANIZATION_NAME_ATTRIBUTE = "kc.org.name";
|
||||
String ORGANIZATION_DOMAIN_ATTRIBUTE = "kc.org.domain";
|
||||
String BROKER_PUBLIC = "kc.org.broker.public";
|
||||
|
||||
|
|
|
@ -43,8 +43,8 @@ import org.keycloak.services.messages.Messages;
|
|||
import org.keycloak.sessions.AuthenticationSessionCompoundId;
|
||||
import org.keycloak.sessions.AuthenticationSessionModel;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* Action token handler for handling invitation of an existing user to an organization. A new user is handled in registration {@link org.keycloak.services.resources.LoginActionsService}.
|
||||
|
@ -114,6 +114,8 @@ public class InviteOrgActionTokenHandler extends AbstractActionTokenHandler<Invi
|
|||
.setAuthenticationSession(authSession)
|
||||
.setSuccess(Messages.CONFIRM_EXECUTION_OF_ACTIONS)
|
||||
.setAttribute(Constants.TEMPLATE_ATTR_ACTION_URI, confirmUri)
|
||||
.setAttribute(Constants.TEMPLATE_ATTR_REQUIRED_ACTIONS, List.of(Messages.CONFIRM_ORGANIZATION_MEMBERSHIP))
|
||||
.setAttribute(OrganizationModel.ORGANIZATION_NAME_ATTRIBUTE, organization.getName())
|
||||
.createInfoPage();
|
||||
}
|
||||
|
||||
|
|
|
@ -404,7 +404,9 @@ public class FreeMarkerLoginFormsProvider implements LoginFormsProvider {
|
|||
Properties messagesBundle;
|
||||
try {
|
||||
messagesBundle = theme.getEnhancedMessages(realm, locale);
|
||||
attributes.put("msg", new MessageFormatterMethod(locale, messagesBundle));
|
||||
Map<Object, Object> msgParams = new HashMap<>(attributes);
|
||||
msgParams.putAll(messagesBundle);
|
||||
attributes.put("msg", new MessageFormatterMethod(locale, msgParams));
|
||||
attributes.put("advancedMsg", new AdvancedMessageFormatterMethod(locale, messagesBundle));
|
||||
} catch (IOException e) {
|
||||
logger.warn("Failed to load messages", e);
|
||||
|
@ -441,7 +443,7 @@ public class FreeMarkerLoginFormsProvider implements LoginFormsProvider {
|
|||
}
|
||||
attributes.put("message", wholeMessage);
|
||||
} else {
|
||||
attributes.put("message", null);
|
||||
attributes.remove("message");
|
||||
}
|
||||
attributes.put("messagesPerField", messagesPerField);
|
||||
}
|
||||
|
@ -486,7 +488,7 @@ public class FreeMarkerLoginFormsProvider implements LoginFormsProvider {
|
|||
attributes.put("url", new UrlBean(realm, theme, baseUri, this.actionUri));
|
||||
attributes.put("requiredActionUrl", new RequiredActionUrlFormatterMethod(realm, baseUri));
|
||||
attributes.put("auth", new AuthenticationContextBean(context, page));
|
||||
attributes.put(Constants.EXECUTION, execution);
|
||||
setAttribute(Constants.EXECUTION, execution);
|
||||
|
||||
if (realm.isInternationalizationEnabled()) {
|
||||
UriBuilder b;
|
||||
|
@ -893,7 +895,11 @@ public class FreeMarkerLoginFormsProvider implements LoginFormsProvider {
|
|||
|
||||
@Override
|
||||
public LoginFormsProvider setAttribute(String name, Object value) {
|
||||
this.attributes.put(name, value);
|
||||
if (value == null) {
|
||||
attributes.remove(name);
|
||||
} else {
|
||||
attributes.put(name, value);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -320,4 +320,5 @@ public class Messages {
|
|||
public static final String OAUTH2_DEVICE_VERIFICATION_FAILED_HEADER = "oauth2DeviceVerificationFailedHeader";
|
||||
public static final String OAUTH2_DEVICE_CONSENT_DENIED = "oauth2DeviceConsentDeniedMessage";
|
||||
|
||||
public static final String CONFIRM_ORGANIZATION_MEMBERSHIP = "organization.confirm-membership";
|
||||
}
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
|
||||
package org.keycloak.theme.beans;
|
||||
|
||||
import static java.util.Optional.ofNullable;
|
||||
|
||||
import freemarker.template.SimpleScalar;
|
||||
import freemarker.template.TemplateMethodModelEx;
|
||||
import freemarker.template.TemplateModelException;
|
||||
|
@ -26,6 +28,8 @@ import java.text.MessageFormat;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
|
@ -40,13 +44,22 @@ public class MessageFormatterMethod implements TemplateMethodModelEx {
|
|||
this.messages = messages;
|
||||
}
|
||||
|
||||
public MessageFormatterMethod(Locale locale, Map<Object, Object> messages) {
|
||||
this.locale = locale;
|
||||
this.messages = new Properties();
|
||||
this.messages.putAll(ofNullable(messages).orElse(Map.of()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object exec(List list) throws TemplateModelException {
|
||||
if (list.size() >= 1) {
|
||||
// resolve any remaining ${} expressions
|
||||
List<Object> resolved = resolve(list.subList(1, list.size()));
|
||||
String key = list.get(0).toString();
|
||||
return new MessageFormat(messages.getProperty(key,key),locale).format(resolved.toArray());
|
||||
String value = messages.getOrDefault(key, key).toString();
|
||||
// try to also resolve placeholders if present in the message bundle
|
||||
value = (String) resolve(List.of(value)).get(0);
|
||||
return new MessageFormat(value, locale).format(resolved.toArray());
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -223,6 +223,7 @@ public class OrganizationInvitationLinkTest extends AbstractOrganizationTest {
|
|||
// not yet a member
|
||||
Assert.assertFalse(organization.members().getAll().stream().anyMatch(actual -> user.getId().equals(actual.getId())));
|
||||
// confirm the intent of membership
|
||||
assertThat(infoPage.getInfo(), containsString("You are about to join organization " + organizationName));
|
||||
infoPage.clickToContinue();
|
||||
assertThat(infoPage.getInfo(), containsString("Your account has been updated."));
|
||||
// now a member
|
||||
|
|
|
@ -517,3 +517,5 @@ doLogout=Logout
|
|||
|
||||
readOnlyUsernameMessage=You can''t update your username as it is read-only.
|
||||
error-invalid-multivalued-size=Attribute {0} must have at least {1} and at most {2} value(s).
|
||||
|
||||
requiredAction.organization.confirm-membership=You are about to join organization ${kc.org.name}
|
Loading…
Reference in a new issue