Skip to content
This repository was archived by the owner on Sep 16, 2024. It is now read-only.

Commit f62448b

Browse files
authored
Merge pull request #196 from miguelrgonzalez/ml-gradle-issue-199
Ml gradle issue 199
2 parents e6db638 + 987dd49 commit f62448b

File tree

11 files changed

+299
-2
lines changed

11 files changed

+299
-2
lines changed

src/main/java/com/marklogic/appdeployer/ConfigDir.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
/**
1010
* Defines all of the directories where configuration files can be found.
1111
*
12-
* TODO Eventually turn this into an interface.
12+
* TODO Eventually turn this into an interface.
1313
*/
1414
public class ConfigDir {
1515

@@ -92,6 +92,10 @@ public File getUsersDir() {
9292
return new File(getSecurityDir(), "users");
9393
}
9494

95+
public File getProtectedPathsDir() { return new File(getSecurityDir(), "protected-paths"); }
96+
97+
public File getQueryRoleSetsDir() { return new File(getSecurityDir(), "query-rolesets"); }
98+
9599
public File getServersDir() {
96100
return new File(baseDir, "servers");
97101
}

src/main/java/com/marklogic/appdeployer/command/SortOrderConstants.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ public abstract class SortOrderConstants {
1313
public static Integer DEPLOY_EXTERNAL_SECURITY = 70;
1414
public static Integer DEPLOY_PROTECTED_COLLECTIONS = 80;
1515
public static Integer DEPLOY_MIMETYPES = 90;
16+
public static Integer DEPLOY_PROTECTED_PATHS = 95;
17+
public static Integer DEPLOY_QUERY_ROLE_SETS = 97;
1618

1719
public static Integer DEPLOY_TRIGGERS_DATABASE = 100;
1820
public static Integer DEPLOY_SCHEMAS_DATABASE = 100;
@@ -71,10 +73,13 @@ public abstract class SortOrderConstants {
7173
public static Integer DELETE_CERTIFICATE_AUTHORITIES = 9020;
7274
public static Integer DELETE_EXTERNAL_SECURITY = 9030;
7375
public static Integer DELETE_PROTECTED_COLLECTIONS = 9040;
76+
public static Integer DELETE_QUERY_ROLE_SETS = 9050;
7477

7578
// Roles can reference privileges, so must delete roles first
7679
public static Integer DELETE_ROLES = 9060;
7780
public static Integer DELETE_PRIVILEGES = 9070;
81+
// Protected paths reference roles
82+
public static Integer DELETE_PROTECTED_PATHS = 9080;
7883

7984
/*
8085
* This executes before databases are deleted, as deleting databases normally deletes the primary forests, so we
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.marklogic.appdeployer.command.security;
2+
3+
import com.marklogic.appdeployer.command.AbstractResourceCommand;
4+
import com.marklogic.appdeployer.command.CommandContext;
5+
import com.marklogic.appdeployer.command.SortOrderConstants;
6+
import com.marklogic.mgmt.resource.ResourceManager;
7+
import com.marklogic.mgmt.resource.security.ProtectedPathManager;
8+
import com.marklogic.mgmt.resource.security.UserManager;
9+
10+
import java.io.File;
11+
12+
public class DeployProtectedPathCommand extends AbstractResourceCommand{
13+
14+
public DeployProtectedPathCommand() {
15+
setExecuteSortOrder(SortOrderConstants.DEPLOY_PROTECTED_PATHS);
16+
setUndoSortOrder(SortOrderConstants.DELETE_PROTECTED_PATHS);
17+
}
18+
19+
@Override
20+
protected File[] getResourceDirs(CommandContext context) {
21+
return new File[] { context.getAppConfig().getConfigDir().getProtectedPathsDir() };
22+
}
23+
24+
@Override
25+
protected ResourceManager getResourceManager(CommandContext context) {
26+
return new ProtectedPathManager(context.getManageClient());
27+
}
28+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.marklogic.appdeployer.command.security;
2+
3+
import com.marklogic.appdeployer.command.AbstractResourceCommand;
4+
import com.marklogic.appdeployer.command.CommandContext;
5+
import com.marklogic.appdeployer.command.SortOrderConstants;
6+
import com.marklogic.mgmt.resource.ResourceManager;
7+
import com.marklogic.mgmt.resource.security.QueryRoleSetsManager;
8+
9+
import java.io.File;
10+
11+
public class DeployQueryRoleSetsCommand extends AbstractResourceCommand {
12+
13+
public DeployQueryRoleSetsCommand() {
14+
setExecuteSortOrder(SortOrderConstants.DEPLOY_QUERY_ROLE_SETS);
15+
setUndoSortOrder(SortOrderConstants.DELETE_QUERY_ROLE_SETS);
16+
}
17+
@Override
18+
protected File[] getResourceDirs(CommandContext context) {
19+
return new File[] { context.getAppConfig().getConfigDir().getQueryRoleSetsDir() };
20+
}
21+
22+
@Override
23+
protected ResourceManager getResourceManager(CommandContext context) {
24+
return new QueryRoleSetsManager(context.getManageClient());
25+
}
26+
}

src/main/java/com/marklogic/mgmt/PayloadParser.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ public String getPayloadFieldValue(String payload, String fieldName) {
3030
throw new RuntimeException("Cannot get field value from JSON; field name: " + fieldName + "; JSON: "
3131
+ payload);
3232
}
33-
return node.get(fieldName).asText();
33+
return node.get(fieldName).isTextual() ? node.get(fieldName).asText() : node.get(fieldName).toString();
34+
3435
} else {
3536
Fragment f = new Fragment(payload);
3637
String xpath = String.format("/node()/*[local-name(.) = '%s']", fieldName);
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
package com.marklogic.mgmt.resource.security;
2+
3+
import com.marklogic.mgmt.ManageClient;
4+
import com.marklogic.mgmt.resource.AbstractResourceManager;
5+
import com.marklogic.rest.util.Fragment;
6+
import com.marklogic.rest.util.ResourcesFragment;
7+
import org.springframework.web.client.ResourceAccessException;
8+
9+
import java.util.List;
10+
11+
public class ProtectedPathManager extends AbstractResourceManager {
12+
public ProtectedPathManager(ManageClient client) {
13+
super(client);
14+
}
15+
16+
@Override
17+
public String getResourcesPath() {
18+
return "/manage/v2/protected-paths";
19+
}
20+
21+
@Override
22+
protected String getResourceName() {
23+
return "protected-path";
24+
}
25+
26+
@Override
27+
protected String getIdFieldName() {
28+
return "path-expression";
29+
}
30+
31+
@Override
32+
public String getPropertiesPath(String resourceNameOrId, String... resourceUrlParams) {
33+
return getResourcesPath() + "/" + getIdForPathExpression(resourceNameOrId) + "/properties";
34+
}
35+
36+
@Override
37+
public String getResourcePath(String resourceNameOrId, String... resourceUrlParams) {
38+
return getResourcesPath() + "/" + getIdForPathExpression(resourceNameOrId);
39+
}
40+
41+
@Override
42+
protected String[] getDeleteResourceParams(String payload) {
43+
// We need to unprotect the path before deleting it
44+
// Otherwise we'll get a SEC-MUSTUNPROTECTPATH error
45+
return new String[]{"force", "true"};
46+
}
47+
48+
@Override
49+
public boolean exists(String resourceNameOrId, String... resourceUrlParams) {
50+
Fragment f = getAsXml();
51+
return f.elementExists(format(
52+
"/node()/*[local-name(.) = 'list-items']/node()[*[local-name(.) = 'nameref'] = '%s']",
53+
resourceNameOrId));
54+
}
55+
56+
public String getIdForPathExpression(String pathExpression) {
57+
Fragment f = getAsXml();
58+
String xpath = "/node()/*[local-name(.) = 'list-items']/node()"
59+
+ "[*[local-name(.) = 'nameref'] = '%s']/*[local-name(.) = 'idref']";
60+
xpath = String.format(xpath, pathExpression);
61+
String id = f.getElementValue(xpath);
62+
if (id == null) {
63+
throw new RuntimeException("Could not find a protected path with a path-expression of: " + pathExpression);
64+
}
65+
return id;
66+
}
67+
68+
@Override
69+
protected boolean useAdminUser() { return true; }
70+
71+
72+
/**
73+
* Testing the deployment/undeployment of protected paths intermittently fails when performing a GET on the
74+
* /manage/v2/protected-paths endpoint. A single retry seems to address the issue, though the cause is still
75+
* unknown.
76+
*
77+
* @return ResourcesFragment
78+
*/
79+
@Override
80+
public ResourcesFragment getAsXml() {
81+
try {
82+
return new ResourcesFragment(getManageClient().getXmlAsAdmin(getResourcesPath()));
83+
} catch (ResourceAccessException ex) {
84+
if (logger.isWarnEnabled()) {
85+
logger.warn("Unable to get list of protected paths, retrying; cause: " + ex.getMessage());
86+
}
87+
return new ResourcesFragment(getManageClient().getXmlAsAdmin(getResourcesPath()));
88+
}
89+
}
90+
91+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package com.marklogic.mgmt.resource.security;
2+
3+
import com.fasterxml.jackson.databind.JsonNode;
4+
import com.marklogic.mgmt.ManageClient;
5+
import com.marklogic.mgmt.PayloadParser;
6+
import com.marklogic.mgmt.resource.AbstractResourceManager;
7+
import com.marklogic.rest.util.Fragment;
8+
9+
import java.util.List;
10+
11+
public class QueryRoleSetsManager extends AbstractResourceManager {
12+
13+
private boolean updateAllowed = false;
14+
15+
public QueryRoleSetsManager(ManageClient client) {
16+
super(client);
17+
}
18+
19+
@Override
20+
public String getResourcesPath() {
21+
return "/manage/v2/query-rolesets";
22+
}
23+
24+
@Override
25+
protected String getResourceName() {
26+
return "query-rolesets";
27+
}
28+
29+
@Override
30+
protected String getIdFieldName() {
31+
return "role-name";
32+
}
33+
34+
@Override
35+
public String getPropertiesPath(String resourceNameOrId, String... resourceUrlParams) {
36+
String id = getIdForRoleNames(resourceNameOrId);
37+
if (id == null) {
38+
throw new RuntimeException("Could not find a query-roleset with roles: " + resourceNameOrId);
39+
} else return getResourcesPath() + "/" + id + "/properties";
40+
}
41+
42+
@Override
43+
public String getResourcePath(String resourceNameOrId, String... resourceUrlParams) {
44+
String id = getIdForRoleNames(resourceNameOrId);
45+
if (id == null) {
46+
throw new RuntimeException("Could not find a query-roleset with roles: " + resourceNameOrId);
47+
}else return getResourcesPath() + "/" + id;
48+
}
49+
50+
@Override
51+
public boolean exists(String resourceNameOrId, String... resourceUrlParams) {
52+
Fragment f = getAsXml();
53+
return f.elementExists(format(
54+
"/node()/*[local-name(.) = 'list-items']/node()[*[local-name(.) = 'idref'] = '%s']",
55+
getIdForRoleNames(resourceNameOrId)));
56+
}
57+
58+
public String getIdForRoleNames(String roles) {
59+
Fragment f = getAsXml();
60+
String xpath = "/node()/*[local-name(.) = 'list-items']/node()/*[local-name(.) = 'idref']";
61+
String roleSetId = null;
62+
63+
//Transform roles into role JSON array
64+
JsonNode roleArray = payloadParser.parseJson(roles);
65+
66+
//Get list of existing rolesets
67+
for(String id : f.getElementValues(xpath)) {
68+
String response =
69+
payloadParser.getPayloadFieldValue(
70+
getManageClient().getJson(getResourcesPath() + "/" + id + "/properties"),
71+
getIdFieldName()
72+
);
73+
74+
//does this roleset contain the same list of roles?
75+
if (roleArray.equals(payloadParser.parseJson(response))) {
76+
roleSetId = id;
77+
break;
78+
}
79+
}
80+
return roleSetId;
81+
}
82+
83+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.marklogic.appdeployer.command.security;
2+
3+
import com.marklogic.appdeployer.command.AbstractManageResourceTest;
4+
import com.marklogic.appdeployer.command.Command;
5+
import com.marklogic.mgmt.resource.ResourceManager;
6+
import com.marklogic.mgmt.resource.security.ProtectedPathManager;
7+
8+
public class ManageProtectedPathsTest extends AbstractManageResourceTest {
9+
@Override
10+
protected ResourceManager newResourceManager() {
11+
return new ProtectedPathManager(manageClient);
12+
}
13+
14+
@Override
15+
protected Command newCommand() {
16+
return new DeployProtectedPathCommand();
17+
}
18+
19+
@Override
20+
protected String[] getResourceNames() {
21+
return new String[] { "/test:element" };
22+
}
23+
24+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.marklogic.appdeployer.command.security;
2+
3+
import com.marklogic.appdeployer.command.AbstractManageResourceTest;
4+
import com.marklogic.appdeployer.command.Command;
5+
import com.marklogic.mgmt.resource.ResourceManager;
6+
import com.marklogic.mgmt.resource.security.QueryRoleSetsManager;
7+
8+
public class ManageQueryRoleSetsTest extends AbstractManageResourceTest {
9+
@Override
10+
protected ResourceManager newResourceManager() {
11+
return new QueryRoleSetsManager(manageClient);
12+
}
13+
14+
@Override
15+
protected Command newCommand() {
16+
return new DeployQueryRoleSetsCommand();
17+
}
18+
19+
@Override
20+
protected String[] getResourceNames() {
21+
return new String[] { "[\"view-admin\"]" };
22+
}
23+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"path-expression":"/test:element",
3+
"path-namespace":[
4+
{"prefix":"test", "namespace-uri":"http://marklogic.com"}
5+
],
6+
"permission": [
7+
{"role-name":"view-admin", "capability":"read"}
8+
]
9+
}

0 commit comments

Comments
 (0)