From 50e30153bc54fe5d015bb89391de66c36c013598 Mon Sep 17 00:00:00 2001 From: Daniel Saidi Date: Wed, 8 Sep 2021 11:06:16 +0200 Subject: [PATCH] Update auth documentation --- .../Authentication/Authentication.swift | 6 ++-- .../AuthenticationService.swift | 3 +- .../BiometricAuthenticationService.swift | 19 +++++++++++ .../CachedAuthenticationService.swift | 21 ++++++------ .../CachedAuthenticationServiceProxy.swift | 34 ++++++++++++++----- ...achedAuthenticationServiceProxyTests.swift | 2 +- 6 files changed, 62 insertions(+), 23 deletions(-) diff --git a/Sources/SwiftKit/Authentication/Authentication.swift b/Sources/SwiftKit/Authentication/Authentication.swift index b9406f3..628114f 100644 --- a/Sources/SwiftKit/Authentication/Authentication.swift +++ b/Sources/SwiftKit/Authentication/Authentication.swift @@ -11,9 +11,9 @@ import Foundation /** This struct represents a unique authentication. - This struct currently only has an `id` but it is still used - to be able to extend the authentication information without - having to change any authentication protocols. + This struct currently only has an `id` but is still used to + be able to extend the authentication info without having to + change any authentication protocols. */ public struct Authentication { diff --git a/Sources/SwiftKit/Authentication/AuthenticationService.swift b/Sources/SwiftKit/Authentication/AuthenticationService.swift index 5a2da95..bb18487 100644 --- a/Sources/SwiftKit/Authentication/AuthenticationService.swift +++ b/Sources/SwiftKit/Authentication/AuthenticationService.swift @@ -20,7 +20,8 @@ public protocol AuthenticationService: AnyObject { /** Authenticate the user for a certain authentication type. - `reason` can be used as display information to the user. + + `reason` can be used to display information to the user. */ func authenticateUser(for auth: Authentication, reason: String, completion: @escaping AuthCompletion) diff --git a/Sources/SwiftKit/Authentication/BiometricAuthenticationService.swift b/Sources/SwiftKit/Authentication/BiometricAuthenticationService.swift index 6a72e4d..ba238a6 100644 --- a/Sources/SwiftKit/Authentication/BiometricAuthenticationService.swift +++ b/Sources/SwiftKit/Authentication/BiometricAuthenticationService.swift @@ -29,6 +29,13 @@ public class BiometricAuthenticationService: AuthenticationService { // MARK: - Public functions + /** + Authenticate the user for a certain authentication type, + provided that the service can authenticate the user for + the provided authentication type. + + `reason` can be used to display information to the user. + */ public func authenticateUser(for auth: Authentication, reason: String, completion: @escaping AuthCompletion) { guard canAuthenticateUser(for: auth) else { return completion(.failure(AuthError.unsupportedAuthentication)) } performAuthentication(for: auth, reason: reason) { result in @@ -36,11 +43,23 @@ public class BiometricAuthenticationService: AuthenticationService { } } + /** + Check if the service instance can authenticate the user + for a certain authentication type. + */ public func canAuthenticateUser(for auth: Authentication) -> Bool { var error: NSError? return LAContext().canEvaluatePolicy(policy, error: &error) } + /** + Authenticate the user for a certain authentication type, + regardless of if this service can authenticate the user + for the provided authentication type or not. + + This is a way to bypass any particular rules and states + of the service and is not part of the service protocol. + */ public func performAuthentication(for auth: Authentication, reason: String, completion: @escaping AuthCompletion) { LAContext().evaluatePolicy(policy, localizedReason: reason) { result, error in if let error = error { return completion(.failure(error)) } diff --git a/Sources/SwiftKit/Authentication/CachedAuthenticationService.swift b/Sources/SwiftKit/Authentication/CachedAuthenticationService.swift index dcc30d4..368788a 100644 --- a/Sources/SwiftKit/Authentication/CachedAuthenticationService.swift +++ b/Sources/SwiftKit/Authentication/CachedAuthenticationService.swift @@ -18,7 +18,7 @@ import Foundation to perform biometric authentication to access critical data. Note that you can't rely on a cached authentication service - to clear its cached state. Call `resetUserAuthentication()` + to clear its cached state. Call `resetUserAuthentications()` or `resetUserAuthentication(for:)` as soon as this state is considered to be invalid, e.g. when your app is send to the background and a new user can open the app at a later time. @@ -26,19 +26,20 @@ import Foundation public protocol CachedAuthenticationService: AuthenticationService { /** - Check if the user has already been authenticated for an - authentication type. + Check if the service has already authenticated the user + for a certain authentication type. */ func isUserAuthenticated(for auth: Authentication) -> Bool /** - Reset the user's entire authentication state. - */ - func resetUserAuthentication() - - /** - Reset the user's authentication state for a single type - of authentication. + Reset the service's cached authentication state for the + provided authentication type. */ func resetUserAuthentication(for auth: Authentication) + + /** + Reset the service's cached authentication state for all + authentication types. + */ + func resetUserAuthentications() } diff --git a/Sources/SwiftKit/Authentication/CachedAuthenticationServiceProxy.swift b/Sources/SwiftKit/Authentication/CachedAuthenticationServiceProxy.swift index dee6bcb..5304804 100644 --- a/Sources/SwiftKit/Authentication/CachedAuthenticationServiceProxy.swift +++ b/Sources/SwiftKit/Authentication/CachedAuthenticationServiceProxy.swift @@ -10,10 +10,7 @@ import Foundation /** This service wraps another authentication service and keeps - authentication results in a cache. `resetUserAuthentication` - can be called to clear one or all caches and force users to - perform new authentications to , e.g. after sending the app - to the background. + authentication results in a cache. */ public class CachedAuthenticationServiceProxy: CachedAuthenticationService { @@ -34,6 +31,11 @@ public class CachedAuthenticationServiceProxy: CachedAuthenticationService { // MARK: - Functions + /** + Authenticate the user for a certain authentication type. + + `reason` can be used to display information to the user. + */ public func authenticateUser(for auth: Authentication, reason: String, completion: @escaping AuthCompletion) { if isUserAuthenticated(for: auth) { return completion(.success(())) } baseService.authenticateUser(for: auth, reason: reason) { result in @@ -42,21 +44,37 @@ public class CachedAuthenticationServiceProxy: CachedAuthenticationService { } } + /** + Check if the service instance can authenticate the user + for a certain authentication type. + */ public func canAuthenticateUser(for auth: Authentication) -> Bool { baseService.canAuthenticateUser(for: auth) } + /** + Check if the service has already authenticated the user + for a certain authentication type. + */ public func isUserAuthenticated(for auth: Authentication) -> Bool { cache[auth.id] ?? false } - public func resetUserAuthentication() { - cache.removeAll() - } - + /** + Reset the service's cached authentication state for the + provided authentication type. + */ public func resetUserAuthentication(for auth: Authentication) { setIsAuthenticated(false, for: auth) } + + /** + Reset the service's cached authentication state for all + authentication types. + */ + public func resetUserAuthentications() { + cache.removeAll() + } } diff --git a/Tests/SwiftKitTests/Authentication/CachedAuthenticationServiceProxyTests.swift b/Tests/SwiftKitTests/Authentication/CachedAuthenticationServiceProxyTests.swift index dbee12b..5177372 100644 --- a/Tests/SwiftKitTests/Authentication/CachedAuthenticationServiceProxyTests.swift +++ b/Tests/SwiftKitTests/Authentication/CachedAuthenticationServiceProxyTests.swift @@ -115,7 +115,7 @@ class CachedAuthenticationServiceProxyTests: QuickSpec { service.authenticateUser(for: auth, reason: "") { _ in expect(service.isUserAuthenticated(for: .standard)).to(beTrue()) expect(service.isUserAuthenticated(for: auth)).to(beTrue()) - service.resetUserAuthentication() + service.resetUserAuthentications() expect(service.isUserAuthenticated(for: .standard)).to(beFalse()) expect(service.isUserAuthenticated(for: auth)).to(beFalse()) asyncTrigger.trigger()