tfa 0.0.3 → 0.0.4

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
  SHA1:
3
- metadata.gz: ebf6d9964833d410f0acdb43efb3c6023c856c81
4
- data.tar.gz: d7a46b812f7d40e668b7adca69af525f489530ed
3
+ metadata.gz: 414adc245dc71f49bbb95a5458410235771fe475
4
+ data.tar.gz: 0e6000d5e9a261ab11281be9927e0038d6de2af2
5
5
  SHA512:
6
- metadata.gz: 42a58b16b4b0675caa6ec321b7814279923f362265d21cb89b6e25bb43859b95527ae84be8b3898b5d849d365e01a31d911862fbfbf9c09d85051f7085a03162
7
- data.tar.gz: 13718267072086181704e5cc9a1ea3694e7e8bc45dfaf27a8c1a70d5da558a98a8edc01438be4ec751b0e9e95fa510cc0a030a5ae6fa8742a3d8278a312b5933
6
+ metadata.gz: 5645d6a5f42cebf8923148d85fc5be2b20e7f26666cc3075972d8ff4ce93ec66ff647b5c6544fb7dd6ed5ce3410cf0bc5879b48f40b44ceb0976dd6d7019fff9
7
+ data.tar.gz: 111d469cf45c8a343fd451b3c890f1b14d2c79533ec5be96a93ee5a31ed042a5d54f07ec1446bc3e2304317def1a1c7ab649fa609aa3c26a4c6a7b374846bf38
@@ -6,10 +6,7 @@ module TFA
6
6
 
7
7
  def run(arguments)
8
8
  name = arguments.first
9
- secret = arguments.last
10
- @storage.transaction do
11
- @storage[name] = secret
12
- end
9
+ @storage.save(arguments.first, arguments.last)
13
10
  "Added #{name}"
14
11
  end
15
12
  end
data/lib/tfa/console.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  module TFA
2
2
  class Console
3
3
  def initialize(filename = "tfa")
4
- @storage = PStore.new(File.join(Dir.home, ".#{filename}.pstore"))
4
+ @storage = Storage.new(filename)
5
5
  end
6
6
 
7
7
  def run(arguments)
@@ -12,15 +12,14 @@ module TFA
12
12
  private
13
13
 
14
14
  def command_for(command_name)
15
- case command_name
16
- when "add"
17
- AddCommand.new(@storage)
18
- when "show"
19
- ShowCommand.new(@storage)
20
- when "totp"
21
- TotpCommand.new(@storage)
22
- else
23
- UsageCommand.new(@storage)
15
+ registry[command_name].call
16
+ end
17
+
18
+ def registry
19
+ Hash.new { |x, y| lambda { UsageCommand.new(@storage) } }.tap do |commands|
20
+ commands['add'] = lambda { AddCommand.new(@storage) }
21
+ commands['show'] = lambda { ShowCommand.new(@storage) }
22
+ commands['totp'] = lambda { TotpCommand.new(@storage) }
24
23
  end
25
24
  end
26
25
  end
@@ -5,10 +5,8 @@ module TFA
5
5
  end
6
6
 
7
7
  def run(arguments)
8
- name = arguments.last
9
- @storage.transaction(true) do
10
- @storage[name]
11
- end
8
+ return @storage.secret_for(arguments.last) if arguments.any?
9
+ @storage.all_secrets
12
10
  end
13
11
  end
14
12
  end
@@ -0,0 +1,33 @@
1
+ module TFA
2
+ class Storage
3
+ def initialize(filename)
4
+ @storage = PStore.new(File.join(Dir.home, ".#{filename}.pstore"))
5
+ end
6
+
7
+ def all_secrets
8
+ open_readonly do |storage|
9
+ storage.roots.map { |key| { key => storage[key] } }
10
+ end
11
+ end
12
+
13
+ def secret_for(key)
14
+ open_readonly do |storage|
15
+ storage[key]
16
+ end
17
+ end
18
+
19
+ def save(key, value)
20
+ @storage.transaction do
21
+ @storage[key] = value
22
+ end
23
+ end
24
+
25
+ private
26
+
27
+ def open_readonly
28
+ @storage.transaction(true) do
29
+ yield @storage
30
+ end
31
+ end
32
+ end
33
+ end
@@ -5,16 +5,26 @@ module TFA
5
5
  end
6
6
 
7
7
  def run(arguments)
8
- name = arguments.first
9
- ::ROTP::TOTP.new(secret_for(name)).now
8
+ return password_for(secret_for(arguments.first)) if arguments.any?
9
+ all_passwords
10
10
  end
11
11
 
12
12
  private
13
13
 
14
- def secret_for(name)
15
- @storage.transaction(true) do
16
- @storage[name]
14
+ def password_for(secret)
15
+ ::ROTP::TOTP.new(secret).now
16
+ end
17
+
18
+ def all_passwords
19
+ secrets = @storage.all_secrets
20
+ secrets.each do |hash|
21
+ hash[hash.keys.first] = password_for(hash[hash.keys.first])
17
22
  end
23
+ secrets
24
+ end
25
+
26
+ def secret_for(key)
27
+ @storage.secret_for(key)
18
28
  end
19
29
  end
20
30
  end
@@ -1,6 +1,7 @@
1
1
  module TFA
2
2
  class UsageCommand
3
3
  def initialize(storage)
4
+ @storage = storage
4
5
  end
5
6
 
6
7
  def run(arguments)
data/lib/tfa/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module TFA
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
data/lib/tfa.rb CHANGED
@@ -6,3 +6,4 @@ require "tfa/show_command"
6
6
  require "tfa/totp_command"
7
7
  require "tfa/usage_command"
8
8
  require "tfa/console"
9
+ require "tfa/storage"
@@ -1,16 +1,26 @@
1
1
  module TFA
2
2
  describe ShowCommand do
3
3
  subject { ShowCommand.new(storage) }
4
- let(:storage) { PStore.new(Tempfile.new('blah').path) }
4
+ let(:storage) { Storage.new(Tempfile.new('blah').path) }
5
5
 
6
- it "retrieves the secret associated with the key given" do
7
- secret = SecureRandom.uuid
8
- storage.transaction do
9
- storage['production'] = secret
6
+ describe "#run" do
7
+ context "when looking up the secret for a specific key" do
8
+ it "retrieves the secret associated with the key given" do
9
+ secret = SecureRandom.uuid
10
+ storage.save('production', secret)
11
+ result = subject.run(['production'])
12
+ expect(result).to eql(secret)
13
+ end
10
14
  end
11
15
 
12
- result = subject.run(['production'])
13
- expect(result).to eql(secret)
16
+ context "when a specific name is not given" do
17
+ it "returns all the secrets" do
18
+ storage.save('development', "1")
19
+ storage.save('staging', "2")
20
+ storage.save('production', "3")
21
+ expect(subject.run([])).to eql([{"development" => "1"}, { "staging" => "2" }, { "production" => "3" }])
22
+ end
23
+ end
14
24
  end
15
25
  end
16
26
  end
@@ -2,18 +2,32 @@ module TFA
2
2
  describe TotpCommand do
3
3
  subject { TotpCommand.new(storage) }
4
4
  let(:secret) { ::ROTP::Base32.random_base32 }
5
- let(:storage) { PStore.new(Tempfile.new('test').path) }
5
+ let(:storage) { Storage.new(Tempfile.new('test').path) }
6
6
 
7
- before :each do
8
- storage.transaction do
9
- storage['development'] = secret
10
- end
7
+ def code_for(secret)
8
+ ::ROTP::TOTP.new(secret).now
11
9
  end
12
10
 
13
11
  describe "#run" do
14
- it "returns a time based one time password for the authentication secret given" do
15
- correct_code = ::ROTP::TOTP.new(secret).now
16
- expect(subject.run(["development"])).to eql(correct_code)
12
+ context "when a single key is given" do
13
+ it "returns a time based one time password for the authentication secret given" do
14
+ storage.save('development', secret)
15
+ expect(subject.run(["development"])).to eql(code_for(secret))
16
+ end
17
+ end
18
+
19
+ context "when no arguments are given" do
20
+ let(:development_secret) { ::ROTP::Base32.random_base32 }
21
+ let(:staging_secret) { ::ROTP::Base32.random_base32 }
22
+
23
+ it "returns the one time password for all keys" do
24
+ storage.save('development', development_secret)
25
+ storage.save('staging', staging_secret)
26
+ expect(subject.run([])).to eql([
27
+ { 'development' => code_for(development_secret) },
28
+ { 'staging' => code_for(staging_secret) }
29
+ ])
30
+ end
17
31
  end
18
32
  end
19
33
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tfa
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - mo khan
@@ -86,6 +86,7 @@ files:
86
86
  - lib/tfa/add_command.rb
87
87
  - lib/tfa/console.rb
88
88
  - lib/tfa/show_command.rb
89
+ - lib/tfa/storage.rb
89
90
  - lib/tfa/totp_command.rb
90
91
  - lib/tfa/usage_command.rb
91
92
  - lib/tfa/version.rb