fastlane-plugin-firebase 0.1.2 → 0.2.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
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ef89928a9b87b6aed33614bcb671d50b4058a76f
|
4
|
+
data.tar.gz: c790ef4fda8c4160027f3cabe5cda9dd98cfa5a9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0c6c50bf6f4400f23d95042830ec52a7fc43d30fc3d456391b3fa493da9457cde41fce14855c62b5a00f2234b33c5ec904ba1d598181e17c6ed8bfead2dcdbc1
|
7
|
+
data.tar.gz: 44ac9bbf5a0393854f1cd980a9a3f869554f3c5c813dfd41349533ddc090995be94c5caf340781586ab3bde06172fbfe282528ace75e74dd9843096c484a01f6
|
@@ -13,7 +13,8 @@ module Fastlane
|
|
13
13
|
|
14
14
|
projects.each_with_index { |p, i|
|
15
15
|
UI.message "#{i+1}. #{p["displayName"]} (#{p["projectNumber"]})"
|
16
|
-
p["clientSummary"]
|
16
|
+
clients = p["clientSummary"] || []
|
17
|
+
clients.sort {|left, right| left["clientId"] <=> right["clientId"] }.each_with_index { |client, j|
|
17
18
|
UI.message " - #{client["clientId"]} (#{client["displayName"]})"
|
18
19
|
}
|
19
20
|
}
|
@@ -17,7 +17,7 @@ module Fastlane
|
|
17
17
|
require 'digest/sha1'
|
18
18
|
require 'json'
|
19
19
|
require 'cgi'
|
20
|
-
|
20
|
+
|
21
21
|
def initialize(email, password)
|
22
22
|
@agent = Mechanize.new
|
23
23
|
@base_url = "https://console.firebase.google.com"
|
@@ -45,21 +45,106 @@ module Fastlane
|
|
45
45
|
|
46
46
|
#Send
|
47
47
|
page = @agent.submit(google_form, google_form.buttons.first)
|
48
|
-
match = page.search("script").text.scan(/\\x22api-key\\x22:\\x22(.*?)\\x22/)
|
49
48
|
|
49
|
+
while page do
|
50
|
+
if extract_api_key(page) then
|
51
|
+
UI.success "Successfuly logged in"
|
52
|
+
return true
|
53
|
+
else
|
54
|
+
|
55
|
+
if error = page.at("#errormsg_0_Passwd") then
|
56
|
+
message = error.text.strip
|
57
|
+
elsif page.xpath("//div[@class='captcha-img']").count > 0 then
|
58
|
+
page = captcha_challenge(page)
|
59
|
+
next
|
60
|
+
elsif page.form.action.include? "/signin/challenge/" then
|
61
|
+
page = signin_challenge(page)
|
62
|
+
next
|
63
|
+
else
|
64
|
+
message = "Unknown error"
|
65
|
+
end
|
66
|
+
raise LoginError, "Login failed: #{message}"
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def extract_api_key(page)
|
73
|
+
#Find api key in javascript
|
74
|
+
match = page.search("script").text.scan(/\\x22api-key\\x22:\\x22(.*?)\\x22/)
|
50
75
|
if match.count == 1 then
|
51
76
|
@api_key = match[0][0]
|
52
77
|
@authorization_headers = create_authorization_headers()
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
78
|
+
return true
|
79
|
+
end
|
80
|
+
|
81
|
+
return false
|
82
|
+
end
|
83
|
+
|
84
|
+
def captcha_challenge(page)
|
85
|
+
if UI.confirm "To proceed you need to fill in captcha. Do you want to download captcha image?" then
|
86
|
+
img_src = page.xpath("//div[@class='captcha-img']/img").attribute("src").value
|
87
|
+
image = @agent.get(img_src)
|
88
|
+
if image != nil then
|
89
|
+
UI.success "Captcha image downloaded"
|
90
|
+
else
|
91
|
+
UI.crash! "Failed to download captcha image"
|
60
92
|
end
|
61
|
-
|
62
|
-
|
93
|
+
|
94
|
+
file = Tempfile.new(["firebase_captcha_image", ".jpg"])
|
95
|
+
path = file.path
|
96
|
+
|
97
|
+
image.save!(path)
|
98
|
+
|
99
|
+
UI.success "Captcha image saved at #{path}"
|
100
|
+
|
101
|
+
if UI.confirm "Preview image?" then
|
102
|
+
if system("qlmanage -p #{path} >& /dev/null &") != true && system("open #{path} 2> /dev/null") != true then
|
103
|
+
UI.error("Unable to find program to preview the image, open it manually")
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
captcha = UI.input "Enter captcha (case insensitive):"
|
108
|
+
password = UI.password "Re-enter password:"
|
109
|
+
|
110
|
+
captcha_form = page.form()
|
111
|
+
|
112
|
+
captcha_form.logincaptcha = captcha
|
113
|
+
captcha_form.Passwd = password
|
114
|
+
|
115
|
+
page = @agent.submit(captcha_form, captcha_form.buttons.first)
|
116
|
+
return page
|
117
|
+
else
|
118
|
+
return nil
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
122
|
+
|
123
|
+
def signin_challenge(page)
|
124
|
+
UI.header "Sign-in challenge"
|
125
|
+
|
126
|
+
form_id = "challenge"
|
127
|
+
form = page.form_with(:id => form_id)
|
128
|
+
type = (form["challengeType"] || "-1").to_i
|
129
|
+
|
130
|
+
# Two factor verification
|
131
|
+
if type == 9 then
|
132
|
+
div = page.at("##{form_id} div")
|
133
|
+
if div != nil then
|
134
|
+
UI.important div.xpath("div[1]").text
|
135
|
+
UI.important div.xpath("div[2]").text
|
136
|
+
end
|
137
|
+
|
138
|
+
code = UI.input "Enter code G-:"
|
139
|
+
form.Pin = code
|
140
|
+
page = @agent.submit(form, form.buttons.first)
|
141
|
+
return page
|
142
|
+
else
|
143
|
+
html = page.at("##{form_id}").to_html
|
144
|
+
UI.user_error! "Unknown challenge type \n\n#{html}"
|
145
|
+
end
|
146
|
+
|
147
|
+
return nil
|
63
148
|
end
|
64
149
|
|
65
150
|
def generate_sapisid_hash(time, sapisid, origin)
|
@@ -122,7 +207,7 @@ module Fastlane
|
|
122
207
|
def project_list
|
123
208
|
UI.message "Retrieving project list"
|
124
209
|
json = request_json("v1/projects")
|
125
|
-
projects = json["project"]
|
210
|
+
projects = json["project"] || []
|
126
211
|
UI.success "Found #{projects.count} projects"
|
127
212
|
projects
|
128
213
|
end
|
@@ -1,36 +1,49 @@
|
|
1
1
|
module Fastlane
|
2
2
|
module Firebase
|
3
3
|
|
4
|
+
|
4
5
|
class Manager
|
5
6
|
def server_name
|
6
7
|
"firebase.google.com"
|
7
8
|
end
|
8
9
|
|
9
|
-
|
10
|
-
|
11
10
|
def login(username)
|
12
11
|
item = Security::InternetPassword.find(server: server_name(), account: username)
|
13
|
-
|
12
|
+
keychain_password = item.password if item
|
14
13
|
|
14
|
+
password = keychain_password
|
15
15
|
begin
|
16
|
-
password = UI.
|
16
|
+
password = UI.password("Password for #{username}") unless password
|
17
17
|
|
18
18
|
#Api instance
|
19
19
|
@api = Firebase::Api.new(username, password)
|
20
20
|
|
21
21
|
#Store password
|
22
|
-
Security::InternetPassword.add(server_name(), username, password) unless
|
22
|
+
Security::InternetPassword.add(server_name(), username, password) unless keychain_password == password
|
23
23
|
|
24
24
|
@api
|
25
25
|
rescue Firebase::Api::LoginError => e
|
26
|
-
password = nil
|
27
26
|
UI.error e.message
|
28
|
-
|
27
|
+
|
28
|
+
if UI.confirm "Do you want to re-enter your password?" then
|
29
|
+
password = nil
|
30
|
+
if keychain_password then
|
31
|
+
puts "Removing Keychain entry for user '#{username}'...".yellow
|
32
|
+
Security::InternetPassword.delete(server: server_name(), account: username)
|
33
|
+
end
|
34
|
+
keychain_password = nil
|
35
|
+
retry
|
36
|
+
end
|
29
37
|
end
|
30
38
|
end
|
31
39
|
|
32
40
|
def select_project(project_number)
|
33
41
|
projects = @api.project_list()
|
42
|
+
if projects.count == 0 then
|
43
|
+
UI.user_error! "No projects exist under the account"
|
44
|
+
return
|
45
|
+
end
|
46
|
+
|
34
47
|
if project = projects.select {|p| p["projectNumber"] == project_number }.first then
|
35
48
|
project
|
36
49
|
else
|
@@ -41,7 +54,12 @@ module Fastlane
|
|
41
54
|
end
|
42
55
|
|
43
56
|
def select_client(project, client_id)
|
44
|
-
|
57
|
+
if project["clientSummary"] == nil then
|
58
|
+
UI.user_error! "Project has no clients"
|
59
|
+
return
|
60
|
+
end
|
61
|
+
|
62
|
+
clients = (project["clientSummary"] || []).sort {|left, right| left["clientId"] <=> right["clientId"] }
|
45
63
|
|
46
64
|
if client = clients.select {|c| c["clientId"] == client_id }.first then
|
47
65
|
client
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fastlane-plugin-firebase
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tomas Kohout
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-06-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|