onetime 0.3.1 → 0.4.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.
@@ -1,5 +1,13 @@
1
1
  ONETIME, CHANGES
2
2
 
3
+ #### 0.4.0 (2012-01-07) ###############################
4
+
5
+ * ADDED: Support for ttl, passphrase, and email recipient
6
+ * ADDED: Better error handling
7
+ * CHANGED: env variable ONETIME_ACCOUNT -> ONETIME_CUSTID
8
+ * CHANGED: global option -u is now -H
9
+
10
+
3
11
  #### 0.3.1 (2012-01-06) ###############################
4
12
 
5
13
  * FIXED: Added httparty to gemspec dependencies
data/README.md CHANGED
@@ -2,27 +2,75 @@
2
2
 
3
3
  **Keep sensitive info out of your chat logs & email.**
4
4
 
5
- ### Usage ###
5
+ ## Basic Usage ##
6
6
 
7
+ Use `onetime` to share something you know (a secret phrase, a special link, etc) or to generate a secret (e.g. a temporary password).
8
+
9
+ ### onetime share ###
10
+
11
+ You can pipe it:
12
+
7
13
  $ echo "I STILL WATCH NIGHT COURT." | onetime
8
-
14
+ https://onetimesecret.com/secret/mc5o2649tva6885wvyspm0flobsasin
15
+
16
+ You can type it:
17
+
9
18
  $ onetime
10
19
  Paste secret here (hit control-D to continue):
11
20
  I STILL WATCH NIGHT COURT.
12
21
  https://onetimesecret.com/secret/3djys3b7tridrcvbiprqjejz0c2g07x
22
+
23
+ And you can read from a file:
13
24
 
25
+ $ <path/2/file onetime
26
+ https://onetimesecret.com/secret/8f8k3ajhax87ctln3h6y11nsb4vf0wq
14
27
 
28
+ *Note that we don't use `cat` in that example! We don't want to provoke the [ire of Randal L. Schwartz](http://partmaps.org/era/unix/award.html).*
29
+
30
+
31
+ ### onetime generate ###
15
32
 
16
- ### Installation ###
33
+ $ onetime generate
34
+ Your secret: CttenFwzVpjs
35
+ https://onetimesecret.com/secret/er5djg1wodsp5m32oyym489bnuhsfp6
36
+
37
+
38
+ ## Output Format ##
39
+
40
+ `onetime` also supports YAML, JSON, and to a limited extent CSV outputs. Specify the format using the `-f ` global option:
41
+
42
+ $ onetime -f yaml generate
43
+ ---
44
+ value: MhYcuge9VxtX
45
+ metadata_key: 4j1122kpd6clemp80gpobu9xfxsp7zu
46
+ secret_key: 8f8k3ajhax87ctln3h6y11nsb4vf0wq
47
+ ttl: 172800
48
+ passphrase_required: false
49
+
50
+ ## Installation ###
17
51
 
18
52
  $ [sudo] gem install onetime
19
53
 
20
- ### More Info ###
54
+ ## More Info ##
21
55
 
22
56
  * [API docs](https://onetimesecret.com/docs/api)
23
57
  * [Codes](https://github.com/onetimesecret/onetime-ruby)
24
58
  * [Rubgems](https://rubygems.org/gems/onetime)
59
+ * [One-Time Secret](https://onetimesecret.com/)
60
+
61
+ See also:
62
+
63
+ $ onetime -h
64
+ $ onetime show-commands
65
+ $ onetime share -h
66
+ $ onetime generate -h
67
+
68
+ ## Thanks ##
69
+
70
+ * Kyle Dawkins for the [perl lib](https://github.com/quile/onetime-perl)
71
+ * Drew Carey for [tweeting about us](https://twitter.com/DrewFromTV/status/142730130689761280)
72
+
25
73
 
26
- ### License ###
74
+ ## License ##
27
75
 
28
76
  See LICENSE.txt
@@ -1,3 +1,3 @@
1
1
  :MAJOR: 0
2
- :MINOR: 3
3
- :PATCH: 1
2
+ :MINOR: 4
3
+ :PATCH: 0
@@ -12,9 +12,9 @@ class Onetime::CLI
12
12
 
13
13
  default :share
14
14
 
15
+ global :H, String, "Base URI (e.g. https://onetimesecret.com/api)"
15
16
  global :c, :custid, String, "Customer ID (e.g. you@yourcompany.com)"
16
17
  global :k, :apikey, String, "API key (e.g. 4eb33c6340006d6607c813fc7e707a32f8bf5342)"
17
- global :u, :uri, String, "Base URI (e.g. https://onetimesecret.com/api)"
18
18
 
19
19
  global :f, :format, String, "Output format (json or yaml)"
20
20
  global :j, :json, "Shorthand for -f json"
@@ -30,6 +30,7 @@ class Onetime::CLI
30
30
  end
31
31
 
32
32
  before do |obj|
33
+ OT::API.base_uri obj.global.H if obj.global.H
33
34
  @api = OT::API.new obj.global.custid, obj.global.apikey
34
35
  obj.global.format = 'yaml' if obj.global.yaml
35
36
  obj.global.format = 'json' if obj.global.json
@@ -45,39 +46,71 @@ class Onetime::CLI
45
46
  after do |obj|
46
47
  case obj.global.format
47
48
  when 'json'
48
- puts @ret.to_json
49
+ puts @res.to_json
49
50
  when 'yaml'
50
- puts @ret.to_yaml
51
+ puts @res.to_yaml
51
52
  end
52
53
  end
53
54
 
55
+ usage "onetime status"
54
56
  command :status do |obj|
55
- @ret = @api.get '/status'
57
+ @res = @api.get '/status'
58
+ if @res.nil?
59
+ raise RuntimeError, 'Could not complete request'
60
+ elsif @api.response.code != 200
61
+ raise RuntimeError, @res['message']
62
+ end
56
63
  unless obj.global.format
57
- puts @ret[:status]
64
+ msg = @api.anonymous ? 'Anonymous' : @api.custid
65
+ STDERR.puts '# Host: %s' % OT::API.base_uri
66
+ STDERR.puts '# Account: %s' % msg
67
+ puts 'Service Status: %s' % @res[:status]
58
68
  end
59
69
  end
60
70
 
61
71
  argv :key
72
+ usage "onetime metadata <KEY>"
62
73
  command :metadata do |obj|
63
74
  raise RuntimeError, "csv not supported" if obj.global.format == 'csv'
64
75
  raise RuntimeError, "Usage: #{$0} metadata <KEY>" unless obj.argv.key
65
- @ret = @api.post '/metadata/%s' % obj.argv.key
76
+ @res = @api.post '/metadata/%s' % obj.argv.key
77
+ if @res.nil?
78
+ raise RuntimeError, 'Could not complete request'
79
+ elsif @api.response.code != 200
80
+ raise RuntimeError, @res['message']
81
+ end
66
82
  unless obj.global.format
67
- puts @ret.to_yaml
83
+ puts @res.to_yaml
68
84
  end
69
85
  end
70
86
 
87
+ option :p, :passphrase, String, "Passphrase to decrypt the secret (only required if one was provided to you)"
71
88
  argv :key
89
+ usage "onetime secret <KEY>"
90
+ usage "onetime secret [-p PASSPHRASE] <KEY>"
72
91
  command :secret do |obj|
73
92
  raise RuntimeError, "csv not supported" if obj.global.format == 'csv'
74
93
  raise RuntimeError, "Usage: #{$0} secret <KEY>" unless obj.argv.key
75
- @ret = @api.post '/secret/%s' % obj.argv.key
94
+ opts = {}
95
+ opts[:passphrase] = obj.option.passphrase if obj.option.passphrase
96
+ @res = @api.post '/secret/%s' % [obj.argv.key], opts
97
+ if @res.nil?
98
+ raise RuntimeError, 'Could not complete request'
99
+ elsif @api.response.code != 200
100
+ raise RuntimeError, @res['message']
101
+ end
76
102
  unless obj.global.format
77
- puts @ret.to_yaml
103
+ puts @res.to_yaml
78
104
  end
79
105
  end
80
106
 
107
+ usage "onetime share"
108
+ usage "onetime share [-t 3600] [-p PASSPHRASE]"
109
+ usage "echo 'your secret' | onetime share"
110
+ usage "<path/2/file onetime share"
111
+ option :t, :ttl, Integer, "Time-to-live in seconds"
112
+ option :p, :passphrase, String, "Passphrase to encrypt the secret (something only you and recipient know)"
113
+ option :r, :recipient, Array, "Email address to deliver the secret link"
81
114
  command :share do |obj|
82
115
  begin
83
116
  if Kernel.select [$stdin], nil, nil, 0
@@ -85,39 +118,72 @@ class Onetime::CLI
85
118
  else
86
119
  STDERR.puts "Paste secret here (hit control-D to continue):"
87
120
  secret_value = ARGF.read
88
- STDERR.puts "Generating link..."
121
+ STDERR.puts # new line to let the person know we got it.
89
122
  end
90
123
  rescue Interrupt => ex
91
124
  puts "Exiting..."
92
125
  exit 0
93
126
  end
94
127
  raise RuntimeError, "No secret provided" if secret_value.chomp.empty?
95
- @ret = @api.post '/share', :secret => secret_value
96
- uri = OT::API.web_uri('secret', @ret[:secret_key])
128
+ opts = { :secret => secret_value, :ttl => obj.option.ttl, :recipient => obj.option.recipient }
129
+ opts[:passphrase] = obj.option.passphrase if obj.option.passphrase
130
+ @res = @api.post '/share', opts
131
+ if @res.nil?
132
+ raise RuntimeError, 'Could not complete request'
133
+ elsif @api.response.code != 200
134
+ raise RuntimeError, @res['message']
135
+ end
136
+ uri = OT::API.web_uri('secret', @res[:secret_key])
97
137
  if obj.global.format == 'csv' || obj.global.format.nil?
98
- puts uri
138
+ if @res[:recipient] && !@res[:recipient].compact.empty?
139
+ STDERR.puts '# Secret link sent to: %s' % @res[:recipient].join(',')
140
+ else
141
+ puts uri
142
+ end
99
143
  end
100
144
  end
101
145
 
146
+ usage "onetime generate"
147
+ usage "onetime generate [-t 3600] [-p PASSPHRASE]"
148
+ option :t, :ttl, Integer, "Time-to-live in seconds"
149
+ option :p, :passphrase, String, "Passphrase to encrypt the secret (something only you and recipient know)"
150
+ option :r, :recipient, Array, "Email address to deliver the secret link"
102
151
  command :generate do |obj|
103
- @ret = @api.post '/generate'
104
- uri, secret_value = OT::API.web_uri('secret', @ret[:secret_key]), @ret[:value]
105
- STDERR.puts @ret.inspect if obj.global.debug
152
+ opts = { :ttl => obj.option.ttl, :recipient => obj.option.recipient }
153
+ opts[:passphrase] = obj.option.passphrase if obj.option.passphrase
154
+ @res = @api.post '/generate', opts
155
+ if @res.nil?
156
+ raise RuntimeError, 'Could not complete request'
157
+ elsif @api.response.code != 200
158
+ raise RuntimeError, @res['message']
159
+ end
160
+ uri, secret_value = OT::API.web_uri('secret', @res[:secret_key]), @res[:value]
161
+ STDERR.puts @res.inspect if obj.global.debug
106
162
  if obj.global.format == 'csv'
107
163
  puts [secret_value,uri].join ','
108
164
  elsif obj.global.format.nil?
109
165
  msg = 'Your secret (hit return to continue): %s' % secret_value
166
+ if @res[:recipient] && !@res[:recipient].compact.empty?
167
+ uri = "\e[K\r# Secret link sent to: %s" % [@res[:recipient].join(',').ljust(40, ' ')]
168
+ end
110
169
  eraser = "\e[K\r%s" % [uri] # \e[K\r
111
170
  print msg
112
- begin
113
- old_stty = `stty -g` # store tty settings
114
- system "stty -echo"
115
- STDIN.getc
116
- rescue Interrupt
117
- ensure
118
- system "stty echo"
119
- system "stty #{old_stty}" # restore stty settings
120
- print eraser
171
+ # Check for tty b/c if we're receiving data via STDIN, even if
172
+ # we're ignoring it, the stty commands return "stdin isn't a terminal"
173
+ if STDIN.tty?
174
+ begin
175
+ old_stty = `stty -g` # store tty settings
176
+ system "stty -echo"
177
+ STDIN.getc
178
+ rescue Interrupt
179
+ ensure
180
+ system "stty echo"
181
+ system "stty #{old_stty}" # restore stty settings
182
+ print eraser
183
+ end
184
+ else
185
+ puts
186
+ print uri
121
187
  end
122
188
  puts
123
189
  end
@@ -51,7 +51,7 @@ module Onetime
51
51
  base_uri 'https://onetimesecret.com/api'
52
52
  format :json
53
53
  headers 'X-Onetime-Client' => Onetime::API::VERSION.to_s
54
- attr_reader :opts, :response, :custid, :key, :default_params
54
+ attr_reader :opts, :response, :custid, :key, :default_params, :anonymous
55
55
  attr_accessor :apiversion
56
56
  def initialize custid=nil, key=nil, opts={}
57
57
  unless ENV['ONETIME_HOST'].to_s.empty?
@@ -60,9 +60,15 @@ module Onetime
60
60
  @apiversion = opts.delete(:apiversion) || opts.delete('apiversion') || 1
61
61
  @opts = opts
62
62
  @default_params = {}
63
- @custid = custid || ENV['ONETIME_ACCOUNT']
63
+ @custid = custid || ENV['ONETIME_CUSTID']
64
64
  @key = key || ENV['ONETIME_APIKEY']
65
- unless @custid.to_s.empty? || @key.to_s.empty?
65
+ if @custid.to_s.empty? && @key.to_s.empty?
66
+ @anonymous = true
67
+ elsif @custid.to_s.empty? || @key.to_s.empty?
68
+ raise RuntimeError, "You provided a custid without an apikey" if @key.to_s.empty?
69
+ raise RuntimeError, "You provided an apikey without a custid" if @custid.to_s.empty?
70
+ else
71
+ @anonymous = false
66
72
  opts[:basic_auth] ||= { :username => @custid, :password => @key }
67
73
  end
68
74
  end
@@ -5,20 +5,22 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "onetime"
8
- s.version = "0.3.0"
8
+ s.version = "0.4.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Delano Mandelbaum"]
12
- s.date = "2012-01-06"
12
+ s.date = "2012-01-07"
13
13
  s.description = "CLI tool and Ruby library for onetimesecret.com"
14
14
  s.email = "delano@onetimesecret.com"
15
15
  s.executables = ["onetime"]
16
16
  s.extra_rdoc_files = [
17
- "LICENSE.txt"
17
+ "LICENSE.txt",
18
+ "README.md"
18
19
  ]
19
20
  s.files = [
20
21
  "CHANGES.txt",
21
22
  "LICENSE.txt",
23
+ "README.md",
22
24
  "Rakefile",
23
25
  "VERSION.yml",
24
26
  "bin/onetime",
@@ -36,13 +38,16 @@ Gem::Specification.new do |s|
36
38
 
37
39
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
38
40
  s.add_runtime_dependency(%q<drydock>, [">= 0.6.9"])
41
+ s.add_runtime_dependency(%q<httparty>, [">= 0.7.7"])
39
42
  s.add_runtime_dependency(%q<json>, [">= 1.6.4"])
40
43
  else
41
44
  s.add_dependency(%q<drydock>, [">= 0.6.9"])
45
+ s.add_dependency(%q<httparty>, [">= 0.7.7"])
42
46
  s.add_dependency(%q<json>, [">= 1.6.4"])
43
47
  end
44
48
  else
45
49
  s.add_dependency(%q<drydock>, [">= 0.6.9"])
50
+ s.add_dependency(%q<httparty>, [">= 0.7.7"])
46
51
  s.add_dependency(%q<json>, [">= 1.6.4"])
47
52
  end
48
53
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: onetime
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.3.1
5
+ version: 0.4.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - Delano Mandelbaum
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2012-01-06 00:00:00 Z
13
+ date: 2012-01-07 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: drydock