Skip to content

Commit

Permalink
use PagingOptions argument instead of separate arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
blevine committed Oct 10, 2024
1 parent 366f0a7 commit f517ef7
Show file tree
Hide file tree
Showing 18 changed files with 292 additions and 107 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,9 @@
import net.brianlevine.keycloak.graphql.queries.ErrorQuery;
import net.brianlevine.keycloak.graphql.queries.RealmQuery;
import net.brianlevine.keycloak.graphql.queries.UserQuery;

import net.brianlevine.keycloak.graphql.util.OverrideTypeInfoGenerator;
import org.keycloak.models.KeycloakSession;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

Expand Down Expand Up @@ -68,9 +66,6 @@ public Map<String, Object> executeQuery(String query, String operationName, Keyc
return executionResult.toSpecification();
}

public Map<String, Object> executeQuery(String query, String operationName, KeycloakSession session, Request request, HttpHeaders headers) {
return executeQuery(query, operationName, session, request, headers, Collections.emptyMap());
}

public String printSchema() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@

/**
* For InputTypes and Scalars. Classes annotated with GraphQLOverrideTypeName will not have a suffix ('Input' for
* InputTypes and 'Scalar' for Scalar types) appended.
* InputTypes and 'Scalar' for Scalar types) appended. The name of the class or the name given in the
* @GraphQLInputType/@GraphQLScalar annotations will be used without modification.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package net.brianlevine.keycloak.graphql.queries;

import jakarta.ws.rs.ForbiddenException;
import net.brianlevine.keycloak.graphql.types.PagingOptions;
import net.brianlevine.keycloak.graphql.util.Page;
import net.brianlevine.keycloak.graphql.util.Auth;

Expand All @@ -25,10 +26,7 @@
public class RealmQuery {

@GraphQLQuery(name = "realms", description = "Return a collection of realms that are viewable by the caller.")
public Page<RealmType> getRealms(
@GraphQLRootContext GraphQLContext ctx,
@GraphQLArgument(name="limit", defaultValue = "100") int limit,
@GraphQLArgument(name="start", defaultValue = "0") int start) {
public Page<RealmType> getRealms(PagingOptions options, @GraphQLRootContext GraphQLContext ctx) {

KeycloakSession session = ctx.get("keycloak.session");
HttpHeaders headers = ctx.get("headers");
Expand All @@ -41,11 +39,15 @@ public Page<RealmType> getRealms(
.filter(Objects::nonNull)
.toList();

options = options == null ? new PagingOptions() : options;

List<RealmType> realmTypes = realms.stream()
.skip(options.start)
.limit(options.limit)
.map(rep -> rep != null ? new RealmType(session, rep) : null)
.toList();

ret = new Page<>(realms.size(), limit, realmTypes);
ret = new Page<>(realms.size(), options.limit, realmTypes);
} catch (ForbiddenException e) {
ret = Page.emptyPage();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collections;
import java.util.Map;


Expand Down Expand Up @@ -52,16 +53,23 @@ public void close() {
public Response postGraphQL(Map<String, Object> body, @Context Request request, @Context HttpHeaders headers) throws JsonProcessingException {
String query = (String)body.get("query");
String operationName = (String)body.get("operationName");
//String variables = (String)body.get("variables");
Object variables = body.get("variables");

// TODO: Deal with variables.
@SuppressWarnings("unchecked")
Map<String, Object> result = graphql.executeQuery(
query,
operationName,
session,
request,
headers,
variables != null ? (Map<String, Object>) variables : Collections.emptyMap());

Map<String, Object> result = graphql.executeQuery(query, operationName, session, request, headers);
ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.WRITE_NULL_MAP_VALUES);

//noinspection deprecation
mapper.enable(SerializationFeature.WRITE_NULL_MAP_VALUES);
String s = mapper.writeValueAsString(result);

//return Response.ok(s).header("Access-Control-Allow-Origin", "*").header("Access-Control-Allow-Credentials", "true").build();
return Response.ok(s).build();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package net.brianlevine.keycloak.graphql.types;

import com.fasterxml.jackson.databind.JsonNode;
import io.leangen.graphql.annotations.types.GraphQLType;
import org.keycloak.representations.idm.ClientPolicyConditionRepresentation;

import java.util.Objects;

@GraphQLType
@SuppressWarnings("unused")
public class ClientPolicyConditionType {
private final ClientPolicyConditionRepresentation delegate;

public ClientPolicyConditionType(ClientPolicyConditionRepresentation clientPolicyConditionRepresentation) {
this.delegate = clientPolicyConditionRepresentation;
}

public String getConditionProviderId() {
return delegate.getConditionProviderId();
}

public void setConditionProviderId(String conditionProviderId) {
delegate.setConditionProviderId(conditionProviderId);
}

public JsonNode getConfiguration() {
return delegate.getConfiguration();
}

public void setConfiguration(JsonNode configuration) {
delegate.setConfiguration(configuration);
}

@Override
public boolean equals(Object o) {
if (delegate.getClass() != o.getClass()) return false;
return delegate.equals(o);
}

@Override
public int hashCode() {
return delegate.hashCode();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package net.brianlevine.keycloak.graphql.types;

import io.leangen.graphql.annotations.GraphQLArgument;
import io.leangen.graphql.annotations.GraphQLQuery;
import io.leangen.graphql.annotations.types.GraphQLType;
import net.brianlevine.keycloak.graphql.util.Page;
import org.keycloak.representations.idm.ClientPolicyConditionRepresentation;
import org.keycloak.representations.idm.ClientPolicyRepresentation;

import java.util.List;

@GraphQLType
@SuppressWarnings("unused")
public class ClientPolicyType {
private final ClientPolicyRepresentation delegate;

public ClientPolicyType(ClientPolicyRepresentation clientPolicyRepresentation) {
this.delegate = clientPolicyRepresentation;
}

public String getName() {
return delegate.getName();
}

public void setName(String name) {
delegate.setName(name);
}

public String getDescription() {
return delegate.getDescription();
}

public void setDescription(String description) {
delegate.setDescription(description);
}

public Boolean isEnabled() {
return delegate.isEnabled();
}

public void setEnabled(Boolean enabled) {
delegate.setEnabled(enabled);
}

@GraphQLQuery
public Page<ClientPolicyConditionType> getConditions(@GraphQLArgument PagingOptions options) {
List<ClientPolicyConditionRepresentation> reps = delegate.getConditions();
List<ClientPolicyConditionType> conditions = reps.stream()
.skip(options.start)
.limit(options.limit)
.map(ClientPolicyConditionType::new)
.toList();

return new Page<>(reps.size(), options.limit, conditions);
}

public void setConditions(List<ClientPolicyConditionRepresentation> conditions) {
delegate.setConditions(conditions);
}

public List<String> getProfiles() {
return delegate.getProfiles();
}

public void setProfiles(List<String> profiles) {
delegate.setProfiles(profiles);
}

@SuppressWarnings("com.intellij.jpb.inspection.EqualsDoesntCheckParameterClassInspection")
@Override
public boolean equals(Object o) {
return delegate.equals(o);
}

@Override
public int hashCode() {
return delegate.hashCode();
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package net.brianlevine.keycloak.graphql.types;

import io.leangen.graphql.annotations.GraphQLArgument;
import io.leangen.graphql.annotations.GraphQLQuery;
import io.leangen.graphql.annotations.types.GraphQLType;
import net.brianlevine.keycloak.graphql.util.Page;
import org.keycloak.representations.idm.ClientPolicyExecutorRepresentation;
Expand Down Expand Up @@ -34,15 +35,18 @@ public void setDescription(String description) {
delegate.setDescription(description);
}

public Page<ClientPolicyExecutorType> getExecutors(@GraphQLArgument(defaultValue = "0")int start, @GraphQLArgument(defaultValue = "100")int limit) {
@GraphQLQuery
public Page<ClientPolicyExecutorType> getExecutors(PagingOptions options) {
List<ClientPolicyExecutorRepresentation> executors = delegate.getExecutors();

options = options == null ? new PagingOptions() : options;
List<ClientPolicyExecutorType> ets = executors.stream()
.skip(start)
.limit(limit)
.skip(options.start)
.limit(options.limit)
.map(ClientPolicyExecutorType::new)
.toList();

return new Page<>(executors.size(), limit, ets);
return new Page<>(executors.size(), options.limit, ets);
}

public void setExecutors(List<ClientPolicyExecutorRepresentation> executors) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,16 @@ public void setDescription(String description) {
delegate.setDescription(description);
}

public Page<ProtocolMapperType> getProtocolMappers(@GraphQLArgument(defaultValue = "0")int start, @GraphQLArgument(defaultValue = "100")int limit) {
public Page<ProtocolMapperType> getProtocolMappers(PagingOptions options) {
options = options == null ? new PagingOptions() : options;

List<ProtocolMapperType> pms = delegate.getProtocolMappers().stream()
.skip(start)
.limit(limit)
.skip(options.start)
.limit(options.limit)
.map(ProtocolMapperType::new)
.toList();

return new Page<>(pms.size(), limit, pms);
return new Page<>(pms.size(), options.limit, pms);
}

public void setProtocolMappers(List<ProtocolMapperRepresentation> protocolMappers) {
Expand All @@ -64,8 +66,8 @@ public void setProtocol(String protocol) {
delegate.setProtocol(protocol);
}

public AttributeMap getAttributes(@GraphQLArgument(defaultValue = "0")int start, @GraphQLArgument(defaultValue = "100")int limit) {
return new AttributeMap(delegate.getAttributes(), start, limit);
public AttributeMap getAttributes(PagingOptions options) {
return new AttributeMap(delegate.getAttributes(), options.start, options.limit);
}

public void setAttributes(Map<String, String> attributes) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,11 @@ public void setSubType(String subType) {
}

@GraphQLQuery
public MultiAttributeMap getConfig(@GraphQLArgument(defaultValue = "0")int start, @GraphQLArgument(defaultValue = "100")int limit) {
public MultiAttributeMap getConfig(PagingOptions options) {
MultivaluedMap<String, String> config = delegate.getConfig();
options = options == null ? new PagingOptions() : options;

return new MultiAttributeMap(config, start, limit);
return new MultiAttributeMap(config, options.start, options.limit);
}

// public void setConfig(MultivaluedHashMap<String, String> config) {
Expand All @@ -73,14 +74,14 @@ public MultiAttributeMap getConfig(@GraphQLArgument(defaultValue = "0")int start
// }

@GraphQLQuery
public ComponentMap getSubComponents(@GraphQLArgument(defaultValue = "0")int start, @GraphQLArgument(defaultValue = "100")int limit) {
public ComponentMap getSubComponents(PagingOptions options) {
MultivaluedHashMap<String, ComponentExportRepresentation> subComponents = delegate.getSubComponents();

Map<String, List<ComponentType>> subs = subComponents != null
? subComponents.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().stream().map(ComponentType::new).toList()))
: new MultivaluedHashMap<>();

return new ComponentMap(subs, start, limit);
options = options == null ? new PagingOptions() : options;
return new ComponentMap(subs, options.start, options.limit);
}

// public void setSubComponents(MultivaluedHashMap<String, ComponentExportRepresentation> subComponents) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,16 @@

public interface GroupHolder extends BaseType {
@GraphQLQuery
default Page<GroupType> getGroups(
@GraphQLArgument(defaultValue = "0") int start,
@GraphQLArgument(defaultValue = "100") int limit,
@GraphQLRootContext GraphQLContext ctx) {

default Page<GroupType> getGroups(PagingOptions options, @GraphQLRootContext GraphQLContext ctx) {
options = options == null ? new PagingOptions() : options;
long totalCount = getGroupsCount(ctx);
Stream<GroupModel> groupModels = getGroupsStream(start, limit, ctx);
Stream<GroupModel> groupModels = getGroupsStream(options.start, options.limit, ctx);

KeycloakSession kcSession = getKeycloakSession();
RealmModel realmModel = getRealmModel();
List<GroupType> groups = groupModels.map(gm -> new GroupType(kcSession, realmModel, gm)).toList();

return new Page<>((int) totalCount, limit, groups);
return new Page<>((int) totalCount, options.limit, groups);
}

// Note: Implementations should make these as @GraphQLIgnore
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,10 +147,7 @@ public void setAttributes(Map<String, List<String>> attributes) {
// }

@GraphQLQuery
public Page<GroupType> getSubGroups(
@GraphQLArgument(defaultValue = "0")int start,
@GraphQLArgument(defaultValue = "100")int limit,
@GraphQLRootContext GraphQLContext ctx) {
public Page<GroupType> getSubGroups(PagingOptions options, @GraphQLRootContext GraphQLContext ctx) {

Page<GroupType> ret;

Expand All @@ -165,12 +162,14 @@ public Page<GroupType> getSubGroups(
if (eval.canView(getGroupModel())) {
boolean canViewGlobal = eval.canView();

options = options == null ? new PagingOptions() : options;

long subGroupCount = gm.getSubGroupsStream().filter(g -> canViewGlobal || eval.canView(g)).count();
Stream<GroupModel> groupModels = gm.getSubGroupsStream(start, limit).filter(g -> canViewGlobal || eval.canView(g));
Stream<GroupModel> groupModels = gm.getSubGroupsStream(options.start, options.limit).filter(g -> canViewGlobal || eval.canView(g));

List<GroupType> groupTypes = groupModels.map(g -> new GroupType(session, realmModel, GroupUtils.toRepresentation(eval, g, true))).toList();

ret = new Page<>((int)subGroupCount, limit, groupTypes);
ret = new Page<>((int)subGroupCount, options.limit, groupTypes);
}
else {
ret = Page.emptyPage();
Expand Down
Loading

0 comments on commit f517ef7

Please sign in to comment.