Class: PWS

Inherits:
Object
  • Object
show all
Extended by:
ClassSupport
Defined in:
lib/pws.rb,
lib/pws/format.rb,
lib/pws/version.rb,
lib/pws/format/0.9.rb,
lib/pws/format/1.0.rb

Defined Under Namespace

Modules: ClassSupport, Encryptor, Format, Runner Classes: NoAccess, NoLegacyAccess

Constant Summary collapse

VERSION =
"1.0.8"

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from ClassSupport

alias_for

Constructor Details

#initialize(options) ⇒ PWS

Creates a new password safe. Takes the path to the password file, by default: ~/.pws Second parameter allows namespaces that get appended to the file name (uses another safe) You can pass the master password as third parameter (not recommended)



25
26
27
28
29
30
31
# File 'lib/pws.rb', line 25

def initialize(options)
  collect_options(options)
  @filename = @options[:cwd] ? File.join(FileUtils.pwd, '.pws') : File.expand_path(@options[:filename])
  @filename << '-' << @options[:namespace] if @options[:namespace]
  
  read_safe(options[:password])
end

Instance Attribute Details

#filenameObject (readonly)

Returns the value of attribute filename.



20
21
22
# File 'lib/pws.rb', line 20

def filename
  @filename
end

Instance Method Details

#add(key, password = nil) ⇒ Object

Add a password entry, params: name, password (optional, opens prompt if not given)



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/pws.rb', line 65

def add(key, password = nil)
  if @data[key]
    pa %[There is already a password stored for #{key}. You need to remove it before creating a new one!], :red
    return false
  else
    @data[key] = {}
    @data[key][:password] = password || ask_for_password(%[please enter a password for #{key}], :yellow)
    if @data[key][:password].empty?
      raise ArgumentError, %[Cannot set an empty password!]
    else
      @data[key][:timestamp] = Time.now.to_i
      write_safe
      pa %[The password for #{key} has been added], :green
      return true
    end
  end
end

#generate(key, seconds = , length = , charpool = , excluded = ) ⇒ Object

Adds a password entry with a freshly generated random password



158
159
160
161
162
163
164
165
166
# File 'lib/pws.rb', line 158

def generate(
      key,
      seconds   = @options[:seconds],
      length    = @options[:length],
      charpool  = @options[:charpool],
      excluded  = @options[:exclude]
  )
  get(key, seconds) if add(key, generator(length, charpool, excluded))
end

#get(key, seconds = ) ⇒ Object

Gets the password entry and copies it to the clipboard. The second parameter is the time in seconds it stays there



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/pws.rb', line 104

def get(key, seconds = @options[:seconds])
  if real_key = @abbrevs[key]
    password = @data[real_key][:password]
    if seconds && seconds.to_i > 0
      original_clipboard_content = Clipboard.paste
      Clipboard.copy password
      pa %[The password for #{real_key} is now available in your clipboard for #{seconds.to_i} second#{?s if seconds.to_i > 1}], :green
      begin
        sleep seconds.to_i
      rescue Interrupt
        Clipboard.copy original_clipboard_content
        raise
      end
      Clipboard.copy original_clipboard_content
      return true
    else
      Clipboard.copy password
      pa %[The password for #{real_key} has been copied to your clipboard], :green
      return true
    end
  else
    pa %[No password found for #{key}!], :red
    return false
  end
end

#master(password = nil) ⇒ Object

Changes the master password



214
215
216
217
218
219
220
221
222
223
224
225
# File 'lib/pws.rb', line 214

def master(password = nil)
  unless @password = password
    new_password = ask_for_password(%[please enter the new master password], :yellow, :bold)
    @password    = ask_for_password(%[please enter the new master password, again], :yellow, :bold)
    if new_password != @password
      raise ArgumentError, %[The passwords don't match!]
    end
  end
  write_safe
  pa %[The master password has been changed], :green
  return true
end

Print a password entry to the screen



132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/pws.rb', line 132

def print_screen(key, seconds = @options[:seconds])
  if real_key = @abbrevs[key]
    password = @data[real_key][:password]
    if seconds && seconds.to_i > 0
      print Paint[%[The password for #{real_key} will be displayed for #{seconds.to_i} second#{?s if seconds.to_i > 1}:\n#{password}], :green]
      begin
        sleep seconds.to_i
      rescue Interrupt
        puts "\e[999D\e[K\e[1A"*2 if $stdin.tty? # clear the pw from the screen
        raise
      end
      puts "\e[999D\e[K\e[1A"*2 if $stdin.tty? # clear the pw from the screen
      return true
    else
      pa %[The password for #{real_key} is:\n#{password}], :green
      return true
    end
  else
    pa %[No password found for #{key}!], :red
    return false
  end
end

#remove(key) ⇒ Object

Removes a specific password entry



184
185
186
187
188
189
190
191
192
193
# File 'lib/pws.rb', line 184

def remove(key)
  if @data.delete key
    write_safe
    pa %[The password for #{key} has been removed], :green
    return true
  else
    pa %[No password found for #{key}!], :red
    return false
  end
end

#rename(old_key, new_key) ⇒ Object

Removes a specific password entry



197
198
199
200
201
202
203
204
205
206
207
208
209
210
# File 'lib/pws.rb', line 197

def rename(old_key, new_key)
  if !@data[old_key]
    pa %[No password found for #{old_key}!], :red
    return false
  elsif @data[new_key]
    pa %[There is already a password stored for #{new_key}. You need to remove it before naming another one #{new_key}!], :red
    return false
  else
    @data[new_key] = @data.delete(old_key)
    write_safe
    pa %[The password entry #{old_key} has been renamed to #{new_key}], :green
    return true
  end
end

#resaveObject

Just writes the safe, useful for converting with –in and –out



228
229
230
231
232
# File 'lib/pws.rb', line 228

def resave
  write_safe
  pa %[The password file has been resaved], :green
  return true
end

#show(pattern = nil) ⇒ Object

Shows a password entry list



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/pws.rb', line 34

def show(pattern = nil)
  if @data.empty? 
    pa %[There aren't any passwords stored at #{@filename}, yet], :red
  else
    if pattern
      keys = @data.keys.grep /#{pattern}/
    else
      keys = @data.keys
    end
    
    if keys.empty?
      pa %[No passwords found for pattern /#{pattern}/], :red
    else
      puts Paint["Entries", :underline] + %[ in ] + @filename
      longest_key_size = keys.max_by(&:size).size
      puts keys.sort.map{ |key|
        "- #{
          Paint[key, :bold]
        } #{ 
          Time.at(@data[key][:timestamp].to_i).strftime('%y-%m-%d') if @data[key][:timestamp].to_i != 0
        }\n"
      }.join
    end
  end
  return true
rescue RegexpError
  raise ArgumentError, %[Invalid regex given]
end

#to_sObject

Prevents accidental displaying, e.g. in irb



236
237
238
# File 'lib/pws.rb', line 236

def to_s
  %[#<password safe>]
end

#update(key, password = nil) ⇒ Object Also known as: update-add

Updates a password entry, params: name, password (optional, opens prompt if not given)



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/pws.rb', line 85

def update(key, password = nil)
  if !@data[key]
    pa %[There is no password stored for #{key}, so you cannot update it!], :red
    return false
  else
    @data[key][:password] = password || ask_for_password(%[please enter a new password for #{key}], :yellow)
    if @data[key][:password].empty?
      raise ArgumentError, %[Cannot set an empty password!]
    else
      @data[key][:timestamp] = Time.now.to_i
      write_safe
      pa %[The password for #{key} has been updated], :green
      return true
    end
  end
end

#update_generate(key, seconds = , length = , charpool = , excluded = ) ⇒ Object Also known as: update-generate, update_gen, update-gen

Updates a password entry with a freshly generated random password



170
171
172
173
174
175
176
177
178
# File 'lib/pws.rb', line 170

def update_generate(
      key,
      seconds   = @options[:seconds],
      length    = @options[:length],
      charpool  = @options[:charpool],
      excluded  = @options[:exclude]
  )
  get(key, seconds) if update(key, generator(length, charpool, excluded))
end