Manage organization attributes
Closes #28253 Signed-off-by: Martin Kanis <mkanis@redhat.com>
This commit is contained in:
parent
41b706bb6a
commit
51fa054ba7
5 changed files with 131 additions and 0 deletions
|
@ -17,10 +17,16 @@
|
||||||
|
|
||||||
package org.keycloak.representations.idm;
|
package org.keycloak.representations.idm;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class OrganizationRepresentation {
|
public class OrganizationRepresentation {
|
||||||
|
|
||||||
private String id;
|
private String id;
|
||||||
private String name;
|
private String name;
|
||||||
|
private Map<String, List<String>> attributes = new HashMap<>();
|
||||||
|
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return id;
|
return id;
|
||||||
|
@ -38,6 +44,20 @@ public class OrganizationRepresentation {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Map<String, List<String>> getAttributes() {
|
||||||
|
return attributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAttributes(Map<String, List<String>> attributes) {
|
||||||
|
this.attributes = attributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OrganizationRepresentation singleAttribute(String name, String value) {
|
||||||
|
if (this.attributes == null) attributes = new HashMap<>();
|
||||||
|
attributes.put(name, Arrays.asList(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
|
|
|
@ -17,15 +17,21 @@
|
||||||
|
|
||||||
package org.keycloak.organization.jpa;
|
package org.keycloak.organization.jpa;
|
||||||
|
|
||||||
|
import org.keycloak.models.GroupModel;
|
||||||
import org.keycloak.models.OrganizationModel;
|
import org.keycloak.models.OrganizationModel;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.jpa.JpaModel;
|
import org.keycloak.models.jpa.JpaModel;
|
||||||
import org.keycloak.models.jpa.entities.OrganizationEntity;
|
import org.keycloak.models.jpa.entities.OrganizationEntity;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public final class OrganizationAdapter implements OrganizationModel, JpaModel<OrganizationEntity> {
|
public final class OrganizationAdapter implements OrganizationModel, JpaModel<OrganizationEntity> {
|
||||||
|
|
||||||
private final RealmModel realm;
|
private final RealmModel realm;
|
||||||
private final OrganizationEntity entity;
|
private final OrganizationEntity entity;
|
||||||
|
private GroupModel group;
|
||||||
|
|
||||||
public OrganizationAdapter(RealmModel realm, OrganizationEntity entity) {
|
public OrganizationAdapter(RealmModel realm, OrganizationEntity entity) {
|
||||||
this.realm = realm;
|
this.realm = realm;
|
||||||
|
@ -55,11 +61,48 @@ public final class OrganizationAdapter implements OrganizationModel, JpaModel<Or
|
||||||
return entity.getName();
|
return entity.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSingleAttribute(String name, String value) {
|
||||||
|
getGroup().setSingleAttribute(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAttribute(String name, List<String> values) {
|
||||||
|
getGroup().setAttribute(name, values);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeAttribute(String name) {
|
||||||
|
getGroup().removeAttribute(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFirstAttribute(String name) {
|
||||||
|
return getGroup().getFirstAttribute(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Stream<String> getAttributeStream(String name) {
|
||||||
|
return getGroup().getAttributeStream(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, List<String>> getAttributes() {
|
||||||
|
return getGroup().getAttributes();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public OrganizationEntity getEntity() {
|
public OrganizationEntity getEntity() {
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private GroupModel getGroup() {
|
||||||
|
if (group == null) {
|
||||||
|
group = realm.getGroupById(getGroupId());
|
||||||
|
}
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return new StringBuilder()
|
return new StringBuilder()
|
||||||
|
|
|
@ -17,6 +17,10 @@
|
||||||
|
|
||||||
package org.keycloak.models;
|
package org.keycloak.models;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public interface OrganizationModel {
|
public interface OrganizationModel {
|
||||||
|
|
||||||
String USER_ORGANIZATION_ATTRIBUTE = "kc.org";
|
String USER_ORGANIZATION_ATTRIBUTE = "kc.org";
|
||||||
|
@ -26,4 +30,16 @@ public interface OrganizationModel {
|
||||||
void setName(String name);
|
void setName(String name);
|
||||||
|
|
||||||
String getName();
|
String getName();
|
||||||
|
|
||||||
|
void setSingleAttribute(String name, String value);
|
||||||
|
|
||||||
|
void setAttribute(String name, List<String> values);
|
||||||
|
|
||||||
|
void removeAttribute(String name);
|
||||||
|
|
||||||
|
String getFirstAttribute(String name);
|
||||||
|
|
||||||
|
Stream<String> getAttributeStream(String name);
|
||||||
|
|
||||||
|
Map<String, List<String>> getAttributes();
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
package org.keycloak.organization.admin.resource;
|
package org.keycloak.organization.admin.resource;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import jakarta.ws.rs.BadRequestException;
|
import jakarta.ws.rs.BadRequestException;
|
||||||
|
@ -141,6 +142,7 @@ public class OrganizationResource {
|
||||||
|
|
||||||
rep.setId(model.getId());
|
rep.setId(model.getId());
|
||||||
rep.setName(model.getName());
|
rep.setName(model.getName());
|
||||||
|
rep.setAttributes(model.getAttributes());
|
||||||
|
|
||||||
return rep;
|
return rep;
|
||||||
}
|
}
|
||||||
|
@ -152,6 +154,14 @@ public class OrganizationResource {
|
||||||
|
|
||||||
model.setName(rep.getName());
|
model.setName(rep.getName());
|
||||||
|
|
||||||
|
if (rep.getAttributes() != null) {
|
||||||
|
Set<String> attrsToRemove = model.getAttributes().keySet();
|
||||||
|
attrsToRemove.removeAll(rep.getAttributes().keySet());
|
||||||
|
attrsToRemove.forEach(model::removeAttribute);
|
||||||
|
|
||||||
|
rep.getAttributes().entrySet().forEach(entry -> model.setAttribute(entry.getKey(), entry.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,9 +20,11 @@ package org.keycloak.testsuite.organization.admin;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import jakarta.ws.rs.NotFoundException;
|
import jakarta.ws.rs.NotFoundException;
|
||||||
|
@ -93,4 +95,44 @@ public class OrganizationTest extends AbstractOrganizationTest {
|
||||||
fail("should be deleted");
|
fail("should be deleted");
|
||||||
} catch (NotFoundException ignore) {}
|
} catch (NotFoundException ignore) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAttributes() {
|
||||||
|
OrganizationRepresentation org = createOrganization();
|
||||||
|
org = org.singleAttribute("key", "value");
|
||||||
|
|
||||||
|
OrganizationResource organization = testRealm().organizations().get(org.getId());
|
||||||
|
|
||||||
|
try (Response response = organization.update(org)) {
|
||||||
|
assertEquals(Status.NO_CONTENT.getStatusCode(), response.getStatus());
|
||||||
|
}
|
||||||
|
|
||||||
|
OrganizationRepresentation updated = organization.toRepresentation();
|
||||||
|
assertEquals(org.getAttributes().get("key"), updated.getAttributes().get("key"));
|
||||||
|
|
||||||
|
HashMap<String, List<String>> attributes = new HashMap<>();
|
||||||
|
attributes.put("attr1", List.of("val11", "val12"));
|
||||||
|
attributes.put("attr2", List.of("val21", "val22"));
|
||||||
|
org.setAttributes(attributes);
|
||||||
|
|
||||||
|
try (Response response = organization.update(org)) {
|
||||||
|
assertEquals(Status.NO_CONTENT.getStatusCode(), response.getStatus());
|
||||||
|
}
|
||||||
|
|
||||||
|
updated = organization.toRepresentation();
|
||||||
|
assertNull(updated.getAttributes().get("key"));
|
||||||
|
assertEquals(2, updated.getAttributes().size());
|
||||||
|
assertEquals(org.getAttributes().get("attr1"), updated.getAttributes().get("attr1"));
|
||||||
|
assertEquals(org.getAttributes().get("attr2"), updated.getAttributes().get("attr2"));
|
||||||
|
|
||||||
|
attributes.clear();
|
||||||
|
org.setAttributes(attributes);
|
||||||
|
|
||||||
|
try (Response response = organization.update(org)) {
|
||||||
|
assertEquals(Status.NO_CONTENT.getStatusCode(), response.getStatus());
|
||||||
|
}
|
||||||
|
|
||||||
|
updated = organization.toRepresentation();
|
||||||
|
assertEquals(0, updated.getAttributes().size());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue