authentic 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a466cc3f5d39c27b78beccb0ae2445838d770a58
4
+ data.tar.gz: 34363dd67e5a8d9139b6836a3cd2883cf49905f5
5
+ SHA512:
6
+ metadata.gz: e25fd334769ab583a9bf4357f149861eddfdac4f3447c6189b6b77c75d3c4915277801d9f653d78411c01995aaa10dc3064de70b50861547f04f19361dfb09da
7
+ data.tar.gz: e9f1b08e6fe772f0cdac82ac16bb5065e405a417f1f8586d10de12af8487de14ca74e86ad64bf785ead2b5caed9274105ebff2a19e916752f0e53823484cd399
@@ -0,0 +1,18 @@
1
+ # EditorConfig helps developers define and maintain consistent
2
+ # coding styles between different editors and IDEs
3
+ # editorconfig.org
4
+
5
+ root = true
6
+
7
+
8
+ [*]
9
+
10
+ # Change these settings to your own preference
11
+ indent_style = space
12
+ indent_size = 2
13
+
14
+ # We recommend you to keep these unchanged
15
+ end_of_line = lf
16
+ charset = utf-8
17
+ trim_trailing_whitespace = true
18
+ insert_final_newline = true
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in authentic.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Ufuk Kayserilioglu
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,31 @@
1
+ # Authentic
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'authentic'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install authentic
20
+
21
+ ## Usage
22
+
23
+ TODO: Write usage instructions here
24
+
25
+ ## Contributing
26
+
27
+ 1. Fork it ( https://github.com/[my-github-username]/authentic/fork )
28
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
29
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
30
+ 4. Push to the branch (`git push origin my-new-feature`)
31
+ 5. Create a new Pull Request
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'authentic/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "authentic"
8
+ spec.version = Authentic::VERSION
9
+ spec.authors = ["Ufuk Kayserilioglu"]
10
+ spec.email = ["ufuk@paralaus.com"]
11
+ spec.summary = %q{A desktop Google Authenticator replacement.}
12
+ spec.description = %q{A desktop Google Authenticator replacement.}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "colorize"
22
+ spec.add_dependency "rotp"
23
+ spec.add_dependency "barby"
24
+ spec.add_dependency "ruby-keychain"
25
+ spec.add_dependency "thor"
26
+
27
+ spec.add_development_dependency "bundler", "~> 1.7"
28
+ spec.add_development_dependency "rake", "~> 10.0"
29
+ end
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'authentic'
4
+
5
+ Authentic::CLI.start
@@ -0,0 +1,105 @@
1
+ require "authentic/version"
2
+ require "authentic/clipboard"
3
+ require "thor"
4
+ require "keychain"
5
+ require "rotp"
6
+ require "colorize"
7
+ require "ostruct"
8
+
9
+ module Authentic
10
+ class CLI < Thor
11
+ package_name "Authentic"
12
+ default_task :generate
13
+
14
+ desc "add NAME SECRET_KEY [LABEL]", "Add a new TOTP key"
15
+ def add(name, secret_key, label = nil)
16
+ params = {
17
+ service: "authentic gem",
18
+ password: secret_key,
19
+ account: name,
20
+ }
21
+ params[:comment] = label if label
22
+
23
+ begin
24
+ item = Keychain.generic_passwords.create(params)
25
+ rescue => e
26
+ message = e.message
27
+ end
28
+
29
+ unless item.nil?
30
+ say "\u2713".colorize(:green) + " Service #{name.colorize(:green)} add to keychain"
31
+ else
32
+ say "\u2717".colorize(:red) + " Couldn't add service #{name.colorize(:red)}..."
33
+ say "Error: #{message}" unless message.nil?
34
+ end
35
+ end
36
+
37
+ desc "delete NAME", "Delete a TOTP key"
38
+ option :force, default: false, type: :boolean, aliases: '-f'
39
+ def delete(name)
40
+ item = Keychain.generic_passwords.where(service: "authentic gem", account: name).first
41
+ unless item
42
+ return say "\u2717".colorize(:red) + " Couldn't find service #{name.colorize(:red)}..."
43
+ end
44
+ if options[:force] || yes?("Do you want to permanently delete #{name.colorize(:green)}?")
45
+ item.delete
46
+ say "\u2713".colorize(:green) + " Service #{name.colorize(:green)} deleted from keychain"
47
+ else
48
+ say "Leaving service #{name.colorize(:green)} in keychain"
49
+ end
50
+ end
51
+
52
+ CLOCKS = {
53
+ 0 => "🌕",
54
+ 7 => "🌖",
55
+ 14 => "🌗",
56
+ 21 => "🌘",
57
+ 28 => "🌑",
58
+ }
59
+
60
+ desc "generate", "Generate TOTP codes"
61
+ option 'skip-copy', default: false, type: :boolean, aliases: '-s'
62
+ def generate
63
+ now = Time.now
64
+ keys = Keychain
65
+ .generic_passwords
66
+ .where(service: "authentic gem")
67
+ .all.map do |key|
68
+ totp = ROTP::TOTP.new(key.password.gsub(/=*$/, ''))
69
+ OpenStruct.new(
70
+ code: totp.at(now),
71
+ name: key.attributes[:account],
72
+ label: key.attributes[:comment],
73
+ remain: now.utc.to_i % totp.interval
74
+ )
75
+ end
76
+
77
+ table = keys.each_with_index.map do |key, idx|
78
+ number = (idx + 1).to_s.rjust(keys.size.to_s.size, ' ')
79
+ [
80
+ number.colorize(:red),
81
+ key.code.colorize(:green),
82
+ "#{key.name} #{(" (#{key.label})" if key.label)}",
83
+ CLOCKS[7 * (key.remain / 7)].colorize(:blue)
84
+ ]
85
+ end
86
+
87
+ print_table(table.to_a)
88
+
89
+ unless options['skip-copy']
90
+ if keys.size > 1
91
+ prompt = "\nWhich key should I copy?"
92
+ prompt += " [1-#{keys.size}, leave empty to exit]"
93
+ response = ask prompt
94
+ return if response.empty?
95
+ idx = response.to_i - 1
96
+ key = keys[idx]
97
+ else
98
+ key = keys.first
99
+ end
100
+ Clipboard.pbcopy key.code
101
+ say "\nKey for account #{key.name.colorize(:green)} copied to clipboard"
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,15 @@
1
+ module Authentic
2
+ module Clipboard
3
+ def pbcopy(input)
4
+ str = input.to_s
5
+ IO.popen('pbcopy', 'w') { |f| f << str }
6
+ str
7
+ end
8
+
9
+ def pbpaste
10
+ `pbpaste`
11
+ end
12
+
13
+ module_function :pbcopy, :pbpaste
14
+ end
15
+ end
@@ -0,0 +1,3 @@
1
+ module Authentic
2
+ VERSION = "0.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,154 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: authentic
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Ufuk Kayserilioglu
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-11-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: colorize
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rotp
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: barby
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: ruby-keychain
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: thor
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: bundler
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.7'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '1.7'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rake
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '10.0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '10.0'
111
+ description: A desktop Google Authenticator replacement.
112
+ email:
113
+ - ufuk@paralaus.com
114
+ executables:
115
+ - authentic
116
+ extensions: []
117
+ extra_rdoc_files: []
118
+ files:
119
+ - ".editorconfig"
120
+ - ".gitignore"
121
+ - Gemfile
122
+ - LICENSE.txt
123
+ - README.md
124
+ - Rakefile
125
+ - authentic.gemspec
126
+ - bin/authentic
127
+ - lib/authentic.rb
128
+ - lib/authentic/clipboard.rb
129
+ - lib/authentic/version.rb
130
+ homepage: ''
131
+ licenses:
132
+ - MIT
133
+ metadata: {}
134
+ post_install_message:
135
+ rdoc_options: []
136
+ require_paths:
137
+ - lib
138
+ required_ruby_version: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - ">="
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ required_rubygems_version: !ruby/object:Gem::Requirement
144
+ requirements:
145
+ - - ">="
146
+ - !ruby/object:Gem::Version
147
+ version: '0'
148
+ requirements: []
149
+ rubyforge_project:
150
+ rubygems_version: 2.2.2
151
+ signing_key:
152
+ specification_version: 4
153
+ summary: A desktop Google Authenticator replacement.
154
+ test_files: []