Class: Rush::Access

Inherits:
Object
  • Object
show all
Defined in:
lib/rush/access.rb

Overview

A class to hold permissions (read, write, execute) for files and dirs. See Rush::Entry#access= for information on the public-facing interface.

Constant Summary collapse

ROLES =
%w(user group other)
PERMISSIONS =
%w(read write execute)
ACCESS_UNITS =
ROLES.product(PERMISSIONS).
map { |r, p| "#{r}_can_#{p}".to_sym }

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.from_hash(hash) ⇒ Object



59
60
61
# File 'lib/rush/access.rb', line 59

def self.from_hash(hash)
  new.from_hash(hash)
end

.parse(options) ⇒ Object



31
32
33
# File 'lib/rush/access.rb', line 31

def self.parse(options)
  new.parse(options)
end

.permissionsObject



16
17
18
# File 'lib/rush/access.rb', line 16

def self.permissions
  PERMISSIONS
end

.rolesObject



12
13
14
# File 'lib/rush/access.rb', line 12

def self.roles
  ROLES
end

Instance Method Details

#apply(full_path) ⇒ Object



35
36
37
38
39
# File 'lib/rush/access.rb', line 35

def apply(full_path)
  FileUtils.chmod(octal_permissions, full_path)
rescue Errno::ENOENT
  raise Rush::DoesNotExist, full_path
end

#display_hashObject



47
48
49
50
# File 'lib/rush/access.rb', line 47

def display_hash
  to_hash.select { |_, v| v == 1 }.
    inject({}) { |r, (k, _)| r.merge k => true }
end

#extract_list(type, value, choices) ⇒ Object



111
112
113
114
115
116
# File 'lib/rush/access.rb', line 111

def extract_list(type, value, choices)
  list = parts_from(value)
  list.each do |value|
    raise(Rush::BadAccessSpecifier, "Unrecognized #{type}: #{value}") unless choices.include? value
  end
end

#from_hash(hash) ⇒ Object



52
53
54
55
56
57
# File 'lib/rush/access.rb', line 52

def from_hash(hash)
  ACCESS_UNITS.each do |unit|
    send("#{unit}=".to_sym, hash[unit].to_i == 1 ? true : false)
  end
  self
end

#from_octal(mode) ⇒ Object



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

def from_octal(mode)
  perms = octal_integer_array(mode)

  self.user_can_read = (perms[0] & 4) > 0 ? true : false
  self.user_can_write = (perms[0] & 2) > 0 ? true : false
  self.user_can_execute = (perms[0] & 1) > 0 ? true : false

  self.group_can_read = (perms[1] & 4) > 0 ? true : false
  self.group_can_write = (perms[1] & 2) > 0 ? true : false
  self.group_can_execute = (perms[1] & 1) > 0 ? true : false

  self.other_can_read = (perms[2] & 4) > 0 ? true : false
  self.other_can_write = (perms[2] & 2) > 0 ? true : false
  self.other_can_execute = (perms[2] & 1) > 0 ? true : false

  self
end

#octal_integer_array(mode) ⇒ Object



98
99
100
101
102
# File 'lib/rush/access.rb', line 98

def octal_integer_array(mode)
  mode %= 01000                      # filter out everything but the bottom three digits
  mode = sprintf("%o", mode)         # convert to string
  mode.split("").map { |p| p.to_i }  # and finally, array of integers
end

#octal_permissionsObject



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/rush/access.rb', line 63

def octal_permissions
  perms = [ 0, 0, 0 ]
  perms[0] += 4 if user_can_read
  perms[0] += 2 if user_can_write
  perms[0] += 1 if user_can_execute

  perms[1] += 4 if group_can_read
  perms[1] += 2 if group_can_write
  perms[1] += 1 if group_can_execute

  perms[2] += 4 if other_can_read
  perms[2] += 2 if other_can_write
  perms[2] += 1 if other_can_execute

  eval("0" + perms.join)
end

#parse(options) ⇒ Object



20
21
22
23
24
25
26
27
28
29
# File 'lib/rush/access.rb', line 20

def parse(options)
  options.each do |key, value|
    next unless m = key.to_s.match(/(.*)_can$/)
    key = m[1].to_sym
    roles = extract_list('role', key, self.class.roles)
    perms = extract_list('permission', value, self.class.permissions)
    set_matrix(perms, roles)
  end
  self
end

#parts_from(value) ⇒ Object



118
119
120
# File 'lib/rush/access.rb', line 118

def parts_from(value)
  value.to_s.split('_').reject { |r| r == 'and' }
end

#set_matrix(perms, roles) ⇒ Object



104
105
106
107
108
109
# File 'lib/rush/access.rb', line 104

def set_matrix(perms, roles)
  ROLES.product(PERMISSIONS).
    select { |r, p| perms.include?(p) && roles.include?(r) }.
    map    { |r, p| "#{r}_can_#{p}=".to_sym }.
    each   { |unit| send unit, true }
end

#to_hashObject



41
42
43
44
45
# File 'lib/rush/access.rb', line 41

def to_hash
  ACCESS_UNITS.inject({}) do |hash, unit|
    hash.merge(unit => send(unit) ? 1 : 0)
  end
end