gas 0.1.8 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/gas +70 -35
- data/bin/gas-add +7 -0
- data/bin/gas-delete +7 -0
- data/bin/gas-import +7 -0
- data/bin/gas-list +6 -0
- data/bin/gas-show +6 -0
- data/bin/gas-use +7 -0
- data/lib/gas.rb +67 -103
- data/lib/gas/git_config.rb +25 -0
- data/lib/gas/user.rb +11 -4
- data/lib/gas/users.rb +110 -0
- data/lib/gas/version.rb +2 -3
- data/spec/integration/gas_spec.rb +118 -0
- data/spec/integration/users_spec.rb +40 -0
- data/spec/spec_helper.rb +10 -141
- data/spec/unit/git_config_spec.rb +82 -0
- data/spec/unit/user_spec.rb +18 -0
- data/spec/unit/users_spec.rb +71 -0
- metadata +23 -112
- data/lib/gas/config.rb +0 -148
- data/lib/gas/gitconfig.rb +0 -46
- data/lib/gas/github_speaker.rb +0 -219
- data/lib/gas/prompter.rb +0 -169
- data/lib/gas/settings.rb +0 -28
- data/lib/gas/ssh.rb +0 -305
- data/spec/integration/ssh_spec.rb +0 -338
- data/spec/unit/config_spec.rb +0 -83
- data/spec/unit/gitconfig_spec.rb +0 -85
- data/spec/unit/github_speaker_spec.rb +0 -107
- data/spec/unit/settings_spec.rb +0 -56
data/lib/gas/gitconfig.rb
DELETED
@@ -1,46 +0,0 @@
|
|
1
|
-
module Gas
|
2
|
-
|
3
|
-
# Class that class that interacts with the git config
|
4
|
-
class Gitconfig
|
5
|
-
@@nickname = ''
|
6
|
-
# Parse out the current user from the gitconfig
|
7
|
-
# @param [String] gitconfig The git configuration
|
8
|
-
# @return [User] The current user or nil if not present
|
9
|
-
def current_user
|
10
|
-
name = `git config --global --get user.name`
|
11
|
-
email = `git config --global --get user.email`
|
12
|
-
|
13
|
-
return nil if name.nil? && email.nil?
|
14
|
-
|
15
|
-
User.new name.delete("\n"), email.delete("\n"), @@nickname # git cli returns the name and email with \n at the end
|
16
|
-
end
|
17
|
-
|
18
|
-
# Get current user
|
19
|
-
def current_user_object
|
20
|
-
name = `git config --global --get user.name`
|
21
|
-
email = `git config --global --get user.email`
|
22
|
-
|
23
|
-
return nil if name.nil? && email.nil?
|
24
|
-
|
25
|
-
return {:name => name.strip, :email => email.strip}
|
26
|
-
end
|
27
|
-
|
28
|
-
# Changes the user
|
29
|
-
# @param [String] name The new name
|
30
|
-
# @param [String] email The new email
|
31
|
-
def change_user(user)
|
32
|
-
nickname = user.nickname
|
33
|
-
@@nickname = nickname # maybe we should make nickname a class variable?
|
34
|
-
name = user.name
|
35
|
-
email = user.email
|
36
|
-
|
37
|
-
`git config --global user.name "#{name}"`
|
38
|
-
`git config --global user.email "#{email}"`
|
39
|
-
|
40
|
-
# confirm that this user has an ssh and if so, swap it in safely
|
41
|
-
Ssh.swap_in_rsa nickname
|
42
|
-
end
|
43
|
-
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
data/lib/gas/github_speaker.rb
DELETED
@@ -1,219 +0,0 @@
|
|
1
|
-
module Gas
|
2
|
-
# A beautiful class that makes working with the github API an enjoyable experience
|
3
|
-
class GithubSpeaker
|
4
|
-
attr_reader :user, :account_name, :password, :keys, :status
|
5
|
-
attr_accessor :server
|
6
|
-
|
7
|
-
def keys
|
8
|
-
refresh_keys if @keys.nil?
|
9
|
-
@keys
|
10
|
-
end
|
11
|
-
|
12
|
-
def initialize(user, account_name=nil, password=nil, server = 'api.github.com')
|
13
|
-
@user = user
|
14
|
-
@server = server
|
15
|
-
@keys = nil
|
16
|
-
|
17
|
-
# sort out username and password... Make it's own function?
|
18
|
-
if account_name.nil? and password.nil?
|
19
|
-
# Prompt for username and password
|
20
|
-
credentials = get_username_and_password_diligently
|
21
|
-
@account_name = credentials[:account_name] # this overwrite happens twice to make testing easier... Stub on get_username, kekeke
|
22
|
-
@password = credentials[:password]
|
23
|
-
else
|
24
|
-
@account_name = account_name
|
25
|
-
@password = password
|
26
|
-
authenticate
|
27
|
-
end
|
28
|
-
|
29
|
-
end
|
30
|
-
|
31
|
-
|
32
|
-
def post_key!(rsa)
|
33
|
-
refresh_keys if @keys.nil?
|
34
|
-
|
35
|
-
puts "Posting key to GitHub.com..."
|
36
|
-
|
37
|
-
# find key...
|
38
|
-
if has_key(rsa)
|
39
|
-
puts "Key already installed."
|
40
|
-
return false
|
41
|
-
end
|
42
|
-
title = "GAS: #{@user.nickname}"
|
43
|
-
result = install_key(rsa)
|
44
|
-
|
45
|
-
if result != false
|
46
|
-
@keys << result
|
47
|
-
return true
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
|
52
|
-
def refresh_keys
|
53
|
-
raise "Attempted to update keys when unable to authenticate credentials with github" if @status != :authenticated
|
54
|
-
|
55
|
-
path = '/user/keys'
|
56
|
-
|
57
|
-
http = Net::HTTP.new(@server,443)
|
58
|
-
req = Net::HTTP::Get.new(path)
|
59
|
-
http.use_ssl = true
|
60
|
-
req.basic_auth @account_name, @password
|
61
|
-
response = http.request(req)
|
62
|
-
|
63
|
-
@keys = JSON.parse(response.body)
|
64
|
-
end
|
65
|
-
|
66
|
-
|
67
|
-
# Cycles through github, looking to see if rsa exists as a public key, then deletes it if it does
|
68
|
-
def remove_key!(rsa)
|
69
|
-
refresh_keys
|
70
|
-
|
71
|
-
# loop through arrays checking against 'key'
|
72
|
-
@keys.each do |key|
|
73
|
-
if key["key"] == rsa
|
74
|
-
return remove_key_by_id!(key["id"])
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
return false # key not found
|
79
|
-
end
|
80
|
-
|
81
|
-
|
82
|
-
private
|
83
|
-
def authenticate
|
84
|
-
path = '/user'
|
85
|
-
|
86
|
-
http = Net::HTTP.new(@server,443)
|
87
|
-
http.use_ssl = true
|
88
|
-
|
89
|
-
req = Net::HTTP::Get.new(path)
|
90
|
-
req.basic_auth @account_name, @password
|
91
|
-
response = http.request(req)
|
92
|
-
|
93
|
-
result = JSON.parse(response.body)["message"]
|
94
|
-
|
95
|
-
if result == "Bad credentials"
|
96
|
-
@status = :bad_credentials
|
97
|
-
return false
|
98
|
-
else
|
99
|
-
@status = :authenticated
|
100
|
-
return true
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
def get_username_and_password_and_authenticate
|
105
|
-
puts "Type your github.com user name:"
|
106
|
-
print "User: "
|
107
|
-
account_name = STDIN.gets.strip
|
108
|
-
|
109
|
-
puts "Type your github password:"
|
110
|
-
password = ask("Password: ") { |q| q.echo = false }
|
111
|
-
puts
|
112
|
-
|
113
|
-
credentials = {:account_name => account_name, :password => password}
|
114
|
-
#p credentials
|
115
|
-
@account_name = account_name
|
116
|
-
@password = password
|
117
|
-
|
118
|
-
if authenticate
|
119
|
-
return credentials
|
120
|
-
else
|
121
|
-
return false
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
# Get's the username and password from the user, then authenticates. If it fails, it asks them if they'd like to try again.
|
126
|
-
# Returns false if aborted
|
127
|
-
def get_username_and_password_diligently
|
128
|
-
while true
|
129
|
-
credentials = get_username_and_password_and_authenticate
|
130
|
-
if credentials == false
|
131
|
-
puts "Could not authenticate, try again?"
|
132
|
-
puts "y/n"
|
133
|
-
|
134
|
-
again = STDIN.gets.strip
|
135
|
-
case again.downcase
|
136
|
-
when "y"
|
137
|
-
when "n"
|
138
|
-
return false
|
139
|
-
end
|
140
|
-
else
|
141
|
-
return credentials
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
def install_key(rsa)
|
147
|
-
require "socket"
|
148
|
-
host_name = Socket.gethostname
|
149
|
-
|
150
|
-
title = "GAS: #{@user.nickname} \-#{host_name}"
|
151
|
-
|
152
|
-
path = '/user/keys'
|
153
|
-
|
154
|
-
http = Net::HTTP.new(@server, 443) # 443 for ssl
|
155
|
-
http.use_ssl = true
|
156
|
-
|
157
|
-
req = Net::HTTP::Post.new(path)
|
158
|
-
req.basic_auth @account_name, @password
|
159
|
-
req.body = "{\"title\":\"#{title}\", \"key\":\"#{rsa}\"}"
|
160
|
-
|
161
|
-
response = http.start {|m_http| m_http.request(req) }
|
162
|
-
the_code = response.code
|
163
|
-
|
164
|
-
key_json = JSON.parse(response.body)
|
165
|
-
|
166
|
-
return key_json if the_code == "201"
|
167
|
-
|
168
|
-
puts "The key you are trying to use already exists in another github user's account. You need to use another key." if the_code == "already_exists"
|
169
|
-
|
170
|
-
# currently.. I think it always returns "already_exists" even if successful. API bug.
|
171
|
-
puts "Something may have gone wrong. Either github changed their API, or your key couldn't be installed." if the_code != "already_exists"
|
172
|
-
|
173
|
-
#return true if my_hash.key?("errors") # this doesn't work due to it being a buggy API atm # false change me to false when they fix their API
|
174
|
-
puts "Server Response: #{response.body}"
|
175
|
-
return false
|
176
|
-
end
|
177
|
-
|
178
|
-
# Cycles through github, looking to see if rsa exists as a public key, then deletes it if it does
|
179
|
-
def has_key(rsa)
|
180
|
-
refresh_keys if @keys.nil?
|
181
|
-
return false if @keys.empty?
|
182
|
-
|
183
|
-
# loop through arrays checking against 'key'
|
184
|
-
@keys.each do |key|
|
185
|
-
return true if key["key"] == rsa
|
186
|
-
end
|
187
|
-
|
188
|
-
return false # key not found
|
189
|
-
end
|
190
|
-
|
191
|
-
def remove_key_by_id!(id)
|
192
|
-
path = "/user/keys/#{id}"
|
193
|
-
|
194
|
-
http = Net::HTTP.new(@server,443)
|
195
|
-
http.use_ssl = true
|
196
|
-
req = Net::HTTP::Delete.new(path)
|
197
|
-
req.basic_auth @account_name, @password
|
198
|
-
|
199
|
-
response = http.request(req)
|
200
|
-
|
201
|
-
if response.body.nil?
|
202
|
-
#@keys = nil # lame hack! sooo lazy of me. I should learn how to remove the proper key from the @keys hash...
|
203
|
-
remove_key_from_keys id
|
204
|
-
return true
|
205
|
-
end
|
206
|
-
end
|
207
|
-
|
208
|
-
|
209
|
-
def remove_key_from_keys(id_to_delete)
|
210
|
-
@keys.each.with_index do |key, i|
|
211
|
-
@keys.delete_at(i) if key['id'].to_i == id_to_delete.to_i
|
212
|
-
end
|
213
|
-
end
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
end
|
219
|
-
end
|
data/lib/gas/prompter.rb
DELETED
@@ -1,169 +0,0 @@
|
|
1
|
-
module Gas
|
2
|
-
module Prompter
|
3
|
-
@invalid_input_response_with_default = "Please use 'y' or 'n' or enter for default."
|
4
|
-
# If the user says 'f', the system will
|
5
|
-
# report that there isn't an id_rsa already in gas. This causes a new key to overwrite automatically down the road.
|
6
|
-
# This is for checking if a .gas/rsa file already exists for a nickname which is being registered
|
7
|
-
# If the rsa exists, then we're goona need to ask if we should use it, or if we should delete it
|
8
|
-
#
|
9
|
-
# Returns true to indicate that the user would like to use the rsa file already in .gas ()
|
10
|
-
# Returns false when there are no naming conflicts.
|
11
|
-
def self.user_wants_to_use_key_already_in_gas?(uid = '')
|
12
|
-
puts "Gas has detected a key in its archive directory ~/.gas/#{uid}_id_rsa. Should gas use this key or overwrite this key with a brand new one?"
|
13
|
-
puts "Keep current key? [y/n]"
|
14
|
-
|
15
|
-
while true
|
16
|
-
keep_current_file = clean_gets
|
17
|
-
|
18
|
-
case keep_current_file
|
19
|
-
|
20
|
-
when "y"
|
21
|
-
return true # keep the files already in .gas, skip making key.
|
22
|
-
when "n"
|
23
|
-
return false
|
24
|
-
else
|
25
|
-
puts "please respond 'y' or 'n'"
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
# Checks if the ~/.ssh directroy contains id_rsa and id_rsa.pub
|
31
|
-
# if it does, it asks the user if they would like to use that as their ssh key, instead of generating a new key pair.
|
32
|
-
#
|
33
|
-
def self.user_wants_to_use_key_already_in_ssh?
|
34
|
-
puts "Generate a brand new ssh key pair? (Choose 'n' to use key in ~/.ssh/id_rsa)"
|
35
|
-
puts "Default: 'y'"
|
36
|
-
puts "[Y/n]"
|
37
|
-
|
38
|
-
while true
|
39
|
-
generate_new_rsa = clean_gets.downcase
|
40
|
-
case generate_new_rsa
|
41
|
-
when "y", ""
|
42
|
-
return false
|
43
|
-
when "n"
|
44
|
-
return true # return true if we aren't generating a new key
|
45
|
-
else
|
46
|
-
puts @invalid_input_response_with_default
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
def self.user_wants_gas_to_handle_rsa_keys?
|
52
|
-
puts
|
53
|
-
puts "Do you want gas to handle switching rsa keys for this user?"
|
54
|
-
puts "[Y/n]"
|
55
|
-
|
56
|
-
while true
|
57
|
-
handle_rsa = clean_gets
|
58
|
-
|
59
|
-
case handle_rsa
|
60
|
-
when "y", ""
|
61
|
-
return true
|
62
|
-
when "n"
|
63
|
-
return false
|
64
|
-
else
|
65
|
-
puts "Please use 'y' or 'n'"
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
def self.user_wants_to_remove_the_keys_that_already_exist_for_this_user?(uid)
|
71
|
-
puts
|
72
|
-
puts "Well... there's already a ~/.gas/#{uid}_id_rsa configured and ready to go. Are you sure you don't want gas to handle rsa switching? (Clicking no will delete the key from the gas directory)"
|
73
|
-
puts "Just let gas handle ssh key for this user? [y/n]"
|
74
|
-
|
75
|
-
while true
|
76
|
-
keep_file = clean_gets
|
77
|
-
|
78
|
-
case keep_file
|
79
|
-
when "n"
|
80
|
-
return true
|
81
|
-
when "y"
|
82
|
-
puts "Excelent! Gas will handle rsa keys for this user."
|
83
|
-
return false
|
84
|
-
else
|
85
|
-
puts @invalid_input_response_with_default
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
# This is another prompt function, but it returns a more complicated lexicon
|
91
|
-
#
|
92
|
-
# returns "a", "l", "g", or "n"
|
93
|
-
def self.user_wants_to_delete_all_ssh_data?
|
94
|
-
puts "Would you like to remove all of this user's ssh keys too!?!"
|
95
|
-
puts "(github account keys can be removed as well!)"
|
96
|
-
puts
|
97
|
-
puts "a: All, the local copy, and checks github too."
|
98
|
-
puts "l: Remove local key only."
|
99
|
-
puts "g: Removes key from github.com only."
|
100
|
-
puts "n: Don't remove this user's keys."
|
101
|
-
puts "Default: l"
|
102
|
-
|
103
|
-
while true
|
104
|
-
delete_all_keys = clean_gets
|
105
|
-
|
106
|
-
case delete_all_keys.downcase
|
107
|
-
when "a"
|
108
|
-
return "a"
|
109
|
-
when "l", ""
|
110
|
-
return "l"
|
111
|
-
when "g"
|
112
|
-
return "g"
|
113
|
-
when "n"
|
114
|
-
return "n"
|
115
|
-
else
|
116
|
-
puts "please use 'a', 'l', 'g' or 'n' for NONE."
|
117
|
-
end
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
def self.user_wants_to_install_key_to_github?
|
122
|
-
puts "Gas can automatically install this ssh key into the github account of your choice. Would you like gas to do this for you? (Requires inputting github username and password)"
|
123
|
-
puts "[Y/n]"
|
124
|
-
|
125
|
-
while true
|
126
|
-
upload_key = clean_gets.downcase
|
127
|
-
case upload_key
|
128
|
-
when "y", ""
|
129
|
-
return true
|
130
|
-
when "n"
|
131
|
-
return false
|
132
|
-
else
|
133
|
-
puts @invalid_input_response_with_default
|
134
|
-
end
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
def self.user_wants_to_overwrite_existing_rsa_key?
|
139
|
-
puts "~/.ssh/id_rsa already exists. Overwrite?"
|
140
|
-
puts "[y/n]"
|
141
|
-
|
142
|
-
while true
|
143
|
-
overwrite = clean_gets
|
144
|
-
case overwrite
|
145
|
-
when "y"
|
146
|
-
return true
|
147
|
-
when "n"
|
148
|
-
return false
|
149
|
-
else
|
150
|
-
puts "please respond 'y' or 'n'"
|
151
|
-
end
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
# If the user hits ctrl+c with this, it will exit cleanly
|
156
|
-
def self.clean_gets
|
157
|
-
begin
|
158
|
-
getit = STDIN.gets.strip
|
159
|
-
rescue SystemExit, Interrupt # catch if they hit ctrl+c
|
160
|
-
puts
|
161
|
-
puts "Safely aborting operation..." # reassure user that ctrl+c is fine to use.
|
162
|
-
exit
|
163
|
-
end
|
164
|
-
|
165
|
-
return getit
|
166
|
-
end
|
167
|
-
|
168
|
-
end
|
169
|
-
end
|
data/lib/gas/settings.rb
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
module Gas
|
2
|
-
|
3
|
-
# Class that contains settings for the app
|
4
|
-
class Settings
|
5
|
-
attr_accessor :base_dir, :github_server
|
6
|
-
attr_reader :gas_dir, :ssh_dir
|
7
|
-
|
8
|
-
def initialize
|
9
|
-
@base_dir = '~'
|
10
|
-
@gas_dir = "#{@base_dir}/.gas"
|
11
|
-
@ssh_dir = "#{@base_dir}/.ssh"
|
12
|
-
@github_server = 'api.github.com'
|
13
|
-
end
|
14
|
-
|
15
|
-
def configure
|
16
|
-
yield self if block_given?
|
17
|
-
end
|
18
|
-
|
19
|
-
def gas_dir=(value)
|
20
|
-
@gas_dir = "#{@base_dir}/#{value}"
|
21
|
-
end
|
22
|
-
|
23
|
-
def ssh_dir=(value)
|
24
|
-
@ssh_dir = "#{@base_dir}/#{value}"
|
25
|
-
end
|
26
|
-
|
27
|
-
end
|
28
|
-
end
|