Class: Cbac::CbacPristine::AbstractPristineFile

Inherits:
ActiveRecord::Base
  • Object
show all
Defined in:
lib/cbac/cbac_pristine/pristine_file.rb

Direct Known Subclasses

GenericPristineFile, PristineFile

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ AbstractPristineFile

Returns a new instance of AbstractPristineFile.



11
12
13
14
15
16
# File 'lib/cbac/cbac_pristine/pristine_file.rb', line 11

def initialize(*args)
  super(*args)
  @generic_roles = []
  @context_roles = []
  @permissions = []
end

Instance Attribute Details

#generic_rolesObject

Returns the value of attribute generic_roles.



8
9
10
# File 'lib/cbac/cbac_pristine/pristine_file.rb', line 8

def generic_roles
  @generic_roles
end

#permissionsObject

Returns the value of attribute permissions.



8
9
10
# File 'lib/cbac/cbac_pristine/pristine_file.rb', line 8

def permissions
  @permissions
end

Instance Method Details

#is_pristine_permission_line?(line, line_number) ⇒ Boolean

Returns:

  • (Boolean)

Raises:

  • (SyntaxError)


70
71
72
73
74
75
76
77
78
# File 'lib/cbac/cbac_pristine/pristine_file.rb', line 70

def is_pristine_permission_line?(line, line_number)
  if line.match(/^\s*(\d+)\s*:\s*([\+-x]|=>)\s*:(\s*[A-Za-z]+\(\s*[A-Za-z_]*\s*\))+\s*\Z/) #looks like pristine line.....
    return true
  end
  if line.match(/^\s*(#.*|\s*)$/) # line is whitespace or comment line
    return false
  end
  raise SyntaxError, "Error: garbage found in input file on line #{(line_number + 1).to_s}" #line is rubbish
end

#parse(use_db = true) ⇒ Object



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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
62
63
64
65
66
67
68
# File 'lib/cbac/cbac_pristine/pristine_file.rb', line 18

def parse(use_db = true)
  @generic_roles = []
  @context_roles = []
  @permissions = []

  f = File.open(file_name, "r")
  last_row_number = -1
  f.each_with_index do |l, line_number|
    pristine_permission = PristinePermission.new
    pristine_permission.pristine_file = self
    permission_line = l.chomp
    # if this is not a line we can convert into a permission, go to next line (or fail.....)
    next unless is_pristine_permission_line?(permission_line, line_number)

    # check if the row numbers are constructed properly.
    # this is needed for migration purposes, each permission should have an unique and persistent row number
    header_match = permission_line.match(/^(\d+):([\+-x]|=>):\s*/)
    pristine_permission.line_number = header_match.captures[0].to_i
    if pristine_permission.line_number != last_row_number.succ
      raise SyntaxError, "Error: row numbers in pristine file do not increase monotonously"
    else
      last_row_number = pristine_permission.line_number
    end
    pristine_permission.operation = header_match.captures[1]
    # parse the role and privilege set name
    pristine_permission.privilege_set_name = parse_privilege_set_name(permission_line, line_number)
    pristine_permission.pristine_role = parse_role(permission_line, line_number, use_db)
    # it's pristine, so changes should be treated as such
    # if a permission was created and later revoked, we should remove the pristine line which was created before
    case pristine_permission.operation
      when '+'
        @permissions.push(pristine_permission)
      when '-'
        permission_to_delete = nil
        #check if this is actually a permission that can be revoked.
        @permissions.each do |known_permission|
          if known_permission.privilege_set_name == pristine_permission.privilege_set_name and known_permission.pristine_role.name == pristine_permission.pristine_role.name
            permission_to_delete = known_permission
            break
          end
        end
        if permission_to_delete.nil?
          raise SyntaxError, "Error: trying to remove a privilege set with \"#{permission_line}\" on line #{(line_number + 1).to_s}, but this privilege set wasn't created!"
        else
          @permissions.push(pristine_permission)
        end
      when 'x', '=>'
        raise NotImplementedError, "Using an x or => in a pristine file is not implemented yet"
    end
  end
end

#parse_privilege_set_name(line, line_number) ⇒ Object

Raises:

  • (SyntaxError)


80
81
82
83
84
85
# File 'lib/cbac/cbac_pristine/pristine_file.rb', line 80

def parse_privilege_set_name(line, line_number)
  if match_data= line.match(/^.*PrivilegeSet\(\s*([A-Za-z0-9_]+)\s*\)\s*/)
    return match_data.captures[0]
  end
  raise SyntaxError, "Error: PrivilegeSet expected, but found: \"#{line}\" on line #{(line_number + 1).to_s}"
end

#parse_role(line, line_number, use_db = true) ⇒ Object



87
88
89
# File 'lib/cbac/cbac_pristine/pristine_file.rb', line 87

def parse_role(line, line_number, use_db = true)
  raise NotImplementedError("Error: the AbstractPristineFile cannot parse roles, use a PristineFile or GenericPristineFile instead")
end

#permission_setObject



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/cbac/cbac_pristine/pristine_file.rb', line 91

def permission_set
  permission_set = Array.new(@permissions)
  @permissions.each do |pristine_permission|
     case pristine_permission.operation
      when '+'
        permission_set.push(pristine_permission)
      when '-'
        permission_to_delete = nil
        #check if this is actually a permission that can be revoked.
        permission_set.each do |known_permission|
          if known_permission.privilege_set_name == pristine_permission.privilege_set_name and known_permission.pristine_role.name == pristine_permission.pristine_role.name and known_permission.operation == '+'
            permission_to_delete = known_permission
            break
          end
        end
        if permission_to_delete.nil?
          raise ArgumentError, "Error: trying to remove permission #{pristine_permission.privilege_set_name}\" for #{pristine_permission.pristine_role.name}, but this permission wasn't created!"
        else
          permission_set.delete(permission_to_delete)
          permission_set.delete(pristine_permission)
        end
      when 'x', '=>'
        raise NotImplementedError, "Using an x or => in a pristine file is not implemented yet"
    end
  end
  permission_set
end