Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve the file-based user store #3007

Merged
merged 1 commit into from
Oct 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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,51 +77,6 @@ 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());
}

private List<InternalAPI> getApis() {
System.setProperty(Constants.PREFIX_TO_ENABLE_INTERNAL_APIS + "SampleAPI", "true");
URL url = getClass().getResource("internal-apis.xml");
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_AS_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_AS_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
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
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.internal.MicroIntegratorBaseConstants;

Expand Down Expand Up @@ -60,6 +59,7 @@ public void getManagementApiElement() throws CarbonException, XMLStreamException
Assert.assertEquals(MGT_API_NAME, managementApiElement.getAttributeValue(NAME_ATTR));
}

/*
@Test
public void testGetUserList() throws UserStoreUndefinedException {
Map<String, UserInfo> userMap = new HashMap<>();
Expand All @@ -79,4 +79,5 @@ public void testGetNullUserStore() throws UserStoreUndefinedException {
ManagementApiParser managementApiParser = new ManagementApiParser();
managementApiParser.getUserMap();
}
*/
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ public class UserCoreConstants {
public static final String IS_USER_IN_ROLE_CACHE_IDENTIFIER = "@__isUserHasTheRole__@";

public static final String DOMAIN_SEPARATOR;
public static final String FILE_BASED_USER_STORE_AS_PRIMARY = "internal_apis.file_user_store.primary";

static {
String userDomainSeparator = CarbonServerConfigurationService.getInstance().getFirstProperty("UserDomainSeparator");
Expand Down
Loading