Added redirect uris to application
This commit is contained in:
parent
7966afb434
commit
79c1230a9d
12 changed files with 454 additions and 127 deletions
|
@ -20,6 +20,7 @@ public class ApplicationRepresentation {
|
||||||
protected List<RoleRepresentation> roles;
|
protected List<RoleRepresentation> roles;
|
||||||
protected List<UserRoleMappingRepresentation> roleMappings;
|
protected List<UserRoleMappingRepresentation> roleMappings;
|
||||||
protected List<ScopeMappingRepresentation> scopeMappings;
|
protected List<ScopeMappingRepresentation> scopeMappings;
|
||||||
|
protected List<String> redirectUris;
|
||||||
|
|
||||||
public String getSelf() {
|
public String getSelf() {
|
||||||
return self;
|
return self;
|
||||||
|
@ -146,4 +147,12 @@ public class ApplicationRepresentation {
|
||||||
public void setUseRealmMappings(boolean useRealmMappings) {
|
public void setUseRealmMappings(boolean useRealmMappings) {
|
||||||
this.useRealmMappings = useRealmMappings;
|
this.useRealmMappings = useRealmMappings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<String> getRedirectUris() {
|
||||||
|
return redirectUris;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRedirectUris(List<String> redirectUris) {
|
||||||
|
this.redirectUris = redirectUris;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,8 +12,7 @@
|
||||||
<#elseif section = "form">
|
<#elseif section = "form">
|
||||||
|
|
||||||
<p class="instruction">Something happened and we could not process your request.</p>
|
<p class="instruction">Something happened and we could not process your request.</p>
|
||||||
<p class="instruction second">${error.summary}</p>
|
<p id="error-summary" class="instruction second">${error.summary}</p>
|
||||||
<a href="saas-login.html" class="link-right">Go to the homepage »</a>
|
|
||||||
|
|
||||||
<#elseif section = "info" >
|
<#elseif section = "info" >
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,14 @@ public interface UserModel {
|
||||||
|
|
||||||
void removeRequiredAction(RequiredAction action);
|
void removeRequiredAction(RequiredAction action);
|
||||||
|
|
||||||
|
Set<String> getRedirectUris();
|
||||||
|
|
||||||
|
void setRedirectUris(Set<String> redirectUris);
|
||||||
|
|
||||||
|
void addRedirectUri(String redirectUri);
|
||||||
|
|
||||||
|
void removeRedirectUri(String redirectUri);
|
||||||
|
|
||||||
String getFirstName();
|
String getFirstName();
|
||||||
|
|
||||||
void setFirstName(String firstName);
|
void setFirstName(String firstName);
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
package org.keycloak.models.utils;
|
|
||||||
|
|
||||||
import java.lang.reflect.Array;
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
public class ArrayUtils {
|
|
||||||
|
|
||||||
public static <T> T[] add(T[] src, T o) {
|
|
||||||
T[] dst = Arrays.copyOf(src, src.length + 1);
|
|
||||||
dst[src.length] = o;
|
|
||||||
return dst;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> T[] remove(T[] src, T o) {
|
|
||||||
int l = Arrays.binarySearch(src, o);
|
|
||||||
if (l < 0) {
|
|
||||||
return src;
|
|
||||||
}
|
|
||||||
|
|
||||||
T[] dst = newInstance(o, src.length - 1);
|
|
||||||
System.arraycopy(src, 0, dst, 0, l);
|
|
||||||
System.arraycopy(src, l + 1, dst, l, dst.length - l);
|
|
||||||
return dst;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
private static <T extends Object> T[] newInstance(T type, int length) {
|
|
||||||
return (T[]) Array.newInstance(type.getClass(), length);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,6 +1,6 @@
|
||||||
package org.keycloak.models.picketlink;
|
package org.keycloak.models.picketlink;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.io.Serializable;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
@ -8,7 +8,6 @@ import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
import org.keycloak.models.utils.ArrayUtils;
|
|
||||||
import org.picketlink.idm.IdentityManager;
|
import org.picketlink.idm.IdentityManager;
|
||||||
import org.picketlink.idm.model.Attribute;
|
import org.picketlink.idm.model.Attribute;
|
||||||
import org.picketlink.idm.model.sample.User;
|
import org.picketlink.idm.model.sample.User;
|
||||||
|
@ -22,6 +21,8 @@ public class UserAdapter implements UserModel {
|
||||||
private static final String KEYCLOAK_TOTP_ATTR = "totpEnabled";
|
private static final String KEYCLOAK_TOTP_ATTR = "totpEnabled";
|
||||||
private static final String REQUIRED_ACTIONS_ATTR = "requiredActions";
|
private static final String REQUIRED_ACTIONS_ATTR = "requiredActions";
|
||||||
|
|
||||||
|
private static final String REDIRECT_URIS = "redirectUris";
|
||||||
|
|
||||||
protected User user;
|
protected User user;
|
||||||
protected IdentityManager idm;
|
protected IdentityManager idm;
|
||||||
|
|
||||||
|
@ -110,7 +111,8 @@ public class UserAdapter implements UserModel {
|
||||||
@Override
|
@Override
|
||||||
public String getAttribute(String name) {
|
public String getAttribute(String name) {
|
||||||
Attribute<String> attribute = user.getAttribute(name);
|
Attribute<String> attribute = user.getAttribute(name);
|
||||||
if (attribute == null || attribute.getValue() == null) return null;
|
if (attribute == null || attribute.getValue() == null)
|
||||||
|
return null;
|
||||||
return attribute.getValue().toString();
|
return attribute.getValue().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,73 +120,45 @@ public class UserAdapter implements UserModel {
|
||||||
public Map<String, String> getAttributes() {
|
public Map<String, String> getAttributes() {
|
||||||
Map<String, String> attributes = new HashMap<String, String>();
|
Map<String, String> attributes = new HashMap<String, String>();
|
||||||
for (Attribute<?> attribute : user.getAttributes()) {
|
for (Attribute<?> attribute : user.getAttributes()) {
|
||||||
if (attribute.getValue() != null) attributes.put(attribute.getName(), attribute.getValue().toString());
|
if (attribute.getValue() != null)
|
||||||
|
attributes.put(attribute.getName(), attribute.getValue().toString());
|
||||||
}
|
}
|
||||||
return attributes;
|
return attributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
private RequiredAction[] getRequiredActionsArray() {
|
|
||||||
Attribute<?> a = user.getAttribute(REQUIRED_ACTIONS_ATTR);
|
|
||||||
if (a == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Object o = a.getValue();
|
|
||||||
if (o instanceof RequiredAction) {
|
|
||||||
return new RequiredAction[] { (RequiredAction) o };
|
|
||||||
} else {
|
|
||||||
return (RequiredAction[]) o;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<RequiredAction> getRequiredActions() {
|
public Set<RequiredAction> getRequiredActions() {
|
||||||
RequiredAction[] actions = getRequiredActionsArray();
|
return getAttributeSet(REQUIRED_ACTIONS_ATTR);
|
||||||
if (actions == null) {
|
|
||||||
return Collections.emptySet();
|
|
||||||
} else {
|
|
||||||
Set<RequiredAction> s = new HashSet<RequiredAction>();
|
|
||||||
for (RequiredAction a : actions) {
|
|
||||||
s.add(a);
|
|
||||||
}
|
|
||||||
return Collections.unmodifiableSet(s);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addRequiredAction(RequiredAction action) {
|
public void addRequiredAction(RequiredAction action) {
|
||||||
RequiredAction[] actions = getRequiredActionsArray();
|
addToAttributeSet(REQUIRED_ACTIONS_ATTR, action);
|
||||||
if (actions == null) {
|
|
||||||
actions = new RequiredAction[] { action };
|
|
||||||
} else {
|
|
||||||
if (Arrays.binarySearch(actions, action) < 0) {
|
|
||||||
actions = ArrayUtils.add(actions, action);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Attribute<RequiredAction[]> a = new Attribute<RequiredAction[]>(REQUIRED_ACTIONS_ATTR, actions);
|
|
||||||
|
|
||||||
user.setAttribute(a);
|
|
||||||
idm.update(user);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeRequiredAction(RequiredAction action) {
|
public void removeRequiredAction(RequiredAction action) {
|
||||||
RequiredAction[] actions = getRequiredActionsArray();
|
removeFromAttributeSet(REQUIRED_ACTIONS_ATTR, action);
|
||||||
if (actions != null) {
|
}
|
||||||
if (Arrays.binarySearch(actions, action) >= 0) {
|
|
||||||
actions = ArrayUtils.remove(actions, action);
|
|
||||||
|
|
||||||
if (actions.length == 0) {
|
@Override
|
||||||
user.removeAttribute(REQUIRED_ACTIONS_ATTR);
|
public Set<String> getRedirectUris() {
|
||||||
} else {
|
return getAttributeSet(REDIRECT_URIS);
|
||||||
Attribute<RequiredAction[]> a = new Attribute<RequiredAction[]>(REQUIRED_ACTIONS_ATTR, actions);
|
}
|
||||||
user.setAttribute(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
idm.update(user);
|
@Override
|
||||||
}
|
public void setRedirectUris(Set<String> redirectUris) {
|
||||||
}
|
setAttributeSet(REDIRECT_URIS, redirectUris);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addRedirectUri(String redirectUri) {
|
||||||
|
addToAttributeSet(REDIRECT_URIS, redirectUri);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeRedirectUri(String redirectUri) {
|
||||||
|
removeFromAttributeSet(REDIRECT_URIS, redirectUri);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -199,4 +173,57 @@ public class UserAdapter implements UserModel {
|
||||||
idm.update(user);
|
idm.update(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private <T extends Serializable> Set<T> getAttributeSet(String name) {
|
||||||
|
Attribute<Serializable> a = user.getAttribute(name);
|
||||||
|
|
||||||
|
Set<Serializable> s = new HashSet<Serializable>();
|
||||||
|
|
||||||
|
if (a != null) {
|
||||||
|
Serializable o = a.getValue();
|
||||||
|
if (o instanceof Serializable[]) {
|
||||||
|
for (Serializable t : (Serializable[]) o) {
|
||||||
|
s.add(t);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
s.add(o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (Set<T>) s;
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T extends Serializable> void setAttributeSet(String name, Set<T> set) {
|
||||||
|
if (set.isEmpty()) {
|
||||||
|
user.removeAttribute(name);
|
||||||
|
} else {
|
||||||
|
user.setAttribute(new Attribute<Serializable[]>(name, set.toArray(new Serializable[set.size()])));
|
||||||
|
}
|
||||||
|
idm.update(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T extends Serializable> void addToAttributeSet(String name, T t) {
|
||||||
|
Set<Serializable> set = getAttributeSet(name);
|
||||||
|
if (set == null) {
|
||||||
|
set = new HashSet<Serializable>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (set.add(t)) {
|
||||||
|
setAttributeSet(name, set);
|
||||||
|
idm.update(user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T extends Serializable> void removeFromAttributeSet(String name, T t) {
|
||||||
|
Set<Serializable> set = getAttributeSet(name);
|
||||||
|
if (set == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (set.remove(t)) {
|
||||||
|
setAttributeSet(name, set);
|
||||||
|
idm.update(user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
package org.keycloak.services.managers;
|
package org.keycloak.services.managers;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.keycloak.models.*;
|
import org.keycloak.models.*;
|
||||||
import org.keycloak.representations.idm.*;
|
import org.keycloak.representations.idm.*;
|
||||||
|
|
||||||
|
@ -32,6 +37,12 @@ public class ApplicationManager {
|
||||||
realm.updateCredential(resourceUser, credential);
|
realm.updateCredential(resourceUser, credential);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (resourceRep.getRedirectUris() != null) {
|
||||||
|
for (String redirectUri : resourceRep.getRedirectUris()) {
|
||||||
|
resourceUser.addRedirectUri(redirectUri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
realm.grantRole(resourceUser, loginRole);
|
realm.grantRole(resourceUser, loginRole);
|
||||||
|
|
||||||
|
|
||||||
|
@ -82,6 +93,10 @@ public class ApplicationManager {
|
||||||
resource.setSurrogateAuthRequired(rep.isSurrogateAuthRequired());
|
resource.setSurrogateAuthRequired(rep.isSurrogateAuthRequired());
|
||||||
resource.updateApplication();
|
resource.updateApplication();
|
||||||
|
|
||||||
|
List<String> redirectUris = rep.getRedirectUris();
|
||||||
|
if (redirectUris != null) {
|
||||||
|
resource.getApplicationUser().setRedirectUris(new HashSet<String>(redirectUris));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ApplicationRepresentation toRepresentation(ApplicationModel applicationModel) {
|
public ApplicationRepresentation toRepresentation(ApplicationModel applicationModel) {
|
||||||
|
@ -92,6 +107,12 @@ public class ApplicationManager {
|
||||||
rep.setAdminUrl(applicationModel.getManagementUrl());
|
rep.setAdminUrl(applicationModel.getManagementUrl());
|
||||||
rep.setSurrogateAuthRequired(applicationModel.isSurrogateAuthRequired());
|
rep.setSurrogateAuthRequired(applicationModel.isSurrogateAuthRequired());
|
||||||
rep.setBaseUrl(applicationModel.getBaseUrl());
|
rep.setBaseUrl(applicationModel.getBaseUrl());
|
||||||
|
|
||||||
|
Set<String> redirectUris = applicationModel.getApplicationUser().getRedirectUris();
|
||||||
|
if (redirectUris != null) {
|
||||||
|
rep.setRedirectUris(new LinkedList<String>(redirectUris));
|
||||||
|
}
|
||||||
|
|
||||||
return rep;
|
return rep;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,6 +68,11 @@ public class OAuthFlows {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Response redirectAccessCode(AccessCodeEntry accessCode, String state, String redirect) {
|
public Response redirectAccessCode(AccessCodeEntry accessCode, String state, String redirect) {
|
||||||
|
Set<String> redirectUris = accessCode.getClient().getRedirectUris();
|
||||||
|
if (!redirectUris.isEmpty() && !redirectUris.contains(redirect)) {
|
||||||
|
return forwardToSecurityFailure("Invalid redirect_uri " + redirect);
|
||||||
|
}
|
||||||
|
|
||||||
String code = accessCode.getCode();
|
String code = accessCode.getCode();
|
||||||
UriBuilder redirectUri = UriBuilder.fromUri(redirect).queryParam("code", code);
|
UriBuilder redirectUri = UriBuilder.fromUri(redirect).queryParam("code", code);
|
||||||
log.info("redirectAccessCode: state: " + state);
|
log.info("redirectAccessCode: state: " + state);
|
||||||
|
|
|
@ -302,42 +302,4 @@ public class AdapterTest extends AbstractKeycloakTest {
|
||||||
Assert.assertEquals("user", role.getName());
|
Assert.assertEquals("user", role.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUserRequiredActions() throws Exception {
|
|
||||||
test1CreateRealm();
|
|
||||||
|
|
||||||
UserModel user = realmModel.addUser("bburke");
|
|
||||||
|
|
||||||
Assert.assertTrue(user.getRequiredActions().isEmpty());
|
|
||||||
|
|
||||||
user.addRequiredAction(UserModel.RequiredAction.CONFIGURE_TOTP);
|
|
||||||
user = realmModel.getUser("bburke");
|
|
||||||
|
|
||||||
Assert.assertEquals(1, user.getRequiredActions().size());
|
|
||||||
Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.CONFIGURE_TOTP));
|
|
||||||
|
|
||||||
user.addRequiredAction(UserModel.RequiredAction.CONFIGURE_TOTP);
|
|
||||||
user = realmModel.getUser("bburke");
|
|
||||||
|
|
||||||
Assert.assertEquals(1, user.getRequiredActions().size());
|
|
||||||
Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.CONFIGURE_TOTP));
|
|
||||||
|
|
||||||
user.addRequiredAction(UserModel.RequiredAction.VERIFY_EMAIL);
|
|
||||||
user = realmModel.getUser("bburke");
|
|
||||||
|
|
||||||
Assert.assertEquals(2, user.getRequiredActions().size());
|
|
||||||
Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.CONFIGURE_TOTP));
|
|
||||||
Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.VERIFY_EMAIL));
|
|
||||||
|
|
||||||
user.removeRequiredAction(UserModel.RequiredAction.CONFIGURE_TOTP);
|
|
||||||
user = realmModel.getUser("bburke");
|
|
||||||
|
|
||||||
Assert.assertEquals(1, user.getRequiredActions().size());
|
|
||||||
Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.VERIFY_EMAIL));
|
|
||||||
|
|
||||||
user.removeRequiredAction(UserModel.RequiredAction.VERIFY_EMAIL);
|
|
||||||
user = realmModel.getUser("bburke");
|
|
||||||
|
|
||||||
Assert.assertTrue(user.getRequiredActions().isEmpty());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,100 @@
|
||||||
|
package org.keycloak.test;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.keycloak.models.ApplicationModel;
|
||||||
|
import org.keycloak.models.KeycloakSession;
|
||||||
|
import org.keycloak.models.KeycloakSessionFactory;
|
||||||
|
import org.keycloak.models.RealmModel;
|
||||||
|
import org.keycloak.models.RoleModel;
|
||||||
|
import org.keycloak.models.UserModel;
|
||||||
|
import org.keycloak.representations.idm.ApplicationRepresentation;
|
||||||
|
import org.keycloak.services.managers.ApplicationManager;
|
||||||
|
import org.keycloak.services.managers.RealmManager;
|
||||||
|
import org.keycloak.services.resources.KeycloakApplication;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
|
*/
|
||||||
|
public class ApplicationModelTest extends AbstractKeycloakServerTest {
|
||||||
|
private KeycloakSessionFactory factory;
|
||||||
|
private KeycloakSession identitySession;
|
||||||
|
private RealmManager manager;
|
||||||
|
private ApplicationModel application;
|
||||||
|
private RealmModel realm;
|
||||||
|
private ApplicationManager appManager;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void before() throws Exception {
|
||||||
|
factory = KeycloakApplication.buildSessionFactory();
|
||||||
|
identitySession = factory.createSession();
|
||||||
|
identitySession.getTransaction().begin();
|
||||||
|
manager = new RealmManager(identitySession);
|
||||||
|
|
||||||
|
appManager = new ApplicationManager(manager);
|
||||||
|
|
||||||
|
realm = manager.createRealm("original");
|
||||||
|
application = realm.addApplication("application");
|
||||||
|
application.setBaseUrl("http://base");
|
||||||
|
application.setManagementUrl("http://management");
|
||||||
|
application.setName("app-name");
|
||||||
|
application.addRole("role-1");
|
||||||
|
application.addRole("role-2");
|
||||||
|
|
||||||
|
application.getApplicationUser().addRedirectUri("redirect-1");
|
||||||
|
application.getApplicationUser().addRedirectUri("redirect-2");
|
||||||
|
|
||||||
|
application.updateApplication();
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void after() throws Exception {
|
||||||
|
identitySession.getTransaction().commit();
|
||||||
|
identitySession.close();
|
||||||
|
factory.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void persist() {
|
||||||
|
RealmModel persisted = manager.getRealm(realm.getId());
|
||||||
|
|
||||||
|
assertEquals(application, persisted.getApplications().get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void json() {
|
||||||
|
ApplicationRepresentation representation = appManager.toRepresentation(application);
|
||||||
|
|
||||||
|
RealmModel realm = manager.createRealm("copy");
|
||||||
|
ApplicationModel copy = appManager.createApplication(realm, representation);
|
||||||
|
|
||||||
|
assertEquals(application, copy);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void assertEquals(ApplicationModel expected, ApplicationModel actual) {
|
||||||
|
Assert.assertEquals(expected.getName(), actual.getName());
|
||||||
|
Assert.assertEquals(expected.getBaseUrl(), actual.getBaseUrl());
|
||||||
|
Assert.assertEquals(expected.getManagementUrl(), actual.getManagementUrl());
|
||||||
|
|
||||||
|
UserModel auser = actual.getApplicationUser();
|
||||||
|
UserModel euser = expected.getApplicationUser();
|
||||||
|
|
||||||
|
Assert.assertTrue(euser.getRedirectUris().containsAll(auser.getRedirectUris()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void assertEquals(List<RoleModel> expected, List<RoleModel> actual) {
|
||||||
|
Assert.assertEquals(expected.size(), actual.size());
|
||||||
|
Iterator<RoleModel> exp = expected.iterator();
|
||||||
|
Iterator<RoleModel> act = actual.iterator();
|
||||||
|
while (exp.hasNext()) {
|
||||||
|
Assert.assertEquals(exp.next().getName(), act.next().getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
118
services/src/test/java/org/keycloak/test/UserModelTest.java
Normal file
118
services/src/test/java/org/keycloak/test/UserModelTest.java
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
package org.keycloak.test;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.keycloak.models.KeycloakSession;
|
||||||
|
import org.keycloak.models.KeycloakSessionFactory;
|
||||||
|
import org.keycloak.models.RealmModel;
|
||||||
|
import org.keycloak.models.RoleModel;
|
||||||
|
import org.keycloak.models.UserModel;
|
||||||
|
import org.keycloak.models.UserModel.RequiredAction;
|
||||||
|
import org.keycloak.services.managers.RealmManager;
|
||||||
|
import org.keycloak.services.resources.KeycloakApplication;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
|
*/
|
||||||
|
public class UserModelTest extends AbstractKeycloakServerTest {
|
||||||
|
private KeycloakSessionFactory factory;
|
||||||
|
private KeycloakSession identitySession;
|
||||||
|
private RealmManager manager;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void before() throws Exception {
|
||||||
|
factory = KeycloakApplication.buildSessionFactory();
|
||||||
|
identitySession = factory.createSession();
|
||||||
|
identitySession.getTransaction().begin();
|
||||||
|
manager = new RealmManager(identitySession);
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void after() throws Exception {
|
||||||
|
identitySession.getTransaction().commit();
|
||||||
|
identitySession.close();
|
||||||
|
factory.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void persistUser() {
|
||||||
|
RealmModel realm = manager.createRealm("original");
|
||||||
|
UserModel user = realm.addUser("user");
|
||||||
|
user.setFirstName("first-name");
|
||||||
|
user.setLastName("last-name");
|
||||||
|
user.setEmail("email");
|
||||||
|
|
||||||
|
user.addRedirectUri("redirect-1");
|
||||||
|
user.addRedirectUri("redirect-2");
|
||||||
|
|
||||||
|
user.addRequiredAction(RequiredAction.CONFIGURE_TOTP);
|
||||||
|
user.addRequiredAction(RequiredAction.UPDATE_PASSWORD);
|
||||||
|
|
||||||
|
UserModel persisted = manager.getRealm(realm.getId()).getUser("user");
|
||||||
|
|
||||||
|
assertEquals(user, persisted);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUserRequiredActions() throws Exception {
|
||||||
|
RealmModel realm = manager.createRealm("original");
|
||||||
|
UserModel user = realm.addUser("user");
|
||||||
|
|
||||||
|
Assert.assertTrue(user.getRequiredActions().isEmpty());
|
||||||
|
|
||||||
|
user.addRequiredAction(UserModel.RequiredAction.CONFIGURE_TOTP);
|
||||||
|
user = realm.getUser("user");
|
||||||
|
|
||||||
|
Assert.assertEquals(1, user.getRequiredActions().size());
|
||||||
|
Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.CONFIGURE_TOTP));
|
||||||
|
|
||||||
|
user.addRequiredAction(UserModel.RequiredAction.CONFIGURE_TOTP);
|
||||||
|
user = realm.getUser("user");
|
||||||
|
|
||||||
|
Assert.assertEquals(1, user.getRequiredActions().size());
|
||||||
|
Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.CONFIGURE_TOTP));
|
||||||
|
|
||||||
|
user.addRequiredAction(UserModel.RequiredAction.VERIFY_EMAIL);
|
||||||
|
user = realm.getUser("user");
|
||||||
|
|
||||||
|
Assert.assertEquals(2, user.getRequiredActions().size());
|
||||||
|
Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.CONFIGURE_TOTP));
|
||||||
|
Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.VERIFY_EMAIL));
|
||||||
|
|
||||||
|
user.removeRequiredAction(UserModel.RequiredAction.CONFIGURE_TOTP);
|
||||||
|
user = realm.getUser("user");
|
||||||
|
|
||||||
|
Assert.assertEquals(1, user.getRequiredActions().size());
|
||||||
|
Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.VERIFY_EMAIL));
|
||||||
|
|
||||||
|
user.removeRequiredAction(UserModel.RequiredAction.VERIFY_EMAIL);
|
||||||
|
user = realm.getUser("user");
|
||||||
|
|
||||||
|
Assert.assertTrue(user.getRequiredActions().isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void assertEquals(UserModel expected, UserModel actual) {
|
||||||
|
Assert.assertEquals(expected.getLoginName(), actual.getLoginName());
|
||||||
|
Assert.assertEquals(expected.getFirstName(), actual.getFirstName());
|
||||||
|
Assert.assertEquals(expected.getLastName(), actual.getLastName());
|
||||||
|
Assert.assertArrayEquals(expected.getRedirectUris().toArray(), actual.getRedirectUris().toArray());
|
||||||
|
Assert.assertArrayEquals(expected.getRequiredActions().toArray(), actual.getRequiredActions().toArray());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void assertEquals(List<RoleModel> expected, List<RoleModel> actual) {
|
||||||
|
Assert.assertEquals(expected.size(), actual.size());
|
||||||
|
Iterator<RoleModel> exp = expected.iterator();
|
||||||
|
Iterator<RoleModel> act = actual.iterator();
|
||||||
|
while (exp.hasNext()) {
|
||||||
|
Assert.assertEquals(exp.next().getName(), act.next().getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -28,8 +28,13 @@ import org.junit.Assert;
|
||||||
import org.junit.ClassRule;
|
import org.junit.ClassRule;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.keycloak.models.ApplicationModel;
|
||||||
|
import org.keycloak.models.RealmModel;
|
||||||
|
import org.keycloak.models.UserModel;
|
||||||
|
import org.keycloak.services.managers.RealmManager;
|
||||||
import org.keycloak.testsuite.OAuthClient;
|
import org.keycloak.testsuite.OAuthClient;
|
||||||
import org.keycloak.testsuite.OAuthClient.AuthorizationCodeResponse;
|
import org.keycloak.testsuite.OAuthClient.AuthorizationCodeResponse;
|
||||||
|
import org.keycloak.testsuite.pages.ErrorPage;
|
||||||
import org.keycloak.testsuite.pages.LoginPage;
|
import org.keycloak.testsuite.pages.LoginPage;
|
||||||
import org.keycloak.testsuite.rule.KeycloakRule;
|
import org.keycloak.testsuite.rule.KeycloakRule;
|
||||||
import org.keycloak.testsuite.rule.WebResource;
|
import org.keycloak.testsuite.rule.WebResource;
|
||||||
|
@ -56,8 +61,11 @@ public class AuthorizationCodeTest {
|
||||||
@WebResource
|
@WebResource
|
||||||
protected LoginPage loginPage;
|
protected LoginPage loginPage;
|
||||||
|
|
||||||
|
@WebResource
|
||||||
|
protected ErrorPage errorPage;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void authorizationRequest() throws ClientProtocolException, IOException {
|
public void authorizationRequest() throws IOException {
|
||||||
oauth.state("mystate");
|
oauth.state("mystate");
|
||||||
|
|
||||||
AuthorizationCodeResponse response = oauth.doLogin("test-user@localhost", "password");
|
AuthorizationCodeResponse response = oauth.doLogin("test-user@localhost", "password");
|
||||||
|
@ -69,7 +77,54 @@ public class AuthorizationCodeTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void authorizationRequestNoState() throws ClientProtocolException, IOException {
|
public void authorizationValidRedirectUri() throws IOException {
|
||||||
|
keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
|
||||||
|
@Override
|
||||||
|
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
|
||||||
|
for (ApplicationModel app : appRealm.getApplications()) {
|
||||||
|
if (app.getName().equals("test-app")) {
|
||||||
|
UserModel client = app.getApplicationUser();
|
||||||
|
client.addRedirectUri(oauth.getRedirectUri());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
oauth.state("mystate");
|
||||||
|
|
||||||
|
AuthorizationCodeResponse response = oauth.doLogin("test-user@localhost", "password");
|
||||||
|
|
||||||
|
Assert.assertTrue(response.isRedirected());
|
||||||
|
Assert.assertNotNull(response.getCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void authorizationRequestInvalidRedirectUri() throws IOException {
|
||||||
|
keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
|
||||||
|
@Override
|
||||||
|
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
|
||||||
|
for (ApplicationModel app : appRealm.getApplications()) {
|
||||||
|
if (app.getName().equals("test-app")) {
|
||||||
|
UserModel client = app.getApplicationUser();
|
||||||
|
client.addRedirectUri(oauth.getRedirectUri());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
oauth.redirectUri("http://invalid");
|
||||||
|
oauth.state("mystate");
|
||||||
|
|
||||||
|
AuthorizationCodeResponse response = oauth.doLogin("test-user@localhost", "password");
|
||||||
|
|
||||||
|
Assert.assertFalse(response.isRedirected());
|
||||||
|
|
||||||
|
Assert.assertTrue(errorPage.isCurrent());
|
||||||
|
Assert.assertEquals("Invalid redirect_uri http://invalid", errorPage.getError());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void authorizationRequestNoState() throws IOException {
|
||||||
AuthorizationCodeResponse response = oauth.doLogin("test-user@localhost", "password");
|
AuthorizationCodeResponse response = oauth.doLogin("test-user@localhost", "password");
|
||||||
|
|
||||||
Assert.assertTrue(response.isRedirected());
|
Assert.assertTrue(response.isRedirected());
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* JBoss, Home of Professional Open Source.
|
||||||
|
* Copyright 2012, Red Hat, Inc., and individual contributors
|
||||||
|
* as indicated by the @author tags. See the copyright.txt file in the
|
||||||
|
* distribution for a full listing of individual contributors.
|
||||||
|
*
|
||||||
|
* This is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2.1 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This software is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this software; if not, write to the Free
|
||||||
|
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
|
||||||
|
*/
|
||||||
|
package org.keycloak.testsuite.pages;
|
||||||
|
|
||||||
|
import org.keycloak.testsuite.OAuthClient;
|
||||||
|
import org.keycloak.testsuite.rule.WebResource;
|
||||||
|
import org.openqa.selenium.By;
|
||||||
|
import org.openqa.selenium.WebElement;
|
||||||
|
import org.openqa.selenium.support.FindBy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
|
*/
|
||||||
|
public class ErrorPage extends Page {
|
||||||
|
|
||||||
|
@WebResource
|
||||||
|
protected OAuthClient oauth;
|
||||||
|
|
||||||
|
@FindBy(id = "error-summary")
|
||||||
|
private WebElement errorMessage;
|
||||||
|
|
||||||
|
public String getError() {
|
||||||
|
return errorMessage.getText();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCurrent() {
|
||||||
|
return driver.getTitle().equals("We're sorry...");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void open() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue