2pass 1.0.0
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 +7 -0
- data/2pass.gemspec +25 -0
- data/README.md +68 -0
- data/bin/2pass +75 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/2pass/version.rb +3 -0
- data/lib/2pass.rb +69 -0
- metadata +113 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 6bc01e1efadcf89aa03153837fe43b43636879457474ed74ec1cc7e8fd23c6db
|
4
|
+
data.tar.gz: f1bc2a3daaf6925a81106c4eae4b7e5ab54a56a31eaf115bca3672523056db3c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: aa7041a6501a9214ee30a21482de8fb5251c35731d23e95f3de87dd746f9c85c8bbc3f6cc03dfadf0126e994ea326e40175a7a408434d98f3bd43f1659ce4473
|
7
|
+
data.tar.gz: 433739132ea8b97032bc3a602da682a655a3a657adaa58d6b32828edd884de102ee2696c1f3f6c01e57b01fd59dc51121c08215f2335c6277e3dcab09f48ca2d
|
data/2pass.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# 2pass.gemspec
|
2
|
+
|
3
|
+
require_relative "lib/2pass/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "2pass"
|
7
|
+
spec.version = ::TwoPass::VERSION
|
8
|
+
spec.authors = ["Olivier"]
|
9
|
+
spec.email = ["contact@yafoy.com"]
|
10
|
+
|
11
|
+
spec.summary = "A CLI app for managing secrets"
|
12
|
+
spec.description = "2pass is a CLI application for managing YAML-based vaults."
|
13
|
+
spec.homepage = "https://2pass.xyz"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = Dir["lib/**/*", "bin/*", "2pass.gemspec", "README.md"]
|
17
|
+
spec.bindir = "bin"
|
18
|
+
spec.executables = ["2pass"]
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 2.0"
|
22
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
23
|
+
spec.add_development_dependency "minitest", "~> 5.0"
|
24
|
+
spec.add_development_dependency "minitest-reporters", "~> 1.3", ">= 1.3.0"
|
25
|
+
end
|
data/README.md
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
# 2Pass CLI
|
2
|
+
|
3
|
+
[](https://yafoy.semaphoreci.com/projects/cli)
|
4
|
+
|
5
|
+
A super simple CLI to access secrets.
|
6
|
+
|
7
|
+
The objective is to have a shared password manager that can be integrated with [Kamal](https://github.com/basecamp/kamal) deployment tool.
|
8
|
+
|
9
|
+
## Getting started
|
10
|
+
|
11
|
+
```sh
|
12
|
+
mkdir ~/.2pass/
|
13
|
+
```
|
14
|
+
|
15
|
+
Create a vault file with the following data structure.
|
16
|
+
An array of hashes with the following keys:
|
17
|
+
|
18
|
+
- id
|
19
|
+
- value
|
20
|
+
- uuid
|
21
|
+
|
22
|
+
```sh
|
23
|
+
touch ~/.2pass/vault_name.yml
|
24
|
+
```
|
25
|
+
|
26
|
+
Alternatively, if you have a vault file in a different location, you can link it.
|
27
|
+
|
28
|
+
```sh
|
29
|
+
2pass link vault_name /path/to/vault_name.yml
|
30
|
+
```
|
31
|
+
|
32
|
+
Then build the gem and install it.
|
33
|
+
|
34
|
+
```sh
|
35
|
+
gem build 2pass.gemspec
|
36
|
+
gem install 2pass-0.1.0.gem
|
37
|
+
```
|
38
|
+
|
39
|
+
## Usage
|
40
|
+
|
41
|
+
```sh
|
42
|
+
2pass -h
|
43
|
+
2pass get <vault_name> <id>
|
44
|
+
2pass list <vault_name>
|
45
|
+
2pass add <vault_name> <id> <value>
|
46
|
+
```
|
47
|
+
|
48
|
+
## Development
|
49
|
+
|
50
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
51
|
+
|
52
|
+
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 tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
53
|
+
|
54
|
+
To experiment with that code, run `bin/console` for an interactive prompt.
|
55
|
+
|
56
|
+
### Testing
|
57
|
+
|
58
|
+
Run tests locally
|
59
|
+
|
60
|
+
```sh
|
61
|
+
rake test TEST=**/*/example_test.rb
|
62
|
+
rake test
|
63
|
+
DEBUG=1 rake test
|
64
|
+
```
|
65
|
+
|
66
|
+
## License
|
67
|
+
|
68
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/bin/2pass
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require_relative "../lib/2pass"
|
4
|
+
|
5
|
+
def help_message
|
6
|
+
puts <<~HELP
|
7
|
+
Usage:
|
8
|
+
2pass add <vault_name> <id> <value> - Add new secret
|
9
|
+
2pass get <vault_name> <id> - Get content by ID from the specified vault
|
10
|
+
2pass list <vault_name> - List the content of the specified vault
|
11
|
+
2pass link <vault_name> <target_path> - Create a symlink for an existing vault. Useful when the vault is stored in a synced place (iCloud, Dropbox, etc.)
|
12
|
+
2pass -h - Display this help message
|
13
|
+
HELP
|
14
|
+
end
|
15
|
+
|
16
|
+
options = {}
|
17
|
+
OptionParser.new do |opts|
|
18
|
+
opts.banner = "Usage: 2pass [options]"
|
19
|
+
|
20
|
+
opts.on("-h", "--help", "Display this help message") do
|
21
|
+
options[:help] = true
|
22
|
+
end
|
23
|
+
end.parse!
|
24
|
+
|
25
|
+
if options[:help]
|
26
|
+
help_message
|
27
|
+
exit
|
28
|
+
end
|
29
|
+
|
30
|
+
if ARGV.length < 2
|
31
|
+
help_message
|
32
|
+
exit(1)
|
33
|
+
end
|
34
|
+
|
35
|
+
command, vault_name, *args = ARGV
|
36
|
+
|
37
|
+
begin
|
38
|
+
case command
|
39
|
+
when "get"
|
40
|
+
if args.length < 1
|
41
|
+
help_message
|
42
|
+
exit(1)
|
43
|
+
end
|
44
|
+
id = args[0]
|
45
|
+
puts TwoPass.get_secret(vault_name, id)
|
46
|
+
when "add"
|
47
|
+
if args.length != 2
|
48
|
+
help_message
|
49
|
+
exit(1)
|
50
|
+
end
|
51
|
+
TwoPass.add_secret(vault_name, args[0], args[1])
|
52
|
+
when "list"
|
53
|
+
puts TwoPass.list_content(vault_name)
|
54
|
+
when "link"
|
55
|
+
if args.length < 1
|
56
|
+
help_message
|
57
|
+
exit(1)
|
58
|
+
end
|
59
|
+
target_path = args[0]
|
60
|
+
TwoPass.create_symlink(vault_name, target_path)
|
61
|
+
when "help"
|
62
|
+
help_message
|
63
|
+
else
|
64
|
+
help_message
|
65
|
+
end
|
66
|
+
rescue => e
|
67
|
+
STDERR.puts e.message
|
68
|
+
|
69
|
+
if ENV["DEBUG"]
|
70
|
+
STDERR.puts
|
71
|
+
STDERR.puts e.backtrace
|
72
|
+
end
|
73
|
+
|
74
|
+
exit 1
|
75
|
+
end
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "2pass"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/lib/2pass.rb
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
require "optparse"
|
2
|
+
require "json"
|
3
|
+
require "yaml"
|
4
|
+
require "fileutils"
|
5
|
+
require "securerandom"
|
6
|
+
|
7
|
+
require_relative "2pass/version"
|
8
|
+
|
9
|
+
module TwoPass
|
10
|
+
VAULT_DIR = "#{Dir.home}/.2pass"
|
11
|
+
|
12
|
+
def self.create_symlink(vault_name, target_path)
|
13
|
+
FileUtils.mkdir_p(VAULT_DIR)
|
14
|
+
symlink_path = "#{VAULT_DIR}/#{vault_name}.yml"
|
15
|
+
|
16
|
+
if File.exist?(symlink_path)
|
17
|
+
puts "Symlink already exists: #{symlink_path}"
|
18
|
+
else
|
19
|
+
File.symlink(target_path, symlink_path)
|
20
|
+
puts "Created symlink: #{symlink_path} -> #{target_path}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.load_vault(vault_name)
|
25
|
+
file_path = "#{VAULT_DIR}/#{vault_name}.yml"
|
26
|
+
return [] unless File.exist?(file_path)
|
27
|
+
|
28
|
+
YAML.load_file(file_path, symbolize_names: true) || []
|
29
|
+
rescue Psych::SyntaxError => e
|
30
|
+
STDERR.puts "Error parsing YAML file: #{e.message}"
|
31
|
+
[]
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.save_vault(vault_name, data)
|
35
|
+
FileUtils.mkdir_p(VAULT_DIR)
|
36
|
+
file_path = "#{VAULT_DIR}/#{vault_name}.yml"
|
37
|
+
File.write(file_path, YAML.dump(data))
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.list_content(vault_name)
|
41
|
+
vault = load_vault(vault_name)
|
42
|
+
JSON.pretty_generate(vault)
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.add_secret(vault_name, id, value)
|
46
|
+
new_secret = {
|
47
|
+
id: id,
|
48
|
+
value: value,
|
49
|
+
uuid: SecureRandom.uuid
|
50
|
+
}
|
51
|
+
data = load_vault(vault_name)
|
52
|
+
existing_entry_id = data.find_index { |hash| hash[:id] == new_secret[:id] }
|
53
|
+
if existing_entry_id
|
54
|
+
raise "The secret already exists"
|
55
|
+
end
|
56
|
+
data << new_secret
|
57
|
+
save_vault(vault_name, data)
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.get_secret(vault_name, id)
|
61
|
+
vault = load_vault(vault_name)
|
62
|
+
entry = vault.find { |hash| hash[:id] == id }
|
63
|
+
if entry
|
64
|
+
entry[:value]
|
65
|
+
else
|
66
|
+
raise "Entry not found"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
metadata
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: 2pass
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Olivier
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-08-31 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '13.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '13.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '5.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '5.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: minitest-reporters
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.3'
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: 1.3.0
|
65
|
+
type: :development
|
66
|
+
prerelease: false
|
67
|
+
version_requirements: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - "~>"
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '1.3'
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: 1.3.0
|
75
|
+
description: 2pass is a CLI application for managing YAML-based vaults.
|
76
|
+
email:
|
77
|
+
- contact@yafoy.com
|
78
|
+
executables:
|
79
|
+
- 2pass
|
80
|
+
extensions: []
|
81
|
+
extra_rdoc_files: []
|
82
|
+
files:
|
83
|
+
- 2pass.gemspec
|
84
|
+
- README.md
|
85
|
+
- bin/2pass
|
86
|
+
- bin/console
|
87
|
+
- bin/setup
|
88
|
+
- lib/2pass.rb
|
89
|
+
- lib/2pass/version.rb
|
90
|
+
homepage: https://2pass.xyz
|
91
|
+
licenses:
|
92
|
+
- MIT
|
93
|
+
metadata: {}
|
94
|
+
post_install_message:
|
95
|
+
rdoc_options: []
|
96
|
+
require_paths:
|
97
|
+
- lib
|
98
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
104
|
+
requirements:
|
105
|
+
- - ">="
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '0'
|
108
|
+
requirements: []
|
109
|
+
rubygems_version: 3.5.11
|
110
|
+
signing_key:
|
111
|
+
specification_version: 4
|
112
|
+
summary: A CLI app for managing secrets
|
113
|
+
test_files: []
|