KEYCLOAK-3003 Support for admin events in AuthenticationManagementResource
This commit is contained in:
parent
5ed09acd94
commit
f58936025f
11 changed files with 252 additions and 49 deletions
|
@ -25,9 +25,18 @@ package org.keycloak.representations.idm;
|
||||||
*/
|
*/
|
||||||
public class RequiredActionProviderSimpleRepresentation {
|
public class RequiredActionProviderSimpleRepresentation {
|
||||||
|
|
||||||
|
private String id;
|
||||||
private String name;
|
private String name;
|
||||||
private String providerId;
|
private String providerId;
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ import org.keycloak.authentication.FormAction;
|
||||||
import org.keycloak.authentication.FormAuthenticator;
|
import org.keycloak.authentication.FormAuthenticator;
|
||||||
import org.keycloak.authentication.RequiredActionFactory;
|
import org.keycloak.authentication.RequiredActionFactory;
|
||||||
import org.keycloak.authentication.RequiredActionProvider;
|
import org.keycloak.authentication.RequiredActionProvider;
|
||||||
|
import org.keycloak.events.admin.OperationType;
|
||||||
import org.keycloak.models.AuthenticationExecutionModel;
|
import org.keycloak.models.AuthenticationExecutionModel;
|
||||||
import org.keycloak.models.AuthenticationFlowModel;
|
import org.keycloak.models.AuthenticationFlowModel;
|
||||||
import org.keycloak.models.AuthenticatorConfigModel;
|
import org.keycloak.models.AuthenticatorConfigModel;
|
||||||
|
@ -212,7 +213,10 @@ public class AuthenticationManagementResource {
|
||||||
return ErrorResponse.exists("Flow " + flow.getAlias() + " already exists");
|
return ErrorResponse.exists("Flow " + flow.getAlias() + " already exists");
|
||||||
}
|
}
|
||||||
|
|
||||||
realm.addAuthenticationFlow(RepresentationToModel.toModel(flow));
|
AuthenticationFlowModel createdModel = realm.addAuthenticationFlow(RepresentationToModel.toModel(flow));
|
||||||
|
|
||||||
|
flow.setId(createdModel.getId());
|
||||||
|
adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo, createdModel.getId()).representation(flow).success();
|
||||||
return Response.status(201).build();
|
return Response.status(201).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,6 +267,9 @@ public class AuthenticationManagementResource {
|
||||||
realm.removeAuthenticatorExecution(execution);
|
realm.removeAuthenticatorExecution(execution);
|
||||||
}
|
}
|
||||||
realm.removeAuthenticationFlow(flow);
|
realm.removeAuthenticationFlow(flow);
|
||||||
|
|
||||||
|
// Use just one event for top-level flow. Using separate events won't work properly for flows of depth 2 or bigger
|
||||||
|
adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).success();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -299,6 +306,9 @@ public class AuthenticationManagementResource {
|
||||||
copy = realm.addAuthenticationFlow(copy);
|
copy = realm.addAuthenticationFlow(copy);
|
||||||
copy(newName, flow, copy);
|
copy(newName, flow, copy);
|
||||||
|
|
||||||
|
data.put("id", copy.getId());
|
||||||
|
adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo).representation(data).success();
|
||||||
|
|
||||||
return Response.status(201).build();
|
return Response.status(201).build();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -362,8 +372,10 @@ public class AuthenticationManagementResource {
|
||||||
execution.setAuthenticatorFlow(true);
|
execution.setAuthenticatorFlow(true);
|
||||||
execution.setAuthenticator(provider);
|
execution.setAuthenticator(provider);
|
||||||
execution.setPriority(getNextPriority(parentFlow));
|
execution.setPriority(getNextPriority(parentFlow));
|
||||||
|
execution = realm.addAuthenticatorExecution(execution);
|
||||||
|
|
||||||
realm.addAuthenticatorExecution(execution);
|
data.put("id", execution.getId());
|
||||||
|
adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo).representation(data).success();
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getNextPriority(AuthenticationFlowModel parentFlow) {
|
private int getNextPriority(AuthenticationFlowModel parentFlow) {
|
||||||
|
@ -413,7 +425,10 @@ public class AuthenticationManagementResource {
|
||||||
execution.setAuthenticator(provider);
|
execution.setAuthenticator(provider);
|
||||||
execution.setPriority(getNextPriority(parentFlow));
|
execution.setPriority(getNextPriority(parentFlow));
|
||||||
|
|
||||||
realm.addAuthenticatorExecution(execution);
|
execution = realm.addAuthenticatorExecution(execution);
|
||||||
|
|
||||||
|
data.put("id", execution.getId());
|
||||||
|
adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo).representation(data).success();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -519,6 +534,7 @@ public class AuthenticationManagementResource {
|
||||||
if (!model.getRequirement().name().equals(rep.getRequirement())) {
|
if (!model.getRequirement().name().equals(rep.getRequirement())) {
|
||||||
model.setRequirement(AuthenticationExecutionModel.Requirement.valueOf(rep.getRequirement()));
|
model.setRequirement(AuthenticationExecutionModel.Requirement.valueOf(rep.getRequirement()));
|
||||||
realm.updateAuthenticatorExecution(model);
|
realm.updateAuthenticatorExecution(model);
|
||||||
|
adminEvent.operation(OperationType.UPDATE).resourcePath(uriInfo).representation(rep).success();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -541,6 +557,8 @@ public class AuthenticationManagementResource {
|
||||||
}
|
}
|
||||||
model.setPriority(getNextPriority(parentFlow));
|
model.setPriority(getNextPriority(parentFlow));
|
||||||
model = realm.addAuthenticatorExecution(model);
|
model = realm.addAuthenticatorExecution(model);
|
||||||
|
|
||||||
|
adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo, model.getId()).representation(execution).success();
|
||||||
return Response.created(uriInfo.getAbsolutePathBuilder().path(model.getId()).build()).build();
|
return Response.created(uriInfo.getAbsolutePathBuilder().path(model.getId()).build()).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -592,6 +610,8 @@ public class AuthenticationManagementResource {
|
||||||
realm.updateAuthenticatorExecution(previous);
|
realm.updateAuthenticatorExecution(previous);
|
||||||
model.setPriority(tmp);
|
model.setPriority(tmp);
|
||||||
realm.updateAuthenticatorExecution(model);
|
realm.updateAuthenticatorExecution(model);
|
||||||
|
|
||||||
|
adminEvent.operation(OperationType.UPDATE).resourcePath(uriInfo).success();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<AuthenticationExecutionModel> getSortedExecutions(AuthenticationFlowModel parentFlow) {
|
public List<AuthenticationExecutionModel> getSortedExecutions(AuthenticationFlowModel parentFlow) {
|
||||||
|
@ -635,6 +655,8 @@ public class AuthenticationManagementResource {
|
||||||
realm.updateAuthenticatorExecution(model);
|
realm.updateAuthenticatorExecution(model);
|
||||||
next.setPriority(tmp);
|
next.setPriority(tmp);
|
||||||
realm.updateAuthenticatorExecution(next);
|
realm.updateAuthenticatorExecution(next);
|
||||||
|
|
||||||
|
adminEvent.operation(OperationType.UPDATE).resourcePath(uriInfo).success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -666,6 +688,8 @@ public class AuthenticationManagementResource {
|
||||||
}
|
}
|
||||||
|
|
||||||
realm.removeAuthenticatorExecution(model);
|
realm.removeAuthenticatorExecution(model);
|
||||||
|
|
||||||
|
adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -693,6 +717,9 @@ public class AuthenticationManagementResource {
|
||||||
config = realm.addAuthenticatorConfig(config);
|
config = realm.addAuthenticatorConfig(config);
|
||||||
model.setAuthenticatorConfig(config.getId());
|
model.setAuthenticatorConfig(config.getId());
|
||||||
realm.updateAuthenticatorExecution(model);
|
realm.updateAuthenticatorExecution(model);
|
||||||
|
|
||||||
|
json.setId(config.getId());
|
||||||
|
adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo).representation(json).success();
|
||||||
return Response.created(uriInfo.getAbsolutePathBuilder().path(config.getId()).build()).build();
|
return Response.created(uriInfo.getAbsolutePathBuilder().path(config.getId()).build()).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -772,7 +799,10 @@ public class AuthenticationManagementResource {
|
||||||
requiredAction.setProviderId(providerId);
|
requiredAction.setProviderId(providerId);
|
||||||
requiredAction.setDefaultAction(false);
|
requiredAction.setDefaultAction(false);
|
||||||
requiredAction.setEnabled(true);
|
requiredAction.setEnabled(true);
|
||||||
realm.addRequiredActionProvider(requiredAction);
|
requiredAction = realm.addRequiredActionProvider(requiredAction);
|
||||||
|
|
||||||
|
data.put("id", requiredAction.getId());
|
||||||
|
adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo).representation(data).success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -850,6 +880,8 @@ public class AuthenticationManagementResource {
|
||||||
update.setEnabled(rep.isEnabled());
|
update.setEnabled(rep.isEnabled());
|
||||||
update.setConfig(rep.getConfig());
|
update.setConfig(rep.getConfig());
|
||||||
realm.updateRequiredActionProvider(update);
|
realm.updateRequiredActionProvider(update);
|
||||||
|
|
||||||
|
adminEvent.operation(OperationType.UPDATE).resourcePath(uriInfo).representation(rep).success();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -866,6 +898,8 @@ public class AuthenticationManagementResource {
|
||||||
throw new NotFoundException("Failed to find required action.");
|
throw new NotFoundException("Failed to find required action.");
|
||||||
}
|
}
|
||||||
realm.removeRequiredActionProvider(model);
|
realm.removeRequiredActionProvider(model);
|
||||||
|
|
||||||
|
adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).success();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -947,6 +981,7 @@ public class AuthenticationManagementResource {
|
||||||
auth.requireManage();
|
auth.requireManage();
|
||||||
|
|
||||||
AuthenticatorConfigModel config = realm.addAuthenticatorConfig(RepresentationToModel.toModel(rep));
|
AuthenticatorConfigModel config = realm.addAuthenticatorConfig(RepresentationToModel.toModel(rep));
|
||||||
|
adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo, config.getId()).representation(rep).success();
|
||||||
return Response.created(uriInfo.getAbsolutePathBuilder().path(config.getId()).build()).build();
|
return Response.created(uriInfo.getAbsolutePathBuilder().path(config.getId()).build()).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -995,6 +1030,8 @@ public class AuthenticationManagementResource {
|
||||||
}
|
}
|
||||||
|
|
||||||
realm.removeAuthenticatorConfig(config);
|
realm.removeAuthenticatorConfig(config);
|
||||||
|
|
||||||
|
adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).success();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1017,5 +1054,6 @@ public class AuthenticationManagementResource {
|
||||||
exists.setAlias(rep.getAlias());
|
exists.setAlias(rep.getAlias());
|
||||||
exists.setConfig(rep.getConfig());
|
exists.setConfig(rep.getConfig());
|
||||||
realm.updateAuthenticatorConfig(exists);
|
realm.updateAuthenticatorConfig(exists);
|
||||||
|
adminEvent.operation(OperationType.UPDATE).resourcePath(uriInfo).representation(rep).success();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -19,19 +19,26 @@ package org.keycloak.testsuite.admin.authentication;
|
||||||
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
import org.junit.Rule;
|
||||||
import org.keycloak.admin.client.resource.AuthenticationManagementResource;
|
import org.keycloak.admin.client.resource.AuthenticationManagementResource;
|
||||||
import org.keycloak.admin.client.resource.RealmResource;
|
import org.keycloak.admin.client.resource.RealmResource;
|
||||||
|
import org.keycloak.events.admin.OperationType;
|
||||||
import org.keycloak.representations.idm.AuthenticationExecutionExportRepresentation;
|
import org.keycloak.representations.idm.AuthenticationExecutionExportRepresentation;
|
||||||
import org.keycloak.representations.idm.AuthenticationExecutionInfoRepresentation;
|
import org.keycloak.representations.idm.AuthenticationExecutionInfoRepresentation;
|
||||||
import org.keycloak.representations.idm.AuthenticationFlowRepresentation;
|
import org.keycloak.representations.idm.AuthenticationFlowRepresentation;
|
||||||
import org.keycloak.representations.idm.AuthenticatorConfigRepresentation;
|
import org.keycloak.representations.idm.AuthenticatorConfigRepresentation;
|
||||||
import org.keycloak.representations.idm.RealmRepresentation;
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
import org.keycloak.testsuite.AbstractKeycloakTest;
|
import org.keycloak.testsuite.AbstractKeycloakTest;
|
||||||
|
import org.keycloak.testsuite.util.AdminEventPaths;
|
||||||
|
import org.keycloak.testsuite.util.AssertAdminEvents;
|
||||||
|
import org.keycloak.testsuite.util.RealmBuilder;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:mstrukel@redhat.com">Marko Strukelj</a>
|
* @author <a href="mailto:mstrukel@redhat.com">Marko Strukelj</a>
|
||||||
|
@ -48,6 +55,9 @@ public abstract class AbstractAuthenticationTest extends AbstractKeycloakTest {
|
||||||
RealmResource realmResource;
|
RealmResource realmResource;
|
||||||
AuthenticationManagementResource authMgmtResource;
|
AuthenticationManagementResource authMgmtResource;
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public AssertAdminEvents assertAdminEvents = new AssertAdminEvents(this);
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void before() {
|
public void before() {
|
||||||
realmResource = adminClient.realms().realm(REALM_NAME);
|
realmResource = adminClient.realms().realm(REALM_NAME);
|
||||||
|
@ -56,9 +66,8 @@ public abstract class AbstractAuthenticationTest extends AbstractKeycloakTest {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addTestRealms(List<RealmRepresentation> testRealms) {
|
public void addTestRealms(List<RealmRepresentation> testRealms) {
|
||||||
RealmRepresentation testRealmRep = new RealmRepresentation();
|
RealmRepresentation testRealmRep = RealmBuilder.create().name(REALM_NAME).testEventListener().build();
|
||||||
testRealmRep.setRealm(REALM_NAME);
|
testRealmRep.setId(REALM_NAME);
|
||||||
testRealmRep.setEnabled(true);
|
|
||||||
testRealms.add(testRealmRep);
|
testRealms.add(testRealmRep);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,4 +191,11 @@ public abstract class AbstractAuthenticationTest extends AbstractKeycloakTest {
|
||||||
config.setConfig(params);
|
config.setConfig(params);
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void createFlow(AuthenticationFlowRepresentation flowRep) {
|
||||||
|
Response response = authMgmtResource.createFlow(flowRep);
|
||||||
|
org.keycloak.testsuite.Assert.assertEquals(201, response.getStatus());
|
||||||
|
response.close();
|
||||||
|
assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AssertAdminEvents.isExpectedPrefixFollowedByUuid(AdminEventPaths.authFlowsPath()), flowRep);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,11 +28,14 @@ import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.keycloak.authentication.authenticators.broker.IdpCreateUserIfUniqueAuthenticator;
|
import org.keycloak.authentication.authenticators.broker.IdpCreateUserIfUniqueAuthenticator;
|
||||||
import org.keycloak.authentication.authenticators.broker.IdpCreateUserIfUniqueAuthenticatorFactory;
|
import org.keycloak.authentication.authenticators.broker.IdpCreateUserIfUniqueAuthenticatorFactory;
|
||||||
|
import org.keycloak.events.admin.OperationType;
|
||||||
import org.keycloak.representations.idm.AuthenticationExecutionInfoRepresentation;
|
import org.keycloak.representations.idm.AuthenticationExecutionInfoRepresentation;
|
||||||
import org.keycloak.representations.idm.AuthenticationFlowRepresentation;
|
import org.keycloak.representations.idm.AuthenticationFlowRepresentation;
|
||||||
import org.keycloak.representations.idm.AuthenticatorConfigRepresentation;
|
import org.keycloak.representations.idm.AuthenticatorConfigRepresentation;
|
||||||
import org.keycloak.testsuite.Assert;
|
import org.keycloak.testsuite.Assert;
|
||||||
import org.keycloak.testsuite.admin.ApiUtil;
|
import org.keycloak.testsuite.admin.ApiUtil;
|
||||||
|
import org.keycloak.testsuite.util.AdminEventPaths;
|
||||||
|
import org.keycloak.testsuite.util.AssertAdminEvents;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
@ -43,13 +46,13 @@ public class AuthenticatorConfigTest extends AbstractAuthenticationTest {
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void beforeConfigTest() {
|
public void beforeConfigTest() {
|
||||||
Response response = authMgmtResource.createFlow(newFlow("firstBrokerLogin2", "firstBrokerLogin2", "basic-flow", true, false));
|
AuthenticationFlowRepresentation flowRep = newFlow("firstBrokerLogin2", "firstBrokerLogin2", "basic-flow", true, false);
|
||||||
Assert.assertEquals(201, response.getStatus());
|
createFlow(flowRep);
|
||||||
response.close();
|
|
||||||
|
|
||||||
HashMap<String, String> params = new HashMap<>();
|
HashMap<String, String> params = new HashMap<>();
|
||||||
params.put("provider", IdpCreateUserIfUniqueAuthenticatorFactory.PROVIDER_ID);
|
params.put("provider", IdpCreateUserIfUniqueAuthenticatorFactory.PROVIDER_ID);
|
||||||
authMgmtResource.addExecution("firstBrokerLogin2", params);
|
authMgmtResource.addExecution("firstBrokerLogin2", params);
|
||||||
|
assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authAddExecutionPath("firstBrokerLogin2"), params);
|
||||||
|
|
||||||
List<AuthenticationExecutionInfoRepresentation> executionReps = authMgmtResource.getExecutions("firstBrokerLogin2");
|
List<AuthenticationExecutionInfoRepresentation> executionReps = authMgmtResource.getExecutions("firstBrokerLogin2");
|
||||||
AuthenticationExecutionInfoRepresentation exec = findExecutionByProvider(IdpCreateUserIfUniqueAuthenticatorFactory.PROVIDER_ID, executionReps);
|
AuthenticationExecutionInfoRepresentation exec = findExecutionByProvider(IdpCreateUserIfUniqueAuthenticatorFactory.PROVIDER_ID, executionReps);
|
||||||
|
@ -57,12 +60,6 @@ public class AuthenticatorConfigTest extends AbstractAuthenticationTest {
|
||||||
executionId = exec.getId();
|
executionId = exec.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void afterAbstractKeycloakTest() {
|
|
||||||
AuthenticationFlowRepresentation flowRep = findFlowByAlias("firstBrokerLogin2", authMgmtResource.getFlows());
|
|
||||||
authMgmtResource.deleteFlow(flowRep.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateConfig() {
|
public void testCreateConfig() {
|
||||||
|
@ -82,6 +79,7 @@ public class AuthenticatorConfigTest extends AbstractAuthenticationTest {
|
||||||
|
|
||||||
// Cleanup
|
// Cleanup
|
||||||
authMgmtResource.removeAuthenticatorConfig(cfgId);
|
authMgmtResource.removeAuthenticatorConfig(cfgId);
|
||||||
|
assertAdminEvents.assertEvent(REALM_NAME, OperationType.DELETE, AdminEventPaths.authExecutionConfigPath(cfgId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -107,6 +105,7 @@ public class AuthenticatorConfigTest extends AbstractAuthenticationTest {
|
||||||
cfgRep.setAlias("foo2");
|
cfgRep.setAlias("foo2");
|
||||||
cfgRep.getConfig().put("configKey2", "configValue2");
|
cfgRep.getConfig().put("configKey2", "configValue2");
|
||||||
authMgmtResource.updateAuthenticatorConfig(cfgRep.getId(), cfgRep);
|
authMgmtResource.updateAuthenticatorConfig(cfgRep.getId(), cfgRep);
|
||||||
|
assertAdminEvents.assertEvent(REALM_NAME, OperationType.UPDATE, AdminEventPaths.authExecutionConfigPath(cfgId), cfgRep);
|
||||||
|
|
||||||
// Assert updated
|
// Assert updated
|
||||||
cfgRep = authMgmtResource.getAuthenticatorConfig(cfgRep.getId());
|
cfgRep = authMgmtResource.getAuthenticatorConfig(cfgRep.getId());
|
||||||
|
@ -137,7 +136,8 @@ public class AuthenticatorConfigTest extends AbstractAuthenticationTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test remove our config
|
// Test remove our config
|
||||||
authMgmtResource.removeAuthenticatorConfig(cfgRep.getId());
|
authMgmtResource.removeAuthenticatorConfig(cfgId);
|
||||||
|
assertAdminEvents.assertEvent(REALM_NAME, OperationType.DELETE, AdminEventPaths.authExecutionConfigPath(cfgId));
|
||||||
|
|
||||||
// Assert config not found
|
// Assert config not found
|
||||||
try {
|
try {
|
||||||
|
@ -159,6 +159,7 @@ public class AuthenticatorConfigTest extends AbstractAuthenticationTest {
|
||||||
Assert.assertEquals(201, resp.getStatus());
|
Assert.assertEquals(201, resp.getStatus());
|
||||||
String cfgId = ApiUtil.getCreatedId(resp);
|
String cfgId = ApiUtil.getCreatedId(resp);
|
||||||
Assert.assertNotNull(cfgId);
|
Assert.assertNotNull(cfgId);
|
||||||
|
assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authAddExecutionConfigPath(executionId), cfg);
|
||||||
return cfgId;
|
return cfgId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,10 +21,12 @@ import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.keycloak.authentication.AuthenticationFlow;
|
import org.keycloak.authentication.AuthenticationFlow;
|
||||||
import org.keycloak.authentication.authenticators.client.ClientIdAndSecretAuthenticator;
|
import org.keycloak.authentication.authenticators.client.ClientIdAndSecretAuthenticator;
|
||||||
import org.keycloak.models.AuthenticationExecutionModel;
|
import org.keycloak.events.admin.OperationType;
|
||||||
import org.keycloak.representations.idm.AuthenticationExecutionInfoRepresentation;
|
import org.keycloak.representations.idm.AuthenticationExecutionInfoRepresentation;
|
||||||
import org.keycloak.representations.idm.AuthenticationExecutionRepresentation;
|
import org.keycloak.representations.idm.AuthenticationExecutionRepresentation;
|
||||||
import org.keycloak.representations.idm.AuthenticationFlowRepresentation;
|
import org.keycloak.representations.idm.AuthenticationFlowRepresentation;
|
||||||
|
import org.keycloak.testsuite.util.AdminEventPaths;
|
||||||
|
import org.keycloak.testsuite.util.AssertAdminEvents;
|
||||||
|
|
||||||
import javax.ws.rs.BadRequestException;
|
import javax.ws.rs.BadRequestException;
|
||||||
import javax.ws.rs.NotFoundException;
|
import javax.ws.rs.NotFoundException;
|
||||||
|
@ -60,8 +62,9 @@ public class ExecutionTest extends AbstractAuthenticationTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy built-in flow so we get a new editable flow
|
// copy built-in flow so we get a new editable flow
|
||||||
params.put("newName", "Copy of browser");
|
params.put("newName", "Copy-of-browser");
|
||||||
Response response = authMgmtResource.copy("browser", params);
|
Response response = authMgmtResource.copy("browser", params);
|
||||||
|
assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authCopyFlowPath("browser"), params);
|
||||||
try {
|
try {
|
||||||
Assert.assertEquals("Copy flow", 201, response.getStatus());
|
Assert.assertEquals("Copy flow", 201, response.getStatus());
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -71,17 +74,19 @@ public class ExecutionTest extends AbstractAuthenticationTest {
|
||||||
// add execution using inexistent provider
|
// add execution using inexistent provider
|
||||||
params.put("provider", "test-execution");
|
params.put("provider", "test-execution");
|
||||||
try {
|
try {
|
||||||
authMgmtResource.addExecution("Copy of browser", params);
|
authMgmtResource.addExecution("CopyOfBrowser", params);
|
||||||
Assert.fail("add execution with inexistent provider should fail");
|
Assert.fail("add execution with inexistent provider should fail");
|
||||||
} catch(BadRequestException expected) {
|
} catch(BadRequestException expected) {
|
||||||
|
// Expected
|
||||||
}
|
}
|
||||||
|
|
||||||
// add execution - should succeed
|
// add execution - should succeed
|
||||||
params.put("provider", "idp-review-profile");
|
params.put("provider", "idp-review-profile");
|
||||||
authMgmtResource.addExecution("Copy of browser", params);
|
authMgmtResource.addExecution("Copy-of-browser", params);
|
||||||
|
assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authAddExecutionPath("Copy-of-browser"), params);
|
||||||
|
|
||||||
// check execution was added
|
// check execution was added
|
||||||
List<AuthenticationExecutionInfoRepresentation> executionReps = authMgmtResource.getExecutions("Copy of browser");
|
List<AuthenticationExecutionInfoRepresentation> executionReps = authMgmtResource.getExecutions("Copy-of-browser");
|
||||||
AuthenticationExecutionInfoRepresentation exec = findExecutionByProvider("idp-review-profile", executionReps);
|
AuthenticationExecutionInfoRepresentation exec = findExecutionByProvider("idp-review-profile", executionReps);
|
||||||
Assert.assertNotNull("idp-review-profile added", exec);
|
Assert.assertNotNull("idp-review-profile added", exec);
|
||||||
|
|
||||||
|
@ -92,9 +97,10 @@ public class ExecutionTest extends AbstractAuthenticationTest {
|
||||||
|
|
||||||
// remove execution
|
// remove execution
|
||||||
authMgmtResource.removeExecution(exec.getId());
|
authMgmtResource.removeExecution(exec.getId());
|
||||||
|
assertAdminEvents.assertEvent(REALM_NAME, OperationType.DELETE, AdminEventPaths.authExecutionPath(exec.getId()));
|
||||||
|
|
||||||
// check execution was removed
|
// check execution was removed
|
||||||
executionReps = authMgmtResource.getExecutions("Copy of browser");
|
executionReps = authMgmtResource.getExecutions("Copy-of-browser");
|
||||||
exec = findExecutionByProvider("idp-review-profile", executionReps);
|
exec = findExecutionByProvider("idp-review-profile", executionReps);
|
||||||
Assert.assertNull("idp-review-profile removed", exec);
|
Assert.assertNull("idp-review-profile removed", exec);
|
||||||
|
|
||||||
|
@ -102,6 +108,7 @@ public class ExecutionTest extends AbstractAuthenticationTest {
|
||||||
|
|
||||||
// delete auth-cookie
|
// delete auth-cookie
|
||||||
authMgmtResource.removeExecution(authCookieExec.getId());
|
authMgmtResource.removeExecution(authCookieExec.getId());
|
||||||
|
assertAdminEvents.assertEvent(REALM_NAME, OperationType.DELETE, AdminEventPaths.authExecutionPath(authCookieExec.getId()));
|
||||||
|
|
||||||
AuthenticationExecutionRepresentation rep = new AuthenticationExecutionRepresentation();
|
AuthenticationExecutionRepresentation rep = new AuthenticationExecutionRepresentation();
|
||||||
rep.setPriority(10);
|
rep.setPriority(10);
|
||||||
|
@ -135,13 +142,14 @@ public class ExecutionTest extends AbstractAuthenticationTest {
|
||||||
response.close();
|
response.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
// get Copy of browser flow id, and set it on execution
|
// get Copy-of-browser flow id, and set it on execution
|
||||||
List<AuthenticationFlowRepresentation> flows = authMgmtResource.getFlows();
|
List<AuthenticationFlowRepresentation> flows = authMgmtResource.getFlows();
|
||||||
AuthenticationFlowRepresentation flow = findFlowByAlias("Copy of browser", flows);
|
AuthenticationFlowRepresentation flow = findFlowByAlias("Copy-of-browser", flows);
|
||||||
rep.setParentFlow(flow.getId());
|
rep.setParentFlow(flow.getId());
|
||||||
|
|
||||||
// add execution - should succeed
|
// add execution - should succeed
|
||||||
response = authMgmtResource.addExecution(rep);
|
response = authMgmtResource.addExecution(rep);
|
||||||
|
assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AssertAdminEvents.isExpectedPrefixFollowedByUuid(AdminEventPaths.authMgmtBasePath() + "/executions"), rep);
|
||||||
try {
|
try {
|
||||||
Assert.assertEquals("added execution", 201, response.getStatus());
|
Assert.assertEquals("added execution", 201, response.getStatus());
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -149,7 +157,7 @@ public class ExecutionTest extends AbstractAuthenticationTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
// check execution was added
|
// check execution was added
|
||||||
List<AuthenticationExecutionInfoRepresentation> executions = authMgmtResource.getExecutions("Copy of browser");
|
List<AuthenticationExecutionInfoRepresentation> executions = authMgmtResource.getExecutions("Copy-of-browser");
|
||||||
exec = findExecutionByProvider("auth-cookie", executions);
|
exec = findExecutionByProvider("auth-cookie", executions);
|
||||||
Assert.assertNotNull("auth-cookie added", exec);
|
Assert.assertNotNull("auth-cookie added", exec);
|
||||||
|
|
||||||
|
@ -170,6 +178,7 @@ public class ExecutionTest extends AbstractAuthenticationTest {
|
||||||
// switch from DISABLED to ALTERNATIVE
|
// switch from DISABLED to ALTERNATIVE
|
||||||
exec.setRequirement(DISABLED);
|
exec.setRequirement(DISABLED);
|
||||||
authMgmtResource.updateExecutions("browser", exec);
|
authMgmtResource.updateExecutions("browser", exec);
|
||||||
|
assertAdminEvents.assertEvent(REALM_NAME, OperationType.UPDATE, AdminEventPaths.authUpdateExecutionPath("browser"), exec);
|
||||||
|
|
||||||
// make sure the change is visible
|
// make sure the change is visible
|
||||||
executionReps = authMgmtResource.getExecutions("browser");
|
executionReps = authMgmtResource.getExecutions("browser");
|
||||||
|
@ -183,14 +192,13 @@ public class ExecutionTest extends AbstractAuthenticationTest {
|
||||||
public void testClientFlowExecutions() {
|
public void testClientFlowExecutions() {
|
||||||
// Create client flow
|
// Create client flow
|
||||||
AuthenticationFlowRepresentation clientFlow = newFlow("new-client-flow", "desc", AuthenticationFlow.CLIENT_FLOW, true, false);
|
AuthenticationFlowRepresentation clientFlow = newFlow("new-client-flow", "desc", AuthenticationFlow.CLIENT_FLOW, true, false);
|
||||||
Response response = authMgmtResource.createFlow(clientFlow);
|
createFlow(clientFlow);
|
||||||
Assert.assertEquals(201, response.getStatus());
|
|
||||||
response.close();
|
|
||||||
|
|
||||||
// Add execution to it
|
// Add execution to it
|
||||||
Map<String, String> executionData = new HashMap<>();
|
Map<String, String> executionData = new HashMap<>();
|
||||||
executionData.put("provider", ClientIdAndSecretAuthenticator.PROVIDER_ID);
|
executionData.put("provider", ClientIdAndSecretAuthenticator.PROVIDER_ID);
|
||||||
authMgmtResource.addExecution("new-client-flow", executionData);
|
authMgmtResource.addExecution("new-client-flow", executionData);
|
||||||
|
assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authAddExecutionPath("new-client-flow"), executionData);
|
||||||
|
|
||||||
// Check executions of not-existent flow - SHOULD FAIL
|
// Check executions of not-existent flow - SHOULD FAIL
|
||||||
try {
|
try {
|
||||||
|
@ -226,6 +234,7 @@ public class ExecutionTest extends AbstractAuthenticationTest {
|
||||||
// Update success
|
// Update success
|
||||||
executionRep.setRequirement(ALTERNATIVE);
|
executionRep.setRequirement(ALTERNATIVE);
|
||||||
authMgmtResource.updateExecutions("new-client-flow", executionRep);
|
authMgmtResource.updateExecutions("new-client-flow", executionRep);
|
||||||
|
assertAdminEvents.assertEvent(REALM_NAME, OperationType.UPDATE, AdminEventPaths.authUpdateExecutionPath("new-client-flow"), executionRep);
|
||||||
|
|
||||||
// Check updated
|
// Check updated
|
||||||
executionRep = findExecutionByProvider(ClientIdAndSecretAuthenticator.PROVIDER_ID, authMgmtResource.getExecutions("new-client-flow"));
|
executionRep = findExecutionByProvider(ClientIdAndSecretAuthenticator.PROVIDER_ID, authMgmtResource.getExecutions("new-client-flow"));
|
||||||
|
@ -241,7 +250,10 @@ public class ExecutionTest extends AbstractAuthenticationTest {
|
||||||
|
|
||||||
// Successfuly remove execution and flow
|
// Successfuly remove execution and flow
|
||||||
authMgmtResource.removeExecution(executionRep.getId());
|
authMgmtResource.removeExecution(executionRep.getId());
|
||||||
|
assertAdminEvents.assertEvent(REALM_NAME, OperationType.DELETE, AdminEventPaths.authExecutionPath(executionRep.getId()));
|
||||||
|
|
||||||
AuthenticationFlowRepresentation rep = findFlowByAlias("new-client-flow", authMgmtResource.getFlows());
|
AuthenticationFlowRepresentation rep = findFlowByAlias("new-client-flow", authMgmtResource.getFlows());
|
||||||
authMgmtResource.deleteFlow(rep.getId());
|
authMgmtResource.deleteFlow(rep.getId());
|
||||||
|
assertAdminEvents.assertEvent(REALM_NAME, OperationType.DELETE, AdminEventPaths.authFlowPath(rep.getId()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,8 +19,10 @@ package org.keycloak.testsuite.admin.authentication;
|
||||||
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.keycloak.events.admin.OperationType;
|
||||||
import org.keycloak.representations.idm.AuthenticationExecutionExportRepresentation;
|
import org.keycloak.representations.idm.AuthenticationExecutionExportRepresentation;
|
||||||
import org.keycloak.representations.idm.AuthenticationFlowRepresentation;
|
import org.keycloak.representations.idm.AuthenticationFlowRepresentation;
|
||||||
|
import org.keycloak.testsuite.util.AdminEventPaths;
|
||||||
|
|
||||||
import javax.ws.rs.BadRequestException;
|
import javax.ws.rs.BadRequestException;
|
||||||
import javax.ws.rs.NotFoundException;
|
import javax.ws.rs.NotFoundException;
|
||||||
|
@ -67,12 +69,7 @@ public class FlowTest extends AbstractAuthenticationTest {
|
||||||
|
|
||||||
// create new flow that should succeed
|
// create new flow that should succeed
|
||||||
AuthenticationFlowRepresentation newFlow = newFlow("browser-2", "Browser flow", "basic-flow", true, false);
|
AuthenticationFlowRepresentation newFlow = newFlow("browser-2", "Browser flow", "basic-flow", true, false);
|
||||||
response = authMgmtResource.createFlow(newFlow);
|
createFlow(newFlow);
|
||||||
try {
|
|
||||||
Assert.assertEquals("createFlow success", 201, response.getStatus());
|
|
||||||
} finally {
|
|
||||||
response.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
// check that new flow is returned in a children list
|
// check that new flow is returned in a children list
|
||||||
flows = authMgmtResource.getFlows();
|
flows = authMgmtResource.getFlows();
|
||||||
|
@ -122,6 +119,7 @@ public class FlowTest extends AbstractAuthenticationTest {
|
||||||
// Successfully add flow
|
// Successfully add flow
|
||||||
data.put("alias", "SomeFlow");
|
data.put("alias", "SomeFlow");
|
||||||
authMgmtResource.addExecutionFlow("browser-2", data);
|
authMgmtResource.addExecutionFlow("browser-2", data);
|
||||||
|
assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authAddExecutionFlowPath("browser-2"), data);
|
||||||
|
|
||||||
// check that new flow is returned in a children list
|
// check that new flow is returned in a children list
|
||||||
flows = authMgmtResource.getFlows();
|
flows = authMgmtResource.getFlows();
|
||||||
|
@ -143,6 +141,7 @@ public class FlowTest extends AbstractAuthenticationTest {
|
||||||
|
|
||||||
// delete non-built-in flow
|
// delete non-built-in flow
|
||||||
authMgmtResource.deleteFlow(found.getId());
|
authMgmtResource.deleteFlow(found.getId());
|
||||||
|
assertAdminEvents.assertEvent(REALM_NAME, OperationType.DELETE, AdminEventPaths.authFlowPath(found.getId()));
|
||||||
|
|
||||||
// check the deleted flow is no longer returned
|
// check the deleted flow is no longer returned
|
||||||
flows = authMgmtResource.getFlows();
|
flows = authMgmtResource.getFlows();
|
||||||
|
@ -185,6 +184,7 @@ public class FlowTest extends AbstractAuthenticationTest {
|
||||||
// copy that should succeed
|
// copy that should succeed
|
||||||
params.put("newName", "Copy of browser");
|
params.put("newName", "Copy of browser");
|
||||||
response = authMgmtResource.copy("browser", params);
|
response = authMgmtResource.copy("browser", params);
|
||||||
|
assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authCopyFlowPath("browser"), params);
|
||||||
try {
|
try {
|
||||||
Assert.assertEquals("Copy flow", 201, response.getStatus());
|
Assert.assertEquals("Copy flow", 201, response.getStatus());
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -219,6 +219,7 @@ public class FlowTest extends AbstractAuthenticationTest {
|
||||||
Response response = authMgmtResource.copy("browser", params);
|
Response response = authMgmtResource.copy("browser", params);
|
||||||
Assert.assertEquals(201, response.getStatus());
|
Assert.assertEquals(201, response.getStatus());
|
||||||
response.close();
|
response.close();
|
||||||
|
assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authCopyFlowPath("browser"), params);
|
||||||
|
|
||||||
params = new HashMap<>();
|
params = new HashMap<>();
|
||||||
params.put("alias", "child");
|
params.put("alias", "child");
|
||||||
|
@ -227,6 +228,7 @@ public class FlowTest extends AbstractAuthenticationTest {
|
||||||
params.put("type", "basic-flow");
|
params.put("type", "basic-flow");
|
||||||
|
|
||||||
authMgmtResource.addExecutionFlow("parent", params);
|
authMgmtResource.addExecutionFlow("parent", params);
|
||||||
|
assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authAddExecutionFlowPath("parent"), params);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,9 @@ import javax.ws.rs.core.Response;
|
||||||
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.keycloak.events.admin.OperationType;
|
||||||
|
import org.keycloak.representations.idm.AuthenticationFlowRepresentation;
|
||||||
|
import org.keycloak.testsuite.util.AdminEventPaths;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
@ -34,13 +37,8 @@ public class RegistrationFlowTest extends AbstractAuthenticationTest {
|
||||||
@Test
|
@Test
|
||||||
public void testAddExecution() {
|
public void testAddExecution() {
|
||||||
// Add registration flow 2
|
// Add registration flow 2
|
||||||
Response response = authMgmtResource.createFlow(newFlow("registration2", "RegistrationFlow2", "basic-flow", true, false));
|
AuthenticationFlowRepresentation flowRep = newFlow("registration2", "RegistrationFlow2", "basic-flow", true, false);
|
||||||
try {
|
createFlow(flowRep);
|
||||||
Assert.assertEquals("createFlow success", 201, response.getStatus());
|
|
||||||
} finally {
|
|
||||||
response.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// add registration execution form flow
|
// add registration execution form flow
|
||||||
Map<String, String> data = new HashMap<>();
|
Map<String, String> data = new HashMap<>();
|
||||||
|
@ -49,6 +47,7 @@ public class RegistrationFlowTest extends AbstractAuthenticationTest {
|
||||||
data.put("description", "registrationForm2 flow");
|
data.put("description", "registrationForm2 flow");
|
||||||
data.put("provider", "registration-page-form");
|
data.put("provider", "registration-page-form");
|
||||||
authMgmtResource.addExecutionFlow("registration2", data);
|
authMgmtResource.addExecutionFlow("registration2", data);
|
||||||
|
assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authAddExecutionFlowPath("registration2"), data);
|
||||||
|
|
||||||
// Should fail to add execution under top level flow
|
// Should fail to add execution under top level flow
|
||||||
Map<String, String> data2 = new HashMap<>();
|
Map<String, String> data2 = new HashMap<>();
|
||||||
|
@ -63,9 +62,9 @@ public class RegistrationFlowTest extends AbstractAuthenticationTest {
|
||||||
|
|
||||||
// Should success to add execution under form flow
|
// Should success to add execution under form flow
|
||||||
authMgmtResource.addExecution("registrationForm2", data2);
|
authMgmtResource.addExecution("registrationForm2", data2);
|
||||||
|
assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authAddExecutionPath("registrationForm2"), data2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: More coverage... And hopefully more type-safety instead of passing generic maps
|
// TODO: More type-safety instead of passing generic maps
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,9 +19,11 @@ package org.keycloak.testsuite.admin.authentication;
|
||||||
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.keycloak.events.admin.OperationType;
|
||||||
import org.keycloak.representations.idm.RequiredActionProviderRepresentation;
|
import org.keycloak.representations.idm.RequiredActionProviderRepresentation;
|
||||||
import org.keycloak.representations.idm.RequiredActionProviderSimpleRepresentation;
|
import org.keycloak.representations.idm.RequiredActionProviderSimpleRepresentation;
|
||||||
import org.keycloak.testsuite.actions.DummyRequiredActionFactory;
|
import org.keycloak.testsuite.actions.DummyRequiredActionFactory;
|
||||||
|
import org.keycloak.testsuite.util.AdminEventPaths;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -59,6 +61,7 @@ public class RequiredActionsTest extends AbstractAuthenticationTest {
|
||||||
|
|
||||||
forUpdate.setConfig(Collections.<String, String>emptyMap());
|
forUpdate.setConfig(Collections.<String, String>emptyMap());
|
||||||
authMgmtResource.updateRequiredAction(forUpdate.getAlias(), forUpdate);
|
authMgmtResource.updateRequiredAction(forUpdate.getAlias(), forUpdate);
|
||||||
|
assertAdminEvents.assertEvent(REALM_NAME, OperationType.UPDATE, AdminEventPaths.authRequiredActionPath(forUpdate.getAlias()));
|
||||||
|
|
||||||
result = authMgmtResource.getRequiredActions();
|
result = authMgmtResource.getRequiredActions();
|
||||||
RequiredActionProviderRepresentation updated = findRequiredActionByAlias(forUpdate.getAlias(), result);
|
RequiredActionProviderRepresentation updated = findRequiredActionByAlias(forUpdate.getAlias(), result);
|
||||||
|
@ -78,6 +81,7 @@ public class RequiredActionsTest extends AbstractAuthenticationTest {
|
||||||
|
|
||||||
// Register it
|
// Register it
|
||||||
authMgmtResource.registerRequiredAction(action);
|
authMgmtResource.registerRequiredAction(action);
|
||||||
|
assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authMgmtBasePath() + "/register-required-action", action);
|
||||||
|
|
||||||
// Try to find not-existent action - should fail
|
// Try to find not-existent action - should fail
|
||||||
try {
|
try {
|
||||||
|
@ -103,6 +107,7 @@ public class RequiredActionsTest extends AbstractAuthenticationTest {
|
||||||
// Update (set it as defaultAction)
|
// Update (set it as defaultAction)
|
||||||
rep.setDefaultAction(true);
|
rep.setDefaultAction(true);
|
||||||
authMgmtResource.updateRequiredAction(DummyRequiredActionFactory.PROVIDER_ID, rep);
|
authMgmtResource.updateRequiredAction(DummyRequiredActionFactory.PROVIDER_ID, rep);
|
||||||
|
assertAdminEvents.assertEvent(REALM_NAME, OperationType.UPDATE, AdminEventPaths.authRequiredActionPath(rep.getAlias()), rep);
|
||||||
compareRequiredAction(rep, newRequiredAction(DummyRequiredActionFactory.PROVIDER_ID, "Dummy Action",
|
compareRequiredAction(rep, newRequiredAction(DummyRequiredActionFactory.PROVIDER_ID, "Dummy Action",
|
||||||
true, true, Collections.emptyMap()));
|
true, true, Collections.emptyMap()));
|
||||||
|
|
||||||
|
@ -116,6 +121,7 @@ public class RequiredActionsTest extends AbstractAuthenticationTest {
|
||||||
|
|
||||||
// Remove success
|
// Remove success
|
||||||
authMgmtResource.removeRequiredAction(DummyRequiredActionFactory.PROVIDER_ID);
|
authMgmtResource.removeRequiredAction(DummyRequiredActionFactory.PROVIDER_ID);
|
||||||
|
assertAdminEvents.assertEvent(REALM_NAME, OperationType.DELETE, AdminEventPaths.authRequiredActionPath(rep.getAlias()));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,9 @@ package org.keycloak.testsuite.admin.authentication;
|
||||||
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.keycloak.events.admin.OperationType;
|
||||||
import org.keycloak.representations.idm.AuthenticationExecutionInfoRepresentation;
|
import org.keycloak.representations.idm.AuthenticationExecutionInfoRepresentation;
|
||||||
|
import org.keycloak.testsuite.util.AdminEventPaths;
|
||||||
|
|
||||||
import javax.ws.rs.NotFoundException;
|
import javax.ws.rs.NotFoundException;
|
||||||
import javax.ws.rs.BadRequestException;
|
import javax.ws.rs.BadRequestException;
|
||||||
|
@ -39,6 +41,7 @@ public class ShiftExecutionTest extends AbstractAuthenticationTest {
|
||||||
HashMap<String, String> params = new HashMap<>();
|
HashMap<String, String> params = new HashMap<>();
|
||||||
params.put("newName", "Copy of browser");
|
params.put("newName", "Copy of browser");
|
||||||
Response response = authMgmtResource.copy("browser", params);
|
Response response = authMgmtResource.copy("browser", params);
|
||||||
|
assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authCopyFlowPath("browser"), params);
|
||||||
try {
|
try {
|
||||||
Assert.assertEquals("Copy flow", 201, response.getStatus());
|
Assert.assertEquals("Copy flow", 201, response.getStatus());
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -61,6 +64,7 @@ public class ShiftExecutionTest extends AbstractAuthenticationTest {
|
||||||
|
|
||||||
// shift last execution up
|
// shift last execution up
|
||||||
authMgmtResource.raisePriority(last.getId());
|
authMgmtResource.raisePriority(last.getId());
|
||||||
|
assertAdminEvents.assertEvent(REALM_NAME, OperationType.UPDATE, AdminEventPaths.authRaiseExecutionPath(last.getId()));
|
||||||
|
|
||||||
List<AuthenticationExecutionInfoRepresentation> executions2 = authMgmtResource.getExecutions("Copy of browser");
|
List<AuthenticationExecutionInfoRepresentation> executions2 = authMgmtResource.getExecutions("Copy of browser");
|
||||||
|
|
||||||
|
@ -80,6 +84,7 @@ public class ShiftExecutionTest extends AbstractAuthenticationTest {
|
||||||
|
|
||||||
// shift one before last down
|
// shift one before last down
|
||||||
authMgmtResource.lowerPriority(oneButLast2.getId());
|
authMgmtResource.lowerPriority(oneButLast2.getId());
|
||||||
|
assertAdminEvents.assertEvent(REALM_NAME, OperationType.UPDATE, AdminEventPaths.authLowerExecutionPath(oneButLast2.getId()));
|
||||||
|
|
||||||
executions2 = authMgmtResource.getExecutions("Copy of browser");
|
executions2 = authMgmtResource.getExecutions("Copy of browser");
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ import java.net.URI;
|
||||||
|
|
||||||
import javax.ws.rs.core.UriBuilder;
|
import javax.ws.rs.core.UriBuilder;
|
||||||
|
|
||||||
|
import org.keycloak.admin.client.resource.AuthenticationManagementResource;
|
||||||
import org.keycloak.admin.client.resource.ClientAttributeCertificateResource;
|
import org.keycloak.admin.client.resource.ClientAttributeCertificateResource;
|
||||||
import org.keycloak.admin.client.resource.ClientInitialAccessResource;
|
import org.keycloak.admin.client.resource.ClientInitialAccessResource;
|
||||||
import org.keycloak.admin.client.resource.ClientResource;
|
import org.keycloak.admin.client.resource.ClientResource;
|
||||||
|
@ -353,4 +354,83 @@ public class AdminEventPaths {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// AUTHENTICATION FLOWS
|
||||||
|
|
||||||
|
public static String authMgmtBasePath() {
|
||||||
|
URI uri = UriBuilder.fromUri("").path(RealmResource.class, "flows")
|
||||||
|
.build();
|
||||||
|
return uri.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String authFlowsPath() {
|
||||||
|
URI uri = UriBuilder.fromUri(authMgmtBasePath()).path(AuthenticationManagementResource.class, "getFlows")
|
||||||
|
.build();
|
||||||
|
return uri.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String authFlowPath(String flowId) {
|
||||||
|
URI uri = UriBuilder.fromUri(authMgmtBasePath()).path(AuthenticationManagementResource.class, "getFlow")
|
||||||
|
.build(flowId);
|
||||||
|
return uri.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String authCopyFlowPath(String flowAlias) {
|
||||||
|
URI uri = UriBuilder.fromUri(authMgmtBasePath()).path(AuthenticationManagementResource.class, "copy")
|
||||||
|
.build(flowAlias);
|
||||||
|
return uri.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String authAddExecutionFlowPath(String flowAlias) {
|
||||||
|
URI uri = UriBuilder.fromUri(authMgmtBasePath()).path(AuthenticationManagementResource.class, "addExecutionFlow")
|
||||||
|
.build(flowAlias);
|
||||||
|
return uri.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String authAddExecutionPath(String flowAlias) {
|
||||||
|
return authFlowPath(flowAlias) + "/executions/execution";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String authUpdateExecutionPath(String flowAlias) {
|
||||||
|
URI uri = UriBuilder.fromUri(authMgmtBasePath()).path(AuthenticationManagementResource.class, "updateExecutions")
|
||||||
|
.build(flowAlias);
|
||||||
|
return uri.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String authExecutionPath(String executionId) {
|
||||||
|
URI uri = UriBuilder.fromUri(authMgmtBasePath()).path(AuthenticationManagementResource.class, "removeExecution")
|
||||||
|
.build(executionId);
|
||||||
|
return uri.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String authAddExecutionConfigPath(String executionId) {
|
||||||
|
URI uri = UriBuilder.fromUri(authMgmtBasePath()).path(AuthenticationManagementResource.class, "newExecutionConfig")
|
||||||
|
.build(executionId);
|
||||||
|
return uri.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String authExecutionConfigPath(String configId) {
|
||||||
|
URI uri = UriBuilder.fromUri(authMgmtBasePath()).path(AuthenticationManagementResource.class, "getAuthenticatorConfig")
|
||||||
|
.build(configId);
|
||||||
|
return uri.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String authRaiseExecutionPath(String executionId) {
|
||||||
|
URI uri = UriBuilder.fromUri(authMgmtBasePath()).path(AuthenticationManagementResource.class, "raisePriority")
|
||||||
|
.build(executionId);
|
||||||
|
return uri.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String authLowerExecutionPath(String executionId) {
|
||||||
|
URI uri = UriBuilder.fromUri(authMgmtBasePath()).path(AuthenticationManagementResource.class, "lowerPriority")
|
||||||
|
.build(executionId);
|
||||||
|
return uri.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String authRequiredActionPath(String requiredActionAlias) {
|
||||||
|
URI uri = UriBuilder.fromUri(authMgmtBasePath()).path(AuthenticationManagementResource.class, "getRequiredAction")
|
||||||
|
.build(requiredActionAlias);
|
||||||
|
return uri.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,11 +19,14 @@ package org.keycloak.testsuite.util;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
|
|
||||||
|
import org.hamcrest.Description;
|
||||||
import org.hamcrest.Matcher;
|
import org.hamcrest.Matcher;
|
||||||
import org.hamcrest.Matchers;
|
import org.hamcrest.Matchers;
|
||||||
|
import org.hamcrest.TypeSafeMatcher;
|
||||||
import org.junit.rules.TestRule;
|
import org.junit.rules.TestRule;
|
||||||
import org.junit.runners.model.Statement;
|
import org.junit.runners.model.Statement;
|
||||||
import org.keycloak.common.util.ObjectUtil;
|
import org.keycloak.common.util.ObjectUtil;
|
||||||
|
@ -205,12 +208,27 @@ public class AssertAdminEvents implements TestRule {
|
||||||
try {
|
try {
|
||||||
Object actualRep = JsonSerialization.readValue(actual.getRepresentation(), expectedRep.getClass());
|
Object actualRep = JsonSerialization.readValue(actual.getRepresentation(), expectedRep.getClass());
|
||||||
|
|
||||||
for (Method method : Reflections.getAllDeclaredMethods(expectedRep.getClass())) {
|
if (expectedRep instanceof Map) {
|
||||||
if (method.getName().startsWith("get") || method.getName().startsWith("is")) {
|
// Special comparing of representations of type map. All of "expected" must be available on "actual"
|
||||||
Object expectedValue = Reflections.invokeMethod(method, expectedRep);
|
Map<?, ?> expectedRepMap = (Map) expectedRep;
|
||||||
|
Map<?, ?> actualRepMap = (Map) actualRep;
|
||||||
|
|
||||||
|
for (Map.Entry entry : expectedRepMap.entrySet()) {
|
||||||
|
Object expectedValue = entry.getValue();
|
||||||
if (expectedValue != null) {
|
if (expectedValue != null) {
|
||||||
Object actualValue = Reflections.invokeMethod(method, actualRep);
|
Object actualValue = actualRepMap.get(entry.getKey());
|
||||||
Assert.assertEquals("Property " + method.getName() + " of representation not equal.", expectedValue, actualValue);
|
Assert.assertEquals("Map item with key '" + entry.getKey() + "' not equal.", expectedValue, actualValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Reflection-baseed comparing for other types
|
||||||
|
for (Method method : Reflections.getAllDeclaredMethods(expectedRep.getClass())) {
|
||||||
|
if (method.getName().startsWith("get") || method.getName().startsWith("is")) {
|
||||||
|
Object expectedValue = Reflections.invokeMethod(method, expectedRep);
|
||||||
|
if (expectedValue != null) {
|
||||||
|
Object actualValue = Reflections.invokeMethod(method, actualRep);
|
||||||
|
Assert.assertEquals("Property method '" + method.getName() + "' of representation not equal.", expectedValue, actualValue);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -241,5 +259,22 @@ public class AssertAdminEvents implements TestRule {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Matcher<String> isExpectedPrefixFollowedByUuid(final String prefix) {
|
||||||
|
return new TypeSafeMatcher<String>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean matchesSafely(String item) {
|
||||||
|
int expectedLength = prefix.length() + 1 + org.keycloak.models.utils.KeycloakModelUtils.generateId().length();
|
||||||
|
return item.startsWith(prefix) && expectedLength == item.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void describeTo(Description description) {
|
||||||
|
description.appendText("resourcePath in the format like \"" + prefix + "/<UUID>\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue