pem 0.6.4 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +15 -8
- data/bin/pem +0 -1
- data/lib/pem.rb +3 -4
- data/lib/pem/dependency_checker.rb +2 -2
- data/lib/pem/manager.rb +63 -19
- data/lib/pem/options.rb +1 -1
- data/lib/pem/version.rb +1 -1
- metadata +36 -25
- data/lib/pem/cert_manager.rb +0 -54
- data/lib/pem/developer_center.rb +0 -142
- data/lib/pem/signing_request.rb +0 -30
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1198e68c415395ece6002c71b82134b9e86c3cf7
|
4
|
+
data.tar.gz: d7b170996e8deb312db5760867c369d955c12556
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 93793c6d827d5aeed902e8c7592bc8795a0b098dc9788a24705d9c95959d5fc73fae449141cb66a6fab8162d0ae0c93a4fbd58d1d40faf4020a409da284a0fa5
|
7
|
+
data.tar.gz: db22fa0fb95801ad98b77da5f151889549527fe54c7f12b42beebad8917418731a1090465c0589006d9ba0529e403a35b446368b1bf9f4f9574a114ec07f8753
|
data/README.md
CHANGED
@@ -13,7 +13,10 @@
|
|
13
13
|
<a href="https://github.com/KrauseFx/sigh">sigh</a> •
|
14
14
|
<a href="https://github.com/KrauseFx/produce">produce</a> •
|
15
15
|
<a href="https://github.com/KrauseFx/cert">cert</a> •
|
16
|
-
<a href="https://github.com/KrauseFx/codes">codes</a>
|
16
|
+
<a href="https://github.com/KrauseFx/codes">codes</a> •
|
17
|
+
<a href="https://github.com/fastlane/spaceship">spaceship</a> •
|
18
|
+
<a href="https://github.com/fastlane/pilot">pilot</a> •
|
19
|
+
<a href="https://github.com/fastlane/boarding">boarding</a>
|
17
20
|
</p>
|
18
21
|
-------
|
19
22
|
|
@@ -21,24 +24,22 @@
|
|
21
24
|
<img src="assets/pem.png">
|
22
25
|
</p>
|
23
26
|
|
24
|
-
PEM
|
27
|
+
PEM
|
25
28
|
============
|
26
29
|
|
27
30
|
[![Twitter: @KauseFx](https://img.shields.io/badge/contact-@KrauseFx-blue.svg?style=flat)](https://twitter.com/KrauseFx)
|
28
31
|
[![License](http://img.shields.io/badge/license-MIT-green.svg?style=flat)](https://github.com/KrauseFx/pem/blob/master/LICENSE)
|
29
32
|
[![Gem](https://img.shields.io/gem/v/pem.svg?style=flat)](http://rubygems.org/gems/pem)
|
30
33
|
|
34
|
+
###### Automatically generate and renew your push notification profiles
|
31
35
|
|
32
|
-
Tired of manually creating and maintaining your push notification profiles for your iOS apps? Tired of generating a
|
36
|
+
Tired of manually creating and maintaining your push notification profiles for your iOS apps? Tired of generating a `pem` file for your server?
|
33
37
|
|
34
38
|
```PEM``` does all that for, just by running ```pem```.
|
35
39
|
|
36
40
|
To automate iOS Provisioning profiles you can use [sigh](https://github.com/KrauseFx/sigh).
|
37
41
|
|
38
|
-
|
39
|
-
Sebastian Mayr ([@sebmasterkde](https://twitter.com/sebmasterkde)) who implemented the download mechanism of signing certificates<br />
|
40
|
-
Alexander Schuch ([@schuchalexander](https://twitter.com/schuchalexander)) who automated the generation of the signing request
|
41
|
-
|
42
|
+
Get in contact with the developer on Twitter: [@KrauseFx](https://twitter.com/KrauseFx)
|
42
43
|
|
43
44
|
-------
|
44
45
|
<p align="center">
|
@@ -135,13 +136,17 @@ There are 2 actions involved:
|
|
135
136
|
## [`fastlane`](https://fastlane.tools) Toolchain
|
136
137
|
|
137
138
|
- [`fastlane`](https://fastlane.tools): Connect all deployment tools into one streamlined workflow
|
138
|
-
- [`deliver`](https://github.com/KrauseFx/deliver): Upload screenshots, metadata and your app to the App Store
|
139
|
+
- [`deliver`](https://github.com/KrauseFx/deliver): Upload screenshots, metadata and your app to the App Store
|
139
140
|
- [`snapshot`](https://github.com/KrauseFx/snapshot): Automate taking localized screenshots of your iOS app on every device
|
140
141
|
- [`frameit`](https://github.com/KrauseFx/frameit): Quickly put your screenshots into the right device frames
|
141
142
|
- [`sigh`](https://github.com/KrauseFx/sigh): Because you would rather spend your time building stuff than fighting provisioning
|
142
143
|
- [`produce`](https://github.com/KrauseFx/produce): Create new iOS apps on iTunes Connect and Dev Portal using the command line
|
143
144
|
- [`cert`](https://github.com/KrauseFx/cert): Automatically create and maintain iOS code signing certificates
|
144
145
|
- [`codes`](https://github.com/KrauseFx/codes): Create promo codes for iOS Apps using the command line
|
146
|
+
- [`spaceship`](https://github.com/fastlane/spaceship): Ruby library to access the Apple Dev Center and iTunes Connect
|
147
|
+
- [`pilot`](https://github.com/fastlane/pilot): The best way to manage your TestFlight testers and builds from your terminal
|
148
|
+
- [`boarding`](https://github.com/fastlane/boarding): The easiest way to invite your TestFlight beta testers
|
149
|
+
|
145
150
|
|
146
151
|
##### [Like this tool? Be the first to know about updates and new fastlane tools](https://tinyletter.com/krausefx)
|
147
152
|
|
@@ -159,6 +164,8 @@ It will show you the ```pem``` files like this:
|
|
159
164
|
# License
|
160
165
|
This project is licensed under the terms of the MIT license. See the LICENSE file.
|
161
166
|
|
167
|
+
> This project and all fastlane tools are in no way affiliated with Apple Inc. This project is open source under the MIT license, which means you have full access to the source code and can modify it to fit your own needs. All fastlane tools run on your own computer or server, so your credentials or other sensitive information will never leave your own computer. You are responsible for how you use fastlane tools.
|
168
|
+
|
162
169
|
# Contributing
|
163
170
|
|
164
171
|
1. Create an issue to discuss about your idea
|
data/bin/pem
CHANGED
data/lib/pem.rb
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
require 'pem/version'
|
2
2
|
require 'pem/dependency_checker'
|
3
|
-
require 'pem/
|
4
|
-
require 'pem/
|
5
|
-
require 'pem/signing_request'
|
3
|
+
require 'pem/manager'
|
4
|
+
require 'pem/options'
|
6
5
|
|
7
6
|
require 'fastlane_core'
|
8
7
|
|
@@ -11,7 +10,7 @@ module PEM
|
|
11
10
|
class << self
|
12
11
|
attr_accessor :config
|
13
12
|
end
|
14
|
-
|
13
|
+
|
15
14
|
TMP_FOLDER = "/tmp/PEM/"
|
16
15
|
FileUtils.mkdir_p TMP_FOLDER
|
17
16
|
|
@@ -6,7 +6,7 @@ module PEM
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def self.check_xcode_select
|
9
|
-
unless `xcode-select -v`.include?"xcode-select version "
|
9
|
+
unless `xcode-select -v`.include?("xcode-select version ")
|
10
10
|
Helper.log.fatal '#############################################################'
|
11
11
|
Helper.log.fatal "# You have to install the Xcode commdand line tools to use PEM"
|
12
12
|
Helper.log.fatal "# Install the latest version of Xcode from the AppStore"
|
@@ -16,4 +16,4 @@ module PEM
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
end
|
19
|
-
end
|
19
|
+
end
|
data/lib/pem/manager.rb
CHANGED
@@ -1,30 +1,74 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'spaceship'
|
3
|
+
|
1
4
|
module PEM
|
2
5
|
# Creates the push profile and stores it in the correct location
|
3
6
|
class Manager
|
7
|
+
|
4
8
|
def self.start
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
9
|
+
password_manager = CredentialsManager::PasswordManager.shared_manager
|
10
|
+
Spaceship.login(password_manager.username, password_manager.password)
|
11
|
+
Spaceship.client.select_team
|
12
|
+
|
13
|
+
existing_certificate = Spaceship.certificate.all.detect {|c| c.name == PEM.config[:app_identifier] }
|
14
|
+
|
15
|
+
if existing_certificate && !PEM.config[:force]
|
16
|
+
Helper.log.info "You already have a push certificate, which is active for more than 30 more days. No need to create a new one".green
|
17
|
+
Helper.log.info "If you still want to create a new one, use the --force option when running PEM.".green
|
18
|
+
return false
|
14
19
|
end
|
15
|
-
|
16
|
-
if
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
20
|
+
|
21
|
+
if existing_certificate && PEM.config[:force]
|
22
|
+
Helper.log.info "You already have an existing push certificate, but a new one will be created since the --force option has been set.".green
|
23
|
+
end
|
24
|
+
|
25
|
+
Helper.log.warn "Creating a new push certificate for app '#{PEM.config[:app_identifier]}'."
|
26
|
+
|
27
|
+
csr, pkey = Spaceship.certificate.create_certificate_signing_request
|
28
|
+
|
29
|
+
begin
|
30
|
+
if PEM.config[:development]
|
31
|
+
cert = Spaceship.certificate.development_push.create!(csr: csr, bundle_id: PEM.config[:app_identifier])
|
32
|
+
else
|
33
|
+
cert = Spaceship.certificate.production_push.create!(csr: csr, bundle_id: PEM.config[:app_identifier])
|
34
|
+
end
|
35
|
+
rescue => ex
|
36
|
+
if ex.to_s.include?"You already have a current"
|
37
|
+
# That's the most common failure probably
|
38
|
+
Helper.log.info ex.to_s
|
39
|
+
Helper.log.error "You already have 2 active push profiles for this application/environment.".red
|
40
|
+
Helper.log.error "You'll need to revoke an old certificate to make room for a new one".red
|
22
41
|
else
|
23
|
-
|
42
|
+
raise ex
|
24
43
|
end
|
25
44
|
end
|
26
45
|
|
27
|
-
|
46
|
+
x509_certificate = cert.download
|
47
|
+
certificate_type = (PEM.config[:development] ? 'development' : 'production')
|
48
|
+
filename_base = PEM.config[:pem_name] || "#{certificate_type}_#{PEM.config[:app_identifier]}"
|
49
|
+
filename_base = File.basename(filename_base, ".pem") # strip off the .pem if it was provided.
|
50
|
+
|
51
|
+
if PEM.config[:save_private_key]
|
52
|
+
file = File.new("#{filename_base}.pkey",'w')
|
53
|
+
file.write(pkey.to_pem)
|
54
|
+
file.close
|
55
|
+
Helper.log.info "Private key: ".green + Pathname.new(file).realpath.to_s
|
56
|
+
end
|
57
|
+
|
58
|
+
if PEM.config[:generate_p12]
|
59
|
+
certificate_type = (PEM.config[:development] ? 'development' : 'production')
|
60
|
+
p12 = OpenSSL::PKCS12.create(PEM.config[:p12_password], certificate_type, pkey, x509_certificate)
|
61
|
+
file = File.new("#{filename_base}.p12", 'wb')
|
62
|
+
file.write(p12.to_der)
|
63
|
+
file.close
|
64
|
+
Helper.log.info "p12 certificate: ".green + Pathname.new(file).realpath.to_s
|
65
|
+
end
|
66
|
+
|
67
|
+
file = File.new("#{filename_base}.pem", 'w')
|
68
|
+
file.write(x509_certificate.to_pem + pkey.to_pem)
|
69
|
+
file.close
|
70
|
+
Helper.log.info "PEM: ".green + Pathname.new(file).realpath.to_s
|
71
|
+
return file
|
28
72
|
end
|
29
73
|
end
|
30
|
-
end
|
74
|
+
end
|
data/lib/pem/options.rb
CHANGED
@@ -19,7 +19,7 @@ module PEM
|
|
19
19
|
env_name: "PEM_SAVE_PRIVATEKEY",
|
20
20
|
description: "Set to save the private RSA key in the current directory",
|
21
21
|
is_string: false,
|
22
|
-
default_value:
|
22
|
+
default_value: true),
|
23
23
|
FastlaneCore::ConfigItem.new(key: :force,
|
24
24
|
env_name: "PEM_FORCE",
|
25
25
|
description: "Create a new push certificate, even if the current one is active for 30 more days",
|
data/lib/pem/version.rb
CHANGED
metadata
CHANGED
@@ -1,125 +1,139 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pem
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Felix Krause
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-08-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: fastlane_core
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: 0.7.2
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 0.7.2
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: spaceship
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.4.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.4.0
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: bundler
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
30
44
|
requirements:
|
31
|
-
- -
|
45
|
+
- - ">="
|
32
46
|
- !ruby/object:Gem::Version
|
33
47
|
version: '0'
|
34
48
|
type: :development
|
35
49
|
prerelease: false
|
36
50
|
version_requirements: !ruby/object:Gem::Requirement
|
37
51
|
requirements:
|
38
|
-
- -
|
52
|
+
- - ">="
|
39
53
|
- !ruby/object:Gem::Version
|
40
54
|
version: '0'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: rake
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
44
58
|
requirements:
|
45
|
-
- -
|
59
|
+
- - ">="
|
46
60
|
- !ruby/object:Gem::Version
|
47
61
|
version: '0'
|
48
62
|
type: :development
|
49
63
|
prerelease: false
|
50
64
|
version_requirements: !ruby/object:Gem::Requirement
|
51
65
|
requirements:
|
52
|
-
- -
|
66
|
+
- - ">="
|
53
67
|
- !ruby/object:Gem::Version
|
54
68
|
version: '0'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: rspec
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
58
72
|
requirements:
|
59
|
-
- - ~>
|
73
|
+
- - "~>"
|
60
74
|
- !ruby/object:Gem::Version
|
61
75
|
version: 3.1.0
|
62
76
|
type: :development
|
63
77
|
prerelease: false
|
64
78
|
version_requirements: !ruby/object:Gem::Requirement
|
65
79
|
requirements:
|
66
|
-
- - ~>
|
80
|
+
- - "~>"
|
67
81
|
- !ruby/object:Gem::Version
|
68
82
|
version: 3.1.0
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: pry
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
72
86
|
requirements:
|
73
|
-
- -
|
87
|
+
- - ">="
|
74
88
|
- !ruby/object:Gem::Version
|
75
89
|
version: '0'
|
76
90
|
type: :development
|
77
91
|
prerelease: false
|
78
92
|
version_requirements: !ruby/object:Gem::Requirement
|
79
93
|
requirements:
|
80
|
-
- -
|
94
|
+
- - ">="
|
81
95
|
- !ruby/object:Gem::Version
|
82
96
|
version: '0'
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
98
|
name: yard
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
86
100
|
requirements:
|
87
|
-
- - ~>
|
101
|
+
- - "~>"
|
88
102
|
- !ruby/object:Gem::Version
|
89
103
|
version: 0.8.7.4
|
90
104
|
type: :development
|
91
105
|
prerelease: false
|
92
106
|
version_requirements: !ruby/object:Gem::Requirement
|
93
107
|
requirements:
|
94
|
-
- - ~>
|
108
|
+
- - "~>"
|
95
109
|
- !ruby/object:Gem::Version
|
96
110
|
version: 0.8.7.4
|
97
111
|
- !ruby/object:Gem::Dependency
|
98
112
|
name: webmock
|
99
113
|
requirement: !ruby/object:Gem::Requirement
|
100
114
|
requirements:
|
101
|
-
- - ~>
|
115
|
+
- - "~>"
|
102
116
|
- !ruby/object:Gem::Version
|
103
117
|
version: 1.19.0
|
104
118
|
type: :development
|
105
119
|
prerelease: false
|
106
120
|
version_requirements: !ruby/object:Gem::Requirement
|
107
121
|
requirements:
|
108
|
-
- - ~>
|
122
|
+
- - "~>"
|
109
123
|
- !ruby/object:Gem::Version
|
110
124
|
version: 1.19.0
|
111
125
|
- !ruby/object:Gem::Dependency
|
112
|
-
name:
|
126
|
+
name: coveralls
|
113
127
|
requirement: !ruby/object:Gem::Requirement
|
114
128
|
requirements:
|
115
|
-
- -
|
129
|
+
- - ">="
|
116
130
|
- !ruby/object:Gem::Version
|
117
131
|
version: '0'
|
118
132
|
type: :development
|
119
133
|
prerelease: false
|
120
134
|
version_requirements: !ruby/object:Gem::Requirement
|
121
135
|
requirements:
|
122
|
-
- -
|
136
|
+
- - ">="
|
123
137
|
- !ruby/object:Gem::Version
|
124
138
|
version: '0'
|
125
139
|
description: Automatically generate and renew your push notification profiles
|
@@ -134,12 +148,9 @@ files:
|
|
134
148
|
- README.md
|
135
149
|
- bin/pem
|
136
150
|
- lib/pem.rb
|
137
|
-
- lib/pem/cert_manager.rb
|
138
151
|
- lib/pem/dependency_checker.rb
|
139
|
-
- lib/pem/developer_center.rb
|
140
152
|
- lib/pem/manager.rb
|
141
153
|
- lib/pem/options.rb
|
142
|
-
- lib/pem/signing_request.rb
|
143
154
|
- lib/pem/version.rb
|
144
155
|
homepage: https://fastlane.tools
|
145
156
|
licenses:
|
@@ -151,17 +162,17 @@ require_paths:
|
|
151
162
|
- lib
|
152
163
|
required_ruby_version: !ruby/object:Gem::Requirement
|
153
164
|
requirements:
|
154
|
-
- -
|
165
|
+
- - ">="
|
155
166
|
- !ruby/object:Gem::Version
|
156
167
|
version: 2.0.0
|
157
168
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
158
169
|
requirements:
|
159
|
-
- -
|
170
|
+
- - ">="
|
160
171
|
- !ruby/object:Gem::Version
|
161
172
|
version: '0'
|
162
173
|
requirements: []
|
163
174
|
rubyforge_project:
|
164
|
-
rubygems_version: 2.4.
|
175
|
+
rubygems_version: 2.4.8
|
165
176
|
signing_key:
|
166
177
|
specification_version: 4
|
167
178
|
summary: Automatically generate and renew your push notification profiles
|
data/lib/pem/cert_manager.rb
DELETED
@@ -1,54 +0,0 @@
|
|
1
|
-
module PEM
|
2
|
-
class CertManager
|
3
|
-
|
4
|
-
attr_accessor :rsa_file, :cert_file, :pem_file, :certificate_type, :passphrase
|
5
|
-
|
6
|
-
# Download the cert, do all kinds of Keychain related things
|
7
|
-
def run
|
8
|
-
# Keychain (security) documentation: https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/security.1.html
|
9
|
-
# Old project, which might be helpful: https://github.com/jprichardson/keychain_manager
|
10
|
-
|
11
|
-
Helper.log.info "Refreshing push notification profiles for app '#{PEM.config[:app_identifier]}'"
|
12
|
-
|
13
|
-
dev = PEM::DeveloperCenter.new
|
14
|
-
|
15
|
-
self.cert_file = dev.fetch_cer_file
|
16
|
-
if self.cert_file
|
17
|
-
self.rsa_file = File.join(TMP_FOLDER, 'private_key.key')
|
18
|
-
self.certificate_type = (PEM.config[:development] ? 'development' : 'production')
|
19
|
-
self.pem_file = File.join(TMP_FOLDER, "#{certificate_type}_#{PEM.config[:app_identifier]}.pem")
|
20
|
-
self.passphrase = PEM.config[:p12_password] || ''
|
21
|
-
|
22
|
-
File.write(pem_file, pem_certificate)
|
23
|
-
|
24
|
-
# Generate p12 file as well
|
25
|
-
if PEM.config[:generate_p12]
|
26
|
-
output = "#{certificate_type}_#{PEM.config[:app_identifier]}.p12"
|
27
|
-
File.write(output, p12_certificate.to_der)
|
28
|
-
puts output.green
|
29
|
-
end
|
30
|
-
|
31
|
-
return pem_file, rsa_file
|
32
|
-
else
|
33
|
-
return nil, nil
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def private_key
|
38
|
-
OpenSSL::PKey::RSA.new(File.read(rsa_file))
|
39
|
-
end
|
40
|
-
|
41
|
-
def x509_certificate
|
42
|
-
OpenSSL::X509::Certificate.new(File.read(cert_file))
|
43
|
-
end
|
44
|
-
|
45
|
-
def p12_certificate
|
46
|
-
OpenSSL::PKCS12.create(passphrase, certificate_type, private_key, x509_certificate)
|
47
|
-
end
|
48
|
-
|
49
|
-
def pem_certificate
|
50
|
-
x509_certificate.to_pem + private_key.to_pem
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
data/lib/pem/developer_center.rb
DELETED
@@ -1,142 +0,0 @@
|
|
1
|
-
require 'fastlane_core/developer_center/developer_center'
|
2
|
-
|
3
|
-
module PEM
|
4
|
-
class DeveloperCenter < FastlaneCore::DeveloperCenter
|
5
|
-
APP_IDS_URL = "https://developer.apple.com/account/ios/identifiers/bundle/bundleList.action"
|
6
|
-
|
7
|
-
|
8
|
-
# This method will enable push for the given app
|
9
|
-
# and download the cer file in any case, no matter if it existed before or not
|
10
|
-
# @return the path to the push file
|
11
|
-
def fetch_cer_file
|
12
|
-
@app_identifier = PEM.config[:app_identifier]
|
13
|
-
begin
|
14
|
-
open_app_page
|
15
|
-
|
16
|
-
click_on "Edit"
|
17
|
-
wait_for_elements(".item-details") # just to finish loading
|
18
|
-
|
19
|
-
push_value = first(:css, '#pushEnabled').value
|
20
|
-
if push_value == "on"
|
21
|
-
Helper.log.info "Push for app '#{@app_identifier}' is enabled"
|
22
|
-
else
|
23
|
-
Helper.log.warn "Push for app '#{@app_identifier}' is disabled. This has to change."
|
24
|
-
first(:css, '#pushEnabled').click
|
25
|
-
sleep 3 # this takes some time
|
26
|
-
end
|
27
|
-
|
28
|
-
if has_actual_cert and not PEM.config[:force]
|
29
|
-
Helper.log.info "You already have a push certificate, which is active for more than 30 more days. No need to create a new one".green
|
30
|
-
Helper.log.info "If you still want to create a new one, use the --force option when running PEM.".green
|
31
|
-
false
|
32
|
-
else
|
33
|
-
Helper.log.warn "Creating push certificate for app '#{@app_identifier}'."
|
34
|
-
create_push_for_app
|
35
|
-
end
|
36
|
-
rescue => ex
|
37
|
-
error_occured(ex)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def has_actual_cert
|
42
|
-
apps = all(:xpath, "//div[@class = 'certificate']")
|
43
|
-
cert_type = PEM.config[:development] ? 'Development' : 'Production'
|
44
|
-
cert_section = apps.select { |c| c.text.include? cert_type }
|
45
|
-
|
46
|
-
unless cert_section.empty?
|
47
|
-
data_s = cert_section.last.all('dd').last.text
|
48
|
-
data = Date.parse(data_s)
|
49
|
-
data - Time.now.to_date > 30 # valid for more than 30 days (Apple email)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
private
|
54
|
-
def open_app_page
|
55
|
-
begin
|
56
|
-
visit APP_IDS_URL
|
57
|
-
sleep 5
|
58
|
-
|
59
|
-
wait_for_elements(".toolbar-button.search").first.click
|
60
|
-
fill_in "bundle-list-search", with: @app_identifier
|
61
|
-
sleep 5
|
62
|
-
|
63
|
-
apps = all(:xpath, "//td[@title='#{@app_identifier}']")
|
64
|
-
if apps.count == 1
|
65
|
-
apps.first.click
|
66
|
-
sleep 2
|
67
|
-
|
68
|
-
return true
|
69
|
-
else
|
70
|
-
raise DeveloperCenterGeneralError.new("Could not find app with identifier '#{@app_identifier}' on apps page. The identifier is case sensitive.")
|
71
|
-
end
|
72
|
-
rescue => ex
|
73
|
-
error_occured(ex)
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
def create_push_for_app
|
78
|
-
|
79
|
-
element_name = (PEM.config[:development] ? '.button.small.navLink.development.enabled' : '.button.small.navLink.distribution.enabled')
|
80
|
-
begin
|
81
|
-
wait_for_elements(element_name).first.click # Create Certificate button
|
82
|
-
rescue
|
83
|
-
raise "Could not create a new push profile for app '#{@app_identifier}'. There are already 2 certificates active. Please revoke one to let PEM create a new one\n\n#{current_url}".red
|
84
|
-
end
|
85
|
-
|
86
|
-
sleep 2
|
87
|
-
|
88
|
-
click_next # "Continue"
|
89
|
-
|
90
|
-
sleep 1
|
91
|
-
|
92
|
-
wait_for_elements(".file-input.validate")
|
93
|
-
wait_for_elements(".button.small.center.back")
|
94
|
-
|
95
|
-
# Upload CSR file
|
96
|
-
first(:xpath, "//input[@type='file']").set PEM::SigningRequest.get_path
|
97
|
-
|
98
|
-
click_next # "Generate"
|
99
|
-
|
100
|
-
while all(:css, '.loadingMessage').count > 0
|
101
|
-
Helper.log.debug "Waiting for iTC to generate the profile"
|
102
|
-
sleep 2
|
103
|
-
end
|
104
|
-
|
105
|
-
certificate_type = (PEM.config[:development] ? 'development' : 'production')
|
106
|
-
|
107
|
-
# Download the newly created certificate
|
108
|
-
Helper.log.info "Going to download the latest profile"
|
109
|
-
|
110
|
-
# It is enabled, now just download it
|
111
|
-
sleep 2
|
112
|
-
|
113
|
-
download_button = first(".button.small.blue")
|
114
|
-
host = Capybara.current_session.current_host
|
115
|
-
url = download_button['href']
|
116
|
-
url = [host, url].join('')
|
117
|
-
Helper.log.info "Downloading URL: '#{url}'"
|
118
|
-
|
119
|
-
cookie_string = page.driver.cookies.collect { |key, cookie| "#{cookie.name}=#{cookie.value}" }.join(";")
|
120
|
-
|
121
|
-
data = open(url, {'Cookie' => cookie_string}).read
|
122
|
-
|
123
|
-
raise "Something went wrong when downloading the certificate" unless data
|
124
|
-
|
125
|
-
path = "#{TMP_FOLDER}aps_#{certificate_type}_#{@app_identifier}.cer"
|
126
|
-
data_written = File.open(path, "wb") do |f|
|
127
|
-
f.write(data)
|
128
|
-
end
|
129
|
-
|
130
|
-
if data_written == 0
|
131
|
-
raise "Can't write to #{TMP_FOLDER}"
|
132
|
-
end
|
133
|
-
|
134
|
-
Helper.log.info "Successfully downloaded latest .cer file to '#{path}'".green
|
135
|
-
return path
|
136
|
-
end
|
137
|
-
|
138
|
-
def click_next
|
139
|
-
wait_for_elements('.button.small.blue.right.submit').last.click
|
140
|
-
end
|
141
|
-
end
|
142
|
-
end
|
data/lib/pem/signing_request.rb
DELETED
@@ -1,30 +0,0 @@
|
|
1
|
-
require 'openssl'
|
2
|
-
|
3
|
-
module PEM
|
4
|
-
class SigningRequest
|
5
|
-
def self.get_path
|
6
|
-
self.generate
|
7
|
-
end
|
8
|
-
|
9
|
-
def self.generate
|
10
|
-
Helper.log.info "Creating a signing certificate for you.".green
|
11
|
-
@key = OpenSSL::PKey::RSA.new 2048
|
12
|
-
|
13
|
-
# Generate CSR
|
14
|
-
csr = OpenSSL::X509::Request.new
|
15
|
-
csr.version = 0
|
16
|
-
csr.subject = OpenSSL::X509::Name.new([
|
17
|
-
['CN', "PEM", OpenSSL::ASN1::UTF8STRING]
|
18
|
-
])
|
19
|
-
csr.public_key = @key.public_key
|
20
|
-
csr.sign @key, OpenSSL::Digest::SHA1.new
|
21
|
-
|
22
|
-
path = File.join(TMP_FOLDER, 'PEMCertificateSigningRequest.certSigningRequest')
|
23
|
-
File.write(path, csr.to_pem)
|
24
|
-
File.write(File.join(TMP_FOLDER, 'private_key.key'), @key)
|
25
|
-
|
26
|
-
Helper.log.info "Successfully generated .certSigningRequest at path '#{path}'"
|
27
|
-
return path
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|