This is an automated email from the ASF dual-hosted git repository.
tabish pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/artemis.git
The following commit(s) were added to refs/heads/main by this push:
new acf60a8809 ARTEMIS-5092 add security-setting mngmnt via JSON
acf60a8809 is described below
commit acf60a880992f61133559f49500ea8330517543c
Author: Justin Bertram <[email protected]>
AuthorDate: Thu Dec 11 17:03:40 2025 -0600
ARTEMIS-5092 add security-setting mngmnt via JSON
This commit includes the following changes:
- A few new testing & debugging helper methods.
- Deprecated existing security-settings management methods
- New security-settings management method accepting JSON input
- Simplified RoleInfo by extending Role
- Added constants for permission types & used them where possible
- Clarified deprepcation for Role ctors
- Added support methods for JSON conversion
- Added tests for JSON conversion support methods, etc.
---
.../apache/activemq/artemis/utils/JsonLoader.java | 23 ++
.../apache/activemq/artemis/utils/RandomUtil.java | 14 +
.../apache/activemq/artemis/api/core/JsonUtil.java | 18 ++
.../api/core/management/ActiveMQServerControl.java | 55 +++-
.../artemis/api/core/management/RoleInfo.java | 122 +--------
.../activemq/artemis/core/security/Role.java | 146 ++++++-----
.../activemq/artemis/utils/SecurityFormatter.java | 284 +++++++++++++++++++--
.../activemq/artemis/api/core/JsonUtilTest.java | 19 ++
.../artemis/util/SecurityFormatterTest.java | 191 ++++++++++++++
.../deployers/impl/FileConfigurationParser.java | 62 ++---
.../management/impl/ActiveMQServerControlImpl.java | 20 +-
.../config/PersistedSecuritySetting.java | 68 +++--
.../core/server/impl/ActiveMQServerImpl.java | 13 +-
.../management/ActiveMQServerControlTest.java | 54 +++-
.../ActiveMQServerControlUsingCoreTest.java | 5 +
.../tests/unit/core/util/RandomUtilTest.java | 19 +-
16 files changed, 854 insertions(+), 259 deletions(-)
diff --git
a/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/JsonLoader.java
b/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/JsonLoader.java
index 6ff1f04129..8ee101c3f6 100644
---
a/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/JsonLoader.java
+++
b/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/JsonLoader.java
@@ -26,8 +26,13 @@ import
org.apache.activemq.artemis.json.impl.JsonObjectBuilderImpl;
import org.apache.activemq.artemis.json.impl.JsonObjectImpl;
import javax.json.JsonReader;
+import javax.json.JsonWriter;
import javax.json.spi.JsonProvider;
import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.Map;
/**
* This is to make sure we use the proper classLoader to load JSon libraries.
This is equivalent to using
@@ -43,6 +48,12 @@ public class JsonLoader {
}
}
+ public static void writeObject(Map<String, Object> properties, Writer
writer, JsonObject jsonObject) {
+ try (JsonWriter jsonReader =
provider.createWriterFactory(properties).createWriter(writer)) {
+ jsonReader.writeObject((((JsonObjectImpl)jsonObject).getRawObject()));
+ }
+ }
+
public static JsonArray readArray(Reader reader) {
try (JsonReader jsonReader = provider.createReader(reader)) {
return new JsonArrayImpl(jsonReader.readArray());
@@ -56,4 +67,16 @@ public class JsonLoader {
public static JsonObjectBuilder createObjectBuilder() {
return new JsonObjectBuilderImpl(provider.createObjectBuilder());
}
+
+ // Please do not remove this method as it's useful for debugging purposes
+ public static String prettyPrint(String json) {
+ String result = json;
+ try (StringReader reader = new StringReader(json);
+ StringWriter writer = new StringWriter()) {
+
JsonLoader.writeObject(Map.of(javax.json.stream.JsonGenerator.PRETTY_PRINTING,
true), writer, JsonLoader.readObject(reader));
+ result = writer.toString();
+ } catch (Exception e) {
+ }
+ return result;
+ }
}
diff --git
a/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/RandomUtil.java
b/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/RandomUtil.java
index 8e88389213..b1d7b032fe 100644
---
a/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/RandomUtil.java
+++
b/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/RandomUtil.java
@@ -175,4 +175,18 @@ public class RandomUtil {
return RandomUtil.random.nextFloat();
}
+ /**
+ * Generates an array of random alpha-numeric words. The words will be of a
random length between 1 and 10
+ * characters.
+ *
+ * @param wordCount the number of random words to generate
+ * @return an array of randomly generated alpha-numeric words between 1 and
10 characters long
+ */
+ public static String[] randomWords(int wordCount) {
+ String[] words = new String[wordCount];
+ for (int i = 0; i < wordCount; i++) {
+ words[i] = randomAlphaNumericString((randomPositiveInt() % 10) + 1);
+ }
+ return words;
+ }
}
diff --git
a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/JsonUtil.java
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/JsonUtil.java
index cfc0fb20eb..4aad12eeea 100644
---
a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/JsonUtil.java
+++
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/JsonUtil.java
@@ -26,6 +26,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.stream.Collectors;
import org.apache.activemq.artemis.json.JsonArray;
import org.apache.activemq.artemis.json.JsonArrayBuilder;
@@ -456,4 +457,21 @@ public final class JsonUtil {
return s;
}
}
+
+ /**
+ * Converts a JSON array from the specified key in a JsonObject into a
comma-separated string. If the key does not
+ * exist or if its value is not a JSON array, then an empty string is
returned.
+ *
+ * @param jsonObject the JsonObject from which to retrieve the array
+ * @param key the key associated with the JSON array in the
JsonObject
+ * @return a comma-separated string representation of the array's elements,
or an empty string if the key does not
+ * exist or the value is not an array
+ */
+ public static String arrayToString(JsonObject jsonObject, String key) {
+ JsonValue value = jsonObject.get(key);
+ if (value == null || value.getValueType() != JsonValue.ValueType.ARRAY) {
+ return "";
+ }
+ return jsonObject.getJsonArray(key).stream().map((s) -> ((JsonString)
s).getString()).collect(Collectors.joining(", "));
+ }
}
diff --git
a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/management/ActiveMQServerControl.java
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/management/ActiveMQServerControl.java
index c744e7aea4..4169cf7898 100644
---
a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/management/ActiveMQServerControl.java
+++
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/management/ActiveMQServerControl.java
@@ -1382,6 +1382,10 @@ public interface ActiveMQServerControl {
@Operation(desc = "List the sessions for the given connectionID", impact =
MBeanOperationInfo.INFO)
String[] listSessions(@Parameter(desc = "a connection ID", name =
"connectionID") String connectionID) throws Exception;
+ /**
+ * @deprecated use {@link ActiveMQServerControl#addSecuritySettings(String,
String)}
+ */
+ @Deprecated(forRemoval = true)
@Operation(desc = "Add security settings for addresses matching the
addressMatch", impact = MBeanOperationInfo.ACTION)
void addSecuritySettings(@Parameter(desc = "an address match", name =
"addressMatch") String addressMatch,
@Parameter(desc = "a comma-separated list of roles
allowed to send messages", name = "send") String sendRoles,
@@ -1392,6 +1396,10 @@ public interface ActiveMQServerControl {
@Parameter(desc = "a comma-separated list of roles
allowed to delete non durable queues", name = "deleteNonDurableQueueRoles")
String deleteNonDurableQueueRoles,
@Parameter(desc = "a comma-separated list of roles
allowed to send management messages messages", name = "manage") String
manageRoles) throws Exception;
+ /**
+ * @deprecated use {@link ActiveMQServerControl#addSecuritySettings(String,
String)}
+ */
+ @Deprecated(forRemoval = true)
@Operation(desc = "Add security settings for addresses matching the
addressMatch", impact = MBeanOperationInfo.ACTION)
void addSecuritySettings(@Parameter(desc = "an address match", name =
"addressMatch") String addressMatch,
@Parameter(desc = "a comma-separated list of roles
allowed to send messages", name = "send") String sendRoles,
@@ -1403,6 +1411,10 @@ public interface ActiveMQServerControl {
@Parameter(desc = "a comma-separated list of roles
allowed to send management messages messages", name = "manage") String
manageRoles,
@Parameter(desc = "a comma-separated list of roles
allowed to browse queues", name = "browse") String browseRoles) throws
Exception;
+ /**
+ * @deprecated use {@link ActiveMQServerControl#addSecuritySettings(String,
String)}
+ */
+ @Deprecated(forRemoval = true)
@Operation(desc = "Add security settings for addresses matching the
addressMatch", impact = MBeanOperationInfo.ACTION)
void addSecuritySettings(@Parameter(desc = "an address match", name =
"addressMatch") String addressMatch,
@Parameter(desc = "a comma-separated list of roles
allowed to send messages", name = "send") String sendRoles,
@@ -1416,6 +1428,10 @@ public interface ActiveMQServerControl {
@Parameter(desc = "a comma-separated list of roles
allowed to create addresses", name = "createAddressRoles") String
createAddressRoles,
@Parameter(desc = "a comma-separated list of roles
allowed to delete addresses", name = "deleteAddressRoles") String
deleteAddressRoles) throws Exception;
+ /**
+ * @deprecated use {@link ActiveMQServerControl#addSecuritySettings(String,
String)}
+ */
+ @Deprecated(forRemoval = true)
@Operation(desc = "Add security settings for addresses matching the
addressMatch", impact = MBeanOperationInfo.ACTION)
void addSecuritySettings(@Parameter(desc = "an address match", name =
"addressMatch") String addressMatch,
@Parameter(desc = "a comma-separated list of roles
allowed to send messages", name = "send") String sendRoles,
@@ -1431,6 +1447,43 @@ public interface ActiveMQServerControl {
@Parameter(desc = "a comma-separated list of roles
allowed to view management resources", name = "view") String viewRoles,
@Parameter(desc = "a comma-separated list of roles
allowed to edit management resources", name = "edit") String editRoles) throws
Exception;
+ /**
+ * Add security-settings for matching addresses.
+ *
+ * @param addressMatch The address match pattern to which the
security-settings will be applied.
+ * @param securitySettingsAsJson The security-settings in JSON format. The
JSON consists of key/value pairs where the
+ * key is a string representing the
permission type, and the value is an array of
+ * strings containing the names of the roles
which will be granted the corresponding
+ * permission, e.g.:
+ * <pre>{@code
+ * {
+ * "send": ["role1", "role2"],
+ * "consume": ["role3", "role4"],
+ * "createDurableQueue": ["role5", "role6"]
+ * }
+ * }</pre>
+ * These permission types are supported:
+ * <ul>
+ * <li>send</li>
+ * <li>consume</li>
+ * <li>createDurableQueue</li>
+ * <li>deleteDurableQueue</li>
+ * <li>createNonDurableQueue</li>
+ * <li>deleteNonDurableQueue</li>
+ * <li>manage</li>
+ * <li>browse</li>
+ * <li>createAddress</li>
+ * <li>deleteAddress</li>
+ * <li>view</li>
+ * <li>edit</li>
+ * </ul>
+ * This JSON can be constructed using methods
from {@link org.apache.activemq.artemis.utils.SecurityFormatter}.
+ * @throws Exception If an error occurs while adding the security-settings.
+ */
+ @Operation(desc = "Add security-settings for matching addresses", impact =
MBeanOperationInfo.ACTION)
+ void addSecuritySettings(@Parameter(desc = "an address match", name =
"addressMatch") String addressMatch,
+ @Parameter(desc = "The configuration of the
security-settings as JSON", name = "securitySettingsAsJson") String
securitySettingsAsJson) throws Exception;
+
@Operation(desc = "Remove security settings for an address", impact =
MBeanOperationInfo.ACTION)
void removeSecuritySettings(@Parameter(desc = "an address match", name =
"addressMatch") String addressMatch) throws Exception;
@@ -1685,7 +1738,7 @@ public interface ActiveMQServerControl {
* adds a new address setting for a specific address
*/
@Operation(desc = "Add address settings for addresses matching the
addressMatch", impact = MBeanOperationInfo.ACTION)
- String addAddressSettings(@Parameter(desc = "an address match", name =
"addressMatch") String address, @Parameter(desc = "The configuration of the
address settings as JSON", name = "addressSettingsConfigurationAsJson") String
addressSettingsConfigurationAsJson) throws Exception;
+ String addAddressSettings(@Parameter(desc = "an address match", name =
"addressMatch") String address, @Parameter(desc = "The configuration of the
address settings as JSON", name = "addressSettingsConfigurationAsJson") String
addressSettingsConfigurationAsJson) throws Exception;
@Operation(desc = "Remove address settings", impact =
MBeanOperationInfo.ACTION)
void removeAddressSettings(@Parameter(desc = "an address match", name =
"addressMatch") String addressMatch) throws Exception;
diff --git
a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/management/RoleInfo.java
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/management/RoleInfo.java
index ec89d552ee..24204e4c8e 100644
---
a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/management/RoleInfo.java
+++
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/management/RoleInfo.java
@@ -16,37 +16,15 @@
*/
package org.apache.activemq.artemis.api.core.management;
+import org.apache.activemq.artemis.api.core.JsonUtil;
+import org.apache.activemq.artemis.core.security.Role;
import org.apache.activemq.artemis.json.JsonArray;
import org.apache.activemq.artemis.json.JsonObject;
-import org.apache.activemq.artemis.api.core.JsonUtil;
-
/**
* Helper class to create Java Objects from the JSON serialization returned by
{@link AddressControl#getRolesAsJSON()}.
*/
-public final class RoleInfo {
-
- private final String name;
-
- private final boolean send;
-
- private final boolean consume;
-
- private final boolean createDurableQueue;
-
- private final boolean deleteDurableQueue;
-
- private final boolean createNonDurableQueue;
-
- private final boolean deleteNonDurableQueue;
-
- private final boolean manage;
-
- private final boolean browse;
-
- private final boolean createAddress;
-
- private final boolean deleteAddress;
+public final class RoleInfo extends Role {
/**
* {@return an array of RoleInfo corresponding to the JSON serialization
returned by {@link
@@ -59,16 +37,16 @@ public final class RoleInfo {
JsonObject r = array.getJsonObject(i);
RoleInfo role = new RoleInfo(
r.getString("name"),
- r.getBoolean("send"),
- r.getBoolean("consume"),
- r.getBoolean("createDurableQueue"),
- r.getBoolean("deleteDurableQueue"),
- r.getBoolean("createNonDurableQueue"),
- r.getBoolean("deleteNonDurableQueue"),
- r.getBoolean("manage"),
- r.getBoolean("browse"),
- r.getBoolean("createAddress"),
- r.getBoolean("deleteAddress"));
+ r.getBoolean(SEND_PERMISSION),
+ r.getBoolean(CONSUME_PERMISSION),
+ r.getBoolean(CREATE_DURABLE_QUEUE_PERMISSION),
+ r.getBoolean(DELETE_DURABLE_QUEUE_PERMISSION),
+ r.getBoolean(CREATE_NONDURABLE_QUEUE_PERMISSION),
+ r.getBoolean(DELETE_NONDURABLE_QUEUE_PERMISSION),
+ r.getBoolean(MANAGE_PERMISSION),
+ r.getBoolean(BROWSE_PERMISSION),
+ r.getBoolean(CREATE_ADDRESS_PERMISSION),
+ r.getBoolean(DELETE_ADDRESS_PERMISSION));
roles[i] = role;
}
return roles;
@@ -97,78 +75,4 @@ public final class RoleInfo {
this.createAddress = createAddress;
this.deleteAddress = deleteAddress;
}
-
- public String getName() {
- return name;
- }
-
- /**
- * {@return whether this role can send messages to the address}
- */
- public boolean isSend() {
- return send;
- }
-
- /**
- * {@return whether this role can consume messages from queues bound to the
address}
- */
- public boolean isConsume() {
- return consume;
- }
-
- /**
- * {@return whether this role can create durable queues bound to the
address}
- */
- public boolean isCreateDurableQueue() {
- return createDurableQueue;
- }
-
- /**
- * {@return whether this role can delete durable queues bound to the
address}
- */
- public boolean isDeleteDurableQueue() {
- return deleteDurableQueue;
- }
-
- /**
- * {@return whether this role can create non-durable queues bound to the
address}
- */
- public boolean isCreateNonDurableQueue() {
- return createNonDurableQueue;
- }
-
- /**
- * {@return whether this role can delete non-durable queues bound to the
address}
- */
- public boolean isDeleteNonDurableQueue() {
- return deleteNonDurableQueue;
- }
-
- /**
- * {@return whether this role can send management messages to the address}
- */
- public boolean isManage() {
- return manage;
- }
-
- /**
- * {@return whether this role can browse queues bound to the address}
- */
- public boolean isBrowse() {
- return browse;
- }
-
- /**
- * {@return whether this role can create addresses}
- */
- public boolean isCreateAddress() {
- return createAddress;
- }
-
- /**
- * {@return whether this role can delete addresses}
- */
- public boolean isDeleteAddress() {
- return deleteAddress;
- }
}
diff --git
a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/security/Role.java
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/security/Role.java
index 395e0cc507..89e2df372a 100644
---
a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/security/Role.java
+++
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/security/Role.java
@@ -27,37 +27,63 @@ import org.apache.activemq.artemis.utils.JsonLoader;
*/
public class Role implements Serializable {
+ public static final String SEND_PERMISSION = "send";
+ public static final String CONSUME_PERMISSION = "consume";
+ public static final String CREATE_DURABLE_QUEUE_PERMISSION =
"createDurableQueue";
+ public static final String DELETE_DURABLE_QUEUE_PERMISSION =
"deleteDurableQueue";
+ public static final String CREATE_NONDURABLE_QUEUE_PERMISSION =
"createNonDurableQueue";
+ public static final String DELETE_NONDURABLE_QUEUE_PERMISSION =
"deleteNonDurableQueue";
+ public static final String MANAGE_PERMISSION = "manage";
+ public static final String BROWSE_PERMISSION = "browse";
+ public static final String CREATE_ADDRESS_PERMISSION = "createAddress";
+ public static final String DELETE_ADDRESS_PERMISSION = "deleteAddress";
+ public static final String VIEW_PERMISSION = "view";
+ public static final String EDIT_PERMISSION = "edit";
+
private static final long serialVersionUID = 3560097227776448872L;
- private String name;
+ protected String name;
- private boolean send;
+ protected boolean send;
- private boolean consume;
+ protected boolean consume;
- private boolean createAddress;
+ protected boolean createAddress;
- private boolean deleteAddress;
+ protected boolean deleteAddress;
- private boolean createDurableQueue;
+ protected boolean createDurableQueue;
- private boolean deleteDurableQueue;
+ protected boolean deleteDurableQueue;
- private boolean createNonDurableQueue;
+ protected boolean createNonDurableQueue;
- private boolean deleteNonDurableQueue;
+ protected boolean deleteNonDurableQueue;
- private boolean manage;
+ protected boolean manage;
- private boolean browse;
+ protected boolean browse;
- private boolean view;
+ protected boolean view;
- private boolean edit;
+ protected boolean edit;
public JsonObject toJson() {
- return JsonLoader.createObjectBuilder().add("name", name).add("send",
send).add("consume", consume).add("createDurableQueue",
createDurableQueue).add("deleteDurableQueue",
deleteDurableQueue).add("createNonDurableQueue",
createNonDurableQueue).add("deleteNonDurableQueue",
deleteNonDurableQueue).add("manage", manage)
- .add("browse", browse).add("createAddress",
createAddress).add("deleteAddress", deleteAddress).add("view",
view).add("edit", edit).build();
+ return JsonLoader.createObjectBuilder()
+ .add("name", name)
+ .add(SEND_PERMISSION, send)
+ .add(CONSUME_PERMISSION, consume)
+ .add(CREATE_DURABLE_QUEUE_PERMISSION, createDurableQueue)
+ .add(DELETE_DURABLE_QUEUE_PERMISSION, deleteDurableQueue)
+ .add(CREATE_NONDURABLE_QUEUE_PERMISSION, createNonDurableQueue)
+ .add(DELETE_NONDURABLE_QUEUE_PERMISSION, deleteNonDurableQueue)
+ .add(MANAGE_PERMISSION, manage)
+ .add(BROWSE_PERMISSION, browse)
+ .add(CREATE_ADDRESS_PERMISSION, createAddress)
+ .add(DELETE_ADDRESS_PERMISSION, deleteAddress)
+ .add(VIEW_PERMISSION, view)
+ .add(EDIT_PERMISSION, edit)
+ .build();
}
public Role() {
@@ -65,9 +91,9 @@ public class Role implements Serializable {
}
/**
- * @deprecated Use {@link #Role(String, boolean, boolean, boolean, boolean,
boolean, boolean, boolean, boolean)}
+ * @deprecated Use {@link #Role(String, boolean, boolean, boolean, boolean,
boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean)}
*/
- @Deprecated
+ @Deprecated(forRemoval = true)
public Role(final String name,
final boolean send,
final boolean consume,
@@ -81,7 +107,10 @@ public class Role implements Serializable {
this(name, send, consume, createDurableQueue, deleteDurableQueue,
createNonDurableQueue, deleteNonDurableQueue, manage, consume);
}
- @Deprecated
+ /**
+ * @deprecated Use {@link #Role(String, boolean, boolean, boolean, boolean,
boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean)}
+ */
+ @Deprecated(forRemoval = true)
public Role(final String name,
final boolean send,
final boolean consume,
@@ -96,7 +125,10 @@ public class Role implements Serializable {
this(name, send, consume, createDurableQueue, deleteDurableQueue,
createNonDurableQueue, deleteNonDurableQueue, manage, browse,
createDurableQueue || createNonDurableQueue, deleteDurableQueue ||
deleteNonDurableQueue, false, false);
}
- @Deprecated
+ /**
+ * @deprecated Use {@link #Role(String, boolean, boolean, boolean, boolean,
boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean)}
+ */
+ @Deprecated(forRemoval = true)
public Role(final String name,
final boolean send,
final boolean consume,
@@ -183,6 +215,14 @@ public class Role implements Serializable {
return browse;
}
+ public boolean isEdit() {
+ return edit;
+ }
+
+ public boolean isView() {
+ return view;
+ }
+
public void setName(String name) {
this.name = name;
}
@@ -227,45 +267,53 @@ public class Role implements Serializable {
this.browse = browse;
}
+ public void setEdit(boolean edit) {
+ this.edit = edit;
+ }
+
+ public void setView(boolean view) {
+ this.view = view;
+ }
+
@Override
public String toString() {
StringBuilder stringReturn = new StringBuilder("Role {name=" + name + ";
allows=[");
if (send) {
- stringReturn.append(" send ");
+ stringReturn.append(" " + SEND_PERMISSION + " ");
}
if (consume) {
- stringReturn.append(" consume ");
- }
- if (createAddress) {
- stringReturn.append(" createAddress ");
- }
- if (deleteAddress) {
- stringReturn.append(" deleteAddress ");
+ stringReturn.append(" " + CONSUME_PERMISSION + " ");
}
if (createDurableQueue) {
- stringReturn.append(" createDurableQueue ");
+ stringReturn.append(" " + CREATE_DURABLE_QUEUE_PERMISSION + " ");
}
if (deleteDurableQueue) {
- stringReturn.append(" deleteDurableQueue ");
+ stringReturn.append(" " + DELETE_DURABLE_QUEUE_PERMISSION + " ");
}
if (createNonDurableQueue) {
- stringReturn.append(" createNonDurableQueue ");
+ stringReturn.append(" " + CREATE_NONDURABLE_QUEUE_PERMISSION + " ");
}
if (deleteNonDurableQueue) {
- stringReturn.append(" deleteNonDurableQueue ");
+ stringReturn.append(" " + DELETE_NONDURABLE_QUEUE_PERMISSION + " ");
}
if (manage) {
- stringReturn.append(" manage ");
+ stringReturn.append(" " + MANAGE_PERMISSION + " ");
}
if (browse) {
- stringReturn.append(" browse ");
+ stringReturn.append(" " + BROWSE_PERMISSION + " ");
+ }
+ if (createAddress) {
+ stringReturn.append(" " + CREATE_ADDRESS_PERMISSION + " ");
+ }
+ if (deleteAddress) {
+ stringReturn.append(" " + DELETE_ADDRESS_PERMISSION + " ");
}
if (view) {
- stringReturn.append(" view ");
+ stringReturn.append(" " + VIEW_PERMISSION + " ");
}
if (edit) {
- stringReturn.append(" edit ");
+ stringReturn.append(" " + EDIT_PERMISSION + " ");
}
stringReturn.append("]}");
@@ -284,52 +332,36 @@ public class Role implements Serializable {
return Objects.equals(name, other.name) &&
send == other.send &&
consume == other.consume &&
- createAddress == other.createAddress &&
- deleteAddress == other.deleteAddress &&
createDurableQueue == other.createDurableQueue &&
createNonDurableQueue == other.createNonDurableQueue &&
deleteDurableQueue == other.deleteDurableQueue &&
deleteNonDurableQueue == other.deleteNonDurableQueue &&
manage == other.manage &&
browse == other.browse &&
+ createAddress == other.createAddress &&
+ deleteAddress == other.deleteAddress &&
view == other.view &&
edit == other.edit;
}
@Override
public int hashCode() {
- return Objects.hash(name, send, consume, createAddress, deleteAddress,
createDurableQueue, deleteDurableQueue,
- createNonDurableQueue, deleteNonDurableQueue,
manage, browse, view, edit);
+ return Objects.hash(name, send, consume, createDurableQueue,
deleteDurableQueue, createNonDurableQueue,
+ deleteNonDurableQueue, manage, browse,
createAddress, deleteAddress, view, edit);
}
public void merge(Role other) {
send = send || other.send;
consume = consume || other.consume;
- createAddress = createAddress || other.createAddress;
- deleteAddress = deleteAddress || other.deleteAddress;
createDurableQueue = createDurableQueue || other.createDurableQueue;
deleteDurableQueue = deleteDurableQueue || other.deleteDurableQueue;
createNonDurableQueue = createNonDurableQueue ||
other.createNonDurableQueue;
deleteNonDurableQueue = deleteNonDurableQueue ||
other.deleteNonDurableQueue;
manage = manage || other.manage;
browse = browse || other.browse;
+ createAddress = createAddress || other.createAddress;
+ deleteAddress = deleteAddress || other.deleteAddress;
view = view || other.view;
edit = edit || other.edit;
}
-
- public boolean isEdit() {
- return edit;
- }
-
- public void setEdit(boolean edit) {
- this.edit = edit;
- }
-
- public boolean isView() {
- return view;
- }
-
- public void setView(boolean view) {
- this.view = view;
- }
}
diff --git
a/artemis-core-client/src/main/java/org/apache/activemq/artemis/utils/SecurityFormatter.java
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/utils/SecurityFormatter.java
index 9dfd54c3c5..373d44c233 100644
---
a/artemis-core-client/src/main/java/org/apache/activemq/artemis/utils/SecurityFormatter.java
+++
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/utils/SecurityFormatter.java
@@ -22,10 +22,231 @@ import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;
+import org.apache.activemq.artemis.api.core.JsonUtil;
+import org.apache.activemq.artemis.api.core.management.ActiveMQServerControl;
import org.apache.activemq.artemis.core.security.Role;
+import org.apache.activemq.artemis.json.JsonArrayBuilder;
+import org.apache.activemq.artemis.json.JsonObject;
+import org.apache.activemq.artemis.json.JsonObjectBuilder;
+import org.apache.activemq.artemis.json.JsonString;
+import static org.apache.activemq.artemis.core.security.Role.BROWSE_PERMISSION;
+import static
org.apache.activemq.artemis.core.security.Role.CONSUME_PERMISSION;
+import static
org.apache.activemq.artemis.core.security.Role.CREATE_ADDRESS_PERMISSION;
+import static
org.apache.activemq.artemis.core.security.Role.CREATE_DURABLE_QUEUE_PERMISSION;
+import static
org.apache.activemq.artemis.core.security.Role.CREATE_NONDURABLE_QUEUE_PERMISSION;
+import static
org.apache.activemq.artemis.core.security.Role.DELETE_ADDRESS_PERMISSION;
+import static
org.apache.activemq.artemis.core.security.Role.DELETE_DURABLE_QUEUE_PERMISSION;
+import static
org.apache.activemq.artemis.core.security.Role.DELETE_NONDURABLE_QUEUE_PERMISSION;
+import static org.apache.activemq.artemis.core.security.Role.EDIT_PERMISSION;
+import static org.apache.activemq.artemis.core.security.Role.MANAGE_PERMISSION;
+import static org.apache.activemq.artemis.core.security.Role.SEND_PERMISSION;
+import static org.apache.activemq.artemis.core.security.Role.VIEW_PERMISSION;
+
+/**
+ * A utility class mainly for converting back and forth between JSON and a
{@code Set} of {@link Role} objects.
+ * <p>
+ * This is necessary because while security-settings are configured via XML
and JSON as well as stored in the journal as
+ * a list of role names keyed by permission type, they are handled by the
broker in a {@code HierarchicalRepository} as
+ * a {@code Set} of {@link Role} objects where each {@link Role} object
contains the role name and a boolean for each
+ * permission type. Therefore, we need methods to convert between the two
representations.
+ */
public class SecurityFormatter {
+ /**
+ * Converts a {@code Set} of {@link Role} objects into a JSON string
representation.
+ *
+ * @param roles the {@code Set} of {@link Role} objects to be converted
into JSON.
+ * @return JSON representing the permission types and their associated role
names. See
+ * {@link ActiveMQServerControl#addSecuritySettings(String, String)} for
details about the JSON structure.
+ */
+ public static String toJSON(Set<Role> roles) {
+ JsonObjectBuilder builder = JsonLoader.createObjectBuilder();
+ JsonArrayBuilder sendRoles = JsonLoader.createArrayBuilder();
+ JsonArrayBuilder consumeRoles = JsonLoader.createArrayBuilder();
+ JsonArrayBuilder createDurableQueueRoles =
JsonLoader.createArrayBuilder();
+ JsonArrayBuilder deleteDurableQueueRoles =
JsonLoader.createArrayBuilder();
+ JsonArrayBuilder createNonDurableQueueRoles =
JsonLoader.createArrayBuilder();
+ JsonArrayBuilder deleteNonDurableQueueRoles =
JsonLoader.createArrayBuilder();
+ JsonArrayBuilder manageRoles = JsonLoader.createArrayBuilder();
+ JsonArrayBuilder browseRoles = JsonLoader.createArrayBuilder();
+ JsonArrayBuilder createAddressRoles = JsonLoader.createArrayBuilder();
+ JsonArrayBuilder deleteAddressRoles = JsonLoader.createArrayBuilder();
+ JsonArrayBuilder viewRoles = JsonLoader.createArrayBuilder();
+ JsonArrayBuilder editRoles = JsonLoader.createArrayBuilder();
+
+ for (Role role : roles) {
+ if (role.isSend()) {
+ sendRoles.add(role.getName());
+ }
+ if (role.isConsume()) {
+ consumeRoles.add(role.getName());
+ }
+ if (role.isCreateDurableQueue()) {
+ createDurableQueueRoles.add(role.getName());
+ }
+ if (role.isDeleteDurableQueue()) {
+ deleteDurableQueueRoles.add(role.getName());
+ }
+ if (role.isCreateNonDurableQueue()) {
+ createNonDurableQueueRoles.add(role.getName());
+ }
+ if (role.isDeleteNonDurableQueue()) {
+ deleteNonDurableQueueRoles.add(role.getName());
+ }
+ if (role.isManage()) {
+ manageRoles.add(role.getName());
+ }
+ if (role.isBrowse()) {
+ browseRoles.add(role.getName());
+ }
+ if (role.isCreateAddress()) {
+ createAddressRoles.add(role.getName());
+ }
+ if (role.isDeleteAddress()) {
+ deleteAddressRoles.add(role.getName());
+ }
+ if (role.isView()) {
+ viewRoles.add(role.getName());
+ }
+ if (role.isEdit()) {
+ editRoles.add(role.getName());
+ }
+ }
+ return builder
+ .add(SEND_PERMISSION, sendRoles)
+ .add(CONSUME_PERMISSION, consumeRoles)
+ .add(CREATE_DURABLE_QUEUE_PERMISSION, createDurableQueueRoles)
+ .add(DELETE_DURABLE_QUEUE_PERMISSION, deleteDurableQueueRoles)
+ .add(CREATE_NONDURABLE_QUEUE_PERMISSION, createNonDurableQueueRoles)
+ .add(DELETE_NONDURABLE_QUEUE_PERMISSION, deleteNonDurableQueueRoles)
+ .add(MANAGE_PERMISSION, manageRoles)
+ .add(BROWSE_PERMISSION, browseRoles)
+ .add(CREATE_ADDRESS_PERMISSION, createAddressRoles)
+ .add(DELETE_ADDRESS_PERMISSION, deleteAddressRoles)
+ .add(VIEW_PERMISSION, viewRoles)
+ .add(EDIT_PERMISSION, editRoles)
+ .build().toString();
+ }
+
+ /**
+ * Converts the specified role permissions into a JSON string
representation. Each permission category maps to an
+ * array of role names.
+ *
+ * @param sendRoles a comma-separated string of role names
allowed to send messages
+ * @param consumeRoles a comma-separated string of role names
allowed to consume messages
+ * @param createDurableQueueRoles a comma-separated string of role names
allowed to create durable queues
+ * @param deleteDurableQueueRoles a comma-separated string of role names
allowed to delete durable queues
+ * @param createNonDurableQueueRoles a comma-separated string of role names
allowed to create non-durable queues
+ * @param deleteNonDurableQueueRoles a comma-separated string of role names
allowed to delete non-durable queues
+ * @param manageRoles a comma-separated string of role names
allowed to manage resources
+ * @param browseRoles a comma-separated string of role names
allowed to browse messages
+ * @param createAddressRoles a comma-separated string of role names
allowed to create addresses
+ * @param deleteAddressRoles a comma-separated string of role names
allowed to delete addresses
+ * @param viewRoles a comma-separated string of role names
allowed to view resources
+ * @param editRoles a comma-separated string of role names
allowed to edit resources
+ * @return JSON representing the permission types and their associated role
names. See
+ * {@link ActiveMQServerControl#addSecuritySettings(String, String)} for
details about the JSON structure.
+ */
+ public static String toJSON(final String sendRoles,
+ final String consumeRoles,
+ final String createDurableQueueRoles,
+ final String deleteDurableQueueRoles,
+ final String createNonDurableQueueRoles,
+ final String deleteNonDurableQueueRoles,
+ final String manageRoles,
+ final String browseRoles,
+ final String createAddressRoles,
+ final String deleteAddressRoles,
+ final String viewRoles,
+ final String editRoles) {
+ return JsonLoader.createObjectBuilder()
+ .add(SEND_PERMISSION, JsonUtil.toJsonArray(toListOfRoles(sendRoles)))
+ .add(CONSUME_PERMISSION,
JsonUtil.toJsonArray(toListOfRoles(consumeRoles)))
+ .add(CREATE_DURABLE_QUEUE_PERMISSION,
JsonUtil.toJsonArray(toListOfRoles(createDurableQueueRoles)))
+ .add(DELETE_DURABLE_QUEUE_PERMISSION,
JsonUtil.toJsonArray(toListOfRoles(deleteDurableQueueRoles)))
+ .add(CREATE_NONDURABLE_QUEUE_PERMISSION,
JsonUtil.toJsonArray(toListOfRoles(createNonDurableQueueRoles)))
+ .add(DELETE_NONDURABLE_QUEUE_PERMISSION,
JsonUtil.toJsonArray(toListOfRoles(deleteNonDurableQueueRoles)))
+ .add(MANAGE_PERMISSION,
JsonUtil.toJsonArray(toListOfRoles(manageRoles)))
+ .add(BROWSE_PERMISSION,
JsonUtil.toJsonArray(toListOfRoles(browseRoles)))
+ .add(CREATE_ADDRESS_PERMISSION,
JsonUtil.toJsonArray(toListOfRoles(createAddressRoles)))
+ .add(DELETE_ADDRESS_PERMISSION,
JsonUtil.toJsonArray(toListOfRoles(deleteAddressRoles)))
+ .add(VIEW_PERMISSION, JsonUtil.toJsonArray(toListOfRoles(viewRoles)))
+ .add(EDIT_PERMISSION, JsonUtil.toJsonArray(toListOfRoles(editRoles)))
+ .build().toString();
+ }
+
+ /**
+ * Parses a JSON String to create a {@code Set} of {@link Role} objects,
where each role is assigned specific
+ * permissions based on the data provided in the JSON structure.
+ *
+ * @param json JSON representing the permission types and their associated
role names. See
+ * {@link ActiveMQServerControl#addSecuritySettings(String,
String)} for details about the JSON
+ * structure.
+ * @return a {@code Set} of {@link Role} objects with permissions assigned
according to the parsed JSON.
+ */
+ public static Set<Role> fromJSON(JsonObject json) {
+ List<String> sendRoles = getListOfRoles(json, SEND_PERMISSION);
+ List<String> consumeRoles = getListOfRoles(json, CONSUME_PERMISSION);
+ List<String> createDurableQueueRoles = getListOfRoles(json,
CREATE_DURABLE_QUEUE_PERMISSION);
+ List<String> deleteDurableQueueRoles = getListOfRoles(json,
DELETE_DURABLE_QUEUE_PERMISSION);
+ List<String> createNonDurableQueueRoles = getListOfRoles(json,
CREATE_NONDURABLE_QUEUE_PERMISSION);
+ List<String> deleteNonDurableQueueRoles = getListOfRoles(json,
DELETE_NONDURABLE_QUEUE_PERMISSION);
+ List<String> manageRoles = getListOfRoles(json, MANAGE_PERMISSION);
+ List<String> browseRoles = getListOfRoles(json, BROWSE_PERMISSION);
+ List<String> createAddressRoles = getListOfRoles(json,
CREATE_ADDRESS_PERMISSION);
+ List<String> deleteAddressRoles = getListOfRoles(json,
DELETE_ADDRESS_PERMISSION);
+ List<String> viewRoles = getListOfRoles(json, VIEW_PERMISSION);
+ List<String> editRoles = getListOfRoles(json, EDIT_PERMISSION);
+
+ Set<String> allRoles = new HashSet<>();
+ allRoles.addAll(sendRoles);
+ allRoles.addAll(consumeRoles);
+ allRoles.addAll(createDurableQueueRoles);
+ allRoles.addAll(deleteDurableQueueRoles);
+ allRoles.addAll(createNonDurableQueueRoles);
+ allRoles.addAll(deleteNonDurableQueueRoles);
+ allRoles.addAll(manageRoles);
+ allRoles.addAll(browseRoles);
+ allRoles.addAll(createAddressRoles);
+ allRoles.addAll(deleteAddressRoles);
+ allRoles.addAll(viewRoles);
+ allRoles.addAll(editRoles);
+
+ Set<Role> roles = new HashSet<>(allRoles.size());
+ for (String role : allRoles) {
+ roles.add(new Role(role,
+ sendRoles.contains(role),
+ consumeRoles.contains(role),
+ createDurableQueueRoles.contains(role),
+ deleteDurableQueueRoles.contains(role),
+ createNonDurableQueueRoles.contains(role),
+ deleteNonDurableQueueRoles.contains(role),
+ manageRoles.contains(role),
+ browseRoles.contains(role),
+ createAddressRoles.contains(role),
+ deleteAddressRoles.contains(role),
+ viewRoles.contains(role),
+ editRoles.contains(role)));
+ }
+ return roles;
+ }
+
+ /**
+ * Creates a {@code Set} of {@link Role} objects with specific permissions
based on the provided input role names.
+ *
+ * @param sendRoles a comma-separated string of role names
allowed to send messages
+ * @param consumeRoles a comma-separated string of role names
allowed to consume messages
+ * @param createDurableQueueRoles a comma-separated string of role names
allowed to create durable queues
+ * @param deleteDurableQueueRoles a comma-separated string of role names
allowed to delete durable queues
+ * @param createNonDurableQueueRoles a comma-separated string of roles
allowed to create non-durable queues
+ * @param deleteNonDurableQueueRoles a comma-separated string of role names
allowed to delete non-durable queues
+ * @param manageRoles a comma-separated string of role names
with manage-level access permissions
+ * @param browseRoles a comma-separated string of role names
allowed to browse messages
+ * @param createAddressRoles a comma-separated string of role names
allowed to create addresses
+ * @param deleteAddressRoles a comma-separated string of role names
allowed to delete addresses
+ * @return a {@code Set} of {@link Role} objects representing the
permissions assigned to each role
+ */
public static Set<Role> createSecurity(String sendRoles,
String consumeRoles,
String createDurableQueueRoles,
@@ -36,16 +257,16 @@ public class SecurityFormatter {
String browseRoles,
String createAddressRoles,
String deleteAddressRoles) {
- List<String> createDurableQueue = toList(createDurableQueueRoles);
- List<String> deleteDurableQueue = toList(deleteDurableQueueRoles);
- List<String> createNonDurableQueue = toList(createNonDurableQueueRoles);
- List<String> deleteNonDurableQueue = toList(deleteNonDurableQueueRoles);
- List<String> send = toList(sendRoles);
- List<String> consume = toList(consumeRoles);
- List<String> manage = toList(manageRoles);
- List<String> browse = toList(browseRoles);
- List<String> createAddress = toList(createAddressRoles);
- List<String> deleteAddress = toList(deleteAddressRoles);
+ List<String> createDurableQueue = toListOfRoles(createDurableQueueRoles);
+ List<String> deleteDurableQueue = toListOfRoles(deleteDurableQueueRoles);
+ List<String> createNonDurableQueue =
toListOfRoles(createNonDurableQueueRoles);
+ List<String> deleteNonDurableQueue =
toListOfRoles(deleteNonDurableQueueRoles);
+ List<String> send = toListOfRoles(sendRoles);
+ List<String> consume = toListOfRoles(consumeRoles);
+ List<String> manage = toListOfRoles(manageRoles);
+ List<String> browse = toListOfRoles(browseRoles);
+ List<String> createAddress = toListOfRoles(createAddressRoles);
+ List<String> deleteAddress = toListOfRoles(deleteAddressRoles);
Set<String> allRoles = new HashSet<>();
allRoles.addAll(createDurableQueue);
@@ -61,16 +282,49 @@ public class SecurityFormatter {
Set<Role> roles = new HashSet<>(allRoles.size());
for (String role : allRoles) {
- roles.add(new Role(role, send.contains(role), consume.contains(role),
createDurableQueue.contains(role), deleteDurableQueue.contains(role),
createNonDurableQueue.contains(role), deleteNonDurableQueue.contains(role),
manageRoles.contains(role), browse.contains(role),
createAddressRoles.contains(role), deleteAddressRoles.contains(role), false,
false));
+ roles.add(new Role(role,
+ send.contains(role),
+ consume.contains(role),
+ createDurableQueue.contains(role),
+ deleteDurableQueue.contains(role),
+ createNonDurableQueue.contains(role),
+ deleteNonDurableQueue.contains(role),
+ manageRoles.contains(role),
+ browse.contains(role),
+ createAddressRoles.contains(role),
+ deleteAddressRoles.contains(role),
+ false,
+ false));
}
return roles;
}
- @SuppressWarnings("unchecked")
- private static List<String> toList(final String commaSeparatedString) {
- if (commaSeparatedString == null ||
commaSeparatedString.trim().isEmpty()) {
+ /**
+ * Retrieves a list of role names from security-settings JSON based on the
specified permission type.
+ *
+ * @param jsonObject the {@code JsonObject} containing various
permission types each mapped to an array of role
+ * names.
+ * @param permissionType the specific permission type key to retrieve the
corresponding list of role names from the
+ * JSON object.
+ * @return a {@code List} of strings representing the role names associated
with the given permission type in the
+ * security-settings JSON.
+ */
+ public static List<String> getListOfRoles(JsonObject jsonObject, String
permissionType) {
+ return jsonObject.getJsonArray(permissionType) == null ?
Collections.emptyList() :
jsonObject.getJsonArray(permissionType).getValuesAs((JsonString v) ->
v.getString());
+ }
+
+ /**
+ * Converts a comma-separated string of role names into a list of Strings.
If the input string is null or empty, an
+ * empty list is returned.
+ *
+ * @param commaSeparatedRoles the input string containing role names
separated by commas
+ * @return a list of Strings populated with the values from the input
string, or an empty list if the input is null
+ * or empty
+ */
+ public static List<String> toListOfRoles(final String commaSeparatedRoles) {
+ if (commaSeparatedRoles == null || commaSeparatedRoles.trim().isEmpty())
{
return Collections.emptyList();
}
- return List.class.cast(Collections.list(new
StringTokenizer(commaSeparatedString, ", ")));
+ return List.class.cast(Collections.list(new
StringTokenizer(commaSeparatedRoles, ", ")));
}
}
diff --git
a/artemis-core-client/src/test/java/org/apache/activemq/artemis/api/core/JsonUtilTest.java
b/artemis-core-client/src/test/java/org/apache/activemq/artemis/api/core/JsonUtilTest.java
index 52c92eed8c..7c521f4744 100644
---
a/artemis-core-client/src/test/java/org/apache/activemq/artemis/api/core/JsonUtilTest.java
+++
b/artemis-core-client/src/test/java/org/apache/activemq/artemis/api/core/JsonUtilTest.java
@@ -231,4 +231,23 @@ public class JsonUtilTest {
assertTrue(inserted.containsKey("c"));
assertEquals(target, inserted.getJsonObject("c"));
}
+
+ @Test
+ public void testArrayToString() {
+ final String keyName = "test";
+
+ // test wrong type (i.e. not an array)
+
assertTrue(JsonUtil.arrayToString(JsonLoader.createObjectBuilder().add(keyName,
0L).build(), keyName).isEmpty());
+
+ // test empty array
+
assertTrue(JsonUtil.arrayToString(JsonLoader.createObjectBuilder().build(),
keyName).isEmpty());
+
+ // test array with 2 elements
+ assertEquals("a, b",
JsonUtil.arrayToString(JsonLoader.createObjectBuilder()
+ .add(keyName,
JsonLoader.createArrayBuilder()
+ .add("a")
+ .add("b")
+ .build())
+ .build(), keyName));
+ }
}
diff --git
a/artemis-core-client/src/test/java/org/apache/activemq/artemis/util/SecurityFormatterTest.java
b/artemis-core-client/src/test/java/org/apache/activemq/artemis/util/SecurityFormatterTest.java
new file mode 100644
index 0000000000..bd7b35ab89
--- /dev/null
+++
b/artemis-core-client/src/test/java/org/apache/activemq/artemis/util/SecurityFormatterTest.java
@@ -0,0 +1,191 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.util;
+
+import java.io.StringReader;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.activemq.artemis.api.core.JsonUtil;
+import org.apache.activemq.artemis.core.security.Role;
+import org.apache.activemq.artemis.json.JsonObject;
+import org.apache.activemq.artemis.utils.JsonLoader;
+import org.apache.activemq.artemis.utils.SecurityFormatter;
+import org.junit.jupiter.api.Test;
+
+import static org.apache.activemq.artemis.core.security.Role.BROWSE_PERMISSION;
+import static
org.apache.activemq.artemis.core.security.Role.CONSUME_PERMISSION;
+import static
org.apache.activemq.artemis.core.security.Role.CREATE_ADDRESS_PERMISSION;
+import static
org.apache.activemq.artemis.core.security.Role.CREATE_DURABLE_QUEUE_PERMISSION;
+import static
org.apache.activemq.artemis.core.security.Role.CREATE_NONDURABLE_QUEUE_PERMISSION;
+import static
org.apache.activemq.artemis.core.security.Role.DELETE_ADDRESS_PERMISSION;
+import static
org.apache.activemq.artemis.core.security.Role.DELETE_DURABLE_QUEUE_PERMISSION;
+import static
org.apache.activemq.artemis.core.security.Role.DELETE_NONDURABLE_QUEUE_PERMISSION;
+import static org.apache.activemq.artemis.core.security.Role.EDIT_PERMISSION;
+import static org.apache.activemq.artemis.core.security.Role.MANAGE_PERMISSION;
+import static org.apache.activemq.artemis.core.security.Role.SEND_PERMISSION;
+import static org.apache.activemq.artemis.core.security.Role.VIEW_PERMISSION;
+import static
org.apache.activemq.artemis.utils.RandomUtil.randomAlphaNumericString;
+import static org.apache.activemq.artemis.utils.RandomUtil.randomBoolean;
+import static org.apache.activemq.artemis.utils.RandomUtil.randomPositiveInt;
+import static org.apache.activemq.artemis.utils.RandomUtil.randomWords;
+import static org.apache.activemq.artemis.utils.SecurityFormatter.fromJSON;
+import static
org.apache.activemq.artemis.utils.SecurityFormatter.getListOfRoles;
+import static org.apache.activemq.artemis.utils.SecurityFormatter.toJSON;
+import static
org.apache.activemq.artemis.utils.SecurityFormatter.toListOfRoles;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class SecurityFormatterTest {
+
+ @Test
+ public void testToJsonFromSet() {
+ Set<Role> originalRoles = new HashSet<>();
+
+ // create several test roles
+ for (int i = 0; i < 10; i++) {
+ boolean[] booleans = new boolean[12];
+ boolean atLeastOneTrue = false;
+
+ // generate a set of permissions that has at least one true value
+ while (!atLeastOneTrue) {
+ for (int j = 0; j < booleans.length; j++) {
+ booleans[j] = randomBoolean();
+ if (booleans[j]) {
+ atLeastOneTrue = true;
+ }
+ }
+ }
+ originalRoles.add(new Role("role-" + randomAlphaNumericString(6),
+ booleans[0],
+ booleans[1],
+ booleans[2],
+ booleans[3],
+ booleans[4],
+ booleans[5],
+ booleans[6],
+ booleans[7],
+ booleans[8],
+ booleans[9],
+ booleans[10],
+ booleans[11]));
+ }
+
+ assertEquals(originalRoles,
fromJSON(JsonUtil.readJsonObject(toJSON(originalRoles))));
+ }
+
+ @Test
+ public void testToJsonFromStrings() {
+ String[] roles = new String[12];
+ for (int i = 0; i < roles.length; i++) {
+ roles[i] = String.join(", ", randomWords(randomPositiveInt() % 5 +
1));
+ }
+
+ String json = toJSON(roles[0],
+ roles[1],
+ roles[2],
+ roles[3],
+ roles[4],
+ roles[5],
+ roles[6],
+ roles[7],
+ roles[8],
+ roles[9],
+ roles[10],
+ roles[11]);
+
+ JsonObject o = JsonLoader.readObject(new StringReader(json));
+ assertEquals(toListOfRoles(roles[0]), getListOfRoles(o,
SEND_PERMISSION));
+ assertEquals(toListOfRoles(roles[1]), getListOfRoles(o,
CONSUME_PERMISSION));
+ assertEquals(toListOfRoles(roles[2]), getListOfRoles(o,
CREATE_DURABLE_QUEUE_PERMISSION));
+ assertEquals(toListOfRoles(roles[3]), getListOfRoles(o,
DELETE_DURABLE_QUEUE_PERMISSION));
+ assertEquals(toListOfRoles(roles[4]), getListOfRoles(o,
CREATE_NONDURABLE_QUEUE_PERMISSION));
+ assertEquals(toListOfRoles(roles[5]), getListOfRoles(o,
DELETE_NONDURABLE_QUEUE_PERMISSION));
+ assertEquals(toListOfRoles(roles[6]), getListOfRoles(o,
MANAGE_PERMISSION));
+ assertEquals(toListOfRoles(roles[7]), getListOfRoles(o,
BROWSE_PERMISSION));
+ assertEquals(toListOfRoles(roles[8]), getListOfRoles(o,
CREATE_ADDRESS_PERMISSION));
+ assertEquals(toListOfRoles(roles[9]), getListOfRoles(o,
DELETE_ADDRESS_PERMISSION));
+ assertEquals(toListOfRoles(roles[10]), getListOfRoles(o,
VIEW_PERMISSION));
+ assertEquals(toListOfRoles(roles[11]), getListOfRoles(o,
EDIT_PERMISSION));
+ }
+
+ @Test
+ public void testToJsonVarious() {
+ final String emptyJson = """
+
{"send":[],"consume":[],"createDurableQueue":[],"deleteDurableQueue":[],"createNonDurableQueue":[],"deleteNonDurableQueue":[],"manage":[],"browse":[],"createAddress":[],"deleteAddress":[],"view":[],"edit":[]}""";
+ assertEquals(emptyJson,
+ toJSON("",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ ""));
+ assertEquals(emptyJson,
+ toJSON(null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null));
+ }
+
+ @Test
+ public void testGetListOfRoles() {
+ String json = """
+ {
+ "send": ["a"],
+ "consume": ["b", "c"],
+ "createDurableQueue": ["d", "e", "f"],
+ "deleteDurableQueue": []
+ }""";
+ JsonObject o = JsonLoader.readObject(new StringReader(json));
+ assertEquals(List.of("a"), SecurityFormatter.getListOfRoles(o,
SEND_PERMISSION));
+ assertEquals(List.of("b", "c"), SecurityFormatter.getListOfRoles(o,
CONSUME_PERMISSION));
+ assertEquals(List.of("d", "e", "f"), SecurityFormatter.getListOfRoles(o,
CREATE_DURABLE_QUEUE_PERMISSION));
+ assertEquals(Collections.emptyList(),
SecurityFormatter.getListOfRoles(o, DELETE_DURABLE_QUEUE_PERMISSION));
+
+ // test something that doesn't exist
+ assertEquals(Collections.emptyList(),
SecurityFormatter.getListOfRoles(o, randomAlphaNumericString(4)));
+ }
+
+ @Test
+ public void testToListOfRoles() {
+ assertEquals(Collections.emptyList(), toListOfRoles(""));
+ assertEquals(Collections.emptyList(), toListOfRoles(null));
+
+ assertEquals(List.of("a"), toListOfRoles("a"));
+ assertEquals(List.of("a"), toListOfRoles(" a"));
+ assertEquals(List.of("a"), toListOfRoles("a "));
+ assertEquals(List.of("a"), toListOfRoles(" a "));
+ assertEquals(List.of("a", "b"), toListOfRoles("a,b"));
+ assertEquals(List.of("a", "b"), toListOfRoles("a, b"));
+ assertEquals(List.of("a", "b"), toListOfRoles(" a, b "));
+ }
+}
diff --git
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java
index ebb479b0c9..f6ad71f36d 100644
---
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java
+++
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java
@@ -151,6 +151,18 @@ import static
org.apache.activemq.artemis.core.config.impl.Validators.POSITIVE_P
import static
org.apache.activemq.artemis.core.config.impl.Validators.ROUTING_TYPE;
import static
org.apache.activemq.artemis.core.config.impl.Validators.SLOW_CONSUMER_POLICY_TYPE;
import static
org.apache.activemq.artemis.core.config.impl.Validators.SLOW_CONSUMER_THRESHOLD_MEASUREMENT_UNIT;
+import static org.apache.activemq.artemis.core.security.Role.BROWSE_PERMISSION;
+import static
org.apache.activemq.artemis.core.security.Role.CONSUME_PERMISSION;
+import static
org.apache.activemq.artemis.core.security.Role.CREATE_ADDRESS_PERMISSION;
+import static
org.apache.activemq.artemis.core.security.Role.CREATE_DURABLE_QUEUE_PERMISSION;
+import static
org.apache.activemq.artemis.core.security.Role.CREATE_NONDURABLE_QUEUE_PERMISSION;
+import static
org.apache.activemq.artemis.core.security.Role.DELETE_ADDRESS_PERMISSION;
+import static
org.apache.activemq.artemis.core.security.Role.DELETE_DURABLE_QUEUE_PERMISSION;
+import static
org.apache.activemq.artemis.core.security.Role.DELETE_NONDURABLE_QUEUE_PERMISSION;
+import static org.apache.activemq.artemis.core.security.Role.EDIT_PERMISSION;
+import static org.apache.activemq.artemis.core.security.Role.MANAGE_PERMISSION;
+import static org.apache.activemq.artemis.core.security.Role.SEND_PERMISSION;
+import static org.apache.activemq.artemis.core.security.Role.VIEW_PERMISSION;
/**
* Parses an XML document according to the {@literal
artemis-configuration.xsd} schema.
@@ -186,35 +198,13 @@ public final class FileConfigurationParser extends
XMLConfigurationUtil {
private static final String ROLE_TO_ATTR_NAME = "to";
- static final String CREATEDURABLEQUEUE_NAME = "createDurableQueue";
-
- private static final String DELETEDURABLEQUEUE_NAME = "deleteDurableQueue";
-
- private static final String CREATE_NON_DURABLE_QUEUE_NAME =
"createNonDurableQueue";
-
- private static final String DELETE_NON_DURABLE_QUEUE_NAME =
"deleteNonDurableQueue";
-
// We keep supporting these attribute names for compatibility
+ @Deprecated(forRemoval = true)
private static final String CREATETEMPQUEUE_NAME = "createTempQueue";
+ @Deprecated(forRemoval = true)
private static final String DELETETEMPQUEUE_NAME = "deleteTempQueue";
- private static final String SEND_NAME = "send";
-
- private static final String CONSUME_NAME = "consume";
-
- private static final String MANAGE_NAME = "manage";
-
- private static final String BROWSE_NAME = "browse";
-
- private static final String CREATEADDRESS_NAME = "createAddress";
-
- private static final String DELETEADDRESS_NAME = "deleteAddress";
-
- private static final String VIEW_NAME = "view";
-
- private static final String EDIT_NAME = "edit";
-
// Address parsing
private static final String DEAD_LETTER_ADDRESS_NODE_NAME =
"dead-letter-address";
@@ -1185,33 +1175,33 @@ public final class FileConfigurationParser extends
XMLConfigurationUtil {
String[] mappedRoles = getMappedRoleNames(roles, roleMappings);
for (String role : mappedRoles) {
- if (SEND_NAME.equals(type)) {
+ if (SEND_PERMISSION.equals(type)) {
send.add(role.trim());
- } else if (CONSUME_NAME.equals(type)) {
+ } else if (CONSUME_PERMISSION.equals(type)) {
consume.add(role.trim());
- } else if (CREATEDURABLEQUEUE_NAME.equals(type)) {
+ } else if (CREATE_DURABLE_QUEUE_PERMISSION.equals(type)) {
createDurableQueue.add(role.trim());
- } else if (DELETEDURABLEQUEUE_NAME.equals(type)) {
+ } else if (DELETE_DURABLE_QUEUE_PERMISSION.equals(type)) {
deleteDurableQueue.add(role.trim());
- } else if (CREATE_NON_DURABLE_QUEUE_NAME.equals(type)) {
+ } else if (CREATE_NONDURABLE_QUEUE_PERMISSION.equals(type)) {
createNonDurableQueue.add(role.trim());
- } else if (DELETE_NON_DURABLE_QUEUE_NAME.equals(type)) {
+ } else if (DELETE_NONDURABLE_QUEUE_PERMISSION.equals(type)) {
deleteNonDurableQueue.add(role.trim());
} else if (CREATETEMPQUEUE_NAME.equals(type)) {
createNonDurableQueue.add(role.trim());
} else if (DELETETEMPQUEUE_NAME.equals(type)) {
deleteNonDurableQueue.add(role.trim());
- } else if (MANAGE_NAME.equals(type)) {
+ } else if (MANAGE_PERMISSION.equals(type)) {
manageRoles.add(role.trim());
- } else if (BROWSE_NAME.equals(type)) {
+ } else if (BROWSE_PERMISSION.equals(type)) {
browseRoles.add(role.trim());
- } else if (CREATEADDRESS_NAME.equals(type)) {
+ } else if (CREATE_ADDRESS_PERMISSION.equals(type)) {
createAddressRoles.add(role.trim());
- } else if (DELETEADDRESS_NAME.equals(type)) {
+ } else if (DELETE_ADDRESS_PERMISSION.equals(type)) {
deleteAddressRoles.add(role.trim());
- } else if (VIEW_NAME.equals(type)) {
+ } else if (VIEW_PERMISSION.equals(type)) {
viewRoles.add(role.trim());
- } else if (EDIT_NAME.equals(type)) {
+ } else if (EDIT_PERMISSION.equals(type)) {
editRoles.add(role.trim());
} else {
ActiveMQServerLogger.LOGGER.rolePermissionConfigurationError(type);
diff --git
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/ActiveMQServerControlImpl.java
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/ActiveMQServerControlImpl.java
index c5cde06c83..d7072f355c 100644
---
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/ActiveMQServerControlImpl.java
+++
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/ActiveMQServerControlImpl.java
@@ -2970,22 +2970,22 @@ public class ActiveMQServerControlImpl extends
AbstractControl implements Active
final String deleteAddressRoles,
final String viewRoles,
final String editRoles) throws Exception {
+ addSecuritySettings(addressMatch, SecurityFormatter.toJSON(sendRoles,
consumeRoles, createDurableQueueRoles, deleteDurableQueueRoles,
createNonDurableQueueRoles, deleteNonDurableQueueRoles, manageRoles,
browseRoles, createAddressRoles, deleteAddressRoles, viewRoles, editRoles));
+ }
+
+ @Override
+ public void addSecuritySettings(final String addressMatch,
+ final String securitySettingsAsJson) throws
Exception {
if (AuditLogger.isBaseLoggingEnabled()) {
- AuditLogger.addSecuritySettings(this.server, addressMatch, sendRoles,
consumeRoles, createDurableQueueRoles,
- deleteDurableQueueRoles, createNonDurableQueueRoles,
deleteNonDurableQueueRoles, manageRoles,
- browseRoles, createAddressRoles, deleteAddressRoles,
viewRoles, editRoles);
+ AuditLogger.addSecuritySettings(this.server, addressMatch,
securitySettingsAsJson);
}
checkStarted();
clearIO();
try {
- Set<Role> roles = SecurityFormatter.createSecurity(sendRoles,
consumeRoles, createDurableQueueRoles, deleteDurableQueueRoles,
createNonDurableQueueRoles, deleteNonDurableQueueRoles, manageRoles,
browseRoles, createAddressRoles, deleteAddressRoles);
-
- server.getSecurityRepository().addMatch(addressMatch, roles);
-
- PersistedSecuritySetting persistedRoles = new
PersistedSecuritySetting(addressMatch, sendRoles, consumeRoles,
createDurableQueueRoles, deleteDurableQueueRoles, createNonDurableQueueRoles,
deleteNonDurableQueueRoles, manageRoles, browseRoles, createAddressRoles,
deleteAddressRoles, viewRoles, editRoles);
-
- storageManager.storeSecuritySetting(persistedRoles);
+ JsonObject o = JsonUtil.readJsonObject(securitySettingsAsJson);
+ server.getSecurityRepository().addMatch(addressMatch,
SecurityFormatter.fromJSON(o));
+ storageManager.storeSecuritySetting(new
PersistedSecuritySetting(addressMatch, o));
} finally {
blockOnIO();
}
diff --git
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/config/PersistedSecuritySetting.java
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/config/PersistedSecuritySetting.java
index d179239ee2..2a679db0f3 100644
---
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/config/PersistedSecuritySetting.java
+++
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/config/PersistedSecuritySetting.java
@@ -19,9 +19,23 @@ package org.apache.activemq.artemis.core.persistence.config;
import java.util.Objects;
import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
+import org.apache.activemq.artemis.api.core.JsonUtil;
import org.apache.activemq.artemis.api.core.SimpleString;
import org.apache.activemq.artemis.core.journal.EncodingSupport;
-
+import org.apache.activemq.artemis.json.JsonObject;
+
+import static org.apache.activemq.artemis.core.security.Role.BROWSE_PERMISSION;
+import static
org.apache.activemq.artemis.core.security.Role.CONSUME_PERMISSION;
+import static
org.apache.activemq.artemis.core.security.Role.CREATE_ADDRESS_PERMISSION;
+import static
org.apache.activemq.artemis.core.security.Role.CREATE_DURABLE_QUEUE_PERMISSION;
+import static
org.apache.activemq.artemis.core.security.Role.CREATE_NONDURABLE_QUEUE_PERMISSION;
+import static
org.apache.activemq.artemis.core.security.Role.DELETE_ADDRESS_PERMISSION;
+import static
org.apache.activemq.artemis.core.security.Role.DELETE_DURABLE_QUEUE_PERMISSION;
+import static
org.apache.activemq.artemis.core.security.Role.DELETE_NONDURABLE_QUEUE_PERMISSION;
+import static org.apache.activemq.artemis.core.security.Role.EDIT_PERMISSION;
+import static org.apache.activemq.artemis.core.security.Role.MANAGE_PERMISSION;
+import static org.apache.activemq.artemis.core.security.Role.SEND_PERMISSION;
+import static org.apache.activemq.artemis.core.security.Role.VIEW_PERMISSION;
import static org.apache.activemq.artemis.utils.DataConstants.SIZE_INT;
import static org.apache.activemq.artemis.utils.DataConstants.SIZE_NULL;
@@ -88,6 +102,22 @@ public class PersistedSecuritySetting implements
EncodingSupport {
this.editRoles = SimpleString.of(editRoles);
}
+ public PersistedSecuritySetting(final String addressMatch, JsonObject o) {
+ this(addressMatch,
+ JsonUtil.arrayToString(o, SEND_PERMISSION),
+ JsonUtil.arrayToString(o, CONSUME_PERMISSION),
+ JsonUtil.arrayToString(o, CREATE_DURABLE_QUEUE_PERMISSION),
+ JsonUtil.arrayToString(o, DELETE_DURABLE_QUEUE_PERMISSION),
+ JsonUtil.arrayToString(o, CREATE_NONDURABLE_QUEUE_PERMISSION),
+ JsonUtil.arrayToString(o, DELETE_NONDURABLE_QUEUE_PERMISSION),
+ JsonUtil.arrayToString(o, MANAGE_PERMISSION),
+ JsonUtil.arrayToString(o, BROWSE_PERMISSION),
+ JsonUtil.arrayToString(o, CREATE_ADDRESS_PERMISSION),
+ JsonUtil.arrayToString(o, DELETE_ADDRESS_PERMISSION),
+ JsonUtil.arrayToString(o, VIEW_PERMISSION),
+ JsonUtil.arrayToString(o, EDIT_PERMISSION));
+ }
+
public long getStoreId() {
return storeId;
@@ -243,30 +273,18 @@ public class PersistedSecuritySetting implements
EncodingSupport {
@Override
public String toString() {
return "PersistedSecuritySetting [storeId=" + storeId +
- ", addressMatch=" +
- addressMatch +
- ", sendRoles=" +
- sendRoles +
- ", consumeRoles=" +
- consumeRoles +
- ", createDurableQueueRoles=" +
- createDurableQueueRoles +
- ", deleteDurableQueueRoles=" +
- deleteDurableQueueRoles +
- ", createNonDurableQueueRoles=" +
- createNonDurableQueueRoles +
- ", deleteNonDurableQueueRoles=" +
- deleteNonDurableQueueRoles +
- ", manageRoles=" +
- manageRoles +
- ", browseRoles=" +
- browseRoles +
- ", createAddressRoles=" +
- createAddressRoles +
- ", deleteAddressRoles=" +
- deleteAddressRoles +
- ", viewRoles=" +
- viewRoles +
+ ", addressMatch=" + addressMatch +
+ ", sendRoles=" + sendRoles +
+ ", consumeRoles=" + consumeRoles +
+ ", createDurableQueueRoles=" + createDurableQueueRoles +
+ ", deleteDurableQueueRoles=" + deleteDurableQueueRoles +
+ ", createNonDurableQueueRoles=" + createNonDurableQueueRoles +
+ ", deleteNonDurableQueueRoles=" + deleteNonDurableQueueRoles +
+ ", manageRoles=" + manageRoles +
+ ", browseRoles=" + browseRoles +
+ ", createAddressRoles=" + createAddressRoles +
+ ", deleteAddressRoles=" + deleteAddressRoles +
+ ", viewRoles=" + viewRoles +
", editRoles=" + editRoles +
"]";
}
diff --git
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java
index cbea15b803..98feca733d 100644
---
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java
+++
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java
@@ -3891,8 +3891,17 @@ public class ActiveMQServerImpl implements
ActiveMQServer {
private void recoverStoredSecuritySettings() throws Exception {
List<PersistedSecuritySetting> roles =
storageManager.recoverSecuritySettings();
for (PersistedSecuritySetting roleItem : roles) {
- Set<Role> setRoles =
SecurityFormatter.createSecurity(roleItem.getSendRoles(),
roleItem.getConsumeRoles(), roleItem.getCreateDurableQueueRoles(),
roleItem.getDeleteDurableQueueRoles(),
roleItem.getCreateNonDurableQueueRoles(),
roleItem.getDeleteNonDurableQueueRoles(), roleItem.getManageRoles(),
roleItem.getBrowseRoles(), roleItem.getCreateAddressRoles(),
roleItem.getDeleteAddressRoles());
- securityRepository.addMatch(roleItem.getAddressMatch().toString(),
setRoles);
+ securityRepository.addMatch(roleItem.getAddressMatch().toString(),
+
SecurityFormatter.createSecurity(roleItem.getSendRoles(),
+
roleItem.getConsumeRoles(),
+
roleItem.getCreateDurableQueueRoles(),
+
roleItem.getDeleteDurableQueueRoles(),
+
roleItem.getCreateNonDurableQueueRoles(),
+
roleItem.getDeleteNonDurableQueueRoles(),
+
roleItem.getManageRoles(),
+
roleItem.getBrowseRoles(),
+
roleItem.getCreateAddressRoles(),
+
roleItem.getDeleteAddressRoles()));
}
}
diff --git
a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlTest.java
b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlTest.java
index 439fd45e5a..5d046a3692 100644
---
a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlTest.java
+++
b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlTest.java
@@ -135,6 +135,7 @@ import
org.apache.activemq.artemis.tests.unit.core.config.impl.fakes.FakeConnect
import org.apache.activemq.artemis.tests.util.CFUtil;
import org.apache.activemq.artemis.tests.util.Wait;
import org.apache.activemq.artemis.utils.RandomUtil;
+import org.apache.activemq.artemis.utils.SecurityFormatter;
import org.apache.activemq.artemis.utils.UUIDGenerator;
import org.apache.qpid.jms.JmsConnectionFactory;
import org.junit.jupiter.api.BeforeEach;
@@ -1174,12 +1175,63 @@ public class ActiveMQServerControlTest extends
ManagementTestBase {
@TestTemplate
public void testSecuritySettings() throws Exception {
+ testSecuritySettings(false);
+ }
+
+
+ @TestTemplate
+ public void testSecuritySettingsJson() throws Exception {
+ testSecuritySettings(true);
+ }
+
+ private void testSecuritySettings(boolean json) throws Exception {
ActiveMQServerControl serverControl = createManagementControl();
String addressMatch = "test.#";
String exactAddress = "test.whatever";
assertEquals(2, serverControl.getRoles(addressMatch).length);
- serverControl.addSecuritySettings(addressMatch, "foo", "foo, bar", null,
"bar", "foo, bar", "", "", "bar", "foo", "foo", "", "");
+ final String sendRoles = "foo";
+ final String consumeRoles = "foo, bar";
+ final String createDurableQueueRoles = null;
+ final String deleteDurableQueueRoles = "bar";
+ final String createNonDurableQueueRoles = "foo, bar";
+ final String deleteNonDurableQueueRoles = "";
+ final String manageRoles = "";
+ final String browseRoles = "bar";
+ final String createAddressRoles = "foo";
+ final String deleteAddressRoles = "foo";
+ final String viewRoles = "";
+ final String editRoles = "";
+
+ if (json) {
+ serverControl.addSecuritySettings(addressMatch,
+ SecurityFormatter.toJSON(sendRoles,
+
consumeRoles,
+
createDurableQueueRoles,
+
deleteDurableQueueRoles,
+
createNonDurableQueueRoles,
+
deleteNonDurableQueueRoles,
+
manageRoles,
+
browseRoles,
+
createAddressRoles,
+
deleteAddressRoles,
+ viewRoles,
+
editRoles));
+ } else {
+ serverControl.addSecuritySettings(addressMatch,
+ sendRoles,
+ consumeRoles,
+ createDurableQueueRoles,
+ deleteDurableQueueRoles,
+ createNonDurableQueueRoles,
+ deleteNonDurableQueueRoles,
+ manageRoles,
+ browseRoles,
+ createAddressRoles,
+ deleteAddressRoles,
+ viewRoles,
+ editRoles);
+ }
// Restart the server. Those settings should be persisted
diff --git
a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlUsingCoreTest.java
b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlUsingCoreTest.java
index b37cab4b33..eaefaad994 100644
---
a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlUsingCoreTest.java
+++
b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlUsingCoreTest.java
@@ -1010,6 +1010,11 @@ public class ActiveMQServerControlUsingCoreTest extends
ActiveMQServerControlTes
proxy.invokeOperation("addSecuritySettings", addressMatch,
sendRoles, consumeRoles, createDurableQueueRoles, deleteDurableQueueRoles,
createNonDurableQueueRoles, deleteNonDurableQueueRoles, manageRoles,
browseRoles, createAddress, deleteAddress, viewRoles, editRoles);
}
+ @Override
+ public void addSecuritySettings(String addressMatch, String
securitySettingsAsJson) throws Exception {
+ proxy.invokeOperation("addSecuritySettings", addressMatch,
securitySettingsAsJson);
+ }
+
@Override
public void removeSecuritySettings(String addressMatch) throws
Exception {
proxy.invokeOperation("removeSecuritySettings", addressMatch);
diff --git
a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/util/RandomUtilTest.java
b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/util/RandomUtilTest.java
index 6ebc2407af..8d6e1b8d76 100644
---
a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/util/RandomUtilTest.java
+++
b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/util/RandomUtilTest.java
@@ -16,12 +16,12 @@
*/
package org.apache.activemq.artemis.tests.unit.core.util;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
import org.apache.activemq.artemis.utils.RandomUtil;
import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
public class RandomUtilTest {
@@ -38,4 +38,17 @@ public class RandomUtilTest {
assertEquals(10, i);
}
+
+ @Test
+ public void testRandomWords() {
+ for (int i = 0; i < 1000; i++) {
+ int wordCount = RandomUtil.randomPositiveInt() % 100 + 10;
+ String[] words = RandomUtil.randomWords(wordCount);
+ assertEquals(wordCount, words.length);
+ for (String word : words) {
+ assertTrue(word.length() > 0);
+ assertTrue(word.length() <= 10);
+ }
+ }
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]