Permalink
Browse files

Got all my test house keeping code written and functional.

  • Loading branch information...
1 parent 3c313ed commit 7591652424cea59e66441b0e13bd72dbe659e65a @lukni lukni committed Oct 10, 2011
Showing with 308 additions and 40 deletions.
  1. +5 −0 bin/gas
  2. +41 −3 lib/gas.rb
  3. +134 −28 lib/gas/ssh.rb
  4. +128 −9 spec/gas/ssh_spec.rb
View
@@ -36,6 +36,11 @@ class GasRunner < Thor
def delete(nickname)
Gas.delete nickname
end
+
+ desc "ssh", "Creates a new ssh key for an existing gas author"
+ def ssh(nickname=nil)
+ Gas.ssh nickname
+ end
desc "version", "Prints Gas's version"
def version
View
@@ -69,6 +69,38 @@ def self.add(nickname, name, email)
puts 'Added author'
puts user
end
+
+
+ # Adds an ssh key for the specified user
+ def self.ssh(nickname)
+ p @config
+ if nickname.nil?
+ puts "Oh, so you'd like an elaborate explanation on how ssh key juggling works? Well pull up a chair!"
+ puts
+ puts "Gas can juggle ssh keys for you. It works best in a unix based environment (so at least use git bash or cygwin on a windows platform)."
+ puts "You will be prompted if you would like to handle SSH keys when you create a new user."
+ puts "If you are a long time user of gas, you can add ssh to an author by the command..."
+ puts "\$ gas ssh NICKNAME"
+ puts "Your ssh keys will be stored in ~/.gas/NICKNAME_id_rsa and automatically copied to ~/.ssh/id_rsa when you use the command..."
+ puts "\$ gas use NICKNAME"
+ puts "if ~/.ssh/id_rsa already exists, you will be prompted UNLESS that rsa file is already backed up in the .gas directory (I'm so sneaky, huh?)"
+ puts "The unix command ssh-add is used in order to link up your rsa keys when you attempt to make an ssh connection (git push uses ssh keys of course)"
+ puts
+ puts "The ssh feautre of gas offers you and the world greater privacy against corporate databases. Did you know that IBM built one of the first automated database systems? These ancient database machines (called tabulators) were used to facilitate the holocaust =("
+ else
+ user = @config[nickname]
+
+ Ssh.setup_ssh_keys user
+
+ Ssh.upload_public_key_to_github user
+ end
+ end
+
+
+
+
+
+
# Imports current user from .gitconfig to .gas
# @param [String] nickname The nickname to give to the new user
@@ -89,14 +121,19 @@ def self.import(nickname)
end
end
- # Deletes a author from the config using nickname
+ # Deletes an author from the config using nickname
# @param [String] nickname The nickname of the author
def self.delete(nickname)
- self.no_user? nickname
+ Ssh.delete nickname
+ return false unless self.no_user? nickname # I re-engineered this section so I could use Gas.delete in a test even when that author didn't exist
+ # TODO: The name no_user? is now very confusing. It should be changed to something like "is_user?" now maybe?
@config.delete nickname
@config.save!
+
+ Ssh.delete nickname
puts "Deleted author #{nickname}"
+ return true
end
# Prints the current version
@@ -109,8 +146,9 @@ def self.version
def self.no_user?(nickname)
if !@config.exists? nickname
puts "Nickname #{nickname} does not exist"
- exit
+ return false
end
+ return true
end
# Checks if the user exists and gives error and exit if so
View
@@ -3,7 +3,34 @@ module Gas
class Ssh
- # This is a little missleading... it's actually a prompt too... If the user says 'f', the system will
+
+ # TODO: remove me, obsolete after "Impliment the below form..." refactor is complete
+ def self.id_rsa_already_in_gas_dir_for_use?
+ if corresponding_rsa_files_exist?
+ 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?"
+ puts "Keep current key? [y/n]"
+
+ while true
+ keep_current_file = STDIN.gets.strip
+
+ case keep_current_file
+
+ when "y"
+ return true # keep the files already in .gas, skip making key.
+ when "n"
+ return false
+ else
+ puts "please respond 'y' or 'n'"
+ end
+ end
+
+ else # no need to do anything if files don't exist
+ return false
+ end
+ end
+
+
+ # If the user says 'f', the system will
# report that there isn't an id_rsa already in gas. This causes a new key to overwrite automatically down the road.
# This is for checking if a .gas/rsa file already exists for a nickname which is being registered
# If the rsa exists, then we're goona need to ask if we should use it, or if we should delete it
@@ -13,7 +40,7 @@ class Ssh
#
# TODO should report an error if there is a write protection problem which prevents gas from deleting the file, or
# at least warn the user that there bidding could not be carried out.
- def self.id_rsa_already_in_gas_dir_for_use?
+ def self.user_wants_to_use_key_already_in_gas?
if corresponding_rsa_files_exist?
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?"
puts "Keep current key? [y/n]"
@@ -63,6 +90,7 @@ def self.gas_dir_exists? # TODO: Wipe this function out, I don't think i
def self.use_current_rsa_files_for_this_user
cmd_result = `cp ~/.ssh/id_rsa ~/.gas/#{@uid}_id_rsa` # TODO: make this into ruby code so its faster I guess?
cmd_result = `cp ~/.ssh/id_rsa.pub ~/.gas/#{@uid}_id_rsa.pub` # TODO: Handle permission errors
+ puts "This is for checking the test... #{@uid}"
return true
end
@@ -75,6 +103,7 @@ def self.ssh_dir_contains_rsa?
# Checks if the ~/.ssh directroy contains id_rsa and id_rsa.pub
# 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.
#
+ # TODO: remove me, obsolete after "Impliment the below form..." refactor is complete
def self.id_rsa_already_in_ssh_directory?
return false unless ssh_dir_contains_rsa?
@@ -95,30 +124,54 @@ def self.id_rsa_already_in_ssh_directory?
end
end
+ # Checks if the ~/.ssh directroy contains id_rsa and id_rsa.pub
+ # 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.
+ #
+ def self.user_wants_to_use_key_already_in_ssh?
+ return false unless ssh_dir_contains_rsa?
+
+ #puts "Gas has detected that an ~/.ssh/id_rsa file already exists. Would you like to use this as your ssh key to connect with github? Otherwise a new key will be generated and stored in ~/.gas (no overwrite concerns until you 'gas use nickname')"
+ puts "Generate a brand new ssh key pair?"
+ puts "[y/n]"
+
+ while true
+ generate_new_rsa = STDIN.gets.strip
+ case generate_new_rsa
+ when "y"
+ return false
+ when "n"
+ return true # return true if we aren't generating a new key
+ else
+ puts "plz answer 'y' or 'n'"
+ end
+ end
+ end
+
+
# Generates a new sshkey putting it in ~/.gas/nickname_id_rsa
def self.generate_new_rsa_keys_in_gas_dir
puts "Generating new ssh key..."
# TODO: Prompt user if they'd like to use a more secure password if physical security to their computer is not possible (dumb imo)
+ # Old ssh key method (relies on unix environment)
# puts `ssh-keygen -f ~/.gas/#{@uid}_id_rsa -t rsa -C "#{@email}" -N ""` # ssh-keygen style key creation
- if true # new sshkey gem method...
- # XXX use sshkey gem instead of command line utilitie
- k = SSHKey.generate(:comment => "#{@email}")
-
- publ = k.ssh_public_key
- privl = k.private_key
-
- my_file_privl = File.open(GAS_DIRECTORY + "/#{@uid}_id_rsa",'w')
- my_file_privl.write(privl)
- my_file_privl.close
-
- my_file_publ = File.open(GAS_DIRECTORY + "/#{@uid}_id_rsa.pub",'w')
- my_file_publ.write(publ)
- my_file_publ.close
- end
+ # new sshkey gem method...
+ # XXX use sshkey gem instead of command line utilitie
+ k = SSHKey.generate(:comment => "#{@email}")
+
+ publ = k.ssh_public_key
+ privl = k.private_key
+
+ my_file_privl = File.open(GAS_DIRECTORY + "/#{@uid}_id_rsa",'w',0700)
+ my_file_privl.write(privl)
+ my_file_privl.close
+
+ my_file_publ = File.open(GAS_DIRECTORY + "/#{@uid}_id_rsa.pub",'w',0700)
+ my_file_publ.write(publ)
+ my_file_publ.close
@@ -131,9 +184,7 @@ def self.generate_new_rsa_keys_in_gas_dir
def self.setup_ssh_keys(user)
@uid = user.nickname # TODO: question: are nicknames allowed to be nil? If not, this coding can be reduced to one line of code
@uid = user.name if @uid.nil?
-
@email = user.email
- # TODO Check and see if i need to "require" ssh-keygen and ssh-add or something like that.
puts "Do you want gas to handle switching rsa keys for this user?"
puts "[y/n]"
@@ -144,12 +195,23 @@ def self.setup_ssh_keys(user)
case handle_rsa
when "y"
puts
- return true if id_rsa_already_in_gas_dir_for_use? # No more work needs to be done if the files already exists
+ # return true if id_rsa_already_in_gas_dir_for_use? # No more work needs to be done if the files already exists
+
+ # TODO: Impliment the below formatting so it's easier to test and easier to read my own code
+ #
+ if user_wants_to_use_key_already_in_gas?
+ return true # because gas directory is already setup
+ elsif user_wants_to_use_key_already_in_ssh? # Check ~/.ssh for a current id_rsa file, if yes, "Do you want to use the current id_rsa file to be used as your key?"
+ use_current_rsa_files_for_this_user # copies the keys from ~/.ssh instead of generating new keys if desired/possible
+ return true
+ else
+ return generate_new_rsa_keys_in_gas_dir
+ end
+
+ #return true if id_rsa_already_in_ssh_directory?
- # Check ~/.ssh for a current id_rsa file, if yes, "Do you want to use the current id_rsa file to be used as your key?"
- return true if id_rsa_already_in_ssh_directory? # copies the keys instead of generating new keys if desired/possible
- return generate_new_rsa_keys_in_gas_dir
+ # return generate_new_rsa_keys_in_gas_dir
when "n"
puts
@@ -225,12 +287,16 @@ def self.swap_in_rsa(nickname)
end
def self.write_to_ssh_dir!
- `ssh-add -d ~/.ssh/id_rsa` # remove the current key from the ssh-agent session (key will no longer be used with github)
+ `ssh-add -d ~/.ssh/id_rsa` if is_ssh_agent_there? # remove the current key from the ssh-agent session (key will no longer be used with github)
- `cp ~/.gas/#{@uid}_id_rsa ~/.ssh/id_rsa`
- `cp ~/.gas/#{@uid}_id_rsa.pub ~/.ssh/id_rsa.pub`
+ FileUtils.cp(GAS_DIRECTORY + "/#{@uid}_id_rsa", SSH_DIRECTORY + "/id_rsa")
+ FileUtils.cp(GAS_DIRECTORY + "/#{@uid}_id_rsa.pub", SSH_DIRECTORY + "/id_rsa.pub")
- `ssh-add ~/.ssh/id_rsa` # TODO: you need to run this command to get the private key to be set to active on unix based machines. Not sure what to do for windows yet...
+ if is_ssh_agent_there?
+ `ssh-add ~/.ssh/id_rsa` # TODO: you need to run this command to get the private key to be set to active on unix based machines. Not sure what to do for windows yet...
+ else
+ puts "Slight Error: The key should now be in ~/.ssh so that's good, BUT ssh-add could not be found. If you're using windows, you'll need to use git bash or cygwin to emulate this unix command and actually do uploads."
+ end
end
# This function scans each file in a directory to check to see if it is the same file which it's being compared against
@@ -260,7 +326,10 @@ def self.current_key_already_backed_up?
end
def self.get_md5_hash(file_path)
- return Digest::MD5.hexdigest(File.open(file_path, "rb").read)
+ if File.exists? file_path
+ return Digest::MD5.hexdigest(File.open(file_path, "rb").read)
+ end
+ return nil
end
@@ -303,6 +372,43 @@ def log_in_and_figure_out_where_to_post_to
def post_key!
end
+
+ # Cross-platform way of finding an executable in the $PATH.
+ # returns nil if command not present
+ #
+ # which('ruby') #=> /usr/bin/ruby
+ def self.which(cmd)
+ exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
+ ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
+ exts.each { |ext|
+ exe = "#{path}/#{cmd}#{ext}"
+ return exe if File.executable? exe
+ }
+ end
+ return nil
+ end
+
+ def self.is_ssh_agent_there?
+ return false if which("ssh-add").nil?
+ return true
+ end
+
+ # deletes the ssh keys associated with a user
+ def self.delete(nickname)
+ # XXX: check if this user's key is also in ~/.ssh
+ ssh_file = get_md5_hash("#{SSH_DIRECTORY}/id_rsa")
+ gas_file = get_md5_hash("#{GAS_DIRECTORY}/#{nickname}_id_rsa")
+
+ return false if gas_file.nil? # if the gas file doesn't exist, return from this function safely
+
+ if ssh_file == gas_file
+ File.delete("#{SSH_DIRECTORY}/id_rsa")
+ File.delete("#{SSH_DIRECTORY}/id_rsa.pub")
+ end
+
+ File.delete("#{GAS_DIRECTORY}/#{nickname}_id_rsa")
+ File.delete("#{GAS_DIRECTORY}/#{nickname}_id_rsa.pub")
+ end
end
end
Oops, something went wrong.

0 comments on commit 7591652

Please sign in to comment.