-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPermissionUtils.rb
124 lines (120 loc) · 3.33 KB
/
PermissionUtils.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
require File.join(File.expand_path(File.dirname(__FILE__)), 'Permission')
require File.join(File.expand_path(File.dirname(__FILE__)), 'PermissionGroup')
# Used for handling Permission and PermissionGroup
# strings for operations such as comparing and such.
class PermissionUtils
# Check if a string is negated.
#
# @param string [String] The permission string to check.
#
# @example
# PermissionUtils.negated?('-a.b.c.d')
# #=> true
#
# PermissionUtils.negated?('a.b.c.d')
# #=> false
#
# PermissionUtils.negated?('a.b.c.*')
# #=> true
#
# PermissionUtils.negated?('a')
# #=> nil
#
# @return [Boolean] on whether string is negated.
def self.negated?(string)
return true if string.start_with?(?-)
false
end
# Opposite of {::negated?}.
#
# @param string [String] The permission string to check.
#
# @example
# PermissionUtils.allowed?('-a.b.c.d')
# #=> false
#
# PermissionUtils.allowed?('a.b.c.d')
# #=> true
#
# PermissionUtils.allowed?('a.b.c.*')
# #=> true
#
# PermissionUtils.allowed?('a')
# #=> nil
#
# @return [Boolean] on whether you should grant permission based on string.
def self.allowed?(string)
!self.negated?(string)
end
# Compare 2 strings (each can be Permission/PermissionGroup)
#
# @param string [String]
# @param another_string [String]
#
# @example
# PermissionUtils.compare('a.b.c.d.e', 'a.b.c.d.*')
# #=> 0
#
# PermissionUtils.compare('a.b.c.d.*', 'a.*')
# #=> 1
#
# PermissionUtils.compare('a.*', 'a.b.c.d.*')
# #=> 1
#
# PermissionUtils.compare('a.b.*', 'c.d.*')
# #=> -1
#
# PermissionUtils.compare('a.b.*', 'a.b.*')
# #=> 0
#
# @return (Integer) on whether string is included in another_string
# |-1| - no match, |0| - exact match, |1, (Symbol) :left or :right| - included
# @return (nil) if either string or another_string is invalid.
def self.compare(string, another_string)
if self.valid?(string) && self.valid?(another_string)
# Determine mode of comparision
str_p = self.valid?(string, :Permission)
str_g = !str_p
astr_p = self.valid?(another_string, :Permission)
astr_g = !astr_p
case
when str_p && astr_p
return 0 if string == another_string
-1
when str_p && astr_g
bool = self.include?(string, another_string)
bool ? 1 : -1
when str_g && astr_p
bool = self.include?(another_string, string)
bool ? 1 : -1
when str_g && astr_g
return 0 if string == another_string
sgroup_nodes = string.split(?.).each
agroup_nodes = another_string.split(?.).each
while true
begin
snode = sgroup_nodes.next
anode = agroup_nodes.next
return -1 if snode != anode
return 1, :left if sgroup_nodes.peek == '*'
return 1, :right if agroup_nodes.peek == '*'
rescue StopIteration
return -1
end
end
end
else
nil
end
end
# Creates a new Permission(Group) object based on a string
# @param string [String] The Permission(Group) string
# @return [Permission, PermissionGroup]
def self.create(string)
if string.end_with?('.*')
PermissionGroup.new(string)
else
Permission.new(string)
end
end
end