Update test and link formation on invite of new user

Signed-off-by: Alice W <105500542+alice-wondered@users.noreply.github.com>
This commit is contained in:
Alice W 2024-05-02 15:30:40 -04:00 committed by Pedro Igor
parent 694105da89
commit ce2e83c7f9
2 changed files with 17 additions and 2 deletions

View file

@ -17,6 +17,7 @@
package org.keycloak.organization.admin.resource; package org.keycloak.organization.admin.resource;
import java.util.Map;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.stream.Stream; import java.util.stream.Stream;
@ -34,11 +35,13 @@ import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.Response.Status; import jakarta.ws.rs.core.Response.Status;
import jakarta.ws.rs.core.UriBuilder;
import jakarta.ws.rs.ext.Provider; import jakarta.ws.rs.ext.Provider;
import java.util.Objects; import java.util.Objects;
import org.eclipse.microprofile.openapi.annotations.Operation; import org.eclipse.microprofile.openapi.annotations.Operation;
import org.eclipse.microprofile.openapi.annotations.parameters.Parameter; import org.eclipse.microprofile.openapi.annotations.parameters.Parameter;
import org.keycloak.OAuth2Constants;
import org.keycloak.common.util.Time; import org.keycloak.common.util.Time;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ModelException; import org.keycloak.models.ModelException;
@ -54,11 +57,14 @@ import org.keycloak.models.*;
import org.keycloak.models.utils.KeycloakModelUtils; import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.models.utils.ModelToRepresentation; import org.keycloak.models.utils.ModelToRepresentation;
import org.keycloak.organization.OrganizationProvider; import org.keycloak.organization.OrganizationProvider;
import org.keycloak.protocol.oidc.OIDCLoginProtocolService;
import org.keycloak.protocol.oidc.utils.OIDCResponseType;
import org.keycloak.representations.idm.OrganizationRepresentation; import org.keycloak.representations.idm.OrganizationRepresentation;
import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.services.ErrorResponse; import org.keycloak.services.ErrorResponse;
import org.keycloak.services.ServicesLogger; import org.keycloak.services.ServicesLogger;
import org.keycloak.services.resources.LoginActionsService; import org.keycloak.services.resources.LoginActionsService;
import org.keycloak.services.resources.RealmsResource;
import org.keycloak.services.resources.admin.AdminEventBuilder; import org.keycloak.services.resources.admin.AdminEventBuilder;
import org.keycloak.services.resources.admin.UserResource; import org.keycloak.services.resources.admin.UserResource;
import org.keycloak.services.resources.admin.UsersResource; import org.keycloak.services.resources.admin.UsersResource;
@ -135,14 +141,19 @@ public class OrganizationMemberResource {
.queryParam("key", token.serialize(session, realm, session.getContext().getUri())) .queryParam("key", token.serialize(session, realm, session.getContext().getUri()))
.build(realm.getName()).toString(); .build(realm.getName()).toString();
} else { } else {
// TODO this link really only works with implicit token grants enabled for the given client
// this path lets us invite a user that doesn't exist yet, letting them register into the organization // this path lets us invite a user that doesn't exist yet, letting them register into the organization
token = new InviteOrgActionToken(null, tokenExpiration, rep.getEmail(), Constants.ACCOUNT_MANAGEMENT_CLIENT_ID); token = new InviteOrgActionToken(null, tokenExpiration, rep.getEmail(), Constants.ACCOUNT_MANAGEMENT_CLIENT_ID);
token.setOrgId(organization.getId()); token.setOrgId(organization.getId());
link = LoginActionsService.registrationFormProcessor(session.getContext().getUri()) Map<String, String> params = Map.of("realm", realm.getName(), "protocol", "openid-connect");
link = OIDCLoginProtocolService.registrationsUrl(session.getContext().getUri().getBaseUriBuilder())
.queryParam(OAuth2Constants.RESPONSE_TYPE, OIDCResponseType.TOKEN)
.queryParam(Constants.CLIENT_ID, Constants.ACCOUNT_MANAGEMENT_CLIENT_ID)
.queryParam(Constants.ORG_TOKEN, token.serialize(session, realm, session.getContext().getUri())) .queryParam(Constants.ORG_TOKEN, token.serialize(session, realm, session.getContext().getUri()))
.build(realm.getName()).toString(); .buildFromMap(params).toString();
} }
if (user == null ) { if (user == null ) {
user = new InMemoryUserAdapter(session, realm, null); user = new InMemoryUserAdapter(session, realm, null);
user.setEmail(rep.getEmail()); user.setEmail(rep.getEmail());

View file

@ -21,6 +21,7 @@ import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.keycloak.models.Constants.ACCOUNT_MANAGEMENT_CLIENT_ID;
import java.io.IOException; import java.io.IOException;
import java.util.Map; import java.util.Map;
@ -30,6 +31,7 @@ import java.util.function.Predicate;
import jakarta.mail.internet.MimeMessage; import jakarta.mail.internet.MimeMessage;
import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response;
import org.jboss.arquillian.drone.webdriver.htmlunit.DroneHtmlUnitDriver;
import org.jboss.arquillian.graphene.page.Page; import org.jboss.arquillian.graphene.page.Page;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
@ -72,6 +74,8 @@ public class OrganizationInvitationLinkTest extends AbstractOrganizationTest {
@Override @Override
public void configureTestRealm(RealmRepresentation testRealm) { public void configureTestRealm(RealmRepresentation testRealm) {
// we need the implicit flow to test user registration with the token return_type; only way to get an authentication session
testRealm.getClients().stream().filter(c -> c != null && c.getName() != null).filter(c -> c.getName().equals(ACCOUNT_MANAGEMENT_CLIENT_ID)).forEach(c -> c.setImplicitFlowEnabled(true));
Map<String, String> smtpConfig = testRealm.getSmtpServer(); Map<String, String> smtpConfig = testRealm.getSmtpServer();
super.configureTestRealm(testRealm); super.configureTestRealm(testRealm);
testRealm.setSmtpServer(smtpConfig); testRealm.setSmtpServer(smtpConfig);