StoreManager
public class StoreManager : FUIPasscodeValidationDelegate, FUIPasscodeControllerDelegate
StoreManagerStep
StoreManagerStep
is responsible to create, open or remove the secure store assigned to an onboarding session.
It has several customization options which can be used alone or together to achieve the required functionality.
As a basic behavior the StoreManagerStep creates a new secure in the onboarding flow, opens it in the restoring flow or removes it as part of the reset flow. By default a store is assign to an onboarding session using the onboardingID
. For the detailed description of the flows see Onboarding overview.
Customization options
- Using different secure storage implementations with the step:
StoreManagerStep
delegates the appropriate kind of store management to an instance ofPersistentStoreManaging
. This way the sameStoreManagerStep
class can use different kind of secure stores without the necessity of subclassing or replacing the whole step in the flow. The following store managers are available: - No-passcode mode: using the
StoreManagerStep
in this mode it won’t present any passcode related screens and won’t pass any passcode to thePersistentStoreManaging
instance. This mode activated when there is no availableFUIPasscodePolicy
and thedefaultPasscodePolicy
is set tonil
on the Step instance. - Use a custom UUID instead of the
onboardingID
: theonboardingID
is used to differentiate the stores (using in the name of the store) and all related stored information (used in the key). Setting thestoreID
property on the instance will override theonboardingID
. This can be used to share a store among different onboarding sessions (see sharing). - Pre-initialized secure store usage during onboarding: in this mode the StoreManagerStep will perform a
restore
inonboard
if the store already exists. It will runonboard
if the store doesn’t exists. Use therunRestoreIfStoreExists
property to activate this behavior. - Alternate
onboardingInfoKey
usage: as with other onboarding steps it is possible to change the keys which are used to access information in theinfo
field of theOnboardingContext
when the automatic mode is used.
Sharing
The StoreManagerStep
can be configured to support shared stores. For the description of configuration options see Customization options
We can distinguish the stores by the number of users: a ‘private’ store is assigned and used by only on ‘onboarding session’ while a ‘shared’ store used among different ‘onboarding sessions’.
A ‘shared’ store can be ‘locally’ shared so it belongs to a particular application and can be shared among applications. When sharing among applications works only with the KeychainStoreManager
which uses ‘keychain sharing’.
It is also possible to use more stores in an ‘onboarding session’. For example when the basic configuration data is stored in a shared store while the user specific information stored in ‘private’ store.
When more stores are used at least the following configuration options should be changed:
- Custom UUID for the store for the shared store(s)
- alternate
onboardingInfoKey
for one of the stores. For example ifSAPcpmsSettingsDownloadStep
is used you have to decide which store should use theFUIPasscodePolicy
downloaded from the server. - Pre-initialized mode for the shared store: if the StoreManagerStep should use the already existing shared store during onboarding. For exampel the connection
- When more
StoreManagerSteps
are used in an onboarding session wrap theStoreManagerStep
(and the steps which have to use that store) into aStoreSelectoreStep
.
Handles all the available operations on the application’s credentialstore:
- create store
- open store
- remove store
- change encryption of store
The store instance should be an implementation of the
PersistentStoreManaging
protocol StoreManager uses multiple screens and passcode/TouchID/FaceID functionalities from SAPFiori.
A StoreManager instance is initialized in StoreManagerStep during onboarding with the required parameters in the StoreManager initializer, which then starts a createStore, which throws FUIPasscodeCreateController from SAPFiori. If the device supports a biometric identifier, such as Touch ID or Face ID and the downloaded passcode policy also allows it, the Touch ID / Face ID screen displays after the passcode creation screens. The user can decide whether or not to use biometrics in the application. When setting the passcode, certain information is stored in the keychain under the application’s default accessGroup. If the developer sets an accessGroup for the StoreManager, the accessGroup must be set, and in every case a storeManager is instantiated later.
There is one exception where the passcode create screen is not shown while onboarding: If the developer does not set the defaultPasscodepolicy on StoreManagerStep, AND the policies are not assigned to the application on the server. Because of this, the passcode is turned off for the application and does not ask for a passcode when it opens later. This is less secure, and is not recommended. Note: The defaultPasscodePolicy is set to nil by default. If the defaultPasscodePolicy is set to the developers own default passcode policy, that becomes the requirement for entering the passcode whether or not the passcode policies assigned to the application on the server.
In the restore case, the StoreManagerStep calls the StoreManager’s openStore function which, if a passcode was previously set, presents a FUIPasscodeInputController from SAPFiori. If the user enters an incorrect passcode, the retry limit decrements. If the retry limit reaches zero, the store is locked and all information is lost. The user must onboard again, after resetting the application. If the entered passcode is correct, then the restore flow starts with the previously defined steps.
PasscodePolicyApplyStep is another step that can call changePasscodePolicy on StoreManager: During the restore flow, if the actual settings are downloaded from the server and the passcode policy changes, PasscodePolicyApplyStep calls the changePasscodePolicy(to newPolicy:completionHandler:) on StoreManager, which triggers a passcode change. This change is mandatory and cannot be cancelled. The change is triggered in every case where the server administrator sets a policy that is either weaker or stronger. StoreManager uses a customized FUIFeedbackScreen from SAPFiori to inform the user of any restrictions or additional possibilities regarding setting the passcode policy. The reason for the passcode change is described on that presented screen. The passcode change flow starts after the user taps the ‘Continue’ button.
Possible passcode change flows:
- No passcode -> passcode ( Turn on passcode, so passcode creation flow without the option to set Face/Touch ID.)
- No passcode -> passcode with Touch/Face ID (Turn on passcode with biometric ID, so passcode creation flow with the option to enable Face/Touch ID.)
- Passcode -> Passcode (Passcode change flow, the user has to enter the current passcode again, then set the new passcode and confirm it.)
- Passcode -> No passcode (Turn off passcode, the user will be notified about the change, has nothing to do. The passcode will be turned off.)
- Passcode -> Passcode with Touch/Face ID (Starting the automatic change flow will be supported in a later release, currently the Touch/Face ID availability will be added to the ‘availableChangePasscodeOptions’, so manually can be turned on if there is an application screen for setting these options.)
- Passcode with Touch/Face ID -> Passcode (Turn off Touch/Face ID, the user will be notified about the restriction and can not use the biometric ID from that point to unlock the application.)
- Passcode with Touch/Face ID -> No passcode (Turn off passcode, the user will be notified about the change, has nothing to do. The passcode and Touch/Face ID will be turned off.)
Developers can provide a screen similar to Settings, where the user can change their own passcode depending on passcode policy and device capabilities: The ‘availablePasscodeActions’ returns an array, which contains the passcode actions which can be performed on StoreManager’s store. This list contains elements depending on passcode policy and device capabilities. After checking the availablePasscodeActions, the developer can call the performPasscodeAction(_ action:completionHandler:) function with the correct PasscodeAction. In this case one of the possible passcode change flows starts, the only difference is that a notification screen does not display by default.
-
Customization of FUIPasscodeController
Declaration
Swift
public var passcodeControllerCustomizationHandler: ((FUIPasscodeController) -> Void)?
-
Used for data source in
FUIMultiUserPasscodeController
Declaration
Swift
public var userDataSource: UserDataSource?
-
Undocumented
Declaration
Swift
public var storeID: UUID! { get set }
-
Undocumented
Declaration
Swift
public var primaryKeychainStorePrefix: String
-
Undocumented
Declaration
Swift
public var primaryAccessGroup: String?
-
FUIPasscodeValidationDelegate used by the FUI passcode screens. For more info @see FUIPasscodeValidationDelegate
Declaration
Swift
public weak var passcodeValidationDelegate: FUIPasscodeValidationDelegate?
-
FUIPasscodeControllerDelegate used by the FUI passcode screens. For more info @see FUIPasscodeControllerDelegate
Declaration
Swift
public weak var userPasscodeControllerDelegate: FUIPasscodeControllerDelegate?
-
This prefix will be used to create the store with the onboardingID in the following format: Name-ID
Declaration
Swift
public var secureStoreNamePrefix: String
-
The
OnboardingInfoKey
associated with an instance ofFUIPasscodePolicy
in theOnboardingContext
info.Declaration
Swift
public var passcodePolicyInfoKey: OnboardingInfoKey!
-
The keychain access group used to store settings. This property has a default value if the
KeychainStoreManager
is used as the persistent store manager.Declaration
Swift
public var accessGroup: String?
-
Default passcode policy for StoreManager. Must be the same as the default policy of
StoreManagerStep
andPasscodePolicyApplyStep
Declaration
Swift
public var defaultPasscodePolicy: FUIPasscodePolicy?
-
Enable adding additional user-defined passcode policy rules. Must be the same as passcodePolicyRules defined for
StoreManagerStep
Declaration
Swift
public var passcodePolicyRules: [FUIPasscodeRule]?
-
If this is true, there will be a “Reset Passcode” button on the passcode input view when user entered a wrong passcode. The result of the passcode flow will be failed with
StoreManagerError.resetPasscode
error when user tapped this “Reset” button. The default value istrue
.Declaration
Swift
public var showsResetButton: Bool
-
If this is true, there will be a “Cancel” button on the passcode input view. The result of this step will be failed with
StoreManagerError.cancelPasscodeEntry
error when user tapped this “Cancel” button. The default value isfalse
. In case of passcodeChange which is triggered by policy change on the server, this value istrue
Declaration
Swift
public var showsCancelButton: Bool
-
Text of AlertController which is thrown when user taps “Cancel” during manual passcode change
Declaration
Swift
public var cancelPasscodeChangeAlertTitleText: String
-
Text of AlertController which is thrown when user taps “Cancel” during restore process
Declaration
Swift
public var cancelPasscodeAlertTitleText: String
-
Title of the presented FUIFeedbackScreen when the policy changed on the server and passcode change is triggered during restore
Declaration
Swift
public var fuiFeedbackScreenTitleText: String
-
Headline text of the presented FUIFeedbackScreen when the policy changed on the server and passcode change is triggered during restore
Declaration
Swift
public var fuiFeedbackScreenHeadlineDescription: String
-
Description text of the presented FUIFeedbackScreen when the policy changed on the server and passcode change is triggered during restore
Declaration
Swift
public var fuiFeedbackScreenDescription: String
-
Text of button on the presented FUIFeedbackScreen when the policy changed on the server and passcode change is triggered during restore
Declaration
Swift
public var fuiFeedbackScreenButtonText: String
-
Title of the presented FUIFeedbackScreen when the policy changed on the server, passcode change is triggered during restore and the Touch ID becomes unavailable
Declaration
Swift
public var fuiFeedbackScreenDisableTouchIDTitleText: String
-
Headline text of the presented FUIFeedbackScreen when the policy changed on the server, passcode change is triggered during restore and the Touch ID becomes unavailable
Declaration
Swift
public var fuiFeedbackScreenDisableTouchIDHeadlineDescription: String
-
Description text of the presented FUIFeedbackScreen when the policy changed on the server, passcode change is triggered during restore and the Touch ID becomes unavailable
Declaration
Swift
public var fuiFeedbackScreenDisableTouchIDDetailDescription: String
-
Text of button on the presented FUIFeedbackScreen when the policy changed on the server, passcode change is triggered during restore and the Touch ID becomes available
Declaration
Swift
public var fuiFeedbackScreenDisableTouchIDButtonText: String
-
Title of the presented FUIFeedbackScreen when the policy changed on the server, passcode change is triggered during restore and the Face ID becomes unavailable
Declaration
Swift
public var fuiFeedbackScreenDisableFaceIDTitleText: String
-
Headline text of the presented FUIFeedbackScreen when the policy changed on the server, passcode change is triggered during restore and the Face ID becomes unavailable
Declaration
Swift
public var fuiFeedbackScreenDisableFaceIDHeadlineDescription: String
-
Description text of the presented FUIFeedbackScreen when the policy changed on the server, passcode change is triggered during restore and the Face ID becomes unavailable
Declaration
Swift
public var fuiFeedbackScreenDisableFaceIDDetailDescription: String
-
Text of button on the presented FUIFeedbackScreen when the policy changed on the server, passcode change is triggered during restore and the Face ID becomes available
Declaration
Swift
public var fuiFeedbackScreenDisableFaceIDButtonText: String
-
Title of the presented FUIFeedbackScreen when the policy has been deleted from the application, turning off passcode is triggered during restore, passcode will be disabled
Declaration
Swift
public var fuiFeedbackScreenTurnOffPasscodeTitleText: String
-
Headline text of the presented FUIFeedbackScreen when the policy has been deleted from the application, turning off passcode is triggered during restore, passcode will be disabled
Declaration
Swift
public var fuiFeedbackScreenTurnOffPasscodeHeadlineDescription: String
-
Description text of the presented FUIFeedbackScreen when the policy has been deleted from the application, turning off passcode is triggered during restore, passcode will be disabled
Declaration
Swift
public var fuiFeedbackScreenTurnOffPasscodeDetailDescription: String
-
Description text of the presented FUIFeedbackScreen when the policy has been deleted from the application, turning off passcode is triggered during restore, passcode and Touch ID will be disabled
Declaration
Swift
public var fuiFeedbackScreenTurnOffPasscodeAndTouchIDDetailDescription: String
-
Description text of the presented FUIFeedbackScreen when the policy has been deleted from the application, turning off passcode is triggered during restore, passcode and Face ID will be disabled
Declaration
Swift
public var fuiFeedbackScreenTurnOffPasscodeAndFaceIDDetailDescription: String
-
Text of button on the presented FUIFeedbackScreen when the policy has been deleted from the application, turning off passcode is triggered during restore, passcode will be disabled
Declaration
Swift
public var fuiFeedbackScreenTurnOffPasscodeButtonText: String
-
Headline text of FUIFeedbackScreen when the application was updated from an earlier version to rel-2.2 and previously there was only Touch ID or Face ID set. The reason is from rel-2.2 the passcode is mandatory.
Declaration
Swift
public var fuiFeedbackScreenMigrationHeadline: String
-
Description text of FUIFeedbackScreen when the application was updated from an earlier version to rel-2.2 and previously there was only Touch ID or Face ID set. The reason is from rel-2.2 the passcode is mandatory.
Declaration
Swift
public var fuiFeedbackScreenMigrationDescription: String
-
Text of button on FUIFeedbackScreen when the application was updated from an earlier version to rel-2.2 and previously there was only Touch ID or Face ID set. The reason is from rel-2.2 the passcode is mandatory.
Declaration
Swift
public var fuiFeedbackScreenMigrationButtonText: String
-
The actual passcode state of StoreManager
Declaration
Swift
public var passcodeState: PasscodeState { get }
-
Returns the selectable passcode options
Declaration
Swift
public var availablePasscodeActions: [PasscodeAction] { get }
-
Initialize the StoreManager object only for changePasscode
Declaration
Swift
public convenience init(storeID: UUID, credentialStore: CompositeCodableStoring, persistentStoreManager: PersistentStoreManaging = SecureKeyValueStoreManager(), presentationDelegate: FlowPresentationDelegate? = nil, passcodePolicy: FUIPasscodePolicy? = nil)
-
Default initializer
Declaration
Swift
public init()
-
Removes the given store using the persistent store manager.
Declaration
Swift
public func removeStore() throws
Parameters
store
the store to remove
-
presentationDelegate which handles the UIViewController presentations
Declaration
Swift
public var presentationDelegate: FlowPresentationDelegate!
-
Starts a creatStore flow Presents UI to enter passcode, then the credentialStore will be created and encrypted using the given passcode
Declaration
Swift
public func createStore(completionHandler: @escaping (_ error: Error?) -> Void)
Parameters
completionHandler
will be called after the store creation flow ends
-
Starts an openStore flow Presents UI to enter the passcode which will open the store
Declaration
Swift
public func openStore(completionHandler: @escaping (_ error: Error?) -> Void)
Parameters
completionHandler
will be called after the opening the store is finished
-
Depending on available passcode actions, the user can select an action (.createPasscode, turnOffPasscode, turnOffBiometric, etc.) to execute on store Will present UIViewControllers to go through the flow triggered by the given action
Declaration
Swift
public func performPasscodeAction(_ action: PasscodeAction, completionHandler: @escaping (Error?) -> Void)
Parameters
action
a PasscodeAction
completionHandler
will be called after the action was performed on the store
-
When the passcodePolicy changes on the server, this function need to be called with the new policy This will trigger an automatic passcode change if it’s necessary
Declaration
Swift
public func changePasscodePolicy(to newPolicy: FUIPasscodePolicy?, completionHandler: @escaping (Error?) -> Void)
Parameters
newPolicy
the new
FUIPasscodePolicy
object which was downloaded from the servercompletionHandler
will be called after the flow ends
-
Reset the storeManager
Declaration
Swift
public func reset(storeID: UUID, credentialStore: CompositeCodableStoring, completionHandler: @escaping () -> Void)
Parameters
storeID
storeID of the store
credentialStore
CompositeCodableStoring object which has the persistentStore
completionHandler
will be called when the process finishes
-
The
FUIPasscodePolicy
for this app. When run in “no-passcode” mode, this method is not called.Declaration
Swift
public func passcodePolicy() -> SAPFiori.FUIPasscodePolicy
Return Value
The FUIPasscodePolicy for this app.
-
validate function of FUIPasscodeValidationDelegate Called when the entered passcode has to be validated against the passcodePolicy restrictions. Can be overriden to provide custom implementation
Throws
FUIPasscodeControllerError
when validation fails.Declaration
Swift
public func validate(passcode: String) throws
Parameters
passcode
String value, the passcode itself given by the user to be validated
-
Implementation of FUIPasscodeControllerDelegate shouldTryPasscode function Regarding the FUIPasscodeControllerDelegate description, The implementation should try the passcode entered by the user either open the secure store or compare with saved passcode If passcode has not been setup previously, the implementation should accept this passcode and store it as the effective passcode. If passcode was already setup, the implementation should try to match the passcode with saved passcode.
Throws
FUIPasscodeControllerError
when try passcode failedDeclaration
Swift
public func shouldTryPasscode(_ passcode: String, forInputMode inputMode: FUIPasscodeInputMode, fromController passcodeController: FUIPasscodeController) throws
Parameters
passcode
The passcode entered by the user.
inputMode
The purpose of the passcode entered
passcodeController
The
FUIPasscodeController
-
User has chosen to cancel the passcode setup or enter passcode process. For app to dismiss the Passcode View when appropriate.
Declaration
Swift
public func didCancelPasscodeEntry(fromController passcodeController: FUIPasscodeController)
Parameters
passcodeController
The
FUIPasscodeController
. -
User has chosen to skip the passcode setup process. For app to dismiss the Passcode View when appropriate.
Declaration
Swift
public func didSkipPasscodeSetup(fromController passcodeController: SAPFiori.FUIPasscodeController)
Parameters
passcodeController
The
FUIPasscodeController
. -
User has chosen to reset the passcode. For application to dismiss the Passcode View when appropriate.
Declaration
Swift
public func shouldResetPasscode(fromController passcodeController: FUIPasscodeController)
Parameters
passcodeController
The
FUIPasscodeController
. -
Changed biometric ID
– Parameter enabled:
Bool
, wheter it is enabled or not – Parameter passcodeController: the presenterFUIPasscodeController
Declaration
Swift
public func didSetBiometricIDOption(to enabled: Bool, fromController passcodeController: FUIPasscodeController)
-
Undocumented
Declaration
Swift
public func addNewUser(_ passcodeController: FUIPasscodeController)
-
Undocumented
Declaration
Swift
public func switchUser(_ newUserId: String, passcodeController: FUIPasscodeController)