Class: Password

Inherits:
Object
  • Object
show all
Includes:
SettingsAccessors
Defined in:
lib/oro/password.rb

Overview

A class epresenting a complete password

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from SettingsAccessors

#actions, #actions=, #config, #config=, #plan, #plan=

Constructor Details

#initialize(clio = '') ⇒ Password

Instance methods



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/oro/password.rb', line 63

def initialize(clio = '')
  # Parse clio for Config and Actions
  @settings = SettingsParser.parse(clio)

  # Parse, manually, remaining non-switch plan parts
  clio.each do |part|
    match = (/\b([a-zA-Z]{1})([0-9]*)\b/).match(part)
    if match
      @settings.plan.push([Password.installed_part_switches[match[1]], match[2] == '' ? nil : match[2].to_i]) # nil behaves better with --prefs
      raise NoMatchingListError.new("No matching dictionary for '#{match[1]}'") unless Password.installed_part_switches.keys.include?(match[1])
    end
  end

  # Add help for installed parts if needed
  @settings.actions[:help].gsub!(/INSTALLED_PARTS_HELP/, Password.installed_parts_help) if @settings.actions[:help]

  # Save virgin parsed settings
  @virgin_settings = @settings.dup

  # Use saved preferences plan, then defaults plan, if no plan provided in clio
  # FIXME: Will require updating to reflect the approach above.
  @settings.plan = (Preferences.instance.plan.empty? ? Defaults.instance.plan : Preferences.instance.plan) if @settings.plan.empty?

  # Settings merged with Preferences, that merged with Defaults
  @settings.config = Defaults.instance.config.merge(Preferences.instance.config.merge(@settings.config))

  # Add lists for required part classes only, check for non-contiguous lists
  Password.components_for(@settings).each do |klass|
    klass.listify
    fail ListIsNonContiguousError, "Dictionary #{klass.name} is noncontiguous and requires at least one entry for each range member\n#{klass.to_s}" unless klass.contiguous?
  end
end

Instance Attribute Details

#settingsObject

Returns the value of attribute settings.



10
11
12
# File 'lib/oro/password.rb', line 10

def settings
  @settings
end

#virgin_settingsObject (readonly)

Returns the value of attribute virgin_settings.



11
12
13
# File 'lib/oro/password.rb', line 11

def virgin_settings
  @virgin_settings
end

Class Method Details

.components_for(settings) ⇒ Object

Singleton helper returning classes required by password



16
17
18
19
20
# File 'lib/oro/password.rb', line 16

def self.components_for(settings)
  parts = []
  settings.plan.each { |part| parts << Object.const_get(part[0]) }
  parts.uniq
end

.installed_part_classesObject

Returns classes for all installed parts



23
24
25
# File 'lib/oro/password.rb', line 23

def self.installed_part_classes
  Part.descendants
end

.installed_part_switchesObject

Returns a hash of “short” => “long” part identifiers



33
34
35
36
37
38
39
# File 'lib/oro/password.rb', line 33

def self.installed_part_switches
  switches = {} # FIXME: This apparently can't be memoized (?)
  installed_parts.each do |part|
    part.downcase.chars.each { |char| switches.key?(char) ? next : (switches[char] = part; break) }
  end
  switches
end

.installed_partsObject

Returns string names for all installed parts



28
29
30
# File 'lib/oro/password.rb', line 28

def self.installed_parts
  Part.descendants.map(&:name)
end

.installed_parts_helpObject

Returns a help message for all installed parts



42
43
44
45
46
47
48
# File 'lib/oro/password.rb', line 42

def self.installed_parts_help
  help = []
  installed_part_switches.each_pair do |s, l|
    help << "    #{s}[n] #{l} part" # FIXME: There has to be a string format approach for making this match up.
  end
  help.join("\n")
end

.installed_parts_summaryObject

Returns a text list of metadata about all installed parts



51
52
53
54
55
56
57
58
59
# File 'lib/oro/password.rb', line 51

def self.installed_parts_summary
  count = 0
  Password.installed_part_classes.each do |klass|
    klass.listify
    count += klass.count
    puts klass.to_s
  end
  "Total list members: #{count}"
end

Instance Method Details

#lengthObject



96
97
98
99
100
# File 'lib/oro/password.rb', line 96

def length
  length = 0
  @settings.plan.each { |part| length += part[1].nil? ? Object.const_get(part[0]).middle : part[1] }
  @settings.config.key?(:l33t) && @settings.config[:l33t] == true ? "#{length}+" : length.to_s # Precision is out the window with l33t; && likely uneeded
end

#resultObject



102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/oro/password.rb', line 102

def result
  current_password = []

  @settings.plan.each do |plan_part|
    part_klass = self.class.const_get(plan_part[0]) # The part descriptor from oro settings
    plan_part[1] = part_klass.middle if plan_part[1].nil?
    current_password << part_klass.get(plan_part[1], @settings.config) # Passing config, Parts don't currently rely on the Preferences singleton
  end

  current_password.shuffle! if @settings.config[:shuffle]
  current_password.join
end