-
Notifications
You must be signed in to change notification settings - Fork 429
Add Login Options to Dev Menu #3950
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 all commits
adbcda5
9159566
2199596
216c632
df68b37
2ffda35
a668f6f
4ba4d12
1afbe29
d9e49e8
796a518
2538b76
0330aa9
a21a187
9a893b4
f9a9f08
02644c6
1e601a4
913b8c8
5dcc5d5
7f9d347
4d2a6e4
ace155d
a1d8029
8dd9bbc
dfda66a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -29,8 +29,8 @@ | |
| #import "SFManagedPreferences.h" | ||
| #import "SFApplicationHelper.h" | ||
| #import "SFSDKAppFeatureMarkers.h" | ||
| #import "SFSDKDevInfoViewController.h" | ||
| #import "SFDefaultUserManagementViewController.h" | ||
| #import "SFSDKAuthRootController.h" | ||
| #import <SalesforceSDKCommon/SFSwiftDetectUtil.h> | ||
| #import "SFSDKEncryptedURLCache.h" | ||
| #import "SFSDKNullURLCache.h" | ||
|
|
@@ -471,25 +471,66 @@ - (NSString *)devInfoTitleString | |
|
|
||
| - (NSArray<SFSDKDevAction *>*) getDevActions:(UIViewController *)presentedViewController | ||
| { | ||
| return @[ | ||
| [[SFSDKDevAction alloc]initWith:@"Show dev info" handler:^{ | ||
| SFSDKDevInfoViewController *devInfo = [[SFSDKDevInfoViewController alloc] init]; | ||
| [presentedViewController presentViewController:devInfo animated:NO completion:nil]; | ||
| }], | ||
| [[SFSDKDevAction alloc]initWith:@"Logout" handler:^{ | ||
| [[SFUserAccountManager sharedInstance] logout:SFLogoutReasonUserInitiated]; | ||
| }], | ||
| [[SFSDKDevAction alloc]initWith:@"Switch user" handler:^{ | ||
| SFDefaultUserManagementViewController *umvc = [[SFDefaultUserManagementViewController alloc] initWithCompletionBlock:^(SFUserManagementAction action) { | ||
| [presentedViewController dismissViewControllerAnimated:YES completion:nil]; | ||
| }]; | ||
| [presentedViewController presentViewController:umvc animated:YES completion:nil]; | ||
| }], | ||
| [[SFSDKDevAction alloc]initWith:@"Inspect Key-Value Store" handler:^{ | ||
| UIViewController *keyValueStoreInspector = [[SFSDKKeyValueEncryptedFileStoreViewController new] createUI]; | ||
| [presentedViewController presentViewController:keyValueStoreInspector animated:YES completion:nil]; | ||
| }] | ||
| ]; | ||
| NSMutableArray<SFSDKDevAction *> *actions = [NSMutableArray array]; | ||
| SFUserAccountManager *userAccountManager = [SFUserAccountManager sharedInstance]; | ||
| SFUserAccount *currentUser = userAccountManager.currentUser; | ||
|
|
||
| // Check if we're showing the login screen | ||
| BOOL isShowingLogin = [presentedViewController isKindOfClass:[SFLoginViewController class]]; | ||
| // TODO uncomment to support advanced auth case (once we add code to restart auth in that case below) | ||
| // || [presentedViewController.presentingViewController isKindOfClass:[SFSDKAuthRootController class]]; | ||
|
|
||
| // Show dev info - always available | ||
| [actions addObject:[[SFSDKDevAction alloc]initWith:@"Show dev info" handler:^{ | ||
| UIViewController *devInfo = [SFSDKDevInfoViewController makeViewController]; | ||
| [presentedViewController presentViewController:devInfo animated:YES completion:nil]; | ||
| }]]; | ||
|
|
||
| // Login Options - only show on login screen | ||
| if (isShowingLogin) { | ||
|
Contributor
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. NIT: Is there a reason to only show it on the login screen?
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. It's only useful if you do a login right after - and if you do a login (let's say after a logout or when adding a new user), then you will get a chance to bring up the screen when the login screen is shown. So it feels like login is the right time to show the login options screen. The oauth settings should be inspectable through dev infos at any time though. |
||
| [actions addObject:[[SFSDKDevAction alloc]initWith:@"Login Options" handler:^{ | ||
| UIViewController *configPicker = [BootConfigPickerViewController makeViewControllerOnConfigurationCompleted:^{ | ||
| [presentedViewController dismissViewControllerAnimated:YES completion:^{ | ||
| // Restart authentication with the updated configuration | ||
| if ([presentedViewController isKindOfClass:[SFLoginViewController class]]) { | ||
| [[SFUserAccountManager sharedInstance] restartAuthenticationForViewController:(SFLoginViewController *)presentedViewController]; | ||
| } | ||
| // TODO support advanced auth case | ||
| }]; | ||
| }]; | ||
| [presentedViewController presentViewController:configPicker animated:YES completion:nil]; | ||
| }]]; | ||
| } | ||
|
|
||
| // Logout - only show if there's a current user and not on login screen | ||
| if (currentUser && !isShowingLogin) { | ||
|
Contributor
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. I was thinking about exactly this the other day. Android doesn't take deferred auth into account, I need to also check for a user. |
||
| [actions addObject:[[SFSDKDevAction alloc]initWith:@"Logout" handler:^{ | ||
| [[SFUserAccountManager sharedInstance] logout:SFLogoutReasonUserInitiated]; | ||
| }]]; | ||
| } | ||
|
|
||
| // Switch user - only show if there's a current user and not on login screen | ||
| if (currentUser && !isShowingLogin) { | ||
| [actions addObject:[[SFSDKDevAction alloc]initWith:@"Switch user" handler:^{ | ||
| SFDefaultUserManagementViewController *umvc = [[SFDefaultUserManagementViewController alloc] initWithCompletionBlock:^(SFUserManagementAction action) { | ||
| [presentedViewController dismissViewControllerAnimated:YES completion:nil]; | ||
| }]; | ||
| [presentedViewController presentViewController:umvc animated:YES completion:nil]; | ||
| }]]; | ||
| } | ||
|
|
||
| // Inspect Key-Value Store - only show if there are stores | ||
| BOOL hasGlobalStores = [SFSDKKeyValueEncryptedFileStore allGlobalStoreNames].count > 0; | ||
| BOOL hasUserStores = currentUser && [SFSDKKeyValueEncryptedFileStore allStoreNames].count > 0; | ||
|
|
||
| if (hasGlobalStores || hasUserStores) { | ||
| [actions addObject:[[SFSDKDevAction alloc]initWith:@"Inspect Key-Value Store" handler:^{ | ||
| UIViewController *keyValueStoreInspector = [[SFSDKKeyValueEncryptedFileStoreViewController new] createUI]; | ||
| [presentedViewController presentViewController:keyValueStoreInspector animated:YES completion:nil]; | ||
| }]]; | ||
| } | ||
|
|
||
| return [actions copy]; | ||
| } | ||
|
|
||
| - (NSArray<NSString *>*) getDevSupportInfos | ||
|
|
@@ -498,25 +539,62 @@ - (NSString *)devInfoTitleString | |
| NSMutableArray * devInfos = [NSMutableArray arrayWithArray:@[ | ||
| @"SDK Version", SALESFORCE_SDK_VERSION, | ||
| @"App Type", [self getAppTypeAsString], | ||
| @"User Agent", self.userAgentString(@""), | ||
| @"User Agent", self.userAgentString(@"") | ||
| ]]; | ||
| NSArray* allUsers = userAccountManager.allUserAccounts; | ||
| if ([allUsers count] > 0) { | ||
| [devInfos addObjectsFromArray:@[ | ||
| @"Authenticated Users", [self usersToString:allUsers] | ||
| ]]; | ||
| } | ||
|
|
||
| // Auth configuration | ||
| [devInfos addObject:@"section:Auth Config"]; | ||
| [devInfos addObjectsFromArray:@[ | ||
| @"Use Web Server Authentication", [self useWebServerAuthentication] ? @"YES" : @"NO", | ||
| @"Use Hybrid Authentication", [self useHybridAuthentication] ? @"YES" : @"NO", | ||
| @"Supports Welcome Discovery", [self supportsWelcomeDiscovery] ? @"YES" : @"NO", | ||
| @"Browser Login Enabled", [SFUserAccountManager sharedInstance].useBrowserAuth? @"YES" : @"NO", | ||
| @"IDP Enabled", [self idpEnabled] ? @"YES" : @"NO", | ||
| @"Identity Provider", [self isIdentityProvider] ? @"YES" : @"NO", | ||
| @"Current User", [self userToString:userAccountManager.currentUser], | ||
| @"Scopes", [userAccountManager.currentUser.credentials.scopes componentsJoinedByString:@" "], | ||
| @"Access Token Expiration", [self accessTokenExpiration], | ||
| @"Authenticated Users", [self usersToString:userAccountManager.allUserAccounts], | ||
| @"User Key-Value Stores", [self safeJoin:[SFSDKKeyValueEncryptedFileStore allStoreNames] separator:@", "], | ||
| @"Global Key-Value Stores", [self safeJoin:[SFSDKKeyValueEncryptedFileStore allGlobalStoreNames] separator:@", "] | ||
| @"Identity Provider", [self isIdentityProvider] ? @"YES" : @"NO" | ||
| ]]; | ||
|
|
||
| [devInfos addObjectsFromArray:[self dictToDevInfos:self.appConfig.configDict keyPrefix:@"BootConfig"]]; | ||
| // Static bootconfig | ||
| [devInfos addObject:@"section:Bootconfig"]; | ||
| [devInfos addObjectsFromArray:[self dictToDevInfos:self.appConfig.configDict]]; | ||
|
|
||
| // Current user info | ||
| SFUserAccount* currentUser = userAccountManager.currentUser; | ||
| if (currentUser) { | ||
| SFOAuthCredentials* creds = currentUser.credentials; | ||
| [devInfos addObject:@"section:Current User"]; | ||
| [devInfos addObjectsFromArray:@[ | ||
| @"Username", [self userToString:currentUser], | ||
| @"Consumer Key", creds.clientId ?: @"(nil)", | ||
| @"Redirect URI", creds.redirectUri ?: @"(nil)", | ||
| @"Scopes", [self scopesToString:currentUser], | ||
| @"Instance URL", [creds.instanceUrl absoluteString] ?: @"(nil)", | ||
| @"Token format", [creds.tokenFormat isEqualToString:@"jwt"] ? @"jwt" : @"opaque", | ||
| @"Access Token Expiration", [self accessTokenExpiration], | ||
| @"Beacon Child Consumer Key", creds.beaconChildConsumerKey ?: @"(empty)" | ||
| ]]; | ||
| } | ||
|
|
||
| // Key Value Stores | ||
| NSArray<NSString*>* globalKeyValueStores = [SFSDKKeyValueEncryptedFileStore allGlobalStoreNames]; | ||
| NSArray<NSString*>* userKeyValueStores = [SFSDKKeyValueEncryptedFileStore allStoreNames]; | ||
| if ([userKeyValueStores count] > 0 || [globalKeyValueStores count] > 0) { | ||
| [devInfos addObject:@"section:Key Value Stores"]; | ||
| [devInfos addObjectsFromArray:@[@"Global stores", [self safeJoin:globalKeyValueStores separator:@", "]]]; | ||
| [devInfos addObjectsFromArray:@[@"User stores", [self safeJoin:globalKeyValueStores separator:@", "]]]; | ||
| } | ||
|
|
||
| // Managed prefs | ||
| SFManagedPreferences *managedPreferences = [SFManagedPreferences sharedPreferences]; | ||
| [devInfos addObjectsFromArray:@[@"Managed", [managedPreferences hasManagedPreferences] ? @"YES" : @"NO"]]; | ||
| if ([managedPreferences hasManagedPreferences]) { | ||
| [devInfos addObjectsFromArray:[self dictToDevInfos:managedPreferences.rawPreferences keyPrefix:@"Managed Pref"]]; | ||
| [devInfos addObject:@"section:Managed Pref"]; | ||
| [devInfos addObjectsFromArray:@[@"Managed", [managedPreferences hasManagedPreferences] ? @"YES" : @"NO"]]; | ||
| [devInfos addObjectsFromArray:[self dictToDevInfos:managedPreferences.rawPreferences]]; | ||
| } | ||
|
|
||
| return devInfos; | ||
|
|
@@ -542,21 +620,31 @@ - (NSString *) accessTokenExpiration { | |
| } | ||
|
|
||
| - (NSString*) userToString:(SFUserAccount*)user { | ||
| return user ? user.idData.username : @""; | ||
| return user.idData.username != nil ? user.idData.username : @""; | ||
| } | ||
|
|
||
| - (NSString*) scopesToString:(SFUserAccount*)user { | ||
| return user.credentials.scopes != nil ? [user.credentials.scopes componentsJoinedByString:@" "] : @""; | ||
| } | ||
|
|
||
| - (NSString*) usersToString:(NSArray<SFUserAccount*>*)userAccounts { | ||
| if (userAccounts == nil) { | ||
| return @""; | ||
| } | ||
| NSMutableArray* usernames = [NSMutableArray new]; | ||
| for (SFUserAccount *userAccount in userAccounts) { | ||
| [usernames addObject:[self userToString:userAccount]]; | ||
| } | ||
| return [usernames componentsJoinedByString:@", "]; | ||
| } | ||
|
|
||
| - (NSArray*) dictToDevInfos:(NSDictionary*)dict keyPrefix:(NSString*)keyPrefix { | ||
| - (NSArray*) dictToDevInfos:(NSDictionary*)dict { | ||
| if (dict == nil) { | ||
| return @[]; | ||
| } | ||
| NSMutableArray * devInfos = [NSMutableArray new]; | ||
| [dict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { | ||
| [devInfos addObject:[NSString stringWithFormat:@"%@ - %@", keyPrefix, key]]; | ||
| [devInfos addObject:key]; | ||
| [devInfos addObject:[[NSString stringWithFormat:@"%@", obj] stringByReplacingOccurrencesOfString:@"\n" withString:@""]]; | ||
| }]; | ||
| return devInfos; | ||
|
|
||
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.
Restarting Auth is included now, right?
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.
Only if it's regular auth - for now I commented out the case it's advanced auth.