tfa 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
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