Skip to content

Commit

Permalink
Show a message when confirming an invitation link
Browse files Browse the repository at this point in the history
Closes keycloak#29794

Signed-off-by: Pedro Igor <[email protected]>
  • Loading branch information
pedroigor committed May 23, 2024
1 parent 653781c commit 342058b
Show file tree
Hide file tree
Showing 7 changed files with 32 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
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";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@
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}.
Expand Down Expand Up @@ -114,6 +114,8 @@ public Response handleToken(InviteOrgActionToken token, ActionTokenContext<Invit
.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();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,9 @@ protected Properties handleThemeResources(Theme theme, Locale locale) {
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);
Expand Down Expand Up @@ -441,7 +443,7 @@ protected void handleMessages(Locale locale, Properties messagesBundle) {
}
attributes.put("message", wholeMessage);
} else {
attributes.put("message", null);
attributes.remove("message");
}
attributes.put("messagesPerField", messagesPerField);
}
Expand Down Expand Up @@ -486,7 +488,7 @@ protected void createCommonAttributes(Theme theme, Locale locale, Properties mes
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;
Expand Down Expand Up @@ -893,7 +895,11 @@ public LoginFormsProvider setAccessRequest(List<AuthorizationDetails> clientScop

@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;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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";
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -26,6 +28,8 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;

/**
Expand All @@ -40,13 +44,22 @@ public MessageFormatterMethod(Locale locale, Properties messages) {
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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ private void acceptInvitation(OrganizationResource organization, UserRepresentat
// 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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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}

0 comments on commit 342058b

Please sign in to comment.