Skip to content

Commit

Permalink
Implement stem-less operation
Browse files Browse the repository at this point in the history
  • Loading branch information
mederly committed Mar 26, 2019
1 parent fe005e3 commit f3701b7
Show file tree
Hide file tree
Showing 8 changed files with 155 additions and 713 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
</parent>

<artifactId>connector-grouper-rest</artifactId>
<version>0.1</version>
<version>0.2</version>
<packaging>jar</packaging>

<name>Grouper REST Connector</name>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/*******************************************************************************
/*
******************************************************************************
* Copyright 2017 Evolveum
*
* Licensed under the Apache License, Version 2.0 (the "License");
Expand All @@ -24,6 +25,7 @@
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

import static com.evolveum.polygon.connector.grouper.rest.Processor.*;

Expand All @@ -32,13 +34,13 @@
* @author mederly
*
*/
public class AccountProcessor {
class AccountProcessor {

private final Processor processor;

public static final String ATTR_GROUP = "group";
private static final String ATTR_GROUP = "group";

public AccountProcessor(Processor processor) {
AccountProcessor(Processor processor) {
this.processor = processor;
}

Expand Down Expand Up @@ -151,13 +153,11 @@ private void getUser(String id, ResultsHandler handler) {

private List<String> selectGroupNames(JSONArray groups) {
List<String> rv = new ArrayList<>();
String expectedPrefix = getConfiguration().getRootStem() + ":";
for (Object group : groups) {
if (group instanceof JSONObject) {
JSONObject gObject = (JSONObject) group;
String name = processor.getStringOrNull(gObject, "name");
String extension = processor.getStringOrNull(gObject, "extension");
if (name != null && name.equals(expectedPrefix + extension)) {
if (groupNameMatches(name)) {
rv.add(name);
}
} else {
Expand All @@ -167,6 +167,27 @@ private List<String> selectGroupNames(JSONArray groups) {
return rv;
}

private boolean groupNameMatches(String name) {
if (name == null) {
return false;
}
return groupNameMatches(name, getConfiguration().getGroupIncludePattern()) &&
!groupNameMatches(name, getConfiguration().getGroupExcludePattern());
}

private boolean groupNameMatches(String name, String[] patterns) {
if (patterns == null) {
return false;
}
for (String pattern : patterns) {
Pattern compiled = Pattern.compile(pattern);
if (compiled.matcher(name).matches()) {
return true;
}
}
return false;
}

private GrouperConfiguration getConfiguration() {
return processor.configuration;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@
* @author mederly
*
*/
public class GroupProcessor {
class GroupProcessor {

private final Processor processor;

private static final String ATTR_EXTENSION = "extension";

public GroupProcessor(Processor processor) {
GroupProcessor(Processor processor) {
this.processor = processor;
}

Expand Down Expand Up @@ -90,11 +90,12 @@ private void getAllGroups(ResultsHandler handler) {
try {
HttpPost request = new HttpPost(uriBuilder.build());
JSONObject body = new JSONObject()
.put("WsRestFindGroupsRequest", new JSONObject()
.put("wsQueryFilter", new JSONObject()
.put("queryFilterType", "FIND_BY_STEM_NAME")
.put("stemName", getConfiguration().getRootStem())));
executeFindGroupsResponse(request, body, handler);
.put("WsRestGetMembersRequest", new JSONObject()
.put("wsGroupLookups", new JSONObject[] { new JSONObject()
.put("groupName", getConfiguration().getSuperGroup()) })
.put("includeSubjectDetail", true)
.put("memberFilter", "Immediate"));
executeFindGroupsAsMembersResponse(request, body, handler);
} catch (RuntimeException | URISyntaxException e) {
throw processor.processException(e, uriBuilder, "Get all groups");
}
Expand All @@ -107,7 +108,20 @@ private void executeFindGroupsResponse(HttpPost request, JSONObject body, Result
processor.checkSuccess(response, "WsFindGroupsResults");
JSONArray groups = processor.getArray(response, "WsFindGroupsResults", "groupResults");
for (Object group : groups) {
if (!handlerGroupJsonObject(group, handler)) {
if (!handleGroupJsonObject(group, handler)) {
return;
}
}
}

private void executeFindGroupsAsMembersResponse(HttpPost request, JSONObject body, ResultsHandler handler) {
System.out.println("Request = " + body.toString());
JSONObject response = processor.callRequest(request, body, true, CONTENT_TYPE_JSON);
System.out.println("Got response: " + response);
processor.checkSuccess(response, WS_GET_MEMBERS_RESULTS);
JSONArray groups = processor.getArray(response, WS_GET_MEMBERS_RESULTS, RESULTS, WS_SUBJECTS);
for (Object group : groups) {
if (!handleGroupAsMemberJsonObject(group, handler)) {
return;
}
}
Expand Down Expand Up @@ -143,7 +157,7 @@ private void getGroupByUuid(String groupUuid, ResultsHandler handler) {
}
}

private boolean handlerGroupJsonObject(Object group, ResultsHandler handler) {
private boolean handleGroupJsonObject(Object group, ResultsHandler handler) {
if (group instanceof JSONObject) {
JSONObject gObject = (JSONObject) group;
String name = processor.getStringOrNull(gObject, "name");
Expand All @@ -160,8 +174,49 @@ private boolean handlerGroupJsonObject(Object group, ResultsHandler handler) {
}
}

private boolean handleGroupAsMemberJsonObject(Object group, ResultsHandler handler) {
if (group instanceof JSONObject) {
JSONObject gObject = (JSONObject) group;
String sourceId = processor.getStringOrNull(gObject, "sourceId");
if (sourceId == null || !sourceId.equals(getConfiguration().getGroupSource())) {
LOG.info("Skipping non-group member (source={0})", sourceId);
return true;
}
String name = processor.getStringOrNull(gObject, "name");
String id = processor.getStringOrNull(gObject, "id");
ConnectorObjectBuilder builder = new ConnectorObjectBuilder();
builder.setObjectClass(ObjectClass.GROUP);
builder.setUid(id);
builder.setName(name);
return handler.handle(builder.build());
} else {
throw new IllegalStateException("Expected group as JSONObject, got " + group);
}
}

private GrouperConfiguration getConfiguration() {
return processor.configuration;
}

void test() {
URIBuilder uriBuilder = processor.getURIBuilder().setPath(URI_BASE_PATH + PATH_GROUPS);
try {
HttpPost request = new HttpPost(uriBuilder.build());
JSONObject body = new JSONObject()
.put("WsRestGetMembersRequest", new JSONObject()
.put("wsGroupLookups", new JSONObject[] { new JSONObject()
.put("groupName", getConfiguration().getSuperGroup()) })
.put("includeSubjectDetail", true)
.put("memberFilter", "Immediate"));
System.out.println("Request = " + body.toString());
JSONObject response = processor.callRequest(request, body, true, CONTENT_TYPE_JSON);
System.out.println("Got response: " + response);
processor.checkSuccess(response, WS_GET_MEMBERS_RESULTS);
JSONArray groups = processor.getArray(response, WS_GET_MEMBERS_RESULTS, RESULTS, WS_SUBJECTS);
System.out.println("Super-group members found: " + groups.length());
} catch (RuntimeException | URISyntaxException e) {
throw processor.processException(e, uriBuilder, "Test");
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,29 @@
import org.identityconnectors.framework.spi.ConfigurationProperty;
import org.identityconnectors.framework.spi.StatefulConfiguration;

import java.util.Arrays;

/**
* @author surmanek
* @author mederly
*
*/
@SuppressWarnings("WeakerAccess")
public class GrouperConfiguration extends AbstractConfiguration implements StatefulConfiguration {

private static final Log LOG = Log.getLog(GrouperConfiguration.class);

private String name;
private GuardedString password;
private static final String DEFAULT_GROUP_SOURCE_ID = "g:gsa";

private String baseUrl;
private String username;
private GuardedString password;
private String superGroup;
private String rootStem;
private String[] groupIncludePattern;
private String[] groupExcludePattern;
private Boolean ignoreSslValidation;
private String subjectSource;
private String groupSource;

// getter and setter methods for "baseUrl" attribute:
@ConfigurationProperty(order = 1, displayMessageKey = "baseUrl.display", helpMessageKey = "baseUrl.help", required = true)
Expand All @@ -50,21 +57,23 @@ public void setBaseUrl(String baseUrl) {
this.baseUrl = baseUrl;
}

// getter and setter methods for "name" attribute:
// getter and setter methods for "username" attribute:
@ConfigurationProperty(order = 2, displayMessageKey = "username.display", helpMessageKey = "username.help", required = true)
public String getUsername() {
return name;
return username;
}

public void setUsername(String name) {
this.name = name;
this.username = name;
}

private String stringPassword = "";

@ConfigurationProperty(order = 3, displayMessageKey = "password.display", helpMessageKey = "password.help", required = true, confidential = false)
public GuardedString getPassword() {
return password;
}

public void setPassword(GuardedString password) {
this.password = password;
}
Expand All @@ -88,16 +97,25 @@ public void setSuperGroup(String superGroup) {
this.superGroup = superGroup;
}

@ConfigurationProperty(order = 5, displayMessageKey = "rootStem.display", helpMessageKey = "superGroup.help", required = true)
public String getRootStem() {
return rootStem;
@ConfigurationProperty(order = 5, displayMessageKey = "groupIncludePattern.display", helpMessageKey = "groupIncludePattern.help", required = true)
public String[] getGroupIncludePattern() {
return groupIncludePattern;
}

public void setGroupIncludePattern(String[] groupIncludePattern) {
this.groupIncludePattern = groupIncludePattern;
}

@ConfigurationProperty(order = 6, displayMessageKey = "groupExcludePattern.display", helpMessageKey = "groupExcludePattern.help", required = true)
public String[] getGroupExcludePattern() {
return groupExcludePattern;
}

public void setRootStem(String rootStem) {
this.rootStem = rootStem;
public void setGroupExcludePattern(String[] groupExcludePattern) {
this.groupExcludePattern = groupExcludePattern;
}

@ConfigurationProperty(order = 6, displayMessageKey = "ignoreSslValidation.display", helpMessageKey = "ignoreSslValidation.help", required = false)
@ConfigurationProperty(order = 7, displayMessageKey = "ignoreSslValidation.display", helpMessageKey = "ignoreSslValidation.help")
public Boolean getIgnoreSslValidation() {
return ignoreSslValidation;
}
Expand All @@ -106,7 +124,7 @@ public void setIgnoreSslValidation(Boolean ignoreSslValidation) {
this.ignoreSslValidation = ignoreSslValidation;
}

@ConfigurationProperty(order = 7, displayMessageKey = "subjectSource.display", helpMessageKey = "subjectSource.help", required = false)
@ConfigurationProperty(order = 8, displayMessageKey = "subjectSource.display", helpMessageKey = "subjectSource.help", required = true)
public String getSubjectSource() {
return subjectSource;
}
Expand All @@ -115,19 +133,28 @@ public void setSubjectSource(String subjectSource) {
this.subjectSource = subjectSource;
}

@ConfigurationProperty(order = 9, displayMessageKey = "groupSource.display", helpMessageKey = "groupSource.help")
public String getGroupSource() {
return groupSource != null ? groupSource : DEFAULT_GROUP_SOURCE_ID;
}

public void setGroupSource(String groupSource) {
this.groupSource = groupSource;
}

@Override
public void validate() {
String exceptionMsg;
if (baseUrl == null || StringUtil.isBlank(baseUrl)) {
exceptionMsg = "Base url is not provided.";
} else if (name == null || StringUtil.isBlank(name)) {
} else if (username == null || StringUtil.isBlank(username)) {
exceptionMsg = "Name is not provided.";
} else if (password == null) {
exceptionMsg = "Password is not provided.";
} else if (superGroup == null) {
exceptionMsg = "Super group is not provided.";
} else if (rootStem == null) {
exceptionMsg = "Root stem is not provided.";
} else if (groupIncludePattern == null || groupIncludePattern.length == 0) {
exceptionMsg = "Group include pattern is not provided.";
} else if (subjectSource == null) {
exceptionMsg = "Subject source is not provided.";
} else {
Expand All @@ -140,22 +167,27 @@ public void validate() {
@Override
public void release() {
LOG.info("The release of configuration resources is being performed");
this.password = null;
this.name = null;
this.baseUrl = null;
this.password = null;
this.username = null;
this.superGroup = null;
this.rootStem = null;
this.groupIncludePattern = null;
this.groupExcludePattern = null;
this.subjectSource = null;
this.groupSource = null;
}

@Override
public String toString() {
return "GrouperConfiguration{" +
"username='" + name + '\'' +
", baseUrl='" + baseUrl + '\'' +
"baseUrl='" + baseUrl + '\'' +
", username='" + username + '\'' +
", superGroup='" + superGroup + '\'' +
", rootStem='" + rootStem + '\'' +
", ignoreSslValidation='" + ignoreSslValidation + '\'' +
", groupIncludePattern=" + Arrays.toString(groupIncludePattern) +
", groupExcludePattern=" + Arrays.toString(groupExcludePattern) +
", ignoreSslValidation=" + ignoreSslValidation +
", subjectSource='" + subjectSource + '\'' +
", groupSource='" + groupSource + '\'' +
'}';
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
*
*/
@ConnectorClass(displayNameKey = "GrouperConnector.rest.display", configurationClass = GrouperConfiguration.class)

public class GrouperConnector implements TestOp, SchemaOp, Connector, SearchOp<Filter> {

private static final Log LOG = Log.getLog(GrouperConnector.class);
Expand Down Expand Up @@ -76,7 +75,7 @@ public void dispose() {
@Override
public void test() {
LOG.info("Testing connection...");
processor.test();
groupProcessor.test();
LOG.ok("Testing finished successfully.");
}

Expand Down
Loading

0 comments on commit f3701b7

Please sign in to comment.