Class: PWS

Inherits:
Object
  • Object
show all
Defined in:
lib/pws.rb,
lib/pws/version.rb

Defined Under Namespace

Modules: Encryptor Classes: NoAccess

Constant Summary collapse

VERSION =
'0.9.1'

Instance Method Summary collapse

Constructor Details

#initialize(filename = nil, namespace = nil, password = nil) ⇒ 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)



16
17
18
19
20
21
# File 'lib/pws.rb', line 16

def initialize(filename = nil, namespace = nil, password = nil)
  @pw_file = File.expand_path(filename || ENV["PWS"] || '~/.pws')
  @pw_file << namespace if namespace
  access_safe(password)
  read_safe
end

Instance Method Details

#add(key, password = nil) ⇒ Object

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



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/pws.rb', line 36

def add(key, password = nil)
  if @pw_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
    @pw_data[key] = password || ask_for_password(%[please enter a password for #{key}], :yellow)
    if @pw_data[key].empty?
      pa %[Cannot add an empty password!], :red
      return false
    else
      write_safe
      pa %[The password for #{key} has been added], :green
      return true
    end
  end
end

#generate(key, seconds = 10, length = 64, char_pool = (32..126).map(&:chr).join.gsub(/\s/, '')) ⇒ Object

Adds a password entry with a freshly generated random password



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/pws.rb', line 82

def generate(
      key,
      seconds = 10,
      length = 64,
      char_pool = (32..126).map(&:chr).join.gsub(/\s/, '')
  )
  char_pool_size = char_pool.size
  new_pw = (1..length.to_i).map{
    char_pool[SecureRandom.random_number(char_pool_size)]
  }.join
  
  if add(key, new_pw) 
    get(key, seconds)
  end
end

#get(key, seconds = 10) ⇒ Object

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



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/pws.rb', line 55

def get(key, seconds = 10)
  if pw_plaintext = @pw_data[key]
    if seconds && seconds.to_i > 0
      original_clipboard_content = Clipboard.paste
      Clipboard.copy pw_plaintext
      pa %[The password for #{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 pw_plaintext
      pa %[The password for #{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



130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/pws.rb', line 130

def master(password = nil)
  if !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
      pa %[The passwords don't match!], :red
      return false
    end
  end
  @pw_hash = Encryptor.hash(password)
  write_safe
  pa %[The master password has been changed], :green
  return true
end

#remove(key) ⇒ Object

Removes a specific password entry



100
101
102
103
104
105
106
107
108
109
# File 'lib/pws.rb', line 100

def remove(key)
  if @pw_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



113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/pws.rb', line 113

def rename(old_key, new_key)
  if !@pw_data[old_key]
    pa %[No password found for #{old_key}!], :red
    return false
  elsif @pw_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
    @pw_data[new_key] = @pw_data.delete(old_key)
    write_safe
    pa %[The password entry #{old_key} has been renamed to #{new_key}], :green
    return true
  end
end

#showObject

Shows a password entry list



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

def show
  if @pw_data.empty? 
    pa %[There aren't any passwords stored at #{@pw_file}, yet], :red
  else
    puts Paint["Entries", :underline] + %[ in ] + @pw_file
    puts @pw_data.keys.sort.map{ |key| %[- #{key}\n] }.join
  end
  return true
end

#to_sObject

Prevents accidental displaying, e.g. in irb



146
147
148
# File 'lib/pws.rb', line 146

def to_s
  %[#<password safe>]
end