-
Notifications
You must be signed in to change notification settings - Fork 393
@W-21148602: Internal Server List does not respect changes made to Servers.xml file #2845
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
Changes from 1 commit
ad8d74f
84a6441
2d06029
99edfa6
48a047e
a754057
7627a75
463b95c
7daebb6
686e433
51d888c
a48ed4d
8724b7e
0406497
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -50,7 +50,6 @@ | |
| import java.util.Deque; | ||
| import java.util.List; | ||
| import java.util.Locale; | ||
| import java.util.Map; | ||
|
|
||
| /** | ||
| * Class to manage login hosts (default and user entered). | ||
|
|
@@ -92,7 +91,14 @@ public LoginServerManager(Context ctx) { | |
| Context.MODE_PRIVATE); | ||
| runtimePrefs = ctx.getSharedPreferences(RUNTIME_PREFS_FILE, | ||
| Context.MODE_PRIVATE); | ||
|
|
||
| // Reset non-custom servers from mobile device management (MDM) and servers XML. | ||
| resetNonCustomLoginServers(runtimePrefs); | ||
| resetNonCustomLoginServers(settings); | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A crux change is here in the constructor to (re-)initialize the non-custom login servers from resources |
||
|
|
||
| // Refresh non-custom servers from MDM or servers.xml | ||
| initSharedPrefFile(); | ||
|
|
||
| getSelectedLoginServer(); | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The updated |
||
| } | ||
|
|
||
|
|
@@ -228,32 +234,48 @@ public void reset() { | |
| } | ||
|
|
||
| /** | ||
| * Removes a login server from the list. | ||
| * Removes a custom login server from the list. | ||
| * | ||
| * @param server the server to remove | ||
| * @param server The server to remove. If the server is not custom, this method does nothing | ||
| */ | ||
| public void removeServer(LoginServer server) { | ||
| removeServer(server, settings, false); | ||
| } | ||
|
|
||
| /** | ||
| * Removes a login server from the list. | ||
| * | ||
| * @param server The server to remove | ||
| * @param sharedPreferences The shared preferences to remove the server from | ||
| * @param allowNonCustomRemoval Boolean true allows the removal of non-custom login servers and | ||
| * false does not | ||
| */ | ||
| private void removeServer( | ||
| final LoginServer server, | ||
| final SharedPreferences sharedPreferences, | ||
| final boolean allowNonCustomRemoval | ||
| ) { | ||
| List<LoginServer> servers = getLoginServers(); | ||
| int index = servers.indexOf(server); | ||
|
|
||
| if (server.isCustom && index != -1) { | ||
| int numServers = settings.getInt(NUMBER_OF_ENTRIES, 0); | ||
| Deque<LoginServer> stack = new ArrayDeque<>(servers.subList(index+1, numServers)); | ||
| if (allowNonCustomRemoval || server.isCustom && index != -1) { | ||
| int numServers = servers.size(); | ||
| Deque<LoginServer> stack = new ArrayDeque<>(servers.subList(index + 1, numServers)); | ||
|
|
||
| final Editor edit = settings.edit(); | ||
| final Editor edit = sharedPreferences.edit(); | ||
| edit.remove(String.format(Locale.US, SERVER_NAME, index)) | ||
| .remove(String.format(Locale.US, SERVER_URL, index)) | ||
| .remove(String.format(Locale.US, IS_CUSTOM, index)); | ||
| .remove(String.format(Locale.US, SERVER_URL, index)) | ||
| .remove(String.format(Locale.US, IS_CUSTOM, index)); | ||
|
|
||
| // Re-index servers after the one removed from the list. | ||
| for (int i = (index + 1); i < numServers; i++) { | ||
| LoginServer reIndexServer = stack.pop(); | ||
| edit.remove(String.format(Locale.US, SERVER_NAME, i)) | ||
| .remove(String.format(Locale.US, SERVER_URL, i)) | ||
| .remove(String.format(Locale.US, IS_CUSTOM, i)) | ||
| .putString(String.format(Locale.US, SERVER_NAME, i-1), reIndexServer.name) | ||
| .putString(String.format(Locale.US, SERVER_URL, i-1), reIndexServer.url) | ||
| .putBoolean(String.format(Locale.US, IS_CUSTOM, i-1), reIndexServer.isCustom); | ||
| .remove(String.format(Locale.US, SERVER_URL, i)) | ||
| .remove(String.format(Locale.US, IS_CUSTOM, i)) | ||
| .putString(String.format(Locale.US, SERVER_NAME, i - 1), reIndexServer.name) | ||
| .putString(String.format(Locale.US, SERVER_URL, i - 1), reIndexServer.url) | ||
| .putBoolean(String.format(Locale.US, IS_CUSTOM, i - 1), reIndexServer.isCustom); | ||
| } | ||
|
|
||
| edit.putInt(NUMBER_OF_ENTRIES, --numServers).apply(); | ||
|
|
@@ -467,16 +489,17 @@ private List<LoginServer> getLoginServersFromXML() { | |
| * first time a user is upgrading to a newer version of the Mobile SDK. | ||
| */ | ||
| private void initSharedPrefFile() { | ||
| final Map<String, ?> values = settings.getAll(); | ||
| if (values != null && !values.isEmpty()) { | ||
| return; | ||
| } | ||
| final List<LoginServer> loginServersFromXml = getLoginServersFromXML(); | ||
|
|
||
| List<LoginServer> servers = getLoginServers(); | ||
| if (servers == null || servers.isEmpty()) { | ||
| servers = getLoginServersFromXML(); | ||
| servers = loginServersFromXml; | ||
| if (servers == null || servers.isEmpty()) { | ||
| servers = getLegacyLoginServers(); | ||
| } | ||
| } else { | ||
| loginServersFromXml.addAll(servers); | ||
| servers = loginServersFromXml; | ||
| } | ||
| int numServers = servers.size(); | ||
| final Editor edit = settings.edit(); | ||
|
|
@@ -538,6 +561,25 @@ private List<LoginServer> getLoginServersFromPreferences(SharedPreferences prefs | |
| return (!allServers.isEmpty() ? allServers : null); | ||
| } | ||
|
|
||
| /** | ||
| * Resets the list of non-custom login servers in the provided shared preferences. | ||
| * | ||
| * @param sharedPreferences The shared preferences | ||
| */ | ||
| private void resetNonCustomLoginServers( | ||
| final SharedPreferences sharedPreferences | ||
| ) { | ||
| final List<LoginServer> loginServersFromPreferences = getLoginServersFromPreferences(sharedPreferences); | ||
| if (loginServersFromPreferences != null) { | ||
| for (int i = 0; i < loginServersFromPreferences.size(); i++) { | ||
| final LoginServer loginServer = loginServersFromPreferences.get(i); | ||
| if (!loginServer.isCustom) { | ||
| removeServer(loginServer, sharedPreferences, true); | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Class to encapsulate a login server name, URL, index and type (custom or not). | ||
| */ | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@wmathurin, @brandonpage and @bbirman, before I update the tests and move this into ready-for-review I wanted to run the concept of the change past you all.
I chatted briefly with @bbirman to review the iOS behavior since the work item specifically hails that logic as working compared to Android's. Currently, MSDK Android loads the
servers.xmlonly once on install. The work item mentions upgrade, but I didn't see that logic. More, when MDM provides servers they're additive only. When MDM drops a server, the app doesn't reflect that.What I'm trying here and seems to manually test well is:
servers.xmland MDM.servers.xmlor MDM according to the existing logic, as much as possible.I'm doing a little more testing around the behavior of the only show authorized hosts parameter. I want to be sure the MDM flow still respects the user's custom servers.
The question to answer is: Does this seem like a reasonable update to the existing logic to resolve this work item? I can manipulate
servers.xmland the MDM data and the app seems to keep the servers list adds, updates or removes non-custom servers just as we'd want. The logic here is older and the methods are not as self-contained as our newer logic, so I wanted to be sure we all got to review any potential side-effects of this before moving further!There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For #3 (and pending your authorized hosts testing), on iOS the custom login servers would be preserved if MDM was enabled as long as "onlyShowAuthorizedHosts" is false
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This sounds good to me.
One thought though: Should we only remove MDM servers when network is available? Security wise, it would be bad it:
LoginServerManagerconstructor does not run again. MDM server list is not respected.Is that scenario possible?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks and that thought about network is a great topic. I'll do some research!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I took a manual look and also asked our agents. RuntimeConfig does cache the policy locally and will give MSDK those values when no network is present ✅