magellan-cli 0.5.9 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4b5b5f0a5bc12049990a5c842393ce408aff9a34
4
- data.tar.gz: f4ce5c56d45a6b7fb2b17cc2620e512312a6d0ed
3
+ metadata.gz: 7db0837835cc09a010e80b50ed05ef816eac9c2d
4
+ data.tar.gz: 5eaf1c7d35daeedab002dd47d6dc1f6298846550
5
5
  SHA512:
6
- metadata.gz: 3f98e6f3f10adb66443ea4ebeaadd4ed16e45b4f875ad1dc23364bd3ed2ae6936c696cca338411ce1cc00f1ede15d7658e63d81dae79a625ac4e4484f251e90d
7
- data.tar.gz: ac3fc0570bb6e17f6c5d5efe7ae0ae09a060ba302c7b92f74b8ba8f7a769072490ec633cf0a94af332aa05c171e6589df982326645896c7ce65577b3d105c774
6
+ metadata.gz: 75ca604ec8f59c335e9eb4fe75e1ee9fff085dcb5212f7c86d47ea16a2efa7a51a2346b22d5738df7b15739a411218772658dffbb8ae6f18a755d0ed1094875e
7
+ data.tar.gz: d60150518e847386d483cd410d06bc8f02c340ffdbe43a34e51574f8023374e9b2d09c2881607be1242018cbddb6a80c5ebe36d14b0b9d32c56317a06db8367f
data/.rspec CHANGED
@@ -1,2 +1,2 @@
1
- --format documentation
1
+ --format Fuubar
2
2
  --color
data/Gemfile CHANGED
@@ -8,4 +8,5 @@ group :development do
8
8
  gem "pry-byebug"
9
9
  gem "pry-stack_explorer"
10
10
  gem "simplecov"
11
+ gem "fuubar"
11
12
  end
data/Gemfile.lock CHANGED
@@ -1,12 +1,12 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- magellan-cli (0.5.9)
4
+ magellan-cli (0.6.0)
5
5
  activesupport (~> 4.1.4)
6
6
  groovenauts-thor
7
7
  httpclient (~> 2.5)
8
8
  i18n
9
- libmagellan (~> 0.2.2)
9
+ libmagellan (~> 0.2.4)
10
10
  nokogiri
11
11
  psych (>= 2.0.0, <= 2.0.8)
12
12
  text-table (~> 1.2.3)
@@ -20,7 +20,7 @@ GEM
20
20
  minitest (~> 5.1)
21
21
  thread_safe (~> 0.1)
22
22
  tzinfo (~> 1.1)
23
- addressable (2.3.6)
23
+ addressable (2.3.7)
24
24
  binding_of_caller (0.7.2)
25
25
  debug_inspector (>= 0.0.1)
26
26
  byebug (2.7.0)
@@ -34,12 +34,15 @@ GEM
34
34
  docile (1.1.5)
35
35
  faraday (0.9.1)
36
36
  multipart-post (>= 1.2, < 3)
37
+ fuubar (2.0.0)
38
+ rspec (~> 3.0)
39
+ ruby-progressbar (~> 1.4)
37
40
  groovenauts-thor (0.19.1.1)
38
41
  httpclient (2.6.0.1)
39
42
  i18n (0.7.0)
40
43
  json (1.8.2)
41
44
  jwt (1.2.1)
42
- libmagellan (0.2.3)
45
+ libmagellan (0.2.4)
43
46
  activesupport
44
47
  mqtt (~> 0.3.1)
45
48
  signet (~> 0.5.0)
@@ -75,6 +78,7 @@ GEM
75
78
  rspec-mocks (3.0.4)
76
79
  rspec-support (~> 3.0.0)
77
80
  rspec-support (3.0.4)
81
+ ruby-progressbar (1.7.1)
78
82
  signet (0.5.1)
79
83
  addressable (>= 2.2.3)
80
84
  faraday (>= 0.9.0.rc5)
@@ -96,6 +100,7 @@ PLATFORMS
96
100
 
97
101
  DEPENDENCIES
98
102
  bundler (~> 1.6)
103
+ fuubar
99
104
  magellan-cli!
100
105
  pry
101
106
  pry-byebug
data/lib/magellan/cli.rb CHANGED
@@ -6,11 +6,10 @@ module Magellan
6
6
  autoload :Command , "magellan/cli/command"
7
7
 
8
8
  autoload :Base , "magellan/cli/base"
9
- autoload :Http , "magellan/cli/http"
10
9
  autoload :Direct , "magellan/cli/direct"
11
10
  autoload :Resources, "magellan/cli/resources"
12
11
 
13
- autoload :Login , "magellan/cli/login"
12
+ autoload :Http , "magellan/cli/http"
14
13
  autoload :Ssl , "magellan/cli/ssl"
15
14
 
16
15
  autoload :Messaging, "magellan/cli/messaging"
@@ -1,3 +1,4 @@
1
+ # coding: utf-8
1
2
  require "magellan/cli"
2
3
 
3
4
  require 'thor'
@@ -36,6 +37,9 @@ module Magellan
36
37
  def log_info(msg)
37
38
  self.class.log_info(msg)
38
39
  end
40
+ def log_warning(msg)
41
+ self.class.log_warning(msg)
42
+ end
39
43
  def log_success(msg)
40
44
  self.class.log_success(msg)
41
45
  end
@@ -53,8 +57,104 @@ module Magellan
53
57
  log_verbose(" " << e.backtrace.join("\n "))
54
58
  exit(1)
55
59
  end
60
+
61
+ def http_conn
62
+ @http_conn ||= Cli::Http.new(self)
63
+ end
64
+
65
+ def login!(email, password)
66
+ logined = http_conn.api_login!(email, password)
67
+ if logined
68
+ log_success I18n.t(:success, scope: [:http, :login])
69
+ else
70
+ log_error I18n.t(:error, scope: [:http, :login])
71
+ exit(1)
72
+ end
73
+ end
74
+
75
+ def login_by_token!(email, token)
76
+ logined = http_conn.api_login_by_token!(email, token)
77
+ if logined
78
+ log_success I18n.t(:success, scope: [:http, :token])
79
+ else
80
+ log_error I18n.t(:error, scope: [:http, :token])
81
+ exit(1)
82
+ end
83
+ end
84
+
85
+ def http_access
86
+ if block_given?
87
+ http_conn.check_login_auth!
88
+ return yield(http_conn)
89
+ else
90
+ return log_success(I18n.t(:ok, scope: [:http, :access_api]))
91
+ end
92
+ end
93
+
94
+
95
+ # ログインしてGETします
96
+ # @param [String] rel_path http.base_url からの相対パス
97
+ # @param [Hash] params クエリ文字列
98
+ # @return [Object] レスポンスのBODYをJSONとしてパースした結果オブジェクト
99
+ def get_json(rel_path, params = {})
100
+ http_access do |api|
101
+ api.get_json(rel_path, params = {})
102
+ end
103
+ end
104
+
105
+ # ログインしてPOSTします
106
+ # @param [String] rel_path http.base_url からの相対パス
107
+ # @param [Hash] params POSTで渡されるパラメータ
108
+ # @return nil
109
+ def post(rel_path, params)
110
+ http_access do |api|
111
+ api.post(rel_path, params)
112
+ end
113
+ end
114
+
115
+ # ログインしてJSON形式のbodyをPOSTします
116
+ # @param [String] rel_path http.base_url からの相対パス
117
+ # @param [Hash] params POSTで渡されるパラメータ
118
+ # @return nil
119
+ def post_json(rel_path, params)
120
+ http_access do |api|
121
+ api.post_json(rel_path, params)
122
+ end
123
+ end
124
+
125
+ # ログインしてPUTします
126
+ # @param [String] rel_path http.base_url からの相対パス
127
+ # @param [Hash] params PUTで渡されるパラメータ
128
+ # @return nil
129
+ def put(rel_path, params)
130
+ http_access do |api|
131
+ api.put(rel_path, params)
132
+ end
133
+ end
134
+
135
+ # ログインしてJSON形式のbodyをPUTします
136
+ # @param [String] rel_path http.base_url からの相対パス
137
+ # @param [Hash] params PUTで渡されるパラメータ
138
+ # @return nil
139
+ def put_json(rel_path, params)
140
+ http_access do |api|
141
+ api.put_json(rel_path, params)
142
+ end
143
+ end
144
+
145
+ # ログインしてDELETEします
146
+ # @param [String] rel_path http.base_url からの相対パス
147
+ # @return nil
148
+ def delete(rel_path)
149
+ http_access do |api|
150
+ api.delete(rel_path)
151
+ end
152
+ end
153
+
56
154
  end
57
155
 
156
+
157
+
58
158
  class << self
59
159
  def puts_with_color(color_no, msg)
60
160
  $stderr.puts("\e[#{color_no}m#{msg}\e[0m")
@@ -66,6 +166,9 @@ module Magellan
66
166
  def log_info(msg)
67
167
  puts_with_color(0, msg)
68
168
  end
169
+ def log_warning(msg)
170
+ puts_with_color(33, msg)
171
+ end
69
172
  def log_success(msg)
70
173
  puts_with_color(32, msg)
71
174
  end
@@ -160,4 +263,3 @@ module Magellan
160
263
  end
161
264
  end
162
265
  end
163
-
@@ -69,29 +69,45 @@ module Magellan
69
69
  desc "login", I18n.t(:login, scope: [:command, :cmd])
70
70
  method_option :email, aliases: "-e", desc: I18n.t(:email, scope: [:command, :cmd_login])
71
71
  method_option :password, aliases: "-p", desc: I18n.t(:password, scope: [:command, :cmd_login])
72
+ method_option :authentication_token, aliases: "-t", desc: I18n.t(:authentication_token, scope: [:command, :cmd_login])
72
73
  def login
73
74
  unless email = options[:email]
74
75
  print "email: "
75
76
  email = STDIN.gets.strip
76
77
  end
77
78
 
78
- unless password = options[:password]
79
+ password = options[:password]
80
+ token = options[:authentication_token]
81
+
82
+ if password.blank? && token.blank?
83
+ log_warning I18n.t(:warning, scope: :login)
79
84
  print "password: "
80
85
  password = STDIN.noecho(&:gets).chomp
81
86
  puts ""
82
87
  end
83
88
 
84
- result = Magellan::Cli::Http.new.login!(email, password)
89
+ if password.blank? && token.blank?
90
+ print "authentication_token: "
91
+ token = STDIN.noecho(&:gets).chomp
92
+ puts ""
93
+ end
94
+
95
+ result =
96
+ if password.present?
97
+ login!(email, password)
98
+ else
99
+ login_by_token!(email, token)
100
+ end
101
+
85
102
  select_single_resources
86
103
  result
87
104
  end
88
105
 
89
106
  desc "info", I18n.t(:info, scope: [:command, :cmd])
90
107
  def info
91
- cli = Magellan::Cli::Login.new
92
- cli.check_login_auth!
108
+ http_conn.check_login_auth!
93
109
  selections = load_selections || {}
94
- d = {"user" => cli.login_auth["email"] }
110
+ d = {"user" => http_conn.login_auth["email"] }
95
111
  Resources::MAPPING.each do |classname, name|
96
112
  klass = ::Magellan::Cli::Resources.const_get(classname)
97
113
  attr = klass.caption_attr
@@ -3,7 +3,7 @@ require "magellan/cli"
3
3
 
4
4
  module Magellan
5
5
  module Cli
6
- class Direct < ::Magellan::Cli::Http
6
+ class Direct < ::Magellan::Cli::Base
7
7
 
8
8
  desc "get PATH", "Send GET request with PATH"
9
9
  def get(path)
@@ -29,4 +29,3 @@ module Magellan
29
29
  end
30
30
  end
31
31
  end
32
-
@@ -1,149 +1,257 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  require "magellan/cli"
3
3
 
4
+ require 'httpclient'
5
+ require 'json'
6
+ require 'uri'
7
+ require 'nokogiri'
8
+
9
+ require 'active_support/core_ext/hash/keys'
10
+
4
11
  module Magellan
5
12
  module Cli
6
- class Http < ::Magellan::Cli::Base
13
+ class Http
14
+ include Magellan::Cli::FileAccess
7
15
 
8
- no_commands do
16
+ DEFAULT_HTTP_PORT = (ENV['DEFAULT_HTTP_PORT' ] || 80).to_i
17
+ DEFAULT_HTTPS_PORT = (ENV['DEFAULT_HTTPS_PORT'] || 443).to_i
9
18
 
10
- def cli
11
- @cli ||= Cli::Login.new
12
- end
19
+ attr_reader :cmd
20
+ attr_reader :httpclient
21
+ attr_reader :base_url
13
22
 
14
- def login!(email, password)
15
- logined = cli.api_login!(email, password)
16
- if logined
17
- log_success I18n.t(:success, scope: [:http, :login])
18
- else
19
- log_error I18n.t(:error, scope: [:http, :login])
20
- exit(1)
21
- end
22
- end
23
+ attr_reader :auth_token
24
+ attr_reader :login_auth
25
+
26
+ def self.base_url
27
+ @base_url ||= (ENV["MAGELLAN_SITE"] || "https://api-asia.magellanic-clouds.com")
28
+ end
23
29
 
24
- def access_api
25
- if block_given?
26
- cli.check_login_auth!
27
- return yield(cli)
30
+ # Magellan::Cli::Httpのコンストラクタです。
31
+ #
32
+ # @param [String] base_url_or_host 接続先の基準となるURLあるいはホスト名
33
+ # @param [Hash] options オプション
34
+ # @option options [String] :api_version APIのバージョン。デフォルトは "1.0.0"
35
+ def initialize(cmd)
36
+ @cmd = cmd
37
+ base_url_or_host = self.class.base_url
38
+ if base_url_or_host =~ URI.regexp
39
+ @base_url = base_url_or_host.sub(/\/\Z/, '')
40
+ uri = URI.parse(@base_url)
41
+ else
42
+ if config_path = search_file(".magellan-cli.yml")
43
+ config = YAML.load_file_with_erb(config_path)
44
+ options = config[base_url_or_host.to_s].deep_symbolize_keys
28
45
  else
29
- return log_success(I18n.t(:ok, scope: [:http, :access_api]))
46
+ options = {}
30
47
  end
48
+ uri = URI::Generic.build({scheme: "http", host: base_url_or_host, port: DEFAULT_HTTP_PORT}.update(options))
49
+ @base_url = uri.to_s
31
50
  end
32
51
 
33
- def check_response(res)
34
- case res.status
35
- when 200...400 then
36
- begin
37
- r = JSON.parse(res.body)
38
- rescue
39
- # DELETE で 302 Found を返す時に HTML がレンダリングされることがあるので
40
- # status code 300 台では JSON パースエラーを無視する
41
- if res.status >= 300
42
- return nil
43
- end
44
- raise
45
- end
46
- log_verbose(JSON.pretty_generate(r))
47
- r
48
- else
49
- obj = JSON.parse(res.body) rescue nil
50
- if obj and obj.is_a?(Hash) and obj["message"]
51
- fatal(obj["message"])
52
- else
53
- msg = "HTTP Error: status=#{res.status}\n#{res.body}"
54
- log_verbose(msg)
55
- end
56
- end
52
+ @httpclient = HTTPClient.new
53
+ @httpclient.debug_dev = ColorDebugDev.new($stderr) if cmd.verbose?
54
+ @httpclient.ssl_config.verify_mode = nil # 自己署名の証明書をOKにする
55
+ @login_auth = load_selections["login"]
56
+ end
57
+
58
+ class ColorDebugDev
59
+ def initialize(dev)
60
+ @dev = dev
61
+ end
62
+ def <<(msg)
63
+ @dev << "\e[34m#{msg}\e[0m"
57
64
  end
65
+ end
58
66
 
59
- # ログインしてGETします
60
- # @param [String] rel_path cli.base_url からの相対パス
61
- # @param [Hash] params クエリ文字列
62
- # @return [Object] レスポンスのBODYをJSONとしてパースした結果オブジェクト
63
- def get_json(rel_path, params = {})
64
- access_api do |api|
65
- url = "#{api.base_url}#{rel_path}"
66
- params.update(yield) if block_given?
67
- params = api.login_auth.merge(params)
68
- if params && !params.empty?
69
- url << '?' << params.map{|k,v| "%s=%s" % [CGI.escape(k.to_s), CGI.escape(v.to_s)] }.join("&")
70
- end
71
- log_verbose("GET #{url}")
72
- # "Unknown key: max-age = 0" というメッセージを表示させないために$stderrを一時的に上書き
73
- $stderr, bak = StringIO.new, $stderr
74
- res = nil
75
- begin
76
- res = api.httpclient.get(url)
77
- ensure
78
- $stderr = bak
79
- end
80
- check_response(res)
81
- end
67
+ def login_form_url
68
+ @login_form_url ||= base_url + "/users/sign_in.html"
69
+ end
70
+ def login_url
71
+ @login_url ||= base_url + "/api/sign_in.json"
72
+ end
73
+
74
+ def check_login_auth!
75
+ auth = login_auth
76
+ if auth.nil? || auth.empty?
77
+ raise Magellan::Cli::Error, I18n.t(:not_logged_in, scope: [:login, :check_login_auth], command: File.basename($0))
82
78
  end
79
+ end
83
80
 
84
- # ログインしてPOSTします
85
- # @param [String] rel_path cli.base_url からの相対パス
86
- # @param [Hash] params POSTで渡されるパラメータ
87
- # @return nil
88
- def post(rel_path, params)
89
- access_api do |api|
90
- params = api.login_auth.update(params || {})
91
- process_res(api, :post, rel_path, params)
92
- end
81
+ # magellan-apiサーバに接続してログインの検証とアクセストークンの保存を行います。
82
+ #
83
+ # @return [boolean] login成功/失敗
84
+ def api_login!(email, password)
85
+ @auth_token ||= get_auth_token
86
+ params = {
87
+ "user" => {
88
+ "email" => email,
89
+ "password" => password
90
+ },
91
+ "authenticity_token" => @auth_token
92
+ }.to_json
93
+ res2 = Ssl.retry_on_ssl_error("login"){ @httpclient.post(login_url, params, JSON_HEADER) }
94
+
95
+ case res2.status
96
+ when 200...300 then logined = true
97
+ else logined = false
93
98
  end
94
99
 
95
- # ログインしてJSON形式のbodyをPOSTします
96
- # @param [String] rel_path cli.base_url からの相対パス
97
- # @param [Hash] params POSTで渡されるパラメータ
98
- # @return nil
99
- def post_json(rel_path, params)
100
- access_api do |api|
101
- params = api.login_auth.update(params || {})
102
- process_res(api, :post, rel_path, params.to_json, JSON_HEADER)
103
- end
100
+ if logined
101
+ body = JSON.parse res2.body
102
+ write_login_info!(email, body["token"])
103
+ else
104
+ reset_login_info!
104
105
  end
106
+ logined
107
+ end
105
108
 
106
- # ログインしてPUTします
107
- # @param [String] rel_path cli.base_url からの相対パス
108
- # @param [Hash] params PUTで渡されるパラメータ
109
- # @return nil
110
- def put(rel_path, params)
111
- access_api do |api|
112
- params = api.login_auth.update(params || {})
113
- process_res(api, :put, rel_path, params)
109
+ def api_login_by_token!(email, token)
110
+ url = "#{base_url}/admin/magellan~auth~organization.json"
111
+ params = {"email" => email, "token" => token}
112
+ res = httpclient.get(url, params)
113
+
114
+ logined =
115
+ case res.status
116
+ when 200...400 then true
117
+ else false
114
118
  end
119
+
120
+ if logined
121
+ write_login_info!(email, token)
122
+ else
123
+ reset_login_info!
115
124
  end
125
+ logined
126
+ end
116
127
 
117
- # ログインしてJSON形式のbodyをPUTします
118
- # @param [String] rel_path cli.base_url からの相対パス
119
- # @param [Hash] params PUTで渡されるパラメータ
120
- # @return nil
121
- def put_json(rel_path, params)
122
- access_api do |api|
123
- params = api.login_auth.update(params || {})
124
- process_res(api, :put, rel_path, params.to_json, JSON_HEADER)
125
- end
128
+
129
+ def write_login_info!(email, token)
130
+ update_selections("login" => {"email" => email, "token" => token })
131
+ end
132
+
133
+ def reset_login_info!
134
+ update_selections("login" => nil)
135
+ end
136
+
137
+ def get_auth_token
138
+ res = Ssl.retry_on_ssl_error("login_form"){ @httpclient.get(login_form_url) }
139
+ doc = Nokogiri::HTML.parse(res.body, login_form_url, res.body_encoding.to_s)
140
+ node = doc.xpath('//input[@name="authenticity_token"]').first
141
+ unless node
142
+ raise Cli::Error.new("fail to login Magellan")
126
143
  end
144
+ node.attribute('value').value
145
+ end
127
146
 
128
- # ログインしてDELETEします
129
- # @param [String] rel_path cli.base_url からの相対パス
130
- # @return nil
131
- def delete(rel_path)
132
- access_api do |api|
133
- params = api.login_auth
134
- process_res(api, :delete, rel_path, params.to_json, JSON_HEADER)
147
+ # @httpclient.inspectの戻り値の文字列が巨大なので、inspectで出力しないようにします。
148
+ def inspect
149
+ r = "#<#{self.class.name}:#{self.object_id} "
150
+ fields = (instance_variables - [:@httpclient]).map{|f| "#{f}=#{instance_variable_get(f).inspect}"}
151
+ r << fields.join(", ") << ">"
152
+ end
153
+
154
+ def search_file(basename)
155
+ dirs = [".", "./config", ENV['HOME']].join(",")
156
+ Dir["{#{dirs}}/#{basename}"].select{|path| File.readable?(path)}.first
157
+ end
158
+ private :search_file
159
+
160
+
161
+ def check_response(res)
162
+ case res.status
163
+ when 200...400 then
164
+ begin
165
+ r = JSON.parse(res.body)
166
+ rescue
167
+ # DELETE で 302 Found を返す時に HTML がレンダリングされることがあるので
168
+ # status code 300 台では JSON パースエラーを無視する
169
+ if res.status >= 300
170
+ return nil
171
+ end
172
+ raise
173
+ end
174
+ r
175
+ else
176
+ obj = JSON.parse(res.body) rescue nil
177
+ if obj and obj.is_a?(Hash) and obj["message"]
178
+ fatal(obj["message"])
135
179
  end
136
180
  end
181
+ end
137
182
 
138
- def process_res(api, http_method, rel_path, *args)
139
- url = "#{api.base_url}#{rel_path}"
140
- log_verbose("%s %s\n%s" % [http_method.to_s.upcase, url, args])
141
- res = api.httpclient.send(http_method, url, *args)
142
- check_response(res)
183
+ # ログインしてGETします
184
+ # @param [String] rel_path cli.base_url からの相対パス
185
+ # @param [Hash] params クエリ文字列
186
+ # @return [Object] レスポンスのBODYをJSONとしてパースした結果オブジェクト
187
+ def get_json(rel_path, params = {})
188
+ url = "#{base_url}#{rel_path}"
189
+ params.update(yield) if block_given?
190
+ params = login_auth.merge(params)
191
+ if params && !params.empty?
192
+ url << '?' << params.map{|k,v| "%s=%s" % [CGI.escape(k.to_s), CGI.escape(v.to_s)] }.join("&")
193
+ end
194
+ # "Unknown key: max-age = 0" というメッセージを表示させないために$stderrを一時的に上書き
195
+ $stderr, bak = StringIO.new, $stderr
196
+ res = nil
197
+ begin
198
+ res = httpclient.get(url)
199
+ ensure
200
+ $stderr = bak
143
201
  end
202
+ check_response(res)
203
+ end
204
+
205
+ # ログインしてPOSTします
206
+ # @param [String] rel_path cli.base_url からの相対パス
207
+ # @param [Hash] params POSTで渡されるパラメータ
208
+ # @return nil
209
+ def post(rel_path, params)
210
+ params = login_auth.update(params || {})
211
+ process_res(:post, rel_path, params)
212
+ end
213
+
214
+ # ログインしてJSON形式のbodyをPOSTします
215
+ # @param [String] rel_path cli.base_url からの相対パス
216
+ # @param [Hash] params POSTで渡されるパラメータ
217
+ # @return nil
218
+ def post_json(rel_path, params)
219
+ params = login_auth.update(params || {})
220
+ process_res(:post, rel_path, params.to_json, JSON_HEADER)
221
+ end
144
222
 
223
+ # ログインしてPUTします
224
+ # @param [String] rel_path cli.base_url からの相対パス
225
+ # @param [Hash] params PUTで渡されるパラメータ
226
+ # @return nil
227
+ def put(rel_path, params)
228
+ params = login_auth.update(params || {})
229
+ process_res(:put, rel_path, params)
145
230
  end
231
+
232
+ # ログインしてJSON形式のbodyをPUTします
233
+ # @param [String] rel_path cli.base_url からの相対パス
234
+ # @param [Hash] params PUTで渡されるパラメータ
235
+ # @return nil
236
+ def put_json(rel_path, params)
237
+ params = login_auth.update(params || {})
238
+ process_res(:put, rel_path, params.to_json, JSON_HEADER)
239
+ end
240
+
241
+ # ログインしてDELETEします
242
+ # @param [String] rel_path cli.base_url からの相対パス
243
+ # @return nil
244
+ def delete(rel_path)
245
+ params = login_auth
246
+ process_res(:delete, rel_path, params.to_json, JSON_HEADER)
247
+ end
248
+
249
+ def process_res(http_method, rel_path, *args)
250
+ url = "#{base_url}#{rel_path}"
251
+ res = httpclient.send(http_method, url, *args)
252
+ check_response(res)
253
+ end
254
+
146
255
  end
147
256
  end
148
257
  end
149
-
@@ -32,6 +32,7 @@ en:
32
32
  cmd_login:
33
33
  email: "email address for login"
34
34
  password: "password for login"
35
+ authentication_token: "authentication token for login"
35
36
  cmd_help:
36
37
  for_more_detail: "type `%{command} help RESOURCE` for more detail"
37
38
  file_access:
@@ -43,9 +44,13 @@ en:
43
44
  error: "Login failure"
44
45
  access_api:
45
46
  ok: "OK"
47
+ token:
48
+ success: "Authorized"
49
+ error: "Unauthorized"
46
50
  login:
47
51
  check_login_auth:
48
52
  not_logged_in: "Not logined yet. type `%{command} login`."
53
+ warning: "Please refer to the password empty if you want to login with authentication token."
49
54
  messaging:
50
55
  http:
51
56
  ping: "Send a HTTP request to check connection"
@@ -30,6 +30,7 @@ ja:
30
30
  cmd_login:
31
31
  email: "ログインするアカウントのメールアドレス"
32
32
  password: "ログインするアカウントのパスワード"
33
+ authentication_token: "ログインするアカウントの認証トークン"
33
34
  cmd_help:
34
35
  for_more_detail: "詳しくは `%{command} help RESOURCE` を実行してください"
35
36
  file_access:
@@ -41,9 +42,13 @@ ja:
41
42
  error: "ログインに失敗しました"
42
43
  access_api:
43
44
  ok: "OK"
45
+ token:
46
+ success: "認証しました"
47
+ error: "認証に失敗しました"
44
48
  login:
45
49
  check_login_auth:
46
50
  not_logged_in: "ログインしていません。`%{command} login` を実行してログインしてください"
51
+ warning: "認証トークンでログインする場合はパスワードを空にしてください"
47
52
  messaging:
48
53
  http:
49
54
  ping: "接続確認のリクエストを送信します"
@@ -7,7 +7,7 @@ require 'yaml'
7
7
  module Magellan
8
8
  module Cli
9
9
  module Messaging
10
- class Base < Magellan::Cli::Http
10
+ class Base < Magellan::Cli::Base
11
11
  include Magellan::Cli::FileAccess
12
12
 
13
13
  no_commands do
@@ -18,7 +18,7 @@ module Magellan
18
18
  private
19
19
 
20
20
  def load_selection!(name, &block)
21
- return access_api{ load_selection(name, &block) }
21
+ return http_access{ load_selection(name, &block) }
22
22
  end
23
23
 
24
24
  def find(klass, id = nil)
@@ -39,6 +39,7 @@ module Magellan
39
39
  client_version: client_version,
40
40
  mqtt_host: ENV["MAGELLAN_MQTT_SERVER_HOST"] || DEFAULT_MAGELLAN_MQTT_SERVER_HOST,
41
41
  mqtt_port: ENV["MAGELLAN_MQTT_SERVER_PORT"] || DEFAULT_MAGELLAN_MQTT_SERVER_PORT,
42
+ verbose: options[:verbose],
42
43
  }
43
44
  uri = ENV["MAGELLAN_HTTP_SERVER_URL"] || DEFAULT_MAGELLAN_HTTP_SERVER_URL
44
45
  log_verbose("HTTP URL : #{uri.inspect}")
@@ -17,16 +17,16 @@ module Magellan
17
17
  class NotFound < Magellan::Cli::Error
18
18
  end
19
19
 
20
- class Base < ::Magellan::Cli::Http
20
+ class Base < ::Magellan::Cli::Base
21
21
  include Magellan::Cli::FileAccess
22
22
 
23
23
  no_commands do
24
24
 
25
25
  def load_selection!(name, &block)
26
- return access_api{ load_selection(name, &block) }
26
+ return http_access{ load_selection(name, &block) }
27
27
  end
28
28
  def update_selections!(hash = nil, &block)
29
- return access_api{ update_selections(hash, &block) }
29
+ return http_access{ update_selections(hash, &block) }
30
30
  end
31
31
 
32
32
  def build_query(hash)
@@ -41,7 +41,7 @@ module Magellan
41
41
  end
42
42
 
43
43
  def default_query
44
- access_api do |cli|
44
+ http_access do |cli|
45
45
  sel = load_selections
46
46
  q = {}
47
47
  (self.class.resource_dependency || {}).each do |f, res|
@@ -169,6 +169,9 @@ module Magellan
169
169
  def select(name)
170
170
  q = build_query(self.class.caption_attr => name).update(default_query)
171
171
  update_first_result(self.class.parameter_name, name, "/admin/#{self.class.resource_key}.json", q)
172
+ update_selections! do |s|
173
+ self.class.deselect_dependants(s)
174
+ end
172
175
  end
173
176
 
174
177
  def deselect
@@ -16,6 +16,7 @@ module Magellan
16
16
  self.caption_attr = "version"
17
17
 
18
18
  desc "create VERSION", I18n.t(:create, scope: [:resources, :client_version, :cmd], resource_name: resource_name)
19
+ method_option :domain, aliases: "-d", desc: I18n.t(:domain, scope: [:resources, :client_version, :cmd_create])
19
20
  def create(version)
20
21
  project = load_selection!(Project)
21
22
  stage = load_selection!(Stage)
@@ -24,12 +25,31 @@ module Magellan
24
25
  "stage_title_id" => stage["id"],
25
26
  "version" => version,
26
27
  }
28
+ if d = options[:domain]
29
+ attrs["domain"] = d
30
+ end
27
31
  params = { parameter_name => attrs }
28
32
  post_json("/admin/#{resource_key}/new.json", params)
29
33
  # TODO implement select method
30
34
  # select(version)
31
35
  end
32
36
 
37
+ desc "update ATTRIBUTES", I18n.t(:update, scope: [:resources, :client_version, :cmd], resource_name: resource_name)
38
+ def update(attrs)
39
+ if File.readable?(attrs)
40
+ attrs = YAML.load_file(attrs)
41
+ else
42
+ attrs = JSON.parse(attrs)
43
+ end
44
+ cv = load_selection!(self.class)
45
+ self.class.hidden_fields.each do |f| attrs.delete(f) end
46
+ self.class.field_associations.keys.each do |f| attrs.delete(f) end
47
+ params = {
48
+ parameter_name => attrs
49
+ }
50
+ put_json("/admin/#{resource_key}/#{cv["id"]}/edit.json", params)
51
+ end
52
+
33
53
  desc "delete VERSION", I18n.t(:delete, scope: [:resources, :client_version, :cmd], resource_name: resource_name)
34
54
  def delete(version)
35
55
  q = build_query("version" => version).update(default_query)
@@ -1,5 +1,5 @@
1
1
  module Magellan
2
2
  module Cli
3
- VERSION = "0.5.9"
3
+ VERSION = "0.6.0"
4
4
  end
5
5
  end
data/magellan-cli.gemspec CHANGED
@@ -25,7 +25,7 @@ Gem::Specification.new do |spec|
25
25
  spec.add_runtime_dependency "text-table", "~> 1.2.3"
26
26
  spec.add_runtime_dependency "i18n"
27
27
  spec.add_runtime_dependency "psych", ">= 2.0.0", "<= 2.0.8"
28
- spec.add_runtime_dependency "libmagellan", "~> 0.2.2"
28
+ spec.add_runtime_dependency "libmagellan", "~> 0.2.4"
29
29
 
30
30
  spec.add_development_dependency "bundler", "~> 1.6"
31
31
  spec.add_development_dependency "rake", "~> 10.0"
@@ -10,7 +10,8 @@ describe Magellan::Cli::Command do
10
10
  before do
11
11
  $stdout = StringIO.new
12
12
  allow(command).to receive(:select_single_resources)
13
- allow(Magellan::Cli::Http).to receive_message_chain(:new, :login!).and_return("OK")
13
+ allow(command).to receive(:login!).and_return("OK")
14
+ allow(command).to receive(:login_by_token!).and_return("OK")
14
15
  end
15
16
  it "nothing options" do
16
17
  allow($stdin).to receive(:gets).and_return(string).once
@@ -19,6 +20,13 @@ describe Magellan::Cli::Command do
19
20
  expect($stdout.string).to eq "email: password: \n"
20
21
  end
21
22
 
23
+ it "nothing options" do
24
+ allow($stdin).to receive(:gets ).and_return(string).once # email
25
+ allow($stdin).to receive(:noecho).and_return("\n").twice # password
26
+ expect(command.login).to eq "OK"
27
+ expect($stdout.string).to eq "email: password: \nauthentication_token: \n"
28
+ end
29
+
22
30
  it "only email" do
23
31
  allow($stdin).to receive(:noecho).and_return(string).twice
24
32
  command.options = Thor::CoreExt::HashWithIndifferentAccess.new email: string
@@ -32,6 +40,13 @@ describe Magellan::Cli::Command do
32
40
  expect(command.login).to eq "OK"
33
41
  expect($stdout.string).to eq "email: "
34
42
  end
43
+
44
+ it "only authentication_token" do
45
+ allow($stdin).to receive(:gets).and_return(string).once
46
+ command.options = Thor::CoreExt::HashWithIndifferentAccess.new authentication_token: string
47
+ expect(command.login).to eq "OK"
48
+ expect($stdout.string).to eq "email: "
49
+ end
35
50
  end
36
51
  end
37
52
  end
@@ -0,0 +1,24 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ describe Magellan::Cli::Messaging::Http do
5
+
6
+ let(:cmd){ Magellan::Cli::Messaging::Http.new }
7
+
8
+ describe :login_by_token do
9
+ let(:email) { "user1@example.com" }
10
+ let(:password) { "password" }
11
+ let(:success_res) { double(:success_res, status: 200) }
12
+ let(:error_res) { double(:error_res, status: 401) }
13
+
14
+ it "success" do
15
+ allow(cmd.http_conn.httpclient).to receive(:get).and_return(success_res)
16
+ cmd.login_by_token!(email, password)
17
+ end
18
+
19
+ it "error" do
20
+ allow(cmd.http_conn.httpclient).to receive(:get).and_return(error_res)
21
+ expect{cmd.login_by_token!(email, password)}.to raise_error(SystemExit)
22
+ end
23
+ end
24
+ end
@@ -1,12 +1,17 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  require 'spec_helper'
3
3
 
4
- describe Magellan::Cli::Login do
4
+ describe Magellan::Cli::Http do
5
5
 
6
6
  describe :login! do
7
7
  let(:email){ "magellan@groovenauts.jp" }
8
8
  let(:password){ "password" }
9
9
  let(:auth_token){ "047bcCC1dnyVE+7DWE6YKIJF97L/qHk1mPrf2oaqWtE=" }
10
+ let(:cmd) do
11
+ cmd = double(:cmd)
12
+ allow(cmd).to receive(:verbose?).and_return(false)
13
+ cmd
14
+ end
10
15
 
11
16
  before do
12
17
  allow(File).to receive(:readable?).and_return(true)
@@ -14,7 +19,8 @@ describe Magellan::Cli::Login do
14
19
  end
15
20
 
16
21
  context :production do
17
- let(:cli){ Magellan::Cli::Login.new("https://example.com") }
22
+ before{ allow(Magellan::Cli::Http).to receive(:base_url).and_return("https://example.com") }
23
+ let(:cli){ Magellan::Cli::Http.new(cmd) }
18
24
  before do
19
25
  res = double(:res)
20
26
  allow(cli.httpclient).to receive(:get).with("https://example.com/users/sign_in.html").and_return(res)
@@ -50,7 +56,8 @@ describe Magellan::Cli::Login do
50
56
  end
51
57
 
52
58
  context :development do
53
- let(:cli){ Magellan::Cli::Login.new("http://localhost:3001") }
59
+ before{ allow(Magellan::Cli::Http).to receive(:base_url).and_return("http://localhost:3001") }
60
+ let(:cli){ Magellan::Cli::Http.new(cmd) }
54
61
  before do
55
62
  res = double(:res)
56
63
  allow(cli.httpclient).to receive(:get).with("http://localhost:3001/users/sign_in.html").and_return(res)
@@ -5,8 +5,8 @@ describe Magellan::Cli::Resources::ClientVersion do
5
5
 
6
6
  let(:cmd){ Magellan::Cli::Resources::ClientVersion.new }
7
7
 
8
- let(:cli){ double(:cli, :check_login_auth! => nil) }
9
- before{ allow(cmd).to receive(:cli).and_return(cli) }
8
+ let(:http_conn){ double(:http_conn, :check_login_auth! => nil) }
9
+ before{ allow(cmd).to receive(:http_conn).and_return(http_conn) }
10
10
 
11
11
  describe :list do
12
12
  before do
@@ -33,6 +33,17 @@ describe Magellan::Cli::Resources::ClientVersion do
33
33
  end
34
34
  end
35
35
 
36
+ describe :success_with_domain do
37
+ before do
38
+ allow(cmd).to receive(:load_selections).and_return({Magellan::Cli::Resources::Project.parameter_name => {"id" => 1, "name" => "ProjectA"}, Magellan::Cli::Resources::Stage.parameter_name => {"id" => 1, "name" => "StageA"} })
39
+ expect(cmd).to receive(:post_json).with("/admin/client_version/new.json", { "client_version" => { "project_id" => 1, "stage_title_id" => 1, "version" => "1.1.0", "domain" => "foo.example.com" } })
40
+ end
41
+ it do
42
+ cmd.options = {domain: "foo.example.com"}
43
+ cmd.create("1.1.0")
44
+ end
45
+ end
46
+
36
47
  describe :error do
37
48
  context "stage not selected" do
38
49
  before do
@@ -47,4 +58,22 @@ describe Magellan::Cli::Resources::ClientVersion do
47
58
  end
48
59
  end
49
60
 
61
+ describe :update do
62
+ let(:selections) do
63
+ {
64
+ Magellan::Cli::Resources::Project.parameter_name => {"id" => 1, "name" => "ProjectA"},
65
+ Magellan::Cli::Resources::ClientVersion.parameter_name => {"id" => 1, "version" => "Sandbox1"}
66
+ }
67
+ end
68
+ describe :success_to_update_domain do
69
+ before do
70
+ allow(cmd).to receive(:load_selections).and_return(selections)
71
+ expect(cmd).to receive(:put_json).with("/admin/client_version/1/edit.json", { "client_version" => { "domain" => "bar.example.com" } })
72
+ end
73
+ it do
74
+ cmd.update('{"domain": "bar.example.com"}')
75
+ end
76
+ end
77
+ end
78
+
50
79
  end
@@ -65,4 +65,17 @@ describe "deselect" do
65
65
  end
66
66
  end
67
67
 
68
+ describe Magellan::Cli::Resources::Organization do
69
+ context "select another one" do
70
+ it do
71
+ allow(subject).to receive(:get_json).
72
+ with("/admin/magellan~auth~organization.json", an_instance_of(Hash)).
73
+ and_return([{"id" => 5, "name" => "test3"}])
74
+ expect(YAML.load_file(work_yaml)).to include(Magellan::Cli::Resources::Project.parameter_name)
75
+ subject.select "test3"
76
+ expect(YAML.load_file(work_yaml)).to_not include(Magellan::Cli::Resources::Project.parameter_name)
77
+ end
78
+ end
79
+ end
80
+
68
81
  end
@@ -5,8 +5,8 @@ describe Magellan::Cli::Resources::Organization do
5
5
 
6
6
  let(:cmd){ Magellan::Cli::Resources::Organization.new }
7
7
 
8
- let(:cli){ double(:cli, :check_login_auth! => nil) }
9
- before{ allow(cmd).to receive(:cli).and_return(cli) }
8
+ let(:http_conn){ double(:http_conn, :check_login_auth! => nil) }
9
+ before{ allow(cmd).to receive(:http_conn).and_return(http_conn) }
10
10
 
11
11
  describe :list do
12
12
  before do
@@ -4,23 +4,21 @@ require 'spec_helper'
4
4
  describe Magellan::Cli::Resources::Project do
5
5
 
6
6
  let(:base_url){ "https://localhost:3000" }
7
+ before{ allow(Magellan::Cli::Http).to receive(:base_url).and_return(base_url) }
7
8
  let(:httpclient){ double(:httpclient) }
8
- let(:cli) do
9
- cli = double(:access_api, base_url: base_url, auth_token: {}, login_auth: {})
10
- allow(cli).to receive(:httpclient).and_return(httpclient)
11
- cli
12
- end
13
9
  let(:res){ double(:res, status: 200, body: {}.to_json) }
14
10
 
15
11
  let(:cmd){ Magellan::Cli::Resources::Project.new }
16
12
 
17
13
  before do
18
- allow(cmd).to receive(:access_api).and_yield(cli)
14
+ allow(cmd.http_conn).to receive(:httpclient).and_return(httpclient)
15
+ allow(cmd.http_conn).to receive(:check_login_auth!)
16
+ allow(cmd.http_conn).to receive(:login_auth).and_return({})
19
17
  end
20
18
 
21
19
  describe :list do
22
20
  it do
23
- expect(httpclient).to receive(:get).with(%r{\A#{base_url}/admin/project.json}).and_return(res)
21
+ expect(httpclient).to receive(:get).with(%{#{base_url}/admin/project.json}).and_return(res)
24
22
  expect($stdout).to receive(:puts)
25
23
  cmd.list
26
24
  end
@@ -5,8 +5,8 @@ describe Magellan::Cli::Resources::Team do
5
5
 
6
6
  let(:cmd){ Magellan::Cli::Resources::Team.new }
7
7
 
8
- let(:cli){ double(:cli, :check_login_auth! => nil) }
9
- before{ allow(cmd).to receive(:cli).and_return(cli) }
8
+ let(:http_conn){ double(:http_conn, :check_login_auth! => nil) }
9
+ before{ allow(cmd).to receive(:http_conn).and_return(http_conn) }
10
10
 
11
11
  describe :list do
12
12
  before do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: magellan-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.9
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - akm2000
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-18 00:00:00.000000000 Z
11
+ date: 2015-02-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httpclient
@@ -120,14 +120,14 @@ dependencies:
120
120
  requirements:
121
121
  - - "~>"
122
122
  - !ruby/object:Gem::Version
123
- version: 0.2.2
123
+ version: 0.2.4
124
124
  type: :runtime
125
125
  prerelease: false
126
126
  version_requirements: !ruby/object:Gem::Requirement
127
127
  requirements:
128
128
  - - "~>"
129
129
  - !ruby/object:Gem::Version
130
- version: 0.2.2
130
+ version: 0.2.4
131
131
  - !ruby/object:Gem::Dependency
132
132
  name: bundler
133
133
  requirement: !ruby/object:Gem::Requirement
@@ -199,7 +199,6 @@ files:
199
199
  - lib/magellan/cli/i18n.rb
200
200
  - lib/magellan/cli/locales/en.yml
201
201
  - lib/magellan/cli/locales/ja.yml
202
- - lib/magellan/cli/login.rb
203
202
  - lib/magellan/cli/messaging.rb
204
203
  - lib/magellan/cli/messaging/base.rb
205
204
  - lib/magellan/cli/messaging/http.rb
@@ -246,6 +245,7 @@ files:
246
245
  - spec/magellan/cli/Magellan.yml
247
246
  - spec/magellan/cli/command_spec.rb
248
247
  - spec/magellan/cli/file_access_spec.rb
248
+ - spec/magellan/cli/http_spec.rb
249
249
  - spec/magellan/cli/login_page.html
250
250
  - spec/magellan/cli/login_spec.rb
251
251
  - spec/magellan/cli/messaging/http_body.json
@@ -292,6 +292,7 @@ test_files:
292
292
  - spec/magellan/cli/Magellan.yml
293
293
  - spec/magellan/cli/command_spec.rb
294
294
  - spec/magellan/cli/file_access_spec.rb
295
+ - spec/magellan/cli/http_spec.rb
295
296
  - spec/magellan/cli/login_page.html
296
297
  - spec/magellan/cli/login_spec.rb
297
298
  - spec/magellan/cli/messaging/http_body.json
@@ -1,119 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- require "magellan/cli"
3
-
4
- require 'httpclient'
5
- require 'json'
6
- require 'uri'
7
- require 'nokogiri'
8
-
9
- require 'active_support/core_ext/hash/keys'
10
-
11
- module Magellan
12
- module Cli
13
- class Login
14
- include Magellan::Cli::FileAccess
15
-
16
- PRODUCTION_HTTP_PORT = 80
17
- PRODUCTION_HTTPS_PORT = 443
18
-
19
- DEFAULT_HTTP_PORT = (ENV['DEFAULT_HTTP_PORT' ] || 80).to_i
20
- DEFAULT_HTTPS_PORT = (ENV['DEFAULT_HTTPS_PORT'] || 443).to_i
21
-
22
- attr_reader :httpclient
23
- attr_reader :base_url
24
-
25
- attr_reader :auth_token
26
- attr_reader :login_auth
27
-
28
- # Magellan::Cli::Loginのコンストラクタです。
29
- #
30
- # @param [String] base_url_or_host 接続先の基準となるURLあるいはホスト名
31
- # @param [Hash] options オプション
32
- # @option options [String] :api_version APIのバージョン。デフォルトは "1.0.0"
33
- def initialize(base_url_or_host = nil, options = {})
34
- base_url_or_host ||= (ENV["MAGELLAN_SITE"] || "https://api-asia.magellanic-clouds.com")
35
- if base_url_or_host =~ URI.regexp
36
- @base_url = base_url_or_host.sub(/\/\Z/, '')
37
- uri = URI.parse(@base_url)
38
- else
39
- if config_path = search_file(".magellan-cli.yml")
40
- config = YAML.load_file_with_erb(config_path)
41
- options = config[base_url_or_host.to_s].deep_symbolize_keys.update(options)
42
- end
43
- uri = URI::Generic.build({scheme: "http", host: base_url_or_host, port: DEFAULT_HTTP_PORT}.update(options))
44
- @base_url = uri.to_s
45
- end
46
-
47
- @httpclient = HTTPClient.new
48
- @httpclient.ssl_config.verify_mode = nil # 自己署名の証明書をOKにする
49
- @login_auth = load_selections["login"]
50
- end
51
-
52
- def login_form_url
53
- @login_form_url ||= base_url + "/users/sign_in.html"
54
- end
55
- def login_url
56
- @login_url ||= base_url + "/api/sign_in.json"
57
- end
58
-
59
- def check_login_auth!
60
- auth = login_auth
61
- if auth.nil? || auth.empty?
62
- raise Magellan::Cli::Error, I18n.t(:not_logged_in, scope: [:login, :check_login_auth], command: File.basename($0))
63
- end
64
- end
65
-
66
- # magellan-apiサーバに接続してログインの検証とアクセストークンの保存を行います。
67
- #
68
- # @return [boolean] login成功/失敗
69
- def api_login!(email, password)
70
- @auth_token ||= get_auth_token
71
- params = {
72
- "user" => {
73
- "email" => email,
74
- "password" => password
75
- },
76
- "authenticity_token" => @auth_token
77
- }.to_json
78
- res2 = Ssl.retry_on_ssl_error("login"){ @httpclient.post(login_url, params, JSON_HEADER) }
79
-
80
- case res2.status
81
- when 200...300 then logined = true
82
- else logined = false
83
- end
84
-
85
- if logined
86
- body = JSON.parse res2.body
87
- update_selections("login" => {"email" => email, "token" => body["token"] })
88
- else
89
- update_selections("login" => nil)
90
- end
91
- logined
92
- end
93
-
94
- def get_auth_token
95
- res = Ssl.retry_on_ssl_error("login_form"){ @httpclient.get(login_form_url) }
96
- doc = Nokogiri::HTML.parse(res.body, login_form_url, res.body_encoding.to_s)
97
- node = doc.xpath('//input[@name="authenticity_token"]').first
98
- unless node
99
- raise Cli::Error.new("fail to login Magellan")
100
- end
101
- node.attribute('value').value
102
- end
103
-
104
- # @httpclient.inspectの戻り値の文字列が巨大なので、inspectで出力しないようにします。
105
- def inspect
106
- r = "#<#{self.class.name}:#{self.object_id} "
107
- fields = (instance_variables - [:@httpclient]).map{|f| "#{f}=#{instance_variable_get(f).inspect}"}
108
- r << fields.join(", ") << ">"
109
- end
110
-
111
- def search_file(basename)
112
- dirs = [".", "./config", ENV['HOME']].join(",")
113
- Dir["{#{dirs}}/#{basename}"].select{|path| File.readable?(path)}.first
114
- end
115
- private :search_file
116
-
117
- end
118
- end
119
- end