motion-firebase 2.1.5 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +192 -64
- data/lib/firebase-auth/firebase_simple_login.rb +0 -76
- data/lib/firebase/fdata_snapshot.rb +4 -0
- data/lib/firebase/firebase.rb +53 -42
- data/lib/firebase/firebase_auth.rb +219 -0
- data/lib/firebase/firebase_facebook_helper.rb +24 -0
- data/lib/firebase/firebase_github_helper.rb +20 -0
- data/lib/firebase/firebase_twitter_helper.rb +169 -0
- data/lib/firebase/fquery.rb +16 -4
- data/lib/firebase/version.rb +2 -1
- data/lib/motion-firebase-auth.rb +3 -11
- data/lib/motion-firebase.rb +3 -1
- metadata +6 -19
- data/lib/vendor/Firebase.framework/Firebase +0 -0
- data/lib/vendor/Firebase.framework/Versions/A/Firebase +0 -0
- data/lib/vendor/Firebase.framework/Versions/A/Headers/FDataSnapshot.h +0 -146
- data/lib/vendor/Firebase.framework/Versions/A/Headers/FEventType.h +0 -43
- data/lib/vendor/Firebase.framework/Versions/A/Headers/FMutableData.h +0 -139
- data/lib/vendor/Firebase.framework/Versions/A/Headers/FQuery.h +0 -229
- data/lib/vendor/Firebase.framework/Versions/A/Headers/FTransactionResult.h +0 -50
- data/lib/vendor/Firebase.framework/Versions/A/Headers/Firebase.h +0 -707
- data/lib/vendor/Firebase.framework/build-MacOSX/Firebase.framework.bridgesupport +0 -582
- data/lib/vendor/Firebase.framework/build-iPhoneSimulator/Firebase.framework.bridgesupport +0 -582
- data/lib/vendor/FirebaseSimpleLogin.framework/FirebaseSimpleLogin +0 -0
- data/lib/vendor/FirebaseSimpleLogin.framework/Versions/A/FirebaseSimpleLogin +0 -0
- data/lib/vendor/FirebaseSimpleLogin.framework/Versions/A/Headers/FATypes.h +0 -52
- data/lib/vendor/FirebaseSimpleLogin.framework/Versions/A/Headers/FAUser.h +0 -97
- data/lib/vendor/FirebaseSimpleLogin.framework/Versions/A/Headers/FirebaseSimpleLogin.h +0 -221
- data/lib/vendor/FirebaseSimpleLogin.framework/build-MacOSX/FirebaseSimpleLogin.framework.bridgesupport +0 -230
- data/lib/vendor/FirebaseSimpleLogin.framework/build-iPhoneSimulator/FirebaseSimpleLogin.framework.bridgesupport +0 -230
data/lib/firebase/firebase.rb
CHANGED
@@ -22,8 +22,41 @@ class Firebase
|
|
22
22
|
return event_type
|
23
23
|
end
|
24
24
|
|
25
|
-
def self.
|
26
|
-
|
25
|
+
def self.url=(url)
|
26
|
+
if url.start_with?('http://')
|
27
|
+
raise "Invalid URL #{url.inspect} in #{__method__}: URL scheme should be 'https://', not 'http://'"
|
28
|
+
elsif url.start_with?('https://')
|
29
|
+
# all good
|
30
|
+
elsif url =~ '^\w+://'
|
31
|
+
raise "Invalid URL #{url.inspect} in #{__method__}: URL scheme should be 'https://', not '#{$~}'"
|
32
|
+
else
|
33
|
+
url = "https://#{url}"
|
34
|
+
end
|
35
|
+
|
36
|
+
# should we support `Firebase.url = 'myapp/path/to/child/'` ? I'm gonna say
|
37
|
+
# NO for now...
|
38
|
+
unless url.include?('.firebaseio.com')
|
39
|
+
if url.include?('/')
|
40
|
+
raise "Invalid URL #{url.inspect} in #{__method__}: URL does not include 'firebaseio.com'"
|
41
|
+
end
|
42
|
+
url = "#{url}.firebaseio.com"
|
43
|
+
end
|
44
|
+
|
45
|
+
@url = url
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.url
|
49
|
+
@url
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.new(url=nil)
|
53
|
+
if url.nil?
|
54
|
+
@shared ||= alloc.initWithUrl(@url)
|
55
|
+
elsif url
|
56
|
+
alloc.initWithUrl(url)
|
57
|
+
else
|
58
|
+
super
|
59
|
+
end
|
27
60
|
end
|
28
61
|
|
29
62
|
# @example
|
@@ -36,52 +69,35 @@ class Firebase
|
|
36
69
|
setDispatchQueue(queue)
|
37
70
|
end
|
38
71
|
|
39
|
-
|
40
|
-
|
41
|
-
# firebase.auth('secretkey') do
|
42
|
-
# # connected
|
43
|
-
# end
|
44
|
-
# firebase.auth('secretkey', disconnect: ->{}) do
|
45
|
-
# # connected
|
46
|
-
# end
|
47
|
-
# firebase.auth('secretkey', completion: ->{}, disconnect: ->{})
|
48
|
-
# # => firebase.authWithCredential(credential)
|
49
|
-
def auth(credential, options={}, &and_then)
|
50
|
-
and_then ||= options[:completion]
|
51
|
-
disconnect_block = options[:disconnect]
|
52
|
-
authWithCredential(credential, withCompletionBlock: and_then, withCancelBlock: disconnect_block)
|
53
|
-
return self
|
72
|
+
def connected_state(&block)
|
73
|
+
connected?
|
54
74
|
end
|
55
75
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
76
|
+
def self.connected?(&block)
|
77
|
+
Firebase.new.connected?(&block)
|
78
|
+
end
|
79
|
+
def connected?(&block)
|
80
|
+
if block
|
81
|
+
connected_state.on(:value) do |snapshot|
|
82
|
+
block.call(snapshot.value?)
|
83
|
+
end
|
61
84
|
else
|
62
|
-
|
85
|
+
self.root['.info/connected']
|
63
86
|
end
|
64
87
|
end
|
65
88
|
|
66
|
-
def
|
67
|
-
|
68
|
-
end
|
69
|
-
|
70
|
-
def connected_state
|
71
|
-
self.root['.info/connected']
|
89
|
+
def self.offline!
|
90
|
+
Firebase.new.offline!
|
72
91
|
end
|
73
|
-
|
74
92
|
def offline!
|
75
|
-
goOffline
|
93
|
+
self.goOffline
|
76
94
|
end
|
77
95
|
|
78
|
-
def online!
|
79
|
-
|
96
|
+
def self.online!
|
97
|
+
Firebase.new.online!
|
80
98
|
end
|
81
|
-
|
82
|
-
|
83
|
-
NSLog('The method ‘Firebase#run’ has been deprecated in favor of ‘Firebase#transaction’')
|
84
|
-
self.transaction(options, &transaction)
|
99
|
+
def online!
|
100
|
+
self.goOnline
|
85
101
|
end
|
86
102
|
|
87
103
|
def transaction(options={}, &transaction)
|
@@ -201,11 +217,6 @@ class Firebase
|
|
201
217
|
return self
|
202
218
|
end
|
203
219
|
|
204
|
-
# Calls the block when the value is true
|
205
|
-
def on_auth(options={}, &block)
|
206
|
-
auth_state.on(:value, options, &block)
|
207
|
-
end
|
208
|
-
|
209
220
|
def on_disconnect(value, &and_then)
|
210
221
|
if block_given?
|
211
222
|
if value.nil?
|
@@ -0,0 +1,219 @@
|
|
1
|
+
# most methods have a static version that make use of Firebase.url = 'global url'
|
2
|
+
# to create a Firebase ref.
|
3
|
+
class Firebase
|
4
|
+
|
5
|
+
def self.auth_data
|
6
|
+
Firebase.new.auth_data
|
7
|
+
end
|
8
|
+
def auth_data
|
9
|
+
authData
|
10
|
+
end
|
11
|
+
|
12
|
+
# @example
|
13
|
+
# Firebase.auth('secrettoken') do |error, auth_data|
|
14
|
+
# if auth_data
|
15
|
+
# # authenticated
|
16
|
+
# end
|
17
|
+
# end
|
18
|
+
def self.auth(token, options={}, &block)
|
19
|
+
Firebase.new.auth(token, options, &block)
|
20
|
+
end
|
21
|
+
def auth(token, options={}, &and_then)
|
22
|
+
and_then ||= options[:completion]
|
23
|
+
disconnect_block = options[:disconnect]
|
24
|
+
if disconnect || and_then.arity < 2
|
25
|
+
NSLog('Warning! The Firebase authWithCredential method is deprecated.')
|
26
|
+
NSLog('Instead of using a completion and cancel block, pass one block:')
|
27
|
+
NSLog('fb.auth(token) do |error, auth_data| .. end')
|
28
|
+
authWithCredential(token, withCompletionBlock:and_then, withCancelBlock: disconnect_block)
|
29
|
+
else
|
30
|
+
authWithCustomToken(token, withCompletionBlock: and_then)
|
31
|
+
end
|
32
|
+
return self
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.logout(&block)
|
36
|
+
Firebase.new.logout(&block)
|
37
|
+
end
|
38
|
+
def logout(&block)
|
39
|
+
if block_given?
|
40
|
+
unauthWithCompletionBlock(block)
|
41
|
+
else
|
42
|
+
unauth
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.authenticated?(&block)
|
47
|
+
Firebase.new.authenticated?(&block)
|
48
|
+
end
|
49
|
+
# checks the auth status. If you pass a block the observeAuthEventWithBlock
|
50
|
+
# is used to determine the status. If you don't pass a block, this method
|
51
|
+
# returns true or false.
|
52
|
+
def authenticated?(&block)
|
53
|
+
if block
|
54
|
+
observeAuthEventWithBlock(:value, block)
|
55
|
+
else
|
56
|
+
!!authData
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# You should call this when you no longer need `authenticated?` data.
|
61
|
+
def self.off_auth(handler)
|
62
|
+
Firebase.new.off_auth(handler)
|
63
|
+
end
|
64
|
+
def off_auth(handler)
|
65
|
+
removeAuthEventObserverWithHandle(handler)
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.create_user(credentials, &block)
|
69
|
+
Firebase.new.create_user(credentials, &block)
|
70
|
+
end
|
71
|
+
def create_user(credentials, &block)
|
72
|
+
raise ":email is required in #{__method__}" unless credentials.key?(:email)
|
73
|
+
raise ":password is required in #{__method__}" unless credentials.key?(:password)
|
74
|
+
email = credentials[:email]
|
75
|
+
password = credentials[:password]
|
76
|
+
begin
|
77
|
+
createUserWithEmail(email, password: password, withCompletionBlock: block)
|
78
|
+
rescue RuntimeError => e
|
79
|
+
block.call(e, nil)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def self.create_user_and_login(credentials, &block)
|
84
|
+
Firebase.new.create_user_and_login(credentials, &block)
|
85
|
+
end
|
86
|
+
def create_user_and_login(credentials, &block)
|
87
|
+
raise ":email is required in #{__method__}" unless credentials.key?(:email)
|
88
|
+
raise ":password is required in #{__method__}" unless credentials.key?(:password)
|
89
|
+
email = credentials[:email]
|
90
|
+
password = credentials[:password]
|
91
|
+
begin
|
92
|
+
createUserWithEmail(email, password: password, withCompletionBlock: -> (error) do
|
93
|
+
if error
|
94
|
+
block.call(error, nil)
|
95
|
+
else
|
96
|
+
login(credentials, &block)
|
97
|
+
end
|
98
|
+
end)
|
99
|
+
rescue RuntimeError => e
|
100
|
+
block.call(e, nil)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def self.update_user(credentials, &block)
|
105
|
+
Firebase.new.update_user(credentials, &block)
|
106
|
+
end
|
107
|
+
def update_user(credentials, &block)
|
108
|
+
raise ":email is required in #{__method__}" unless credentials.key?(:email)
|
109
|
+
raise ":old_password is required in #{__method__}" unless credentials.key?(:old_password)
|
110
|
+
raise ":new_password is required in #{__method__}" unless credentials.key?(:new_password)
|
111
|
+
email = credentials[:email]
|
112
|
+
old_password = credentials[:old_password]
|
113
|
+
new_password = credentials[:new_password]
|
114
|
+
changePasswordForUser(email, fromOld: old_password, toNew: new_password, withCompletionBlock: block)
|
115
|
+
end
|
116
|
+
|
117
|
+
def self.send_password_reset(credentials, &block)
|
118
|
+
Firebase.new.send_password_reset(credentials, &block)
|
119
|
+
end
|
120
|
+
def send_password_reset(email, &block)
|
121
|
+
resetPasswordForUser(email, withCompletionBlock: block)
|
122
|
+
end
|
123
|
+
|
124
|
+
def self.remove_user(credentials, &block)
|
125
|
+
Firebase.new.remove_user(credentials, &block)
|
126
|
+
end
|
127
|
+
def remove_user(credentials, &block)
|
128
|
+
raise ":email is required in #{__method__}" unless credentials.key?(:email)
|
129
|
+
raise ":password is required in #{__method__}" unless credentials.key?(:password)
|
130
|
+
email = credentials[:email]
|
131
|
+
password = credentials[:password]
|
132
|
+
removeUser(email, password: password, withCompletionBlock: block)
|
133
|
+
end
|
134
|
+
|
135
|
+
def login_anonymously(&block)
|
136
|
+
authAnonymouslyWithCompletionBlock(block)
|
137
|
+
end
|
138
|
+
|
139
|
+
def login(credentials, &block)
|
140
|
+
raise ":email is required in #{__method__}" unless credentials.key?(:email)
|
141
|
+
raise ":password is required in #{__method__}" unless credentials.key?(:password)
|
142
|
+
email = credentials[:email]
|
143
|
+
password = credentials[:password]
|
144
|
+
begin
|
145
|
+
authUser(email, password: password, withCompletionBlock: block)
|
146
|
+
rescue RuntimeError => e
|
147
|
+
block.call(e, nil)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def login_to_oauth(provider, parameters={}, &block)
|
152
|
+
if parameters.is_a?(NSString)
|
153
|
+
token = parameters
|
154
|
+
elsif parameters.key?(:token)
|
155
|
+
token = parameters[:token]
|
156
|
+
else
|
157
|
+
token = nil
|
158
|
+
end
|
159
|
+
|
160
|
+
if token
|
161
|
+
authWithOAuthProvider(provider, token: token, withCompletionBlock: block)
|
162
|
+
else
|
163
|
+
objc_params = {}
|
164
|
+
parameters.each do |key, value|
|
165
|
+
# explicitly convert :sym to 'sym'
|
166
|
+
objc_params[key.to_s] = value
|
167
|
+
end
|
168
|
+
authWithOAuthProvider(provider, parameters: objc_params, withCompletionBlock: block)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def login_to_facebook(credentials, &block)
|
173
|
+
if credentials.is_a?(NSString)
|
174
|
+
token = credentials
|
175
|
+
else
|
176
|
+
token = credentials[:token]
|
177
|
+
end
|
178
|
+
raise ":token is required in #{__method__}" unless token
|
179
|
+
|
180
|
+
authWithOAuthProvider('facebook', token: token, withCompletionBlock: block)
|
181
|
+
end
|
182
|
+
|
183
|
+
def login_to_twitter(credentials, &block)
|
184
|
+
oauth_token = credentials[:token] || credentials[:oauth_token]
|
185
|
+
oauth_token_secret = credentials[:secret] || credentials[:oauth_token_secret]
|
186
|
+
raise ":token is required in #{__method__}" unless oauth_token
|
187
|
+
raise ":secret is required in #{__method__}" unless oauth_token_secret
|
188
|
+
|
189
|
+
provider = 'twitter'
|
190
|
+
options = {
|
191
|
+
'oauth_token' => oauth_token,
|
192
|
+
'oauth_token_secret' => oauth_token_secret,
|
193
|
+
}
|
194
|
+
login_to_oauth(provider, options, &block)
|
195
|
+
end
|
196
|
+
|
197
|
+
def login_to_github(credentials, &block)
|
198
|
+
if credentials.is_a?(NSString)
|
199
|
+
token = credentials
|
200
|
+
else
|
201
|
+
token = credentials[:token]
|
202
|
+
end
|
203
|
+
raise ":token is required in #{__method__}" unless token
|
204
|
+
|
205
|
+
authWithOAuthProvider('github', token: token, withCompletionBlock: block)
|
206
|
+
end
|
207
|
+
|
208
|
+
def login_to_google(credentials, &block)
|
209
|
+
if credentials.is_a?(NSString)
|
210
|
+
token = credentials
|
211
|
+
else
|
212
|
+
token = credentials[:token]
|
213
|
+
end
|
214
|
+
raise ":token is required in #{__method__}" unless token
|
215
|
+
|
216
|
+
authWithOAuthProvider('google', token: token, withCompletionBlock: block)
|
217
|
+
end
|
218
|
+
|
219
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# see https://www.firebase.com/docs/ios/guide/login/facebook.html for more info
|
2
|
+
# (that's where this code came from)
|
3
|
+
class Firebase
|
4
|
+
def self.open_facebook_session(options={}, &block)
|
5
|
+
self.new.open_facebook_session(options={}, &block)
|
6
|
+
end
|
7
|
+
|
8
|
+
def open_facebook_session(options={}, &block)
|
9
|
+
ref = self
|
10
|
+
permissions = options[:permissions] || ['public_profile']
|
11
|
+
allow_ui = options.fetch(:allow_login_ui, true)
|
12
|
+
FBSession.openActiveSessionWithReadPermissions(permissions, allowLoginUI: allow_ui,
|
13
|
+
completionHandler: -> (session, state, error) do
|
14
|
+
if error
|
15
|
+
block.call(error, nil)
|
16
|
+
elsif state == FBSessionStateOpen
|
17
|
+
token = session.accessTokenData.accessToken
|
18
|
+
|
19
|
+
ref.authWithOAuthProvider('facebook', token:token, withCompletionBlock:block)
|
20
|
+
end
|
21
|
+
end)
|
22
|
+
nil
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# see https://www.firebase.com/docs/ios/guide/login/github.html for more info
|
2
|
+
# (that's where this code came from)
|
3
|
+
class Firebase
|
4
|
+
def self.github_token=(value)
|
5
|
+
@github_token = value
|
6
|
+
end
|
7
|
+
def self.github_token
|
8
|
+
@github_token
|
9
|
+
end
|
10
|
+
def self.open_github_session(options={}, &block)
|
11
|
+
self.new.open_github_session(options={}, &block)
|
12
|
+
end
|
13
|
+
|
14
|
+
def open_github_session(options={}, &block)
|
15
|
+
ref = self
|
16
|
+
token = options[:token] || Firebase.github_token
|
17
|
+
raise "token is required in #{__method__}" unless token
|
18
|
+
firebase_ref.login_to_github('github', token)
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,169 @@
|
|
1
|
+
# see https://www.firebase.com/docs/ios/guide/login/twitter.html for more info
|
2
|
+
# (that's where this code came from)
|
3
|
+
class Firebase
|
4
|
+
def self.twitter_api_key=(value)
|
5
|
+
@twitter_api_key = value
|
6
|
+
end
|
7
|
+
def self.twitter_api_key
|
8
|
+
@twitter_api_key
|
9
|
+
end
|
10
|
+
def self.open_twitter_session(options={}, &block)
|
11
|
+
self.new.open_twitter_session(options={}, &block)
|
12
|
+
end
|
13
|
+
|
14
|
+
def open_twitter_session(options={}, &block)
|
15
|
+
ref = self
|
16
|
+
api_key = options[:api_key] || Firebase.twitter_api_key
|
17
|
+
raise "api_key is required in #{__method__}" unless api_key
|
18
|
+
|
19
|
+
helper = Motion::Firebase::TwitterAuthHelper.new(ref, api_key)
|
20
|
+
helper.select_twitter_account(&block)
|
21
|
+
nil
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
module Motion
|
27
|
+
module Firebase
|
28
|
+
class TwitterAuthHelper
|
29
|
+
|
30
|
+
def initialize(ref, api_key)
|
31
|
+
@store = ACAccountStore.new
|
32
|
+
@ref = ref
|
33
|
+
@api_key = api_key
|
34
|
+
@account = nil
|
35
|
+
@acounts = nil
|
36
|
+
@firebase_callback = nil
|
37
|
+
end
|
38
|
+
|
39
|
+
# Step 1a -- get account
|
40
|
+
def select_twitter_account(&callback)
|
41
|
+
account_type = @store.accountTypeWithAccountTypeIdentifier(ACAccountTypeIdentifierTwitter)
|
42
|
+
|
43
|
+
@store.requestAccessToAccountsWithType(account_type, options: nil, completion: -> (granted, error) do
|
44
|
+
if granted
|
45
|
+
@accounts = @store.accountsWithAccountType(account_type)
|
46
|
+
if @accounts.length > 0
|
47
|
+
Dispatch::Queue.main.async do
|
48
|
+
next_step = -> (account, &firebase_handler) do
|
49
|
+
self.authenticate_account(account, &firebase_handler)
|
50
|
+
end
|
51
|
+
callback.call(nil, @accounts, next_step)
|
52
|
+
end if callback
|
53
|
+
else
|
54
|
+
error = NSError.alloc.initWithDomain('TwitterAuthHelper',
|
55
|
+
code: AuthHelperErrorAccountAccessDenied,
|
56
|
+
userInfo: { NSLocalizedDescriptionKey => 'No Twitter accounts detected on phone. Please add one in the settings first.' })
|
57
|
+
Dispatch::Queue.main.async do
|
58
|
+
callback.call(error, nil, nil)
|
59
|
+
end if callback
|
60
|
+
end
|
61
|
+
else
|
62
|
+
error = NSError.alloc.initWithDomain('TwitterAuthHelper',
|
63
|
+
code: AuthHelperErrorAccountAccessDenied,
|
64
|
+
userInfo: { NSLocalizedDescriptionKey => 'Access to twitter accounts denied.' })
|
65
|
+
Dispatch::Queue.main.async do
|
66
|
+
callback.call(error, nil, nil)
|
67
|
+
end if callback
|
68
|
+
end
|
69
|
+
end)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Last public facing method
|
73
|
+
def authenticate_account(account, &firebase_handler)
|
74
|
+
if !account
|
75
|
+
error = NSError.alloc.initWithDomain('TwitterAuthHelper',
|
76
|
+
code: AuthHelperErrorAccountAccessDenied,
|
77
|
+
userInfo: { NSLocalizedDescriptionKey => 'No Twitter account to authenticate.' })
|
78
|
+
Dispatch::Queue.main.async do
|
79
|
+
firebase_handler.call(error, nil)
|
80
|
+
end if firebase_handler
|
81
|
+
else
|
82
|
+
@account = account
|
83
|
+
@firebase_callback = firebase_handler
|
84
|
+
make_reverse_request # kick off step 1b
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def callback_if_exists_with_error(error)
|
89
|
+
if @firebase_callback
|
90
|
+
Dispatch::Queue.main.async do
|
91
|
+
@firebase_callback.call(error, nil)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# Step 1b -- get request token from Twitter
|
97
|
+
def make_reverse_request
|
98
|
+
@ref.makeReverseOAuthRequestTo('twitter', withCompletionBlock: -> (error, json) do
|
99
|
+
if error
|
100
|
+
callback_if_exists_with_error(error)
|
101
|
+
else
|
102
|
+
request = create_credential_request_with_reverse_auth_payload(json)
|
103
|
+
request_twitter_credentials(request)
|
104
|
+
end
|
105
|
+
end)
|
106
|
+
end
|
107
|
+
|
108
|
+
# Step 1b Helper -- creates request to Twitter
|
109
|
+
def create_credential_request_with_reverse_auth_payload(json)
|
110
|
+
params = {}
|
111
|
+
|
112
|
+
request_token = json['auth']
|
113
|
+
params['x_reverse_auth_parameters'] = request_token
|
114
|
+
params['x_reverse_auth_target'] = @api_key
|
115
|
+
|
116
|
+
url = NSURL.URLWithString('https://api.twitter.com/oauth/access_token')
|
117
|
+
req = SLRequest.requestForServiceType(SLServiceTypeTwitter, requestMethod: SLRequestMethodPOST, URL: url, parameters: params)
|
118
|
+
req.setAccount(@account)
|
119
|
+
|
120
|
+
req
|
121
|
+
end
|
122
|
+
|
123
|
+
# Step 2 -- request credentials from Twitter
|
124
|
+
def request_twitter_credentials(request)
|
125
|
+
request.performRequestWithHandler(-> (response_data, url_response, error) do
|
126
|
+
if error
|
127
|
+
callback_if_exists_with_error(error)
|
128
|
+
else
|
129
|
+
authenticate_with_twitter_credentials(response_data)
|
130
|
+
end
|
131
|
+
end)
|
132
|
+
end
|
133
|
+
|
134
|
+
# Step 3 -- authenticate with Firebase using Twitter credentials
|
135
|
+
def authenticate_with_twitter_credentials(response_data)
|
136
|
+
params = parse_twitter_credentials(response_data)
|
137
|
+
if params['error']
|
138
|
+
error = NSError.alloc.initWithDomain('TwitterAuthHelper',
|
139
|
+
code: AuthHelperErrorOAuthTokenRequestDenied,
|
140
|
+
userInfo: { NSLocalizedDescriptionKey => 'OAuth token request was denied.',
|
141
|
+
'details' => params['error']})
|
142
|
+
callback_if_exists_with_error(error)
|
143
|
+
else
|
144
|
+
@ref.authWithOAuthProvider('twitter', parameters: params, withCompletionBlock: @firebase_callback)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
# Step 3 Helper -- parsers credentials into dictionary
|
149
|
+
def parse_twitter_credentials(response_data)
|
150
|
+
account_data = NSString.alloc.initWithData(response_data, encoding:NSUTF8StringEncoding)
|
151
|
+
params = {}
|
152
|
+
|
153
|
+
account_data.split('&').each do |param|
|
154
|
+
key, value = param.split('=')
|
155
|
+
params[key] = value
|
156
|
+
end
|
157
|
+
|
158
|
+
# This is super fragile error handling, but basically check that the token and token secret are there.
|
159
|
+
# If not, return the result that Twitter returned.
|
160
|
+
if params['oauth_token_secret'] && params['oauth_token']
|
161
|
+
params
|
162
|
+
else
|
163
|
+
{ 'error': account_data }
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|