ssh_key_switcher 1.0.3 → 1.0.5

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e7f59312f44c114b17c557087b6dc0e604fbfe025db9613d06be9bd19753a8c3
4
- data.tar.gz: 427d18035620685e542db76f523ef15517d1ade3f3ff9b8adc445e3ad925a4b1
3
+ metadata.gz: e2ad23e81673482e19d3eae55c0b787ef26f1dfd3f1d1e213a1c10039495478d
4
+ data.tar.gz: 1f539080d59584e814f18d4732df9e89e1c13c8607b9d5b12de6c30d536b9db4
5
5
  SHA512:
6
- metadata.gz: dd423e8c3d1d5b009c8baf5d15546e61173f264cacb73541de8ca25f02812a35915f997d1f1a696b789c77a62189cacf8e8f3818c1f92424f184d001bd1f4155
7
- data.tar.gz: 3832b8f3f06e805b4922b154e1593092b78d7498894784b257fdb79c36eca9de79c6f53297123bdbc744ccef6ac82e5374c9c3b4cb1448ff911adb2c9c6a8931
6
+ metadata.gz: e294cfbab8f108aa2138b780636ae58ef0686b8a62554c8d986b3d621379c56e3f03644e1a778616b727e0259e82562fa02810ad0214009f9d2dd3a84c7e45c6
7
+ data.tar.gz: 96ff45770f8fe42842fa55466e84cfd3f340bc4e14827ee120605d45b6ce6f7e96d56e26e61af3970b73cd3f6a67e024ed639058011f3407f7dba76778a9e2a2
data/README.md CHANGED
@@ -64,6 +64,15 @@ $ sks -s [--select]
64
64
 
65
65
  Allows you to interactively select and set an OpenSSH key for your sessions.
66
66
 
67
+ ### List of OpenSSH Keys
68
+
69
+ ```bash
70
+ $ sks -l [--list]
71
+
72
+ ```
73
+
74
+ Display a list of OpenSSH keys.
75
+
67
76
  ### List Active OpenSSH Keys
68
77
 
69
78
  ```bash
@@ -92,10 +101,23 @@ The gem is available as open source under the terms of the [MIT License](https:/
92
101
 
93
102
  ## Development
94
103
 
95
- After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
104
+ **Debug**
96
105
 
97
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
106
+ ```bash
107
+ bundle exec sks [option]
108
+ ```
98
109
 
110
+ **Install locally to test**
111
+
112
+ ```bash
113
+ bin/install-local [version]
114
+ ```
115
+
116
+ **Release**
117
+
118
+ ```bash
119
+ bin/release [version]
120
+ ```
99
121
 
100
122
  ## Contributor
101
123
 
@@ -5,24 +5,11 @@ module SshKeySwitcher
5
5
  class CurrentAgent
6
6
  class << self
7
7
  def fetch_results
8
- results = []
9
- payload = Cmd.exec('ssh-add -l')[0]
10
- payload.each_line { |line| results << line.split.last(2).join(' ') }
11
- results
8
+ Helper.current_active_keys
12
9
  end
13
10
 
14
11
  def display
15
- if fetch_results[0].include?('no identities')
16
- prompt.warn('No active SSH keys')
17
- elsif fetch_results.size == 1
18
- prompt.say('Active SSH key: ')
19
- prompt.ok(fetch_results[0])
20
- else
21
- prompt.say('List of active SSH keys:')
22
- fetch_results.each.with_index(1) do |result, index|
23
- prompt.ok(" #{index}) #{result}")
24
- end
25
- end
12
+ Helper.display_current_ssh_keys(prompt)
26
13
  end
27
14
 
28
15
  private
@@ -5,9 +5,9 @@ module SshKeySwitcher
5
5
  class Delete
6
6
  class << self
7
7
  def display_select
8
- keys = Helper.find_open_ssh_keys
9
- if keys.empty?
10
- prompt.error('No OpenSSH keys found in ~/.ssh')
8
+ files = Helper.find_ssh_keys
9
+ if files.empty?
10
+ prompt.error("No OpenSSH keys found in #{SSH_DIR}")
11
11
  nil
12
12
  else
13
13
  msg = 'Choose the OpenSSH keys to REMOVE. Press [CTRL+C] to exit.'
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SshKeySwitcher
4
+ module Options
5
+ class List
6
+ class << self
7
+ def display
8
+ ssh_keys = Helper.find_ssh_keys
9
+ if ssh_keys.empty?
10
+ prompt.error("No OpenSSH keys found in #{SSH_DIR}")
11
+ nil
12
+ else
13
+ prompt.say('List of OpenSSH keys:')
14
+ Helper.display_list_keys(prompt, ssh_keys, color: :blue)
15
+ end
16
+
17
+ print "\n"
18
+ Helper.display_current_ssh_keys(prompt)
19
+ end
20
+
21
+ private
22
+
23
+ include SshKeySwitcher::Contains
24
+ include SshKeySwitcher::Utils
25
+
26
+ def prompt
27
+ @prompt ||= TTY::Prompt.new(interrupt: :exit)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -7,7 +7,10 @@ module SshKeySwitcher
7
7
  def pong
8
8
  server_names = SERVER_NAMES.map { |server| "git@#{server}" }
9
9
  result = prompt.select('Connect to', server_names, default: 'git@github.com')
10
- Cmd.exec("ssh -T #{result}", print: true)
10
+ stdout, stderr, status = Cmd.exec("ssh -T #{result}")
11
+ return prompt.ok(stdout) if status.success?
12
+
13
+ prompt.error(stderr)
11
14
  end
12
15
 
13
16
  private
@@ -5,7 +5,7 @@ module SshKeySwitcher
5
5
  class Remove
6
6
  class << self
7
7
  def display_select
8
- keys = Helper.find_open_ssh_keys
8
+ keys = Helper.find_ssh_keys
9
9
  if keys.empty?
10
10
  prompt.error('No OpenSSH keys found in ~/.ssh')
11
11
  nil
@@ -5,23 +5,26 @@ module SshKeySwitcher
5
5
  class Select
6
6
  class << self
7
7
  def display_select
8
- ssh_keys = Helper.find_open_ssh_keys
8
+ ssh_keys = Helper.find_ssh_keys
9
9
  if ssh_keys.empty?
10
- prompt.error('No OpenSSH keys found in ~/.ssh')
10
+ prompt.error("No OpenSSH keys found in #{SSH_DIR}")
11
11
  nil
12
12
  else
13
13
  prompt.select('Select an OpenSSH key:', select_options) do |menu|
14
14
  menu.enum '.'
15
15
  select_choices(menu, ssh_keys)
16
16
  end
17
-
18
17
  end
19
18
  end
20
19
 
21
20
  def add(path_open_ssh_key)
21
+ return if path_open_ssh_key.nil?
22
+
22
23
  SshKeySwitcher::Utils::SshAgent.remove_all
23
- SshKeySwitcher::Utils::SshAgent.add(path_open_ssh_key)
24
- prompt.ok('OpenSSH key added successfully!')
24
+ _stdout, stderr, status = SshKeySwitcher::Utils::SshAgent.add(path_open_ssh_key)
25
+ return prompt.ok('Add OpenSSH key successfully!') if status.success?
26
+
27
+ prompt.error(stderr)
25
28
  end
26
29
 
27
30
  private
@@ -44,10 +47,10 @@ module SshKeySwitcher
44
47
  }
45
48
  end
46
49
 
47
- def select_choices(menu, keys)
48
- keys.each do |value|
49
- display_text = value.split('/').last(2).join('/').gsub('.ssh/', '')
50
- menu.choice display_text, value
50
+ def select_choices(menu, ssh_keys)
51
+ ssh_keys.each do |key|
52
+ display_text = Helper.filename(key)
53
+ menu.choice display_text, key
51
54
  end
52
55
  end
53
56
  end
@@ -7,12 +7,8 @@ module SshKeySwitcher
7
7
  module Cmd
8
8
  module_function
9
9
 
10
- def exec(command, opts = {})
10
+ def exec(command, _opts = {})
11
11
  stdout, stderr, status = Open3.capture3(command)
12
- if opts[:print]
13
- print stderr
14
- print stdout
15
- end
16
12
  [stdout, stderr, status]
17
13
  end
18
14
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module SshKeySwitcher
4
4
  module Contains
5
- SSH_DIR = '~/.ssh'
5
+ SSH_DIR = "#{Dir.home}/.ssh"
6
6
  STRING_DETECT_OPENSSH_KEY = 'OPENSSH'
7
7
  SERVER_NAMES = %w[github.com gitlab.com bitbucket.org].freeze
8
8
  end
@@ -7,20 +7,61 @@ module SshKeySwitcher
7
7
 
8
8
  module_function
9
9
 
10
- def find_open_ssh_keys
11
- ssh_folder = File.expand_path(SSH_DIR)
10
+ def find_ssh_keys
11
+ files = fetch_private_ssh_keys_via_header
12
+ files += fetch_private_ssh_keys_via_filename
13
+ files.flatten.uniq.sort
14
+ end
15
+
16
+ def fetch_private_ssh_keys_via_header
17
+ ssh_dir = File.expand_path(SSH_DIR)
18
+ Dir.glob("#{ssh_dir}/**/*").select do |file|
19
+ next if File.directory?(file)
20
+
21
+ File.open(file, 'rb') do |f|
22
+ # Read the first 20 bytes from the file
23
+ header = f.read(20)
24
+ header.include?(STRING_DETECT_OPENSSH_KEY)
25
+ end
26
+ end
27
+ end
28
+
29
+ def fetch_private_ssh_keys_via_filename
30
+ ssh_dir = File.expand_path(SSH_DIR)
31
+ Dir.glob("#{ssh_dir}/**/*.pub").map { |file| file.gsub('.pub', '') }
32
+ end
12
33
 
13
- Dir.glob("#{ssh_folder}/*").select { |file| valid_ssh_key?(file) }.sort
34
+ def filename(key)
35
+ key.gsub("#{SSH_DIR}/", '').gsub('.pub', '').strip
36
+ end
37
+
38
+ def current_active_keys
39
+ results = []
40
+ payload = Cmd.exec('ssh-add -l')[0]
41
+ payload.each_line { |line| results << line.split.last(2).join(' ') }
42
+ results
43
+ end
44
+
45
+ def display_current_ssh_keys(prompt, color: :green)
46
+ ssh_keys = Helper.current_active_keys
47
+
48
+ if ssh_keys[0].include?('no identities')
49
+ prompt.warn('No active SSH keys')
50
+ elsif ssh_keys.size == 1
51
+ prompt.say("Active SSH key: #{ssh_keys[0]}", color: color)
52
+ else
53
+ prompt.say('List of active SSH keys:')
54
+ Helper.display_list_keys(prompt, ssh_keys, color: color)
55
+ end
14
56
  end
15
57
 
16
- def valid_ssh_key?(file)
17
- File.open(file, 'rb') do |f|
18
- # Read the first 20 bytes from the file
19
- header = f.read(20)
20
- header.include?(STRING_DETECT_OPENSSH_KEY)
58
+ def display_list_keys(prompt, ssh_keys, color: :blue)
59
+ max_space_size = ssh_keys.size.to_s.size
60
+ ssh_keys.each.with_index(1) do |key, idx|
61
+ space_size = max_space_size - (idx < 10 ? 0 : idx.to_s.size - 1)
62
+ filename = Helper.filename(key)
63
+ prompt.say(format(" %d.%#{space_size}s%s", idx, ' ', filename), color: color)
21
64
  end
22
- rescue StandardError
23
- false
24
65
  end
25
66
  end
26
67
  end
@@ -3,8 +3,12 @@
3
3
  module SshKeySwitcher
4
4
  module Utils
5
5
  class SshAgent
6
- def self.add(key)
7
- Cmd.exec("ssh-add #{key}")
6
+ def self.start_ssh_agent
7
+ Cmd.exec('eval $(ssh-agent -s)')
8
+ end
9
+
10
+ def self.add(private_key)
11
+ Cmd.exec("ssh-add #{private_key}")
8
12
  end
9
13
 
10
14
  def self.remove_all
@@ -14,6 +18,11 @@ module SshKeySwitcher
14
18
  def self.del(path)
15
19
  Cmd.exec("ssh-add -d #{path}")
16
20
  end
21
+
22
+ def self.start_ssh_agent_if_needed
23
+ ssh_agent_pid = ENV.fetch('SSH_AGENT_PID', nil)
24
+ start_ssh_agent if ssh_agent_pid.nil? || !system("ps -p #{ssh_agent_pid} > /dev/null 2>&1")
25
+ end
17
26
  end
18
27
  end
19
28
  end
@@ -1,3 +1,3 @@
1
1
  module SshKeySwitcher
2
- VERSION = "1.0.3"
2
+ VERSION = "1.0.5"
3
3
  end
@@ -10,6 +10,7 @@ module SshKeySwitcher
10
10
  class Error < StandardError; end
11
11
 
12
12
  class CLI < Thor
13
+ SshKeySwitcher::Utils::SshAgent.start_ssh_agent_if_needed
13
14
  ENV['THOR_SILENCE_DEPRECATION'] = 'true'
14
15
 
15
16
  desc 'version [-v, --version]', 'Show version'
@@ -31,6 +32,12 @@ module SshKeySwitcher
31
32
  SshKeySwitcher::Options::Select.add(path_open_ssh_key)
32
33
  end
33
34
 
35
+ desc 'list [-l, --list]', 'List of OpenSSH key files'
36
+ map %w[-l --list] => :list
37
+ def list
38
+ SshKeySwitcher::Options::List.display
39
+ end
40
+
34
41
  desc 'current [-c, --current]', 'List of active OpenSSH keys'
35
42
  map %w[-c --current] => :current
36
43
  def current
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ssh_key_switcher
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
4
+ version: 1.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Minh Tang Q.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-12-05 00:00:00.000000000 Z
11
+ date: 2024-08-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -52,6 +52,7 @@ files:
52
52
  - lib/ssh_key_switcher.rb
53
53
  - lib/ssh_key_switcher/options/current_agent.rb
54
54
  - lib/ssh_key_switcher/options/delete.rb
55
+ - lib/ssh_key_switcher/options/list.rb
55
56
  - lib/ssh_key_switcher/options/ping.rb
56
57
  - lib/ssh_key_switcher/options/remove.rb
57
58
  - lib/ssh_key_switcher/options/select.rb
@@ -83,7 +84,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
83
84
  - !ruby/object:Gem::Version
84
85
  version: '0'
85
86
  requirements: []
86
- rubygems_version: 3.1.4
87
+ rubygems_version: 3.4.6
87
88
  signing_key:
88
89
  specification_version: 4
89
90
  summary: A simple and efficient for managing and switching between OpenSSH keys seamlessly