asca 0.1.0 → 1.0.2

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.
@@ -0,0 +1,102 @@
1
+ require 'json'
2
+ require 'jwt'
3
+
4
+ module Asca
5
+ module Tools
6
+ class Token
7
+ EXPIRE_DURATION = 20 * 60
8
+ class << self
9
+ # Generate new jwt token.
10
+ def new_token
11
+ # get token from cache
12
+ token = get_token_from_cache
13
+ if token
14
+ return token
15
+ end
16
+
17
+ # get kid
18
+ kid = Asca::Tools::Configuration.get_config('kid')
19
+ if !kid
20
+ Asca::Tools::Log.info "Before generating a jwt token, please enter your kid:"
21
+ kid = gets.chomp
22
+ Asca::Tools::Configuration.update_config('kid', kid)
23
+ end
24
+ if !kid
25
+ Asca::Tools::Log.error "Error: no kid!"
26
+ return
27
+ end
28
+
29
+ # get issuer id
30
+ iss = Asca::Tools::Configuration.get_config('iss')
31
+ if !iss
32
+ Asca::Tools::Log.info "Before generating a jwt token, please enter your issuer id:"
33
+ iss = gets.chomp
34
+ Asca::Tools::Configuration.update_config('iss', iss)
35
+ end
36
+ if !iss
37
+ Asca::Tools::Log.error "Error: no issuer id!"
38
+ return
39
+ end
40
+
41
+ # get private key
42
+ private_key = Asca::Tools::Configuration.get_config('private_key')
43
+ if !private_key
44
+ Asca::Tools::Log.info "Before generating a jwt token, please enter your private key path:"
45
+ private_key_path = gets.chomp
46
+ private_key = File.read private_key_path
47
+ Asca::Tools::Configuration.update_config('private_key', private_key)
48
+ end
49
+ if !private_key
50
+ Asca::Tools::Log.error "Error: no private key!"
51
+ return
52
+ end
53
+
54
+ # generate jwt header
55
+ jwt_header = {
56
+ "alg": "ES256",
57
+ "kid": kid,
58
+ "typ": "JWT"
59
+ }
60
+
61
+ # generate jwt payload
62
+ exp = Time.now.to_i + EXPIRE_DURATION
63
+ jwt_payload = {
64
+ "iss": iss,
65
+ "exp": exp,
66
+ "aud": "appstoreconnect-v1"
67
+ }
68
+
69
+ begin
70
+ es_key = OpenSSL::PKey::EC.new private_key
71
+ rescue => exception
72
+ Asca::Tools::Log.info "Invalid private key, please enter your correct private key path:"
73
+ private_key_path = gets.chomp
74
+ private_key = File.read private_key_path
75
+ Asca::Tools::Configuration.update_config('private_key', private_key)
76
+ es_key = OpenSSL::PKey::EC.new private_key
77
+ end
78
+
79
+ token = JWT.encode jwt_payload, es_key, 'ES256', jwt_header
80
+ Asca::Tools::Configuration.update_config('cache_token_time', exp)
81
+ Asca::Tools::Configuration.update_config('cache_token', token)
82
+ Asca::Tools::Log.info "==== New token generated ===="
83
+ Asca::Tools::Log.info token
84
+ Asca::Tools::Log.info "============================="
85
+ return token
86
+ end
87
+
88
+ def get_token_from_cache
89
+ token_valid_max_time = Asca::Tools::Configuration.get_config('cache_token_time')
90
+ if !token_valid_max_time
91
+ return nil
92
+ end
93
+ current = Time.now.to_i
94
+ if token_valid_max_time > current
95
+ return Asca::Tools::Configuration.get_config('cache_token')
96
+ end
97
+ return nil
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,22 @@
1
+ require 'http'
2
+ require "json"
3
+
4
+ module Asca
5
+ module Tools
6
+ # register a new device and update corresponding profiles
7
+ def self.register_device(options = {})
8
+ device_info = options[:device_info]
9
+ profile_names = options[:profile_names]
10
+ if !device_info || !profile_names
11
+ Asca::Tools::Log.error('Wrong parameters for register device')
12
+ return
13
+ end
14
+
15
+ Asca::REST::Provisioning::Devices.register_new_device :udid => device_info[:udid], :name => device_info[:name]
16
+
17
+ profile_names.each { |profile_name|
18
+ Asca::REST::Provisioning::Profiles.update_profile :name => profile_name
19
+ }
20
+ end
21
+ end
22
+ end
@@ -1,3 +1,3 @@
1
1
  module Asca
2
- VERSION = "0.1.0"
2
+ VERSION = "1.0.2"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: asca
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - xueminghao
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-08-18 00:00:00.000000000 Z
11
+ date: 2020-09-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -67,7 +67,7 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: curb
70
+ name: http
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ">="
@@ -111,15 +111,21 @@ files:
111
111
  - LICENSE.txt
112
112
  - README.md
113
113
  - Rakefile
114
+ - app-store-connect-openapi-spec.json
114
115
  - asca.gemspec
115
116
  - bin/console
116
117
  - bin/setup
117
118
  - exe/asca
118
119
  - lib/asca.rb
119
- - lib/asca/configuration.rb
120
120
  - lib/asca/consts.rb
121
- - lib/asca/profiles.rb
122
- - lib/asca/token.rb
121
+ - lib/asca/rest/provisioning/bundleids.rb
122
+ - lib/asca/rest/provisioning/certificates.rb
123
+ - lib/asca/rest/provisioning/devices.rb
124
+ - lib/asca/rest/provisioning/profiles.rb
125
+ - lib/asca/tools/configuration.rb
126
+ - lib/asca/tools/log.rb
127
+ - lib/asca/tools/token.rb
128
+ - lib/asca/tools/tools.rb
123
129
  - lib/asca/version.rb
124
130
  homepage: https://github.com/xueminghao/appstoreconnectapi
125
131
  licenses:
@@ -1,55 +0,0 @@
1
- require 'json'
2
- require 'fileutils'
3
-
4
- module Asca
5
- class Configuration
6
- ROOTDIR = File.expand_path '~/.com.hurryup.asca'
7
- JSONFILE = File.expand_path 'config.json', ROOTDIR
8
- CACHE_DIR = File.expand_path 'cache', ROOTDIR
9
- class << self
10
- # reset config file
11
- def reset_config
12
- # remove all
13
- FileUtils.rm_rf(ROOTDIR)
14
-
15
- # create root dir
16
- Dir.mkdir ROOTDIR
17
-
18
- # create cache dir
19
- Dir.mkdir CACHE_DIR
20
-
21
- # init config file
22
- File.open(JSONFILE, 'w') { |file|
23
- file.write("{}")
24
- }
25
- end
26
-
27
- # update config
28
- def update_config(key, value)
29
- if !File.exist?(JSONFILE)
30
- reset_config
31
- end
32
- file_content = File.read(JSONFILE)
33
- configuration = JSON.parse(file_content)
34
- if value
35
- configuration[key] = value
36
- else
37
- configuration.delete(key)
38
- end
39
- File.open(JSONFILE, 'w') { |file|
40
- file.write(JSON.pretty_generate(configuration))
41
- }
42
- return 0
43
- end
44
-
45
- def get_config(key)
46
- if !File.exist?(JSONFILE)
47
- reset_config
48
- end
49
- file_content = File.read(JSONFILE)
50
- configuration = JSON.parse(file_content)
51
- return configuration[key]
52
- end
53
- end
54
- end
55
- end
@@ -1,36 +0,0 @@
1
- require 'curb'
2
- require 'json'
3
- require "base64"
4
-
5
- module Asca
6
- class Profiles
7
- class << self
8
- def download_profile(profile_name, out_put_dir = nil)
9
- if !out_put_dir
10
- out_put_dir = Asca::Configuration.get_config('out_put_dir')
11
- if !out_put_dir
12
- puts "Please enter your out put dir:"
13
- out_put_dir = File.expand_path(gets.chomp)
14
- Asca::Configuration.update_config('out_put_dir', out_put_dir)
15
- end
16
- end
17
- http = Curl.get(URI_PROFILES, { 'filter[name]' => profile_name}) do |http|
18
- http.headers['Authorization'] = ' Bearer ' + Asca::Token.new_token
19
- end
20
- profile_obj = JSON.parse(http.body_str)
21
- profile_content = profile_obj["data"][0]["attributes"]['profileContent']
22
- File.open(File.expand_path(profile_name + ".mobileprovision", out_put_dir), 'w') do |file|
23
- file.write(Base64.decode64(profile_content))
24
- end
25
- end
26
-
27
- def install_profile(profile_name)
28
- download_profile profile_name, Asca::Configuration::CACHE_DIR
29
- profile_file_path = File.expand_path(profile_name + ".mobileprovision", Asca::Configuration::CACHE_DIR)
30
-
31
- # install profile
32
- `open #{profile_file_path}`
33
- end
34
- end
35
- end
36
- end
@@ -1,92 +0,0 @@
1
- require 'json'
2
- require 'jwt'
3
-
4
- module Asca
5
- class Token
6
- EXPIRE_DURATION = 20 * 60
7
- class << self
8
- # Generate new jwt token.
9
- def new_token
10
- # get token from cache
11
- token = get_token_from_cache
12
- if token
13
- return token
14
- end
15
-
16
- # get kid
17
- kid = Asca::Configuration.get_config('kid')
18
- if !kid
19
- puts "Before generating a jwt token, please enter your kid:"
20
- kid = gets.chomp
21
- Asca::Configuration.update_config('kid', kid)
22
- end
23
- if !kid
24
- puts "Error: no kid!"
25
- return
26
- end
27
-
28
- # get issuer id
29
- iss = Asca::Configuration.get_config('iss')
30
- if !iss
31
- puts "Before generating a jwt token, please enter your issuer id:"
32
- iss = gets.chomp
33
- Asca::Configuration.update_config('iss', iss)
34
- end
35
- if !iss
36
- puts "Error: no issuer id!"
37
- return
38
- end
39
-
40
- # get private key
41
- private_key = Asca::Configuration.get_config('private_key')
42
- if !private_key
43
- puts "Before generating a jwt token, please enter your private key path:"
44
- private_key_path = gets.chomp
45
- private_key = File.read private_key_path
46
- Asca::Configuration.update_config('private_key', private_key)
47
- end
48
- if !private_key
49
- puts "Error: no private key!"
50
- return
51
- end
52
-
53
- # generate jwt header
54
- jwt_header = {
55
- "alg": "ES256",
56
- "kid": kid,
57
- "typ": "JWT"
58
- }
59
-
60
- # generate jwt payload
61
- exp = Time.now.to_i + EXPIRE_DURATION
62
- jwt_payload = {
63
- "iss": iss,
64
- "exp": exp,
65
- "aud": "appstoreconnect-v1"
66
- }
67
-
68
- es_key = OpenSSL::PKey::EC.new private_key
69
-
70
- token = JWT.encode jwt_payload, es_key, 'ES256', jwt_header
71
- Asca::Configuration.update_config('cache_token_time', exp)
72
- Asca::Configuration.update_config('cache_token', token)
73
- puts "==== New token generated ===="
74
- puts token
75
- puts "============================="
76
- return token
77
- end
78
-
79
- def get_token_from_cache
80
- cached_token_time = Asca::Configuration.get_config('cache_token_time')
81
- if !cached_token_time
82
- return nil
83
- end
84
- current = Time.now.to_i
85
- if cached_token_time - current > EXPIRE_DURATION
86
- return nil
87
- end
88
- return Asca::Configuration.get_config('cache_token')
89
- end
90
- end
91
- end
92
- end