This closes #2532
This commit is contained in:
commit
9b9fe8a73f
|
@ -118,13 +118,12 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-configuration2</artifactId>
|
||||
<version>${commons.config.version}</version>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${commons.lang.version}</version>
|
||||
<artifactId>commons-configuration2</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.winsw</groupId>
|
||||
|
|
|
@ -20,6 +20,7 @@ import io.airlift.airline.Command;
|
|||
import io.airlift.airline.Option;
|
||||
import org.apache.activemq.artemis.cli.commands.ActionContext;
|
||||
import org.apache.activemq.artemis.cli.commands.util.HashUtil;
|
||||
import org.apache.activemq.artemis.spi.core.security.jaas.PropertiesLoginModuleConfigurator;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
/**
|
||||
|
@ -53,7 +54,7 @@ public class AddUser extends PasswordAction {
|
|||
* @throws IllegalArgumentException if user exists
|
||||
*/
|
||||
private void add(String hash, String... role) throws Exception {
|
||||
FileBasedSecStoreConfig config = getConfiguration();
|
||||
PropertiesLoginModuleConfigurator config = new PropertiesLoginModuleConfigurator(entry, getBrokerEtc());
|
||||
config.addNewUser(username, hash, role);
|
||||
config.save();
|
||||
context.out.println("User added successfully.");
|
||||
|
|
|
@ -16,10 +16,12 @@
|
|||
*/
|
||||
package org.apache.activemq.artemis.cli.commands.user;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import io.airlift.airline.Command;
|
||||
import org.apache.activemq.artemis.cli.commands.ActionContext;
|
||||
import org.apache.activemq.artemis.spi.core.security.jaas.PropertiesLoginModuleConfigurator;
|
||||
|
||||
/**
|
||||
* list existing users, example:
|
||||
|
@ -42,11 +44,24 @@ public class ListUser extends UserAction {
|
|||
* if username is not specified
|
||||
*/
|
||||
private void list() throws Exception {
|
||||
FileBasedSecStoreConfig config = getConfiguration();
|
||||
List<String> result = config.listUser(username);
|
||||
for (String str : result) {
|
||||
context.out.println(str);
|
||||
PropertiesLoginModuleConfigurator config = new PropertiesLoginModuleConfigurator(entry, getBrokerEtc());
|
||||
Map<String, Set<String>> result = config.listUser(username);
|
||||
StringBuilder logMessage = new StringBuilder("--- \"user\"(roles) ---\n");
|
||||
int userCount = 0;
|
||||
for (Map.Entry<String, Set<String>> entry : result.entrySet()) {
|
||||
logMessage.append("\"").append(entry.getKey()).append("\"(");
|
||||
int roleCount = 0;
|
||||
for (String role : entry.getValue()) {
|
||||
logMessage.append(role);
|
||||
if (++roleCount < entry.getValue().size()) {
|
||||
logMessage.append(",");
|
||||
}
|
||||
}
|
||||
logMessage.append(")\n");
|
||||
userCount++;
|
||||
}
|
||||
logMessage.append("\n Total: ").append(userCount);
|
||||
context.out.println(logMessage);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ package org.apache.activemq.artemis.cli.commands.user;
|
|||
|
||||
import io.airlift.airline.Command;
|
||||
import org.apache.activemq.artemis.cli.commands.ActionContext;
|
||||
import org.apache.activemq.artemis.spi.core.security.jaas.PropertiesLoginModuleConfigurator;
|
||||
|
||||
/**
|
||||
* Remove a user, example:
|
||||
|
@ -35,7 +36,7 @@ public class RemoveUser extends UserAction {
|
|||
}
|
||||
|
||||
private void remove() throws Exception {
|
||||
FileBasedSecStoreConfig config = getConfiguration();
|
||||
PropertiesLoginModuleConfigurator config = new PropertiesLoginModuleConfigurator(entry, getBrokerEtc());
|
||||
config.removeUser(username);
|
||||
config.save();
|
||||
context.out.println("User removed.");
|
||||
|
|
|
@ -20,6 +20,7 @@ import io.airlift.airline.Command;
|
|||
import io.airlift.airline.Option;
|
||||
import org.apache.activemq.artemis.cli.commands.ActionContext;
|
||||
import org.apache.activemq.artemis.cli.commands.util.HashUtil;
|
||||
import org.apache.activemq.artemis.spi.core.security.jaas.PropertiesLoginModuleConfigurator;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
/**
|
||||
|
@ -57,7 +58,7 @@ public class ResetUser extends PasswordAction {
|
|||
context.err.println("Nothing to update.");
|
||||
return;
|
||||
}
|
||||
FileBasedSecStoreConfig config = getConfiguration();
|
||||
PropertiesLoginModuleConfigurator config = new PropertiesLoginModuleConfigurator(entry, getBrokerEtc());
|
||||
config.updateUser(username, password, roles);
|
||||
config.save();
|
||||
context.out.println("User updated");
|
||||
|
|
|
@ -16,16 +16,8 @@
|
|||
*/
|
||||
package org.apache.activemq.artemis.cli.commands.user;
|
||||
|
||||
import javax.security.auth.login.AppConfigurationEntry;
|
||||
import javax.security.auth.login.Configuration;
|
||||
import java.io.File;
|
||||
|
||||
import io.airlift.airline.Option;
|
||||
import org.apache.activemq.artemis.cli.commands.InputAbstract;
|
||||
import org.apache.activemq.artemis.spi.core.security.jaas.PropertiesLoginModule;
|
||||
|
||||
import static org.apache.activemq.artemis.spi.core.security.jaas.PropertiesLoginModule.ROLE_FILE_PROP_NAME;
|
||||
import static org.apache.activemq.artemis.spi.core.security.jaas.PropertiesLoginModule.USER_FILE_PROP_NAME;
|
||||
|
||||
public abstract class UserAction extends InputAbstract {
|
||||
|
||||
|
@ -50,30 +42,6 @@ public abstract class UserAction extends InputAbstract {
|
|||
}
|
||||
}
|
||||
|
||||
FileBasedSecStoreConfig getConfiguration() throws Exception {
|
||||
|
||||
Configuration securityConfig = Configuration.getConfiguration();
|
||||
AppConfigurationEntry[] entries = securityConfig.getAppConfigurationEntry(entry);
|
||||
|
||||
for (AppConfigurationEntry entry : entries) {
|
||||
if (entry.getLoginModuleName().equals(PropertiesLoginModule.class.getName())) {
|
||||
String userFileName = (String) entry.getOptions().get(USER_FILE_PROP_NAME);
|
||||
String roleFileName = (String) entry.getOptions().get(ROLE_FILE_PROP_NAME);
|
||||
|
||||
File etcDir = new File(getBrokerEtc());
|
||||
File userFile = new File(etcDir, userFileName);
|
||||
File roleFile = new File(etcDir, roleFileName);
|
||||
|
||||
if (!userFile.exists() || !roleFile.exists()) {
|
||||
throw new IllegalArgumentException("Couldn't find user file or role file!");
|
||||
}
|
||||
|
||||
return new FileBasedSecStoreConfig(userFile, roleFile);
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Failed to load security file");
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
|
|
@ -23,6 +23,8 @@ import javax.jms.MessageConsumer;
|
|||
import javax.jms.MessageProducer;
|
||||
import javax.jms.Session;
|
||||
import javax.jms.TextMessage;
|
||||
import javax.json.JsonArray;
|
||||
import javax.json.JsonObject;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
|
@ -34,20 +36,24 @@ import java.io.InputStreamReader;
|
|||
import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.activemq.artemis.api.core.ActiveMQIllegalStateException;
|
||||
import org.apache.activemq.artemis.api.core.JsonUtil;
|
||||
import org.apache.activemq.artemis.api.core.Pair;
|
||||
import org.apache.activemq.artemis.api.core.RoutingType;
|
||||
import org.apache.activemq.artemis.api.core.SimpleString;
|
||||
import org.apache.activemq.artemis.api.core.client.ClientSession;
|
||||
import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
|
||||
import org.apache.activemq.artemis.api.core.client.ServerLocator;
|
||||
import org.apache.activemq.artemis.api.core.management.ActiveMQServerControl;
|
||||
import org.apache.activemq.artemis.cli.Artemis;
|
||||
import org.apache.activemq.artemis.cli.CLIException;
|
||||
import org.apache.activemq.artemis.cli.commands.ActionContext;
|
||||
import org.apache.activemq.artemis.cli.commands.Create;
|
||||
import org.apache.activemq.artemis.cli.commands.Mask;
|
||||
import org.apache.activemq.artemis.cli.commands.queue.StatQueue;
|
||||
import org.apache.activemq.artemis.cli.commands.Run;
|
||||
import org.apache.activemq.artemis.cli.commands.queue.StatQueue;
|
||||
import org.apache.activemq.artemis.cli.commands.user.AddUser;
|
||||
import org.apache.activemq.artemis.cli.commands.user.ListUser;
|
||||
import org.apache.activemq.artemis.cli.commands.user.RemoveUser;
|
||||
|
@ -389,6 +395,173 @@ public class ArtemisTest extends CliTestBase {
|
|||
assertTrue(result.contains("Total: 0"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUserCommandViaManagement() throws Exception {
|
||||
Run.setEmbedded(true);
|
||||
File instance1 = new File(temporaryFolder.getRoot(), "instance_user");
|
||||
System.setProperty("java.security.auth.login.config", instance1.getAbsolutePath() + "/etc/login.config");
|
||||
Artemis.main("create", instance1.getAbsolutePath(), "--silent", "--no-autotune", "--no-web", "--no-amqp-acceptor", "--no-mqtt-acceptor", "--no-stomp-acceptor", "--no-hornetq-acceptor");
|
||||
System.setProperty("artemis.instance", instance1.getAbsolutePath());
|
||||
Object result = Artemis.internalExecute("run");
|
||||
ActiveMQServer activeMQServer = ((Pair<ManagementContext, ActiveMQServer>)result).getB();
|
||||
ActiveMQServerControl activeMQServerControl = activeMQServer.getActiveMQServerControl();
|
||||
|
||||
File userFile = new File(instance1.getAbsolutePath() + "/etc/artemis-users.properties");
|
||||
File roleFile = new File(instance1.getAbsolutePath() + "/etc/artemis-roles.properties");
|
||||
|
||||
//default only one user admin with role amq
|
||||
String jsonResult = activeMQServerControl.listUser("", "activemq");
|
||||
contains(JsonUtil.readJsonArray(jsonResult), "admin", "amq");
|
||||
checkRole("admin", roleFile, "amq");
|
||||
|
||||
//add a simple user
|
||||
activeMQServerControl.addUser("guest", "guest123", "admin", true, "activemq");
|
||||
|
||||
//verify add
|
||||
jsonResult = activeMQServerControl.listUser("", "activemq");
|
||||
contains(JsonUtil.readJsonArray(jsonResult), "guest", "admin");
|
||||
checkRole("guest", roleFile, "admin");
|
||||
assertTrue(checkPassword("guest", "guest123", userFile));
|
||||
|
||||
//add a user with 2 roles
|
||||
activeMQServerControl.addUser("scott", "tiger", "admin,operator", true, "activemq");
|
||||
|
||||
//verify add
|
||||
jsonResult = activeMQServerControl.listUser("", "activemq");
|
||||
contains(JsonUtil.readJsonArray(jsonResult), "scott", "admin");
|
||||
contains(JsonUtil.readJsonArray(jsonResult), "scott", "operator");
|
||||
checkRole("scott", roleFile, "admin", "operator");
|
||||
assertTrue(checkPassword("scott", "tiger", userFile));
|
||||
|
||||
try {
|
||||
activeMQServerControl.addUser("scott", "password", "visitor", true, "activemq");
|
||||
fail("should throw an exception if adding a existing user");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
}
|
||||
|
||||
//check existing users are intact
|
||||
jsonResult = activeMQServerControl.listUser("", "activemq");
|
||||
contains(JsonUtil.readJsonArray(jsonResult), "admin", "amq");
|
||||
contains(JsonUtil.readJsonArray(jsonResult), "guest", "admin");
|
||||
contains(JsonUtil.readJsonArray(jsonResult), "scott", "admin");
|
||||
contains(JsonUtil.readJsonArray(jsonResult), "scott", "operator");
|
||||
|
||||
//check listing with just one user
|
||||
jsonResult = activeMQServerControl.listUser("admin", "activemq");
|
||||
contains(JsonUtil.readJsonArray(jsonResult), "admin", "amq");
|
||||
contains(JsonUtil.readJsonArray(jsonResult), "guest", "admin", false);
|
||||
contains(JsonUtil.readJsonArray(jsonResult), "scott", "admin", false);
|
||||
contains(JsonUtil.readJsonArray(jsonResult), "scott", "operator", false);
|
||||
|
||||
//check listing with another single user
|
||||
jsonResult = activeMQServerControl.listUser("guest", "activemq");
|
||||
contains(JsonUtil.readJsonArray(jsonResult), "admin", "amq", false);
|
||||
contains(JsonUtil.readJsonArray(jsonResult), "guest", "admin");
|
||||
contains(JsonUtil.readJsonArray(jsonResult), "scott", "admin", false);
|
||||
contains(JsonUtil.readJsonArray(jsonResult), "scott", "operator", false);
|
||||
|
||||
//remove a user
|
||||
activeMQServerControl.removeUser("guest", "activemq");
|
||||
jsonResult = activeMQServerControl.listUser("", "activemq");
|
||||
contains(JsonUtil.readJsonArray(jsonResult), "admin", "amq");
|
||||
contains(JsonUtil.readJsonArray(jsonResult), "guest", "admin", false);
|
||||
contains(JsonUtil.readJsonArray(jsonResult), "scott", "admin");
|
||||
contains(JsonUtil.readJsonArray(jsonResult), "scott", "operator");
|
||||
|
||||
//remove another
|
||||
activeMQServerControl.removeUser("scott", "activemq");
|
||||
jsonResult = activeMQServerControl.listUser("", "activemq");
|
||||
contains(JsonUtil.readJsonArray(jsonResult), "admin", "amq");
|
||||
contains(JsonUtil.readJsonArray(jsonResult), "guest", "admin", false);
|
||||
contains(JsonUtil.readJsonArray(jsonResult), "scott", "admin", false);
|
||||
contains(JsonUtil.readJsonArray(jsonResult), "scott", "operator", false);
|
||||
|
||||
//remove non-exist
|
||||
try {
|
||||
activeMQServerControl.removeUser("alien", "activemq");
|
||||
fail("should throw exception when removing a non-existing user");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
}
|
||||
|
||||
//check
|
||||
jsonResult = activeMQServerControl.listUser("", "activemq");
|
||||
contains(JsonUtil.readJsonArray(jsonResult), "admin", "amq");
|
||||
|
||||
//now remove last
|
||||
activeMQServerControl.removeUser("admin", "activemq");
|
||||
jsonResult = activeMQServerControl.listUser("", "activemq");
|
||||
contains(JsonUtil.readJsonArray(jsonResult), "admin", "amq", false);
|
||||
|
||||
stopServer();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBadSecurityEntryNameViaManagement() throws Exception {
|
||||
Run.setEmbedded(true);
|
||||
File instance1 = new File(temporaryFolder.getRoot(), "instance_user");
|
||||
System.setProperty("java.security.auth.login.config", instance1.getAbsolutePath() + "/etc/login.config");
|
||||
Artemis.main("create", instance1.getAbsolutePath(), "--silent", "--no-autotune", "--no-web", "--no-amqp-acceptor", "--no-mqtt-acceptor", "--no-stomp-acceptor", "--no-hornetq-acceptor");
|
||||
System.setProperty("artemis.instance", instance1.getAbsolutePath());
|
||||
Object result = Artemis.internalExecute("run");
|
||||
ActiveMQServer activeMQServer = ((Pair<ManagementContext, ActiveMQServer>)result).getB();
|
||||
ActiveMQServerControl activeMQServerControl = activeMQServer.getActiveMQServerControl();
|
||||
|
||||
try {
|
||||
activeMQServerControl.listUser("", "activemqx");
|
||||
fail();
|
||||
} catch (ActiveMQIllegalStateException expected) {
|
||||
}
|
||||
|
||||
stopServer();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMissingUserFileViaManagement() throws Exception {
|
||||
Run.setEmbedded(true);
|
||||
File instance1 = new File(temporaryFolder.getRoot(), "instance_user");
|
||||
System.setProperty("java.security.auth.login.config", instance1.getAbsolutePath() + "/etc/login.config");
|
||||
Artemis.main("create", instance1.getAbsolutePath(), "--silent", "--no-autotune", "--no-web", "--no-amqp-acceptor", "--no-mqtt-acceptor", "--no-stomp-acceptor", "--no-hornetq-acceptor");
|
||||
System.setProperty("artemis.instance", instance1.getAbsolutePath());
|
||||
Object result = Artemis.internalExecute("run");
|
||||
ActiveMQServer activeMQServer = ((Pair<ManagementContext, ActiveMQServer>)result).getB();
|
||||
ActiveMQServerControl activeMQServerControl = activeMQServer.getActiveMQServerControl();
|
||||
|
||||
File userFile = new File(instance1.getAbsolutePath() + "/etc/artemis-users.properties");
|
||||
userFile.delete();
|
||||
// File roleFile = new File(instance1.getAbsolutePath() + "/etc/artemis-roles.properties");
|
||||
|
||||
try {
|
||||
activeMQServerControl.listUser("", "activemq");
|
||||
fail();
|
||||
} catch (ActiveMQIllegalStateException expected) {
|
||||
}
|
||||
|
||||
stopServer();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMissingRoleFileViaManagement() throws Exception {
|
||||
Run.setEmbedded(true);
|
||||
File instance1 = new File(temporaryFolder.getRoot(), "instance_user");
|
||||
System.setProperty("java.security.auth.login.config", instance1.getAbsolutePath() + "/etc/login.config");
|
||||
Artemis.main("create", instance1.getAbsolutePath(), "--silent", "--no-autotune", "--no-web", "--no-amqp-acceptor", "--no-mqtt-acceptor", "--no-stomp-acceptor", "--no-hornetq-acceptor");
|
||||
System.setProperty("artemis.instance", instance1.getAbsolutePath());
|
||||
Object result = Artemis.internalExecute("run");
|
||||
ActiveMQServer activeMQServer = ((Pair<ManagementContext, ActiveMQServer>)result).getB();
|
||||
ActiveMQServerControl activeMQServerControl = activeMQServer.getActiveMQServerControl();
|
||||
|
||||
File roleFile = new File(instance1.getAbsolutePath() + "/etc/artemis-roles.properties");
|
||||
roleFile.delete();
|
||||
|
||||
try {
|
||||
activeMQServerControl.listUser("", "activemq");
|
||||
fail();
|
||||
} catch (ActiveMQIllegalStateException expected) {
|
||||
}
|
||||
|
||||
stopServer();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUserCommandReset() throws Exception {
|
||||
Run.setEmbedded(true);
|
||||
|
@ -454,9 +627,9 @@ public class ArtemisTest extends CliTestBase {
|
|||
|
||||
assertTrue(result.contains("Total: 4"));
|
||||
assertTrue(result.contains("\"guest\"(admin)"));
|
||||
assertTrue(result.contains("\"user1\"(admin,manager)"));
|
||||
assertTrue(result.contains("\"user2\"(admin,manager,master)"));
|
||||
assertTrue(result.contains("\"user3\"(master,system)"));
|
||||
assertTrue(Pattern.compile("\"user1\"\\((admin|manager),(admin|manager)\\)").matcher(result).find());
|
||||
assertTrue(Pattern.compile("\"user2\"\\((admin|manager|master),(admin|manager|master),(admin|manager|master)\\)").matcher(result).find());
|
||||
assertTrue(Pattern.compile("\"user3\"\\((master|system),(master|system)\\)").matcher(result).find());
|
||||
|
||||
checkRole("user1", roleFile, "admin", "manager");
|
||||
|
||||
|
@ -488,6 +661,72 @@ public class ArtemisTest extends CliTestBase {
|
|||
assertTrue(checkPassword("user3", "newpassword3", userFile));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUserCommandResetViaManagement() throws Exception {
|
||||
Run.setEmbedded(true);
|
||||
File instance1 = new File(temporaryFolder.getRoot(), "instance_user");
|
||||
System.setProperty("java.security.auth.login.config", instance1.getAbsolutePath() + "/etc/login.config");
|
||||
Artemis.main("create", instance1.getAbsolutePath(), "--silent", "--no-autotune", "--no-web", "--no-amqp-acceptor", "--no-mqtt-acceptor", "--no-stomp-acceptor", "--no-hornetq-acceptor");
|
||||
System.setProperty("artemis.instance", instance1.getAbsolutePath());
|
||||
Object result = Artemis.internalExecute("run");
|
||||
ActiveMQServer activeMQServer = ((Pair<ManagementContext, ActiveMQServer>)result).getB();
|
||||
ActiveMQServerControl activeMQServerControl = activeMQServer.getActiveMQServerControl();
|
||||
|
||||
File userFile = new File(instance1.getAbsolutePath() + "/etc/artemis-users.properties");
|
||||
File roleFile = new File(instance1.getAbsolutePath() + "/etc/artemis-roles.properties");
|
||||
|
||||
//default only one user admin with role amq
|
||||
String jsonResult = activeMQServerControl.listUser("", "activemq");
|
||||
contains(JsonUtil.readJsonArray(jsonResult), "admin", "amq");
|
||||
checkRole("admin", roleFile, "amq");
|
||||
|
||||
//remove a user
|
||||
activeMQServerControl.removeUser("admin", "activemq");
|
||||
jsonResult = activeMQServerControl.listUser("", "activemq");
|
||||
contains(JsonUtil.readJsonArray(jsonResult), "admin", "amq", false);
|
||||
|
||||
//add some users
|
||||
activeMQServerControl.addUser("guest", "guest123", "admin", true, "activemq");
|
||||
activeMQServerControl.addUser("user1", "password1", "admin,manager", true, "activemq");
|
||||
assertTrue(checkPassword("user1", "password1", userFile));
|
||||
activeMQServerControl.addUser("user2", "password2", "admin,manager,master", true, "activemq");
|
||||
activeMQServerControl.addUser("user3", "password3", "system,master", true, "activemq");
|
||||
|
||||
|
||||
//verify use list cmd
|
||||
jsonResult = activeMQServerControl.listUser("", "activemq");
|
||||
contains(JsonUtil.readJsonArray(jsonResult), "guest", "admin");
|
||||
contains(JsonUtil.readJsonArray(jsonResult), "user1", "admin");
|
||||
contains(JsonUtil.readJsonArray(jsonResult), "user1", "manager");
|
||||
contains(JsonUtil.readJsonArray(jsonResult), "user2", "admin");
|
||||
contains(JsonUtil.readJsonArray(jsonResult), "user2", "manager");
|
||||
contains(JsonUtil.readJsonArray(jsonResult), "user2", "master");
|
||||
contains(JsonUtil.readJsonArray(jsonResult), "user3", "master");
|
||||
contains(JsonUtil.readJsonArray(jsonResult), "user3", "system");
|
||||
|
||||
checkRole("user1", roleFile, "admin", "manager");
|
||||
|
||||
//reset password
|
||||
activeMQServerControl.resetUser("user1", "newpassword1", null, "activemq");
|
||||
|
||||
checkRole("user1", roleFile, "admin", "manager");
|
||||
assertFalse(checkPassword("user1", "password1", userFile));
|
||||
assertTrue(checkPassword("user1", "newpassword1", userFile));
|
||||
|
||||
//reset role
|
||||
activeMQServerControl.resetUser("user2", null, "manager,master,operator", "activemq");
|
||||
|
||||
checkRole("user2", roleFile, "manager", "master", "operator");
|
||||
assertTrue(checkPassword("user2", "password2", userFile));
|
||||
|
||||
//reset both
|
||||
activeMQServerControl.resetUser("user3", "newpassword3", "admin,system", "activemq");
|
||||
|
||||
checkRole("user3", roleFile, "admin", "system");
|
||||
assertTrue(checkPassword("user3", "newpassword3", userFile));
|
||||
stopServer();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMaskCommand() throws Exception {
|
||||
|
||||
|
@ -1074,4 +1313,33 @@ public class ArtemisTest extends CliTestBase {
|
|||
return processor.compare(password.toCharArray(), storedPassword);
|
||||
}
|
||||
|
||||
private void contains(JsonArray users, String username, String role) {
|
||||
contains(users, username, role, true);
|
||||
}
|
||||
|
||||
private void contains(JsonArray users, String username, String role, boolean contains) {
|
||||
boolean userFound = false;
|
||||
boolean roleFound = false;
|
||||
for (int i = 0; i < users.size(); i++) {
|
||||
JsonObject user = users.getJsonObject(i);
|
||||
if (user.getString("username").equals(username)) {
|
||||
userFound = true;
|
||||
JsonArray roles = user.getJsonArray("roles");
|
||||
for (int j = 0; j < roles.size(); j++) {
|
||||
if (roles.getString(j).equals(role)) {
|
||||
roleFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (contains) {
|
||||
assertTrue("user " + username + " not found", userFound);
|
||||
assertTrue("role " + role + " not found", roleFound);
|
||||
} else {
|
||||
assertFalse("user " + username + " found", userFound);
|
||||
assertFalse("role " + role + " found", roleFound);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1341,5 +1341,59 @@ public interface ActiveMQServerControl {
|
|||
*/
|
||||
@Operation(desc = "Names of the cluster-connections deployed on this server", impact = MBeanOperationInfo.INFO)
|
||||
String[] getClusterConnectionNames();
|
||||
|
||||
/**
|
||||
* Add a user (only applicable when using the JAAS PropertiesLoginModule)
|
||||
*
|
||||
* @param username
|
||||
* @param password
|
||||
* @param roles
|
||||
* @param entryName
|
||||
* @throws Exception
|
||||
*/
|
||||
@Operation(desc = "add a user (only applicable when using the JAAS PropertiesLoginModule)", impact = MBeanOperationInfo.ACTION)
|
||||
void addUser(@Parameter(name = "username", desc = "Name of the user") String username,
|
||||
@Parameter(name = "password", desc = "User's password") String password,
|
||||
@Parameter(name = "roles (comma separated)", desc = "User's role") String roles,
|
||||
@Parameter(name = "plaintext", desc = "whether or not to store the password in plaintext or hash it") boolean plaintext,
|
||||
@Parameter(name = "entryName", desc = "Name of entry in login.config ('activemq' by default)") String entryName) throws Exception;
|
||||
|
||||
/**
|
||||
* List the information about a user or all users if no username is supplied (only applicable when using the JAAS PropertiesLoginModule).
|
||||
*
|
||||
* @param username
|
||||
* @param entryName
|
||||
* @return JSON array of user & role information
|
||||
* @throws Exception
|
||||
*/
|
||||
@Operation(desc = "list info about a user or all users if no username is supplied (only applicable when using the JAAS PropertiesLoginModule)", impact = MBeanOperationInfo.ACTION)
|
||||
String listUser(@Parameter(name = "username", desc = "Name of the user; leave null to list all known users") String username,
|
||||
@Parameter(name = "entryName", desc = "Name of entry in login.config ('activemq' by default)") String entryName) throws Exception;
|
||||
|
||||
/**
|
||||
* Remove a user (only applicable when using the JAAS PropertiesLoginModule).
|
||||
*
|
||||
* @param username
|
||||
* @param entryName
|
||||
* @throws Exception
|
||||
*/
|
||||
@Operation(desc = "remove a user (only applicable when using the JAAS PropertiesLoginModule)", impact = MBeanOperationInfo.ACTION)
|
||||
void removeUser(@Parameter(name = "username", desc = "Name of the user") String username,
|
||||
@Parameter(name = "entryName", desc = "Name of entry in login.config ('activemq' by default)") String entryName) throws Exception;
|
||||
|
||||
/**
|
||||
* Set new properties on an existing user (only applicable when using the JAAS PropertiesLoginModule).
|
||||
*
|
||||
* @param username
|
||||
* @param password
|
||||
* @param roles
|
||||
* @param entryName
|
||||
* @throws Exception
|
||||
*/
|
||||
@Operation(desc = "set new properties on an existing user (only applicable when using the JAAS PropertiesLoginModule)", impact = MBeanOperationInfo.ACTION)
|
||||
void resetUser(@Parameter(name = "username", desc = "Name of the user") String username,
|
||||
@Parameter(name = "password", desc = "User's password") String password,
|
||||
@Parameter(name = "roles (comma separated)", desc = "User's role") String roles,
|
||||
@Parameter(name = "entryName", desc = "Name of entry in login.config ('activemq' by default)") String entryName) throws Exception;
|
||||
}
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ fi
|
|||
|
||||
# Set Defaults Properties
|
||||
JAVA_ARGS="-XX:+UseParallelGC -Xms512M -Xmx1024M"
|
||||
CLASSPATH="$ARTEMIS_HOME/lib/artemis-boot.jar"
|
||||
CLASSPATH="$ARTEMIS_HOME/lib/*"
|
||||
|
||||
# OS specific support.
|
||||
cygwin=false;
|
||||
|
|
|
@ -50,7 +50,7 @@ set JAVA_ARGS=-XX:+UseParallelGC -Xms512M -Xmx1024M
|
|||
rem "Create full JVM Args"
|
||||
set JVM_ARGS=%JAVA_ARGS%
|
||||
if not "%ARTEMIS_CLUSTER_PROPS%"=="" set JVM_ARGS=%JVM_ARGS% %ARTEMIS_CLUSTER_PROPS%
|
||||
set JVM_ARGS=%JVM_ARGS% -classpath %ARTEMIS_HOME%\lib\artemis-boot.jar
|
||||
set JVM_ARGS=%JVM_ARGS% -classpath %ARTEMIS_HOME%\lib\*
|
||||
set JVM_ARGS=%JVM_ARGS% -Dartemis.home=%ARTEMIS_HOME%
|
||||
if not "%DEBUG_ARGS%"=="" set JVM_ARGS=%JVM_ARGS% %DEBUG_ARGS%
|
||||
|
||||
|
|
|
@ -62,6 +62,9 @@
|
|||
<configfile finalname="etc/artemis.xml">mvn:org.apache.activemq/artemis-features/${pom.version}/xml/artemis</configfile>
|
||||
|
||||
<bundle dependency="true">mvn:org.apache.geronimo.specs/geronimo-jms_2.0_spec/${geronimo.jms.2.spec.version}</bundle>
|
||||
<bundle dependency="true">mvn:org.apache.commons/commons-configuration2/${commons.config.version}</bundle>
|
||||
<bundle dependency="true">mvn:org.apache.commons/commons-text/1.6</bundle>
|
||||
<bundle dependency="true">mvn:org.apache.commons/commons-lang3/${commons.lang.version}</bundle>
|
||||
|
||||
<bundle>mvn:org.apache.activemq/artemis-native/${pom.version}</bundle>
|
||||
<bundle>mvn:org.apache.activemq/artemis-server-osgi/${pom.version}</bundle>
|
||||
|
|
|
@ -127,6 +127,10 @@
|
|||
<groupId>commons-beanutils</groupId>
|
||||
<artifactId>commons-beanutils</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-configuration2</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
|
|
|
@ -30,6 +30,7 @@ import javax.management.NotificationEmitter;
|
|||
import javax.management.NotificationFilter;
|
||||
import javax.management.NotificationListener;
|
||||
import javax.transaction.xa.Xid;
|
||||
import java.net.URL;
|
||||
import java.text.DateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
@ -118,8 +119,10 @@ import org.apache.activemq.artemis.core.transaction.TransactionDetailFactory;
|
|||
import org.apache.activemq.artemis.core.transaction.impl.CoreTransactionDetail;
|
||||
import org.apache.activemq.artemis.core.transaction.impl.XidImpl;
|
||||
import org.apache.activemq.artemis.spi.core.protocol.RemotingConnection;
|
||||
import org.apache.activemq.artemis.spi.core.security.jaas.PropertiesLoginModuleConfigurator;
|
||||
import org.apache.activemq.artemis.utils.JsonLoader;
|
||||
import org.apache.activemq.artemis.utils.ListUtil;
|
||||
import org.apache.activemq.artemis.utils.PasswordMaskingUtil;
|
||||
import org.apache.activemq.artemis.utils.SecurityFormatter;
|
||||
import org.apache.activemq.artemis.utils.collections.TypedProperties;
|
||||
import org.jboss.logging.Logger;
|
||||
|
@ -2956,5 +2959,52 @@ public class ActiveMQServerControlImpl extends AbstractControl implements Active
|
|||
this.broadcaster.sendNotification(new Notification(type.toString(), this, notifSeq.incrementAndGet(), notification.toString()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addUser(String username, String password, String roles, boolean plaintext, String entryName) throws Exception {
|
||||
PropertiesLoginModuleConfigurator config = getPropertiesLoginModuleConfigurator(entryName);
|
||||
config.addNewUser(username, plaintext ? password : PasswordMaskingUtil.getHashProcessor().hash(password), roles.split(","));
|
||||
config.save();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String listUser(String username, String entryName) throws Exception {
|
||||
PropertiesLoginModuleConfigurator config = getPropertiesLoginModuleConfigurator(entryName);
|
||||
Map<String, Set<String>> info = config.listUser(username);
|
||||
JsonArrayBuilder users = JsonLoader.createArrayBuilder();
|
||||
for (Entry<String, Set<String>> entry : info.entrySet()) {
|
||||
JsonObjectBuilder user = JsonLoader.createObjectBuilder();
|
||||
user.add("username", entry.getKey());
|
||||
JsonArrayBuilder roles = JsonLoader.createArrayBuilder();
|
||||
for (String role : entry.getValue()) {
|
||||
roles.add(role);
|
||||
}
|
||||
user.add("roles", roles);
|
||||
users.add(user);
|
||||
}
|
||||
return users.build().toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeUser(String username, String entryName) throws Exception {
|
||||
PropertiesLoginModuleConfigurator config = getPropertiesLoginModuleConfigurator(entryName);
|
||||
config.removeUser(username);
|
||||
config.save();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetUser(String username, String password, String roles, String entryName) throws Exception {
|
||||
PropertiesLoginModuleConfigurator config = getPropertiesLoginModuleConfigurator(entryName);
|
||||
config.updateUser(username, password, roles == null ? null : roles.split(","));
|
||||
config.save();
|
||||
}
|
||||
|
||||
private PropertiesLoginModuleConfigurator getPropertiesLoginModuleConfigurator(String entryName) throws Exception {
|
||||
URL configurationUrl = server.getConfiguration().getConfigurationUrl();
|
||||
if (configurationUrl == null) {
|
||||
throw ActiveMQMessageBundle.BUNDLE.failedToLocateConfigURL();
|
||||
}
|
||||
String path = configurationUrl.getPath();
|
||||
return new PropertiesLoginModuleConfigurator(entryName, path.substring(0, path.lastIndexOf("/")));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -449,4 +449,24 @@ public interface ActiveMQMessageBundle {
|
|||
@Message(id = 119217, value = "Can't write to closed file: {0}", format = Message.Format.MESSAGE_FORMAT)
|
||||
ActiveMQIOErrorException cannotWriteToClosedFile(SequentialFile file);
|
||||
|
||||
@Message(id = 229218, value = "Failed to locate broker configuration URL")
|
||||
ActiveMQIllegalStateException failedToLocateConfigURL();
|
||||
|
||||
@Message(id = 229219, value = "Failed to load security configuration")
|
||||
ActiveMQIllegalStateException failedToLoadSecurityConfig();
|
||||
|
||||
@Message(id = 229220, value = "Failed to load user file: {0}", format = Message.Format.MESSAGE_FORMAT)
|
||||
ActiveMQIllegalStateException failedToLoadUserFile(String path);
|
||||
|
||||
@Message(id = 229221, value = "Failed to load role file: {0}", format = Message.Format.MESSAGE_FORMAT)
|
||||
ActiveMQIllegalStateException failedToLoadRoleFile(String path);
|
||||
|
||||
@Message(id = 229222, value = "Failed to find login module entry {0} from JAAS configuration", format = Message.Format.MESSAGE_FORMAT)
|
||||
ActiveMQIllegalStateException failedToFindLoginModuleEntry(String entry);
|
||||
|
||||
@Message(id = 229223, value = "User {0} already exists", format = Message.Format.MESSAGE_FORMAT)
|
||||
IllegalArgumentException userAlreadyExists(String user);
|
||||
|
||||
@Message(id = 229224, value = "User {0} does not exist", format = Message.Format.MESSAGE_FORMAT)
|
||||
IllegalArgumentException userDoesNotExist(String user);
|
||||
}
|
||||
|
|
|
@ -14,20 +14,30 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.activemq.artemis.cli.commands.user;
|
||||
package org.apache.activemq.artemis.spi.core.security.jaas;
|
||||
|
||||
import javax.security.auth.login.AppConfigurationEntry;
|
||||
import javax.security.auth.login.Configuration;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.activemq.artemis.api.core.Pair;
|
||||
import org.apache.activemq.artemis.core.server.ActiveMQMessageBundle;
|
||||
import org.apache.activemq.artemis.utils.StringUtil;
|
||||
import org.apache.commons.configuration2.PropertiesConfiguration;
|
||||
import org.apache.commons.configuration2.builder.FileBasedConfigurationBuilder;
|
||||
import org.apache.commons.configuration2.builder.fluent.Configurations;
|
||||
|
||||
class FileBasedSecStoreConfig {
|
||||
import static org.apache.activemq.artemis.spi.core.security.jaas.PropertiesLoginModule.ROLE_FILE_PROP_NAME;
|
||||
import static org.apache.activemq.artemis.spi.core.security.jaas.PropertiesLoginModule.USER_FILE_PROP_NAME;
|
||||
|
||||
public class PropertiesLoginModuleConfigurator {
|
||||
|
||||
private static final String LICENSE_HEADER =
|
||||
"## ---------------------------------------------------------------------------\n" +
|
||||
|
@ -51,80 +61,110 @@ class FileBasedSecStoreConfig {
|
|||
private PropertiesConfiguration userConfig;
|
||||
private PropertiesConfiguration roleConfig;
|
||||
|
||||
FileBasedSecStoreConfig(File userFile, File roleFile) throws Exception {
|
||||
Configurations configs = new Configurations();
|
||||
userBuilder = configs.propertiesBuilder(userFile);
|
||||
roleBuilder = configs.propertiesBuilder(roleFile);
|
||||
userConfig = userBuilder.getConfiguration();
|
||||
roleConfig = roleBuilder.getConfiguration();
|
||||
public PropertiesLoginModuleConfigurator(String entryName, String brokerEtc) throws Exception {
|
||||
if (entryName == null || entryName.length() == 0) {
|
||||
entryName = "activemq";
|
||||
}
|
||||
|
||||
String roleHeader = roleConfig.getLayout().getHeaderComment();
|
||||
String userHeader = userConfig.getLayout().getHeaderComment();
|
||||
Configuration securityConfig = Configuration.getConfiguration();
|
||||
AppConfigurationEntry[] entries = securityConfig.getAppConfigurationEntry(entryName);
|
||||
|
||||
if (userHeader == null) {
|
||||
if (userConfig.isEmpty()) {
|
||||
//clean and reset header
|
||||
userConfig.clear();
|
||||
userConfig.setHeader(LICENSE_HEADER);
|
||||
if (entries == null || entries.length == 0) {
|
||||
throw ActiveMQMessageBundle.BUNDLE.failedToLoadSecurityConfig();
|
||||
}
|
||||
|
||||
int entriesInspected = 0;
|
||||
for (AppConfigurationEntry entry : entries) {
|
||||
entriesInspected++;
|
||||
if (entry.getLoginModuleName().equals(PropertiesLoginModule.class.getName())) {
|
||||
String userFileName = (String) entry.getOptions().get(USER_FILE_PROP_NAME);
|
||||
String roleFileName = (String) entry.getOptions().get(ROLE_FILE_PROP_NAME);
|
||||
|
||||
File etcDir = new File(brokerEtc);
|
||||
File userFile = new File(etcDir, userFileName);
|
||||
File roleFile = new File(etcDir, roleFileName);
|
||||
|
||||
if (!userFile.exists()) {
|
||||
throw ActiveMQMessageBundle.BUNDLE.failedToLoadUserFile(brokerEtc + userFileName);
|
||||
}
|
||||
|
||||
if (!roleFile.exists()) {
|
||||
throw ActiveMQMessageBundle.BUNDLE.failedToLoadRoleFile(brokerEtc + roleFileName);
|
||||
}
|
||||
|
||||
Configurations configs = new Configurations();
|
||||
userBuilder = configs.propertiesBuilder(userFile);
|
||||
roleBuilder = configs.propertiesBuilder(roleFile);
|
||||
userConfig = userBuilder.getConfiguration();
|
||||
roleConfig = roleBuilder.getConfiguration();
|
||||
|
||||
String roleHeader = roleConfig.getLayout().getHeaderComment();
|
||||
String userHeader = userConfig.getLayout().getHeaderComment();
|
||||
|
||||
if (userHeader == null) {
|
||||
if (userConfig.isEmpty()) {
|
||||
//clean and reset header
|
||||
userConfig.clear();
|
||||
userConfig.setHeader(LICENSE_HEADER);
|
||||
}
|
||||
}
|
||||
|
||||
if (roleHeader == null) {
|
||||
if (roleConfig.isEmpty()) {
|
||||
//clean and reset header
|
||||
roleConfig.clear();
|
||||
roleConfig.setHeader(LICENSE_HEADER);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (roleHeader == null) {
|
||||
if (roleConfig.isEmpty()) {
|
||||
//clean and reset header
|
||||
roleConfig.clear();
|
||||
roleConfig.setHeader(LICENSE_HEADER);
|
||||
}
|
||||
if (entriesInspected == entries.length) {
|
||||
throw ActiveMQMessageBundle.BUNDLE.failedToFindLoginModuleEntry(entryName);
|
||||
}
|
||||
}
|
||||
|
||||
void addNewUser(String username, String hash, String... roles) throws Exception {
|
||||
public void addNewUser(String username, String hash, String... roles) throws Exception {
|
||||
if (userConfig.getString(username) != null) {
|
||||
throw new IllegalArgumentException("User already exist: " + username);
|
||||
throw ActiveMQMessageBundle.BUNDLE.userAlreadyExists(username);
|
||||
}
|
||||
userConfig.addProperty(username, hash);
|
||||
addRoles(username, roles);
|
||||
}
|
||||
|
||||
void save() throws Exception {
|
||||
public void save() throws Exception {
|
||||
userBuilder.save();
|
||||
roleBuilder.save();
|
||||
}
|
||||
|
||||
void removeUser(String username) throws Exception {
|
||||
public void removeUser(String username) {
|
||||
if (userConfig.getProperty(username) == null) {
|
||||
throw new IllegalArgumentException("user " + username + " doesn't exist.");
|
||||
throw ActiveMQMessageBundle.BUNDLE.userDoesNotExist(username);
|
||||
}
|
||||
userConfig.clearProperty(username);
|
||||
removeRoles(username);
|
||||
}
|
||||
|
||||
List<String> listUser(String username) {
|
||||
List<String> result = new ArrayList<>();
|
||||
result.add("--- \"user\"(roles) ---\n");
|
||||
public Map<String, Set<String>> listUser(String username) {
|
||||
Map<String, Set<String>> result = new HashMap<>();
|
||||
|
||||
int totalUsers = 0;
|
||||
if (username != null) {
|
||||
String roles = findRoles(username);
|
||||
result.add("\"" + username + "\"(" + roles + ")");
|
||||
totalUsers++;
|
||||
if (username != null && username.length() > 0) {
|
||||
result.put(username, findRoles(username));
|
||||
} else {
|
||||
Iterator<String> iter = userConfig.getKeys();
|
||||
while (iter.hasNext()) {
|
||||
String keyUser = iter.next();
|
||||
String roles = findRoles(keyUser);
|
||||
result.add("\"" + keyUser + "\"(" + roles + ")");
|
||||
totalUsers++;
|
||||
result.put(keyUser, findRoles(keyUser));
|
||||
}
|
||||
}
|
||||
result.add("\n Total: " + totalUsers);
|
||||
return result;
|
||||
}
|
||||
|
||||
void updateUser(String username, String password, String[] roles) {
|
||||
public void updateUser(String username, String password, String[] roles) {
|
||||
String oldPassword = (String) userConfig.getProperty(username);
|
||||
if (oldPassword == null) {
|
||||
throw new IllegalArgumentException("user " + username + " doesn't exist.");
|
||||
throw ActiveMQMessageBundle.BUNDLE.userDoesNotExist(username);
|
||||
}
|
||||
|
||||
if (password != null) {
|
||||
|
@ -138,33 +178,28 @@ class FileBasedSecStoreConfig {
|
|||
}
|
||||
}
|
||||
|
||||
private String findRoles(String uname) {
|
||||
private Set<String> findRoles(String username) {
|
||||
Iterator<String> iter = roleConfig.getKeys();
|
||||
StringBuilder builder = new StringBuilder();
|
||||
boolean first = true;
|
||||
Set<String> roles = new HashSet();
|
||||
while (iter.hasNext()) {
|
||||
String role = iter.next();
|
||||
List<String> names = roleConfig.getList(String.class, role);
|
||||
for (String value : names) {
|
||||
//each value may be a comma separated list
|
||||
String[] items = value.split(",");
|
||||
for (String roleList : roleConfig.getList(String.class, role)) {
|
||||
//each roleList may be a comma separated list
|
||||
String[] items = roleList.split(",");
|
||||
for (String item : items) {
|
||||
if (item.equals(uname)) {
|
||||
if (!first) {
|
||||
builder.append(",");
|
||||
}
|
||||
builder.append(role);
|
||||
first = false;
|
||||
if (item.equals(username)) {
|
||||
roles.add(role);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
return roles;
|
||||
}
|
||||
|
||||
private void addRoles(String username, String[] roles) {
|
||||
for (String role : roles) {
|
||||
role = role.trim();
|
||||
List<String> users = roleConfig.getList(String.class, role);
|
||||
if (users == null) {
|
||||
users = new ArrayList<>();
|
|
@ -546,6 +546,17 @@ users=system,user
|
|||
guests=guest
|
||||
```
|
||||
|
||||
As mentioned above, the Artemis command-line interface supports a command to
|
||||
`add` a user. Commands to `list` (one or all) users, `remove` a user, and `reset`
|
||||
a user's password and/or role(s) are also supported via the command-line
|
||||
interface as well as the normal management interfaces (e.g. JMX, web console,
|
||||
etc.).
|
||||
|
||||
> **Warning**
|
||||
>
|
||||
> Management and CLI operations to manipulate user & role data are only available
|
||||
> when using the `PropertiesLoginModule`.
|
||||
|
||||
#### LDAPLoginModule
|
||||
|
||||
The LDAP login module enables you to perform authentication and authorization
|
||||
|
|
2
pom.xml
2
pom.xml
|
@ -77,7 +77,7 @@
|
|||
|
||||
<karaf.version>4.0.6</karaf.version>
|
||||
<pax.exam.version>4.9.1</pax.exam.version>
|
||||
<commons.config.version>2.1</commons.config.version>
|
||||
<commons.config.version>2.4</commons.config.version>
|
||||
<commons.lang.version>3.0</commons.lang.version>
|
||||
<activemq5-version>5.14.5</activemq5-version>
|
||||
<apache.derby.version>10.11.1.1</apache.derby.version>
|
||||
|
|
|
@ -2683,6 +2683,46 @@ public class ActiveMQServerControlTest extends ManagementTestBase {
|
|||
Assert.assertTrue(((org.apache.activemq.artemis.jms.client.ActiveMQMessageConsumer)JMSclient).isClosed());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddUser() throws Exception {
|
||||
ActiveMQServerControl serverControl = createManagementControl();
|
||||
try {
|
||||
serverControl.addUser("x", "x", "x", true, "x");
|
||||
fail();
|
||||
} catch (Exception expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveUser() throws Exception {
|
||||
ActiveMQServerControl serverControl = createManagementControl();
|
||||
try {
|
||||
serverControl.removeUser("x", "x");
|
||||
fail();
|
||||
} catch (Exception expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListUser() throws Exception {
|
||||
ActiveMQServerControl serverControl = createManagementControl();
|
||||
try {
|
||||
serverControl.listUser("x", "x");
|
||||
fail();
|
||||
} catch (Exception expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResetUser() throws Exception {
|
||||
ActiveMQServerControl serverControl = createManagementControl();
|
||||
try {
|
||||
serverControl.resetUser("x","x","x", "x");
|
||||
fail();
|
||||
} catch (Exception expected) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void scaleDown(ScaleDownHandler handler) throws Exception {
|
||||
SimpleString address = new SimpleString("testQueue");
|
||||
|
|
|
@ -335,6 +335,31 @@ public class ActiveMQServerControlUsingCoreTest extends ActiveMQServerControlTes
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addUser(String username,
|
||||
String password,
|
||||
String role,
|
||||
boolean plaintext,
|
||||
String entryName) throws Exception {
|
||||
proxy.invokeOperation("addUser", username, password, role, plaintext, entryName);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String listUser(String username, String entryName) throws Exception {
|
||||
return (String) proxy.invokeOperation("listUser", username, entryName, String.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeUser(String username, String entryName) throws Exception {
|
||||
proxy.invokeOperation("removeUser", username, entryName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetUser(String username, String password, String roles, String entryName) throws Exception {
|
||||
proxy.invokeOperation("resetUser", username, password, roles, entryName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUptime() {
|
||||
return null;
|
||||
|
|
Loading…
Reference in New Issue