1require 'rubygems/remote_fetcher'
2
3module Gem::GemcutterUtilities
4  # TODO: move to Gem::Command
5  OptionParser.accept Symbol do |value|
6    value.to_sym
7  end
8
9  ##
10  # Add the --key option
11
12  def add_key_option
13    add_option('-k', '--key KEYNAME', Symbol,
14               'Use the given API key',
15               'from ~/.gem/credentials') do |value,options|
16      options[:key] = value
17    end
18  end
19
20  def api_key
21    if options[:key] then
22      verify_api_key options[:key]
23    elsif Gem.configuration.api_keys.key?(host)
24      Gem.configuration.api_keys[host]
25    else
26      Gem.configuration.rubygems_api_key
27    end
28  end
29
30  def sign_in sign_in_host = nil
31    sign_in_host ||= self.host
32    return if Gem.configuration.rubygems_api_key
33
34    pretty_host = if Gem::DEFAULT_HOST == sign_in_host then
35                    'RubyGems.org'
36                  else
37                    sign_in_host
38                  end
39
40    say "Enter your #{pretty_host} credentials."
41    say "Don't have an account yet? " +
42        "Create one at #{sign_in_host}/sign_up"
43
44    email    =              ask "   Email: "
45    password = ask_for_password "Password: "
46    say "\n"
47
48    response = rubygems_api_request(:get, "api/v1/api_key",
49                                    sign_in_host) do |request|
50      request.basic_auth email, password
51    end
52
53    with_response response do |resp|
54      say "Signed in."
55      Gem.configuration.rubygems_api_key = resp.body
56    end
57  end
58
59  attr_writer :host
60  def host
61    configured_host = Gem.host unless
62      Gem.configuration.disable_default_gem_server
63
64    @host ||=
65      begin
66        env_rubygems_host = ENV['RUBYGEMS_HOST']
67        env_rubygems_host = nil if
68          env_rubygems_host and env_rubygems_host.empty?
69
70        env_rubygems_host|| configured_host
71      end
72  end
73
74  def rubygems_api_request(method, path, host = nil, &block)
75    require 'net/http'
76
77    self.host = host if host
78    unless self.host
79      alert_error "You must specify a gem server"
80      terminate_interaction 1 # TODO: question this
81    end
82
83    uri = URI.parse "#{self.host}/#{path}"
84
85    request_method = Net::HTTP.const_get method.to_s.capitalize
86
87    Gem::RemoteFetcher.fetcher.request(uri, request_method, &block)
88  end
89
90  def with_response resp, error_prefix = nil
91    case resp
92    when Net::HTTPSuccess then
93      if block_given? then
94        yield resp
95      else
96        say resp.body
97      end
98    else
99      message = resp.body
100      message = "#{error_prefix}: #{message}" if error_prefix
101
102      say message
103      terminate_interaction 1 # TODO: question this
104    end
105  end
106
107  def verify_api_key(key)
108    if Gem.configuration.api_keys.key? key then
109      Gem.configuration.api_keys[key]
110    else
111      alert_error "No such API key. Please add it to your configuration (done automatically on initial `gem push`)."
112      terminate_interaction 1 # TODO: question this
113    end
114  end
115
116end
117