@@ -6,6 +6,7 @@ import Foundation
6
6
import Shared
7
7
import XCGLogger
8
8
import Deferred
9
+ import SwiftyJSON
9
10
10
11
private let log = Logger . syncLogger
11
12
@@ -20,31 +21,31 @@ let AccountSchemaVersion = 1
20
21
///
21
22
/// Non-sensitive but persistent data should be maintained outside of
22
23
/// the account itself.
23
- public class FirefoxAccount {
24
+ open class FirefoxAccount {
24
25
/// The email address identifying the account. A Firefox Account is uniquely identified on a particular server
25
26
/// (auth endpoint) by its email address.
26
- public let email : String
27
+ open let email : String
27
28
28
29
/// The auth endpoint user identifier identifying the account. A Firefox Account is uniquely identified on a
29
30
/// particular server (auth endpoint) by its assigned uid.
30
- public let uid : String
31
+ open let uid : String
31
32
32
- public var deviceRegistration : FxADeviceRegistration ?
33
+ open var deviceRegistration : FxADeviceRegistration ?
33
34
34
- public let configuration : FirefoxAccountConfiguration
35
+ open let configuration : FirefoxAccountConfiguration
35
36
36
- private let stateCache : KeychainCache < FxAState >
37
- public var syncAuthState : SyncAuthState ! // We can't give a reference to self if this is a let.
37
+ fileprivate let stateCache : KeychainCache < FxAState >
38
+ open var syncAuthState : SyncAuthState ! // We can't give a reference to self if this is a let.
38
39
39
40
// To prevent advance() consumers racing, we maintain a shared advance() deferred (`advanceDeferred`). If an
40
41
// advance() is in progress, the shared deferred will be returned. (Multiple consumers can chain off a single
41
42
// deferred safely.) If no advance() is in progress, a new shared deferred will be scheduled and returned. To
42
43
// prevent data races against the shared deferred, advance() locks accesses to `advanceDeferred` using
43
44
// `advanceLock`.
44
- private var advanceLock = OSSpinLock ( )
45
- private var advanceDeferred : Deferred < FxAState > ? = nil
45
+ fileprivate var advanceLock = OSSpinLock ( )
46
+ fileprivate var advanceDeferred : Deferred < FxAState > ?
46
47
47
- public var actionNeeded : FxAActionNeeded {
48
+ open var actionNeeded : FxAActionNeeded {
48
49
return stateCache. value!. actionNeeded
49
50
}
50
51
@@ -63,34 +64,34 @@ public class FirefoxAccount {
63
64
cache: KeychainCache . fromBranch ( " account.syncAuthState " , withLabel: self . stateCache. label, factory: syncAuthStateCachefromJSON) )
64
65
}
65
66
66
- public class func fromConfigurationAndJSON ( configuration: FirefoxAccountConfiguration , data: JSON ) -> FirefoxAccount ? {
67
- guard let email = data [ " email " ] . asString ,
68
- let uid = data [ " uid " ] . asString ,
69
- let sessionToken = data [ " sessionToken " ] . asString ? . hexDecodedData,
70
- let keyFetchToken = data [ " keyFetchToken " ] . asString ? . hexDecodedData,
71
- let unwrapkB = data [ " unwrapBKey " ] . asString ? . hexDecodedData else {
67
+ open class func from ( _ configuration: FirefoxAccountConfiguration , andJSON data: JSON ) -> FirefoxAccount ? {
68
+ guard let email = data [ " email " ] . string ,
69
+ let uid = data [ " uid " ] . string ,
70
+ let sessionToken = data [ " sessionToken " ] . string ? . hexDecodedData,
71
+ let keyFetchToken = data [ " keyFetchToken " ] . string ? . hexDecodedData,
72
+ let unwrapkB = data [ " unwrapBKey " ] . string ? . hexDecodedData else {
72
73
return nil
73
74
}
74
75
75
- let verified = data [ " verified " ] . asBool ?? false
76
- return FirefoxAccount . fromConfigurationAndParameters ( configuration,
77
- email : email, uid: uid, deviceRegistration: nil , verified: verified,
76
+ let verified = data [ " verified " ] . bool ?? false
77
+ return FirefoxAccount . from ( configuration : configuration,
78
+ andParametersWithEmail : email, uid: uid, deviceRegistration: nil , verified: verified,
78
79
sessionToken: sessionToken, keyFetchToken: keyFetchToken, unwrapkB: unwrapkB)
79
80
}
80
81
81
- public class func fromConfigurationAndLoginResponse ( configuration: FirefoxAccountConfiguration ,
82
- response: FxALoginResponse , unwrapkB: NSData ) -> FirefoxAccount {
83
- return FirefoxAccount . fromConfigurationAndParameters ( configuration,
84
- email : response. remoteEmail, uid: response. uid, deviceRegistration: nil , verified: response. verified,
85
- sessionToken: response. sessionToken, keyFetchToken: response. keyFetchToken, unwrapkB: unwrapkB)
82
+ open class func from ( _ configuration: FirefoxAccountConfiguration ,
83
+ andLoginResponse response: FxALoginResponse , unwrapkB: Data ) -> FirefoxAccount {
84
+ return FirefoxAccount . from ( configuration : configuration,
85
+ andParametersWithEmail : response. remoteEmail, uid: response. uid, deviceRegistration: nil , verified: response. verified,
86
+ sessionToken: response. sessionToken as Data , keyFetchToken: response. keyFetchToken as Data , unwrapkB: unwrapkB)
86
87
}
87
88
88
- private class func fromConfigurationAndParameters ( configuration: FirefoxAccountConfiguration ,
89
- email: String , uid: String , deviceRegistration: FxADeviceRegistration ? , verified: Bool ,
90
- sessionToken: NSData , keyFetchToken: NSData , unwrapkB: NSData ) -> FirefoxAccount {
89
+ fileprivate class func from ( configuration: FirefoxAccountConfiguration ,
90
+ andParametersWithEmail email: String , uid: String , deviceRegistration: FxADeviceRegistration ? , verified: Bool ,
91
+ sessionToken: Data , keyFetchToken: Data , unwrapkB: Data ) -> FirefoxAccount {
91
92
var state : FxAState ! = nil
92
93
if !verified {
93
- let now = NSDate . now ( )
94
+ let now = Date . now ( )
94
95
state = EngagedBeforeVerifiedState ( knownUnverifiedAt: now,
95
96
lastNotifiedUserAt: now,
96
97
sessionToken: sessionToken,
@@ -116,8 +117,8 @@ public class FirefoxAccount {
116
117
return account
117
118
}
118
119
119
- public func asDictionary ( ) -> [ String : AnyObject ] {
120
- var dict : [ String : AnyObject ] = [ : ]
120
+ open func dictionary ( ) -> [ String : Any ] {
121
+ var dict : [ String : Any ] = [ : ]
121
122
dict [ " version " ] = AccountSchemaVersion
122
123
dict [ " email " ] = email
123
124
dict [ " uid " ] = uid
@@ -127,7 +128,7 @@ public class FirefoxAccount {
127
128
return dict
128
129
}
129
130
130
- public class func fromDictionary( dictionary: [ String : AnyObject ] ) -> FirefoxAccount ? {
131
+ open class func fromDictionary( _ dictionary: [ String : Any ] ) -> FirefoxAccount ? {
131
132
if let version = dictionary [ " version " ] as? Int {
132
133
if version == AccountSchemaVersion {
133
134
return FirefoxAccount . fromDictionaryV1 ( dictionary)
@@ -136,17 +137,17 @@ public class FirefoxAccount {
136
137
return nil
137
138
}
138
139
139
- private class func fromDictionaryV1( dictionary: [ String : AnyObject ] ) -> FirefoxAccount ? {
140
+ fileprivate class func fromDictionaryV1( _ dictionary: [ String : Any ] ) -> FirefoxAccount ? {
140
141
var configurationLabel : FirefoxAccountConfigurationLabel ? = nil
141
142
if let rawValue = dictionary [ " configurationLabel " ] as? String {
142
143
configurationLabel = FirefoxAccountConfigurationLabel ( rawValue: rawValue)
143
144
}
144
145
if let
145
146
configurationLabel = configurationLabel,
146
- email = dictionary [ " email " ] as? String ,
147
- uid = dictionary [ " uid " ] as? String {
147
+ let email = dictionary [ " email " ] as? String ,
148
+ let uid = dictionary [ " uid " ] as? String {
148
149
let deviceRegistration = dictionary [ " deviceRegistration " ] as? FxADeviceRegistration
149
- let stateCache = KeychainCache . fromBranch ( " account.state " , withLabel: dictionary [ " stateKeyLabel " ] as? String , withDefault: SeparatedState ( ) , factory: stateFromJSON )
150
+ let stateCache = KeychainCache . fromBranch ( " account.state " , withLabel: dictionary [ " stateKeyLabel " ] as? String , withDefault: SeparatedState ( ) , factory: state )
150
151
return FirefoxAccount (
151
152
configuration: configurationLabel. toConfiguration ( ) ,
152
153
email: email, uid: uid,
@@ -157,16 +158,16 @@ public class FirefoxAccount {
157
158
}
158
159
159
160
public enum AccountError : MaybeErrorType {
160
- case NotMarried
161
+ case notMarried
161
162
162
163
public var description : String {
163
164
switch self {
164
- case NotMarried : return " Not married. "
165
+ case . notMarried : return " Not married. "
165
166
}
166
167
}
167
168
}
168
169
169
- public func advance( ) - > Deferred< FxAState> {
170
+ @ discardableResult open func advance( ) -> Deferred < FxAState > {
170
171
OSSpinLockLock ( & advanceLock)
171
172
if let deferred = advanceDeferred {
172
173
// We already have an advance() in progress. This consumer can chain from it.
@@ -179,10 +180,9 @@ public class FirefoxAccount {
179
180
let cachedState = stateCache. value!
180
181
var registration = succeed ( )
181
182
if let session = cachedState as? TokenState {
182
- registration = FxADeviceRegistrator . registerOrUpdateDevice ( self , sessionToken: session. sessionToken) . bind { result in
183
- if result. successValue != FxADeviceRegistrationResult . AlreadyRegistered {
184
- let notification = NSNotification ( name: NotificationFirefoxAccountDeviceRegistrationUpdated, object: nil )
185
- NSNotificationCenter . defaultCenter ( ) . postNotification ( notification)
183
+ registration = FxADeviceRegistrator . registerOrUpdateDevice ( self , sessionToken: session. sessionToken as NSData ) . bind { result in
184
+ if result. successValue != FxADeviceRegistrationResult . alreadyRegistered {
185
+ NotificationCenter . default. post ( name: NotificationFirefoxAccountDeviceRegistrationUpdated, object: nil )
186
186
}
187
187
return succeed ( )
188
188
}
@@ -191,8 +191,8 @@ public class FirefoxAccount {
191
191
let deferred : Deferred < FxAState > = registration. bind { _ in
192
192
let client = FxAClient10 ( endpoint: self . configuration. authEndpointURL)
193
193
let stateMachine = FxALoginStateMachine ( client: client)
194
- let now = NSDate . now ( )
195
- return stateMachine. advanceFromState ( cachedState, now: now) . map { newState in
194
+ let now = Date . now ( )
195
+ return stateMachine. advance ( fromState : cachedState, now: now) . map { newState in
196
196
self . stateCache. value = newState
197
197
return newState
198
198
}
@@ -205,7 +205,7 @@ public class FirefoxAccount {
205
205
deferred. upon { _ in
206
206
// This advance() is complete. Clear the shared deferred.
207
207
OSSpinLockLock ( & self . advanceLock)
208
- if let existingDeferred = self . advanceDeferred where existingDeferred === deferred {
208
+ if let existingDeferred = self . advanceDeferred, existingDeferred === deferred {
209
209
// The guard should not be needed, but should prevent trampling racing consumers.
210
210
self . advanceDeferred = nil
211
211
log. debug ( " advance() completed and shared deferred is existing deferred; clearing shared deferred. " )
@@ -217,30 +217,30 @@ public class FirefoxAccount {
217
217
return deferred
218
218
}
219
219
220
- public func marriedState( ) - > Deferred< Maybe< MarriedState>> {
220
+ open func marriedState( ) -> Deferred < Maybe < MarriedState > > {
221
221
return advance ( ) . map { newState in
222
- if newState. label == FxAStateLabel . Married {
222
+ if newState. label == FxAStateLabel . married {
223
223
if let married = newState as? MarriedState {
224
224
return Maybe ( success: married)
225
225
}
226
226
}
227
- return Maybe ( failure: AccountError . NotMarried )
227
+ return Maybe ( failure: AccountError . notMarried )
228
228
}
229
229
}
230
230
231
- public func makeSeparated( ) - > Bool {
231
+ @ discardableResult open func makeSeparated( ) -> Bool {
232
232
log. info ( " Making Account State be Separated. " )
233
233
self . stateCache. value = SeparatedState ( )
234
234
return true
235
235
}
236
236
237
- public func makeDoghouse( ) - > Bool {
237
+ @ discardableResult open func makeDoghouse( ) -> Bool {
238
238
log. info ( " Making Account State be Doghouse. " )
239
239
self . stateCache. value = DoghouseState ( )
240
240
return true
241
241
}
242
242
243
- public func makeCohabitingWithoutKeyPair( ) - > Bool {
243
+ open func makeCohabitingWithoutKeyPair( ) -> Bool {
244
244
if let married = self . stateCache. value as? MarriedState {
245
245
log. info ( " Making Account State be CohabitingWithoutKeyPair. " )
246
246
self . stateCache. value = married. withoutKeyPair ( )
0 commit comments