Skip to content

Commit

Permalink
Improve the file-based user store
Browse files Browse the repository at this point in the history
Improve file-based user store to work as a primary user store.
Fixes /issues/3006
  • Loading branch information
GDLMadushanka committed Oct 25, 2023
1 parent b37b267 commit 13c1615
Show file tree
Hide file tree
Showing 19 changed files with 703 additions and 284 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,6 @@ public class ConfigurationLoader {
private static final QName PROTOCOL_Q = new QName("protocol");
private static final QName HANDLERS_Q = new QName("handlers");
private static final QName RESOURCES_Q = new QName("resources");
private static final QName USER_STORE_Q = new QName("userStore");
private static final QName USERS_Q = new QName("users");
private static final QName USER_Q = new QName("user");
private static final QName USERNAME_Q = new QName("username");
private static final QName PASSWORD_Q = new QName("password");
private static final QName IS_ADMIN_Q = new QName("isAdmin");
private static final QName STORE_PASSWORD_Q = new QName("Password");
private static final QName KEY_PASSWORD_Q = new QName("KeyPassword");

Expand All @@ -84,7 +78,6 @@ public class ConfigurationLoader {

private static SSLConfiguration sslConfiguration;
private static boolean sslConfiguredSuccessfully;
private static Map<String, UserInfo> userMap;

private static List<InternalAPI> internalHttpApiList = new ArrayList<>();
private static List<InternalAPI> internalHttpsApiList = new ArrayList<>();
Expand All @@ -107,7 +100,6 @@ public static void loadInternalApis(String apiFilePath) {
}

setSecretResolver(apiConfig);
populateUserStore(apiConfig);

Iterator apiIterator = apiConfig.getChildrenWithLocalName(APIS);

Expand Down Expand Up @@ -187,54 +179,6 @@ public static void loadInternalApis(String apiFilePath) {
}
}

/**
* Populates the userList hashMap by userStore OM element
*/
private static void populateUserStore(OMElement apiConfig) {
OMElement userStoreOM = apiConfig.getFirstChildWithName(USER_STORE_Q);
if (Objects.nonNull(userStoreOM)) {
userMap = populateUsers(userStoreOM.getFirstChildWithName(USERS_Q));
} else {
userMap = null;
}
}

/**
* Populates individual users.
*
* @param users the parent element of users
* @return map of users against UserInfo config
*/
private static Map<String, UserInfo> populateUsers(OMElement users) {
HashMap<String, UserInfo> userMap = new HashMap<>();
if (users != null) {
@SuppressWarnings("unchecked")
Iterator<OMElement> usersIterator = users.getChildrenWithName(USER_Q);
if (usersIterator != null) {
while (usersIterator.hasNext()) {
OMElement userElement = usersIterator.next();
OMElement userNameElement = userElement.getFirstChildWithName(USERNAME_Q);
OMElement passwordElement = userElement.getFirstChildWithName(PASSWORD_Q);
OMElement isAdminElement = userElement.getFirstChildWithName(IS_ADMIN_Q);
if (userNameElement != null && passwordElement != null) {
String userName = userNameElement.getText();
if (userMap.containsKey(userName)) {
handleException("Error parsing the file based user store. User: " + userName + " defined "
+ "more than once. ");
}
boolean isAdmin = false;
if (isAdminElement != null) {
isAdmin = Boolean.parseBoolean(isAdminElement.getText().trim());
}
userMap.put(userName, new UserInfo(userName,
resolveSecret(passwordElement.getText()).toCharArray(), isAdmin));
}
}
}
}
return userMap;
}

/**
* Checks if the text is protected and returns decrypted text if protected, else returns the plain text
* @param text
Expand Down Expand Up @@ -337,10 +281,6 @@ private static InternalAPI createApi(String classFQName) {
}
}

public static Map<String, UserInfo> getUserMap() {
return userMap;
}

public static int getInternalInboundHttpPort() {

return getPort(Constants.INTERNAL_HTTP_API_PORT, internalInboundHttpPortProperty,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import org.wso2.carbon.inbound.endpoint.internal.http.api.Constants;
import org.wso2.carbon.inbound.endpoint.internal.http.api.InternalAPI;
import org.wso2.carbon.inbound.endpoint.internal.http.api.InternalAPIHandler;
import org.wso2.carbon.inbound.endpoint.internal.http.api.UserInfo;

import java.net.URL;
import java.util.List;
Expand Down Expand Up @@ -78,50 +77,50 @@ public void testLoadHandlers() {

}

/**
* Test loading of internal apis from the internal-apis.xml file.
*/
@Test
public void testLoadUsers() {

// test configuration with users
URL url = getClass().getResource("internal-apis.xml");
Assert.assertNotNull("Configuration file not found", url);

ConfigurationLoader.loadInternalApis("internal/http/api/internal-apis.xml");
Map<String, UserInfo> userMap = ConfigurationLoader.getUserMap();

org.junit.Assert.assertEquals(3, userMap.size());
//Assert admin:admin
org.junit.Assert.assertNotNull(userMap.get("admin"));
org.junit.Assert.assertEquals("admin", String.valueOf(userMap.get("admin").getPassword()));
org.junit.Assert.assertTrue("isAdmin", userMap.get("admin").isAdmin());

//Assert user1:pwd1
org.junit.Assert.assertNotNull(userMap.get("user1"));
org.junit.Assert.assertEquals("pwd1", String.valueOf(userMap.get("user1").getPassword()));
org.junit.Assert.assertFalse("isAdmin", userMap.get("user1").isAdmin());

//Assert user2:pwd2
org.junit.Assert.assertNotNull(userMap.get("user2"));
org.junit.Assert.assertEquals("pwd2", String.valueOf(userMap.get("user2").getPassword()));
org.junit.Assert.assertFalse("isAdmin", userMap.get("user2").isAdmin());
}

/**
* Test loading of internal apis from the internal-apis.xml file.
*/
@Test
public void testLoadInternalApisWithNoUserStore() {

// test configuration with users
URL url = getClass().getResource("internal-apis-without-user-store.xml");
Assert.assertNotNull("Configuration file not found", url);

ConfigurationLoader.loadInternalApis("internal/http/api/internal-apis-without-user-store.xml");
Assert.assertNull("User store is not defined in the file but it is not null",
ConfigurationLoader.getUserMap());
}
// /**
// * Test loading of internal apis from the internal-apis.xml file.
// */
// @Test
// public void testLoadUsers() {
//
// // test configuration with users
// URL url = getClass().getResource("internal-apis.xml");
// Assert.assertNotNull("Configuration file not found", url);
//
// ConfigurationLoader.loadInternalApis("internal/http/api/internal-apis.xml");
// Map<String, UserInfo> userMap = ConfigurationLoader.getUserMap();
//
// org.junit.Assert.assertEquals(3, userMap.size());
// //Assert admin:admin
// org.junit.Assert.assertNotNull(userMap.get("admin"));
// org.junit.Assert.assertEquals("admin", String.valueOf(userMap.get("admin").getPassword()));
// org.junit.Assert.assertTrue("isAdmin", userMap.get("admin").isAdmin());
//
// //Assert user1:pwd1
// org.junit.Assert.assertNotNull(userMap.get("user1"));
// org.junit.Assert.assertEquals("pwd1", String.valueOf(userMap.get("user1").getPassword()));
// org.junit.Assert.assertFalse("isAdmin", userMap.get("user1").isAdmin());
//
// //Assert user2:pwd2
// org.junit.Assert.assertNotNull(userMap.get("user2"));
// org.junit.Assert.assertEquals("pwd2", String.valueOf(userMap.get("user2").getPassword()));
// org.junit.Assert.assertFalse("isAdmin", userMap.get("user2").isAdmin());
// }
//
// /**
// * Test loading of internal apis from the internal-apis.xml file.
// */
// @Test
// public void testLoadInternalApisWithNoUserStore() {
//
// // test configuration with users
// URL url = getClass().getResource("internal-apis-without-user-store.xml");
// Assert.assertNotNull("Configuration file not found", url);
//
// ConfigurationLoader.loadInternalApis("internal/http/api/internal-apis-without-user-store.xml");
// Assert.assertNull("User store is not defined in the file but it is not null",
// ConfigurationLoader.getUserMap());
// }

private List<InternalAPI> getApis() {
System.setProperty(Constants.PREFIX_TO_ENABLE_INTERNAL_APIS + "SampleAPI", "true");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.inbound.endpoint.internal.http.api.ConfigurationLoader;
import org.wso2.carbon.inbound.endpoint.internal.http.api.UserInfo;
import org.wso2.micro.core.util.CarbonException;
import org.wso2.micro.integrator.core.util.MicroIntegratorBaseUtils;
import org.wso2.securevault.SecretResolverFactory;
Expand Down Expand Up @@ -89,21 +88,6 @@ public static OMElement getManagementApiElement() throws IOException, CarbonExce
throw new ManagementApiUndefinedException("Management API not defined in " + getConfigurationFilePath());
}

/**
* Method to get the user store define in internal-apis.xml
*
* @return a non null map if the user store is defined.
* @throws UserStoreUndefinedException if the user store is not defined in internal-apis.xml
*/
public Map<String, UserInfo> getUserMap() throws UserStoreUndefinedException {
Map<String, UserInfo> usersMap = ConfigurationLoader.getUserMap();
if (Objects.nonNull(usersMap)) {
return usersMap;
} else {
throw new UserStoreUndefinedException("UserStore tag not defined inside the Management API");
}
}

private static OMElement getInternalApisElement() throws IOException, CarbonException, XMLStreamException {
File mgtApiUserConfig = getConfigurationFile();
try (InputStream fileInputStream = new FileInputStream(mgtApiUserConfig)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.wso2.micro.integrator.management.apis.ManagementApiUndefinedException;
import org.wso2.micro.integrator.security.MicroIntegratorSecurityUtils;
import org.wso2.micro.integrator.security.user.api.UserStoreException;
import org.wso2.micro.integrator.security.user.core.file.FileBasedUserStoreManager;

import java.io.IOException;
import java.util.Map;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.wso2.micro.integrator.management.apis.ManagementApiUndefinedException;
import org.wso2.micro.integrator.security.MicroIntegratorSecurityUtils;
import org.wso2.micro.integrator.security.user.api.UserStoreException;
import org.wso2.micro.integrator.security.user.core.file.FileBasedUserStoreManager;

import javax.xml.stream.XMLStreamException;
import java.io.IOException;
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@
import org.apache.synapse.MessageContext;
import org.apache.synapse.rest.RESTConstants;
import org.wso2.carbon.inbound.endpoint.internal.http.api.InternalAPIHandler;
import org.wso2.config.mapper.ConfigParser;
import org.wso2.micro.core.util.CarbonException;
import org.wso2.micro.integrator.management.apis.Constants;
import org.wso2.micro.integrator.management.apis.ManagementApiUndefinedException;
import org.wso2.micro.integrator.security.user.core.file.FileBasedUserStoreManager;

import java.io.IOException;
import java.util.ArrayList;
Expand All @@ -40,6 +42,7 @@ public abstract class SecurityHandlerAdapter implements InternalAPIHandler {

protected static boolean useCarbonUserStore = false;
private static boolean isInitialized = false;
private static String FILE_BASED_USER_STORE_PRIMARY = "internal_apis.file_user_store.primary";
/**
* Resources defined in internal-apis.xml to be handled
*/
Expand Down Expand Up @@ -67,6 +70,10 @@ private static void initializeUserStore() throws CarbonException, IOException, M
XMLStreamException {
if (!isInitialized) {
if (SecurityUtils.isFileBasedUserStoreEnabled()) {
Object fileUserStore = ConfigParser.getParsedConfigs().get(FILE_BASED_USER_STORE_PRIMARY);
if (fileUserStore != null && Boolean.parseBoolean(fileUserStore.toString())) {
useCarbonUserStore = true;
}
isInitialized = FileBasedUserStoreManager.getUserStoreManager().isInitialized();
} else {
LOG.info("File based user store has been disabled. Carbon user store settings will be used.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.wso2.micro.integrator.management.apis.Constants;
import org.wso2.micro.integrator.security.MicroIntegratorSecurityUtils;
import org.wso2.micro.integrator.security.user.api.UserStoreException;
import org.wso2.micro.integrator.security.user.core.file.FileBasedUserStoreManager;
import org.wso2.securevault.SecretResolver;
import org.wso2.securevault.SecureVaultException;

Expand Down
Loading

0 comments on commit 13c1615

Please sign in to comment.