Ruby-ACL 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/ACL_Object.rb +224 -0
- data/lib/Ruby-ACL.rb +908 -0
- data/lib/ace.rb +91 -0
- data/lib/ace_rule.rb +36 -0
- data/lib/group.rb +32 -0
- data/lib/individual.rb +14 -0
- data/lib/principal.rb +44 -0
- data/lib/privilege.rb +13 -0
- data/lib/resource_object.rb +208 -0
- data/lib/rubyacl_exception.rb +69 -0
- metadata +57 -0
data/lib/ACL_Object.rb
ADDED
@@ -0,0 +1,224 @@
|
|
1
|
+
|
2
|
+
class ACL_Object
|
3
|
+
|
4
|
+
attr_reader :doc
|
5
|
+
attr_reader :col_path
|
6
|
+
|
7
|
+
def initialize(connector, col_path, report = false)
|
8
|
+
@connector = connector
|
9
|
+
@col_path = col_path
|
10
|
+
@report = report
|
11
|
+
end
|
12
|
+
|
13
|
+
private #--------------PRIVATE-----------------------------------------------
|
14
|
+
|
15
|
+
def generate_expr(name)
|
16
|
+
expr = <<END
|
17
|
+
<#{self.class.name} id="#{name}">
|
18
|
+
<membership>
|
19
|
+
|
20
|
+
</membership>
|
21
|
+
</#{self.class.name}>
|
22
|
+
END
|
23
|
+
return expr
|
24
|
+
rescue => e
|
25
|
+
raise e
|
26
|
+
end
|
27
|
+
|
28
|
+
def exists?(name, query = "#{@doc}//node()[@id=\"#{name}\"]")
|
29
|
+
handle = @connector.execute_query(query)
|
30
|
+
hits = @connector.get_hits(handle)
|
31
|
+
if(hits >= 1)
|
32
|
+
return true
|
33
|
+
else
|
34
|
+
return false
|
35
|
+
end
|
36
|
+
rescue => e
|
37
|
+
raise e
|
38
|
+
end
|
39
|
+
|
40
|
+
def exist_membership?(name, member_of) #Is <name> member of <member_of>
|
41
|
+
expr = "#{@doc}//#{self.class.name}s/descendant::*[@id=\"#{name}\"]/membership/mgroup[@idref=\"#{member_of}\"]"
|
42
|
+
exists?(name, expr)
|
43
|
+
rescue => e
|
44
|
+
raise e
|
45
|
+
end
|
46
|
+
|
47
|
+
public #------------------PUBLIC----------------------------------------------
|
48
|
+
|
49
|
+
def create_new(name, groups)
|
50
|
+
bool=true
|
51
|
+
if(name == nil || name == '')
|
52
|
+
bool = false
|
53
|
+
raise RubyACLException.new(self.class.name, __method__,
|
54
|
+
"Name is empty", 110), caller
|
55
|
+
end
|
56
|
+
if(exists?(name))
|
57
|
+
bool = false
|
58
|
+
raise RubyACLException.new(self.class.name, __method__,
|
59
|
+
"#{self.class.name} \"#{name}\" already exist(s)", 111), caller
|
60
|
+
end
|
61
|
+
|
62
|
+
if(bool)
|
63
|
+
expr = generate_expr(name)
|
64
|
+
expr_loc = "#{@doc}//#{self.class.name}s/#{self.class.name}[last()]"
|
65
|
+
@connector.update_insert(expr, "following", expr_loc)
|
66
|
+
if(exists?(name))
|
67
|
+
puts "New #{self.class.name} \"#{name}\" created." if @report
|
68
|
+
else
|
69
|
+
raise RubyACLException.new(self.class.name, __method__,
|
70
|
+
"#{self.class.name} \"#{name}\" was not able to create", 112), caller
|
71
|
+
end
|
72
|
+
end
|
73
|
+
if(groups.length > 0)
|
74
|
+
add_membership(name, groups, true)
|
75
|
+
end
|
76
|
+
return name
|
77
|
+
rescue XMLRPC::FaultException => e
|
78
|
+
raise e
|
79
|
+
rescue => e
|
80
|
+
raise e
|
81
|
+
end
|
82
|
+
|
83
|
+
#adds acl object into group(s); if you know prin exists set true for prin_exists
|
84
|
+
def add_membership(name, groups, ob_exists = false)
|
85
|
+
if(ob_exists || exists?(name))#, "#{@doc}//Individual[@id=\"#{name}\"]"))
|
86
|
+
for group in groups
|
87
|
+
if(!exists?(group))#, "#{@doc}//Group[@id=\"#{group}\"]"))
|
88
|
+
raise RubyACLException.new(self.class.name, __method__,
|
89
|
+
"Failed to add membership. Group \"#{group}\" does not exist.", 113), caller
|
90
|
+
end
|
91
|
+
query = "#{@doc}//node()[@id=\"#{name}\"]/membership/mgroup[@idref=\"#{group}\"]"
|
92
|
+
handle = @connector.execute_query(query)
|
93
|
+
hits = @connector.get_hits(handle)
|
94
|
+
if(hits == 0)
|
95
|
+
#protection against cycle in membership
|
96
|
+
if(find_parents(group).find_index(name).nil?)
|
97
|
+
expr = "<mgroup idref=\"#{group}\"/>"
|
98
|
+
expr_single = "#{@doc}//node()[@id=\"#{name}\"]/membership"
|
99
|
+
@connector.update_insert(expr, "into", expr_single)
|
100
|
+
else
|
101
|
+
raise RubyACLException.new(self.class.name, __method__,
|
102
|
+
"Failed to add membership. Membership is in cycle.", 118), caller
|
103
|
+
end
|
104
|
+
else
|
105
|
+
puts "Membership already exists." if @report
|
106
|
+
end
|
107
|
+
end
|
108
|
+
else
|
109
|
+
raise RubyACLException.new(self.class.name, __method__,
|
110
|
+
"Failed to add membership. #{self.class.name} \"#{name}\" does not exist.", 114), caller
|
111
|
+
end
|
112
|
+
return name
|
113
|
+
rescue => e
|
114
|
+
raise e
|
115
|
+
end #def add_membership
|
116
|
+
|
117
|
+
def del_membership(name, groups) #deletes prin_name from group(s)
|
118
|
+
if(exists?(name))
|
119
|
+
for group in groups
|
120
|
+
expr = "#{@doc}//#{self.class.name}s/descendant::*[@id=\"#{name}\"]/membership/mgroup[@idref=\"#{group}\"]"
|
121
|
+
@connector.update_delete(expr)
|
122
|
+
#end
|
123
|
+
if(!exists?(group))
|
124
|
+
raise RubyACLException.new(self.class.name, __method__,
|
125
|
+
"Failed to delete membership. Group \"#{group}\" does not exist.", 115), caller
|
126
|
+
end
|
127
|
+
end
|
128
|
+
else
|
129
|
+
raise RubyACLException.new(self.class.name, __method__,
|
130
|
+
"Failed to delete membership. #{self.class.name} \"#{name}\" does not exist.", 116), caller
|
131
|
+
end
|
132
|
+
return name
|
133
|
+
rescue => e
|
134
|
+
raise e
|
135
|
+
end #def del_membership
|
136
|
+
|
137
|
+
def delete(name)
|
138
|
+
if(exists?(name))
|
139
|
+
#deletes ACL_Object
|
140
|
+
expr = "#{@doc}//#{self.class.name}s/descendant::*[@id=\"#{name}\"]"
|
141
|
+
@connector.update_delete(expr)
|
142
|
+
#deletes references at ACL_Object
|
143
|
+
expr = "#{@doc}//node()[@idref=\"#{name}\"]"
|
144
|
+
@connector.update_delete(expr)
|
145
|
+
#deletes ACE mentioning ACL_Object
|
146
|
+
expr = "doc(\"#{@col_path}acl.xml\")//node()[@idref=\"#{name}\"]/parent::node()"
|
147
|
+
@connector.update_delete(expr)
|
148
|
+
else
|
149
|
+
raise RubyACLException.new(self.class.name, __method__,
|
150
|
+
"Failed to delete #{self.class.name}. #{self.class.name} \"#{name}\" does not exist.", 117), caller
|
151
|
+
end
|
152
|
+
return name
|
153
|
+
rescue => e
|
154
|
+
raise e
|
155
|
+
end #def delete
|
156
|
+
|
157
|
+
def rename(old_name, new_name)
|
158
|
+
if(!exists?(new_name))
|
159
|
+
|
160
|
+
expr = "#{@doc}//node()[@id=\"#{old_name}\"]/@id"
|
161
|
+
expr_single = "\"#{new_name}\""
|
162
|
+
@connector.update_value(expr, expr_single)
|
163
|
+
|
164
|
+
expr = "#{@doc}//node()[@idref=\"#{old_name}\"]/@idref"
|
165
|
+
expr_single = "\"#{new_name}\""
|
166
|
+
@connector.update_value(expr, expr_single)
|
167
|
+
|
168
|
+
expr = "doc(\"#{@col_path}acl.xml\")//node()[@idref=\"#{old_name}\"]/@idref"
|
169
|
+
expr_single = "\"#{new_name}\""
|
170
|
+
@connector.update_value(expr, expr_single)
|
171
|
+
|
172
|
+
query = "doc(\"#{@col_path}acl.xml\")//node()[@id=\"#{old_name}\"]"
|
173
|
+
handle = @connector.execute_query(query)
|
174
|
+
hits = @connector.get_hits(handle)
|
175
|
+
query = "#{@doc}//node()[@id=\"#{old_name}\"]"
|
176
|
+
handle = @connector.execute_query(query)
|
177
|
+
hits += @connector.get_hits(handle)
|
178
|
+
if(hits == 0)
|
179
|
+
puts "Rename succeeded." if @report
|
180
|
+
else
|
181
|
+
raise RubyACLException.new(self.class.name, __method__,
|
182
|
+
"Failed to rename", 120), caller
|
183
|
+
end
|
184
|
+
else
|
185
|
+
raise RubyACLException.new(self.class.name, __method__,
|
186
|
+
"Failed to rename #{self.class.name}. #{self.class.name} \"#{new_name}\" already exists.", 119), caller
|
187
|
+
end
|
188
|
+
return old_name
|
189
|
+
rescue XMLRPC::FaultException => e
|
190
|
+
raise e
|
191
|
+
rescue => e
|
192
|
+
raise e
|
193
|
+
end
|
194
|
+
|
195
|
+
def ge(t, f)
|
196
|
+
if(t >= f)
|
197
|
+
return true
|
198
|
+
else
|
199
|
+
return false
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
#finds membership parrent and returns in sorted array by level,
|
204
|
+
#Root is first leaf is last.
|
205
|
+
#e.g. dog's parrent is mammal.
|
206
|
+
def find_parents(id)
|
207
|
+
query = "#{@doc}//node()[@id=\"#{id}\"]/membership/*/string(@idref)"
|
208
|
+
ids = []
|
209
|
+
handle = @connector.execute_query(query)
|
210
|
+
hits = @connector.get_hits(handle)
|
211
|
+
hits.times {
|
212
|
+
|i|
|
213
|
+
id_ref = @connector.retrieve(handle, i)
|
214
|
+
if(id_ref=="")
|
215
|
+
next #for unknown reason eXist returns 1 empty hit even any exists therefore unite is skipped (e.g. //node()[@id="all"]/membership/*/string(@idref)
|
216
|
+
end
|
217
|
+
ids = find_parents(id_ref) | ids | [id_ref] #unite arrays
|
218
|
+
}
|
219
|
+
return ids
|
220
|
+
rescue => e
|
221
|
+
raise e
|
222
|
+
end
|
223
|
+
|
224
|
+
end
|
data/lib/Ruby-ACL.rb
ADDED
@@ -0,0 +1,908 @@
|
|
1
|
+
$:.unshift("./lib")
|
2
|
+
$:.unshift(".")
|
3
|
+
$:.unshift('D:\\eXistAPI\\lib\\')
|
4
|
+
require 'ACL_Object'
|
5
|
+
require 'Principal'
|
6
|
+
require 'individual'
|
7
|
+
require 'group'
|
8
|
+
require 'privilege'
|
9
|
+
require 'resource_object'
|
10
|
+
require 'ace'
|
11
|
+
require 'date'
|
12
|
+
require 'ace_rule'
|
13
|
+
require 'rubyacl_exception'
|
14
|
+
|
15
|
+
#RubyACL is library that handles access permisions. RubyACL offers to create and modify three ACL objects - three dimensions: Principal, Privilege, Resource object.
|
16
|
+
#Principal is someone or something that want to access.
|
17
|
+
#Privilege is level of access. (read, write etc.).
|
18
|
+
#Resource object is what is principal accessing.
|
19
|
+
#RubyACL uses API interface to communicate with database. This interface is described by class API_inteface.
|
20
|
+
#At the end of the class you can see set of examples. Also good source of information are testcases.
|
21
|
+
class RubyACL
|
22
|
+
|
23
|
+
# name of the ACL
|
24
|
+
attr_reader :name
|
25
|
+
# collection path in db, where ACL will be stored.
|
26
|
+
attr_reader :col_path
|
27
|
+
|
28
|
+
#Creates new instance of Ruby-ACL. Ruby-ACL works if principals, privileges and resource object.
|
29
|
+
#With Ruby-ACL you can manage permsion to person for resource objects.
|
30
|
+
#
|
31
|
+
# * *Args* :
|
32
|
+
# - +name+ -> name of the ACL
|
33
|
+
# - +connector+ -> instance of connection manager with db. e.g. ExistAPI.new("http://localhost:8080/exist/xmlrpc", "admin", "admin")
|
34
|
+
# - +colpath+ -> path of collection in db. e.g. "/db/acl/"
|
35
|
+
# - +src_files_path+ -> path of source files in local location.
|
36
|
+
# - +report+ -> boolean - if true Ruby-ACL
|
37
|
+
# * *Returns* :
|
38
|
+
# - instance of RubyACL
|
39
|
+
# * *Raises* :
|
40
|
+
# - +RubyACLException+ -> Name is empty
|
41
|
+
def initialize(name, connector, colpath = "/db/acl/", src_files_path = "./src_files/", report = false)
|
42
|
+
if(name == "")
|
43
|
+
raise RubyACLException.new(self.class.name, __method__, "Name is empty", 0), caller
|
44
|
+
end
|
45
|
+
@name = name
|
46
|
+
@connector = connector
|
47
|
+
if(colpath[-1] != "/")
|
48
|
+
colpath += "/"
|
49
|
+
end
|
50
|
+
@col_path = colpath
|
51
|
+
@src_files_path = src_files_path
|
52
|
+
@report = report
|
53
|
+
@prin = Principal.new(@connector, @col_path, @report)
|
54
|
+
@indi = Individual.new(@connector, @col_path, @report)
|
55
|
+
@group = Group.new(@connector, @col_path, @report)
|
56
|
+
@priv = Privilege.new(@connector, @col_path, @report)
|
57
|
+
@res_obj = ResourceObject.new(@connector, @col_path, @report)
|
58
|
+
@ace = Ace.new(@connector, @col_path, @report)
|
59
|
+
create_acl_in_db()
|
60
|
+
rename(name)
|
61
|
+
rescue => e
|
62
|
+
raise e
|
63
|
+
end
|
64
|
+
|
65
|
+
private # private methods follow
|
66
|
+
|
67
|
+
def create_acl_in_db()
|
68
|
+
if(!@connector.existscollection?(@col_path))
|
69
|
+
#puts "Collection doesn't exist. Creating collection."
|
70
|
+
@connector.createcollection(@col_path)
|
71
|
+
end
|
72
|
+
col = @connector.getcollection(@col_path)
|
73
|
+
sfs = missing_src_files(col)
|
74
|
+
if(sfs != []) #creates array of documents that dont exist in collection
|
75
|
+
missing_files = ""
|
76
|
+
sfs.each { |sf|
|
77
|
+
missing_files = missing_files + '"'+sf+'"'
|
78
|
+
if(sf != sfs.last())
|
79
|
+
missing_files = missing_files + ", "
|
80
|
+
end
|
81
|
+
}
|
82
|
+
#Creating new source file(s)
|
83
|
+
for sfile in sfs
|
84
|
+
xmlfile = File.read(@src_files_path + sfile)
|
85
|
+
@connector.storeresource(xmlfile, @col_path + sfile)
|
86
|
+
end
|
87
|
+
col = @connector.getcollection(@col_path)
|
88
|
+
end
|
89
|
+
|
90
|
+
if(col.name == @col_path && missing_src_files(col) == [])
|
91
|
+
puts "ACL collection with source files created." if @report
|
92
|
+
else
|
93
|
+
raise RubyACLException.new(self.class.name, __method__, "Failed to create ACL in database", 1), caller
|
94
|
+
end
|
95
|
+
rescue XMLRPC::FaultException => e
|
96
|
+
raise e
|
97
|
+
rescue => e
|
98
|
+
raise e
|
99
|
+
end
|
100
|
+
|
101
|
+
def missing_src_files(col) #returns array of files that are not present in acl collection
|
102
|
+
files = []
|
103
|
+
if(col['acl.xml'] == nil)
|
104
|
+
files.push('acl.xml')
|
105
|
+
end
|
106
|
+
if(col['Principals.xml'] == nil)
|
107
|
+
files.push('Principals.xml')
|
108
|
+
end
|
109
|
+
if(col['Privileges.xml'] == nil)
|
110
|
+
files.push('Privileges.xml')
|
111
|
+
end
|
112
|
+
if(col['ResourceObjects.xml'] == nil)
|
113
|
+
files.push('ResourceObjects.xml')
|
114
|
+
end
|
115
|
+
return files
|
116
|
+
end
|
117
|
+
|
118
|
+
def decide(res)
|
119
|
+
#puts "decide"
|
120
|
+
if(res == "allow")
|
121
|
+
return true
|
122
|
+
elsif(res == "deny")
|
123
|
+
return false
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
#Returns ACE that has higher priority.
|
128
|
+
#Lowest number has highest priority:
|
129
|
+
#1. Owner - owner is handled in method check
|
130
|
+
#2. Explicit Deny
|
131
|
+
#3. Explicit Allow
|
132
|
+
#4. Inherited Deny
|
133
|
+
#5. Inherited Allow
|
134
|
+
#6. If not found then Access denied
|
135
|
+
#
|
136
|
+
# * *Args* :
|
137
|
+
# - +final_ace+ -> first ace to compare
|
138
|
+
# - +temp_ace+ -> second ace to compare
|
139
|
+
# * *Returns* :
|
140
|
+
# - returns ace that has higher priority
|
141
|
+
# * *Raises* :
|
142
|
+
# - +RubyACLException+ -> Failed to create ACL in database
|
143
|
+
#
|
144
|
+
def compare(final_ace, temp_ace) #returns ace that has higher priority
|
145
|
+
if(final_ace == nil)
|
146
|
+
return temp_ace
|
147
|
+
end
|
148
|
+
|
149
|
+
if(@prin.eq(temp_ace, final_ace) && final_ace.acc_type == "deny")
|
150
|
+
if(@priv.ge(temp_ace, final_ace, @privs) && @res_obj.ge(temp_ace, final_ace, @res_obs))
|
151
|
+
final_ace = temp_ace
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
if(@prin.ne(temp_ace, final_ace))
|
156
|
+
if(@priv.ge(temp_ace, final_ace, @privs) && @res_obj.ge(temp_ace, final_ace, @res_obs))
|
157
|
+
final_ace = temp_ace
|
158
|
+
end
|
159
|
+
end
|
160
|
+
return final_ace
|
161
|
+
rescue => e
|
162
|
+
raise e
|
163
|
+
end
|
164
|
+
|
165
|
+
#Prepares query in xQuery language. This query selects all ace that has
|
166
|
+
#principale && one of the privileges && one of the resource objects.
|
167
|
+
#
|
168
|
+
#
|
169
|
+
# * *Args* :
|
170
|
+
# - +prin+ -> principal
|
171
|
+
# - +privs+ -> privilege and all parental privileges
|
172
|
+
# - +res_obs+ -> resource object and all parental resource objects
|
173
|
+
# * *Returns* :
|
174
|
+
# - string, created query
|
175
|
+
# * *Raises* :
|
176
|
+
# - +nothing+
|
177
|
+
#
|
178
|
+
def prepare_query(prin, privs, res_obs)
|
179
|
+
query = <<END
|
180
|
+
for $ace in #{@ace.doc}//Ace
|
181
|
+
where (
|
182
|
+
END
|
183
|
+
|
184
|
+
query += "($ace/Principal/@idref=\"#{prin}\")"
|
185
|
+
|
186
|
+
query += " and ("
|
187
|
+
for priv in privs
|
188
|
+
query += "$ace/Privilege/@idref=\"#{priv}\""
|
189
|
+
if(priv != privs.last)
|
190
|
+
query+=" or "
|
191
|
+
else
|
192
|
+
query+=") "
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
query += " and ("
|
197
|
+
for res_ob in res_obs
|
198
|
+
query += "$ace/ResourceObject/@idref=\"#{res_ob}\""
|
199
|
+
if(res_ob != res_obs.last)
|
200
|
+
query+=" or "
|
201
|
+
else
|
202
|
+
query+=") "
|
203
|
+
end
|
204
|
+
end
|
205
|
+
query+=")"
|
206
|
+
query += "return $ace/string(@id)"
|
207
|
+
return query
|
208
|
+
rescue => e
|
209
|
+
raise e
|
210
|
+
end
|
211
|
+
|
212
|
+
#In array res_obs are all optencial resource objects.
|
213
|
+
#It transform array into string (id="something" or id=... and so on)
|
214
|
+
def is_owner?(prin_name, res_obs)
|
215
|
+
res_obs = prepare_res_obs(res_obs)
|
216
|
+
#Select only those resOb that have wanted owner.
|
217
|
+
query = "#{@res_obj.doc}//ResourceObject[#{res_obs} and owner/string(@idref)=\"#{prin_name}\"]"
|
218
|
+
#puts query
|
219
|
+
handle = @connector.execute_query(query)
|
220
|
+
hits = @connector.get_hits(handle)
|
221
|
+
if(hits>0) #if owner exist, lets grand access
|
222
|
+
return true
|
223
|
+
else
|
224
|
+
return false
|
225
|
+
end
|
226
|
+
rescue => e
|
227
|
+
raise e
|
228
|
+
end
|
229
|
+
|
230
|
+
#Creates part of the query. Inserts "or" between each of resource object and whole string is in ()
|
231
|
+
#
|
232
|
+
# * *Args* :
|
233
|
+
# - +res_obs+ -> array of resource objects
|
234
|
+
# * *Returns* :
|
235
|
+
# -string
|
236
|
+
# * *Raises* :
|
237
|
+
# - +nothing+
|
238
|
+
#
|
239
|
+
def prepare_res_obs(res_obs)
|
240
|
+
str = "("
|
241
|
+
for res_ob in res_obs
|
242
|
+
str = str + "@id=\""
|
243
|
+
str += res_ob
|
244
|
+
str += "\" or "
|
245
|
+
end
|
246
|
+
str = str[0..-4] #delete last " OR "
|
247
|
+
str += ")"
|
248
|
+
return str
|
249
|
+
end
|
250
|
+
|
251
|
+
#Creates ace in acl.xml in db
|
252
|
+
#
|
253
|
+
# * *Args* :
|
254
|
+
# - +prin_name+ -> name of the principal
|
255
|
+
# - +acc_type+ -> access type. allow to allow. deny to revoke
|
256
|
+
# - +priv_name+ -> name of the privilege
|
257
|
+
# - +res_ob_type+ -> type of resource object
|
258
|
+
# - +res_ob_adrs+ -> address of resource object.
|
259
|
+
# * *Returns* :
|
260
|
+
# -id of ace
|
261
|
+
# * *Raises* :
|
262
|
+
# - +nothing+
|
263
|
+
#
|
264
|
+
def insert_ace(prin_name, acc_type, priv_name, res_ob_type, res_ob_adrs)
|
265
|
+
res_ob_id = @res_obj.find_res_ob(res_ob_type, res_ob_adrs)
|
266
|
+
if(res_ob_id == nil)
|
267
|
+
res_ob_id = @res_obj.create_new(res_ob_type, res_ob_adrs, prin_name)
|
268
|
+
end
|
269
|
+
id = @ace.create_new(prin_name, acc_type, priv_name, res_ob_id)
|
270
|
+
return id
|
271
|
+
end
|
272
|
+
|
273
|
+
protected
|
274
|
+
|
275
|
+
public # follow public methods
|
276
|
+
|
277
|
+
#Renames acl (also in db)
|
278
|
+
#
|
279
|
+
# * *Args* :
|
280
|
+
# - +new_name+ -> new name of acl
|
281
|
+
# * *Returns* :
|
282
|
+
# -int, handle of the query
|
283
|
+
# * *Raises* :
|
284
|
+
# - +RubyACLException+ -> Failed to set new name
|
285
|
+
#
|
286
|
+
def rename(new_name)
|
287
|
+
query = "update value doc(\"#{@col_path}acl.xml\")/acl/@aclname with \"#{new_name}\""
|
288
|
+
@connector.execute_query(query)
|
289
|
+
query = "doc(\"#{@col_path}acl.xml\")/acl/string(@aclname)"
|
290
|
+
handle = @connector.execute_query(query)
|
291
|
+
if(new_name != @connector.retrieve(handle, 0))
|
292
|
+
raise RubyACLException.new(self.class.name, __method__, "Failed to set new name", 2), caller
|
293
|
+
end
|
294
|
+
rescue XMLRPC::FaultException => e
|
295
|
+
raise e
|
296
|
+
rescue => e
|
297
|
+
raise e
|
298
|
+
end
|
299
|
+
|
300
|
+
#It saves/backs up acl
|
301
|
+
#
|
302
|
+
# * *Args* :
|
303
|
+
# - +path+ -> to local location
|
304
|
+
# * *Returns* :
|
305
|
+
# - array of documents in ACL working collection
|
306
|
+
# * *Raises* :
|
307
|
+
# - +nothing+
|
308
|
+
#
|
309
|
+
def save(path, date = false)
|
310
|
+
col = @connector.getcollection(@col_path)
|
311
|
+
docs = col.docs()
|
312
|
+
if(date)
|
313
|
+
path = path + Date.today.to_s + "/"
|
314
|
+
end
|
315
|
+
if(!File.exists?(path))
|
316
|
+
Dir.mkdir(path)
|
317
|
+
end
|
318
|
+
docs.each{|doc|
|
319
|
+
document = col[doc]
|
320
|
+
#doc = doc + "_BU"
|
321
|
+
filename = path + doc
|
322
|
+
f = File.new(filename, 'w')
|
323
|
+
f.puts(document.content)
|
324
|
+
f.close
|
325
|
+
}
|
326
|
+
rescue => e
|
327
|
+
raise e
|
328
|
+
end
|
329
|
+
|
330
|
+
#It loads backuped acl data.
|
331
|
+
#
|
332
|
+
# * *Args* :
|
333
|
+
# - +connector+ -> instance of connection manager with db. e.g. ExistAPI.new("http://localhost:8080/exist/xmlrpc", "admin", "admin")
|
334
|
+
# - +colpath+ -> path of collection in db. e.g. "/db/acl/"
|
335
|
+
# - +src_files_path+ -> path of source files in local location.
|
336
|
+
# - +report+ -> boolean - if true Ruby-ACL
|
337
|
+
# * *Returns* :
|
338
|
+
# -new instance of Ruby-ACL
|
339
|
+
# * *Raises* :
|
340
|
+
# - +nothin+
|
341
|
+
#
|
342
|
+
def RubyACL.load(connector, colpath, src_files_path, report = false)
|
343
|
+
xmlfile = File.read(src_files_path+"acl.xml")
|
344
|
+
startindex = xmlfile.index('"', xmlfile.index("aclname="))
|
345
|
+
endindex = xmlfile.index('"', startindex+1)
|
346
|
+
name = xmlfile[startindex+1..endindex-1]
|
347
|
+
newacl = RubyACL.new(name, connector, colpath, src_files_path, report)
|
348
|
+
return newacl
|
349
|
+
rescue => e
|
350
|
+
raise e
|
351
|
+
end
|
352
|
+
|
353
|
+
#Decides whether principal has privilege or not to resource object identified
|
354
|
+
#by access type and address. If the accessType of ace is allow - returns true.
|
355
|
+
#If accessType of ace is deny return false.
|
356
|
+
#
|
357
|
+
#Priority of decision is as follows lower.
|
358
|
+
#Lowest number has highest priority:
|
359
|
+
#1. Owner
|
360
|
+
#2. Explicit Deny
|
361
|
+
#3. Explicit Allow
|
362
|
+
#4. Inherited Deny
|
363
|
+
#5. Inherited Allow
|
364
|
+
#6. If not found then Deny
|
365
|
+
#
|
366
|
+
# * *Args* :
|
367
|
+
# - +prin_name+ -> name of the principal
|
368
|
+
# - +priv_name+ -> name of the privilege
|
369
|
+
# - +res_ob_type+ -> type of the resource object
|
370
|
+
# - +res_ob_adr+ -> address of the resource object
|
371
|
+
# * *Returns* :
|
372
|
+
# -boolean - true - has privilege to resource object, false - has not
|
373
|
+
# * *Raises* :
|
374
|
+
# - +nothing+
|
375
|
+
#
|
376
|
+
def check(prin_name, priv_name, res_ob_type, res_ob_adr)
|
377
|
+
res_ob_id = @res_obj.find_res_ob(res_ob_type, res_ob_adr)
|
378
|
+
#creates the set of resOb (wanted resOb and all resOb from root to address, unsorted)
|
379
|
+
@res_obs = @res_obj.find_res_ob_parents(res_ob_type, res_ob_adr)
|
380
|
+
#adds resOb, which ends with /* + wanted resOb
|
381
|
+
@res_obs = @res_obj.res_obs_grand2children(@res_obs) + [res_ob_id]
|
382
|
+
|
383
|
+
if(is_owner?(prin_name, @res_obs))
|
384
|
+
#puts "owner"
|
385
|
+
return true #access allowed - owner can do everything
|
386
|
+
end
|
387
|
+
|
388
|
+
#creates the set of principals {wanted principal and all groups wanted principal is member of}
|
389
|
+
prins = @prin.find_parents(prin_name) + [prin_name]
|
390
|
+
@privs = @priv.find_parents(priv_name) + [priv_name] #same for privilege
|
391
|
+
|
392
|
+
final_ace = nil
|
393
|
+
for prin in prins
|
394
|
+
#ask for principal with privilege or higher privileges and and resob or higher resob.
|
395
|
+
query = prepare_query(prin, @privs, @res_obs)
|
396
|
+
#puts query
|
397
|
+
handle = @connector.execute_query(query)
|
398
|
+
hits = @connector.get_hits(handle)
|
399
|
+
#puts "hits #{hits}"
|
400
|
+
if(hits > 0)
|
401
|
+
temp_id = @connector.retrieve(handle, 0) #retrieve id of first Ace
|
402
|
+
temp_ace = AceRule.new(temp_id, @ace, @connector)
|
403
|
+
if(hits == 1)
|
404
|
+
final_ace = compare(final_ace, temp_ace)
|
405
|
+
else #there are more rules
|
406
|
+
hits.times { |i|
|
407
|
+
temp_id = @connector.retrieve(handle, i) #retrieve id of next Ace
|
408
|
+
temp_ace.reload!(temp_id)
|
409
|
+
final_ace = compare(final_ace, temp_ace)
|
410
|
+
}
|
411
|
+
end
|
412
|
+
end
|
413
|
+
end
|
414
|
+
|
415
|
+
if(final_ace == nil) #Rule doesnt exist = access denied
|
416
|
+
#puts "nil"
|
417
|
+
puts "Required rule
|
418
|
+
(#{prin_name}, #{priv_name}, #{res_ob_type}, #{res_ob_adr}) does not exist.
|
419
|
+
Access denied." if @report
|
420
|
+
return false
|
421
|
+
else
|
422
|
+
return decide(final_ace.acc_type)
|
423
|
+
end
|
424
|
+
rescue => e
|
425
|
+
raise e
|
426
|
+
#puts e.backtrace.join("\n")
|
427
|
+
#raise RubyACLException.new(self.class.name, __method__, "Failed to check ACE", 3), caller
|
428
|
+
end
|
429
|
+
|
430
|
+
#It shows permissions for principal all its parents.
|
431
|
+
#
|
432
|
+
# * *Args* :
|
433
|
+
# - +prin_name+ -> name of the principal
|
434
|
+
# * *Returns* :
|
435
|
+
# - string -> all aces that has principal and all its parents.
|
436
|
+
# * *Raises* :
|
437
|
+
# - +nothing+
|
438
|
+
#
|
439
|
+
def show_permissions_for(prin_name)
|
440
|
+
#creates the set of principals {wanted principal and all groups wanted principal is member of}
|
441
|
+
prins = [prin_name] + @prin.find_parents(prin_name)
|
442
|
+
|
443
|
+
#creates query, ask for principal permisions and all his parents permisions
|
444
|
+
query = "for $ace in #{@ace.doc}//Ace where ("
|
445
|
+
for prin in prins
|
446
|
+
query += "($ace/Principal/@idref=\"#{prin}\") or"
|
447
|
+
end
|
448
|
+
query = query[0..-4] #delete last or
|
449
|
+
query += ") return $ace"
|
450
|
+
|
451
|
+
ace = ""
|
452
|
+
handle = @connector.execute_query(query)
|
453
|
+
hits = @connector.get_hits(handle)
|
454
|
+
hits.times { |i|
|
455
|
+
ace = ace + @connector.retrieve(handle, i) + "\n" #retrieve and add next ACE
|
456
|
+
}
|
457
|
+
ace = ace[0..-2] #delete last \n
|
458
|
+
return ace
|
459
|
+
rescue => e
|
460
|
+
raise e
|
461
|
+
end
|
462
|
+
|
463
|
+
#Creates ace in acl. If resource object doesn't exist it creates resource object first.
|
464
|
+
#
|
465
|
+
#Address:
|
466
|
+
#If is used:
|
467
|
+
# resource address /something/somethingelse and grand2children = true
|
468
|
+
# then will be created access for somthingelse and its children
|
469
|
+
#If is used:
|
470
|
+
# only /something/somethingelse/*
|
471
|
+
# then will be created access only to somethingelse's children
|
472
|
+
#
|
473
|
+
#
|
474
|
+
# * *Args* :
|
475
|
+
# - +prin_name+ -> name of the principal
|
476
|
+
# - +acc_type+ -> access type. True = grant, false = revoke
|
477
|
+
# - +priv_name+ -> name of the privilege
|
478
|
+
# - +res_ob_type+ -> type of the resource object
|
479
|
+
# - +res_ob_adr+ -> address of the resource object
|
480
|
+
# - +grand2children+ -> boolean.
|
481
|
+
# True = grant to all children.
|
482
|
+
# False = grant only to specified resource object
|
483
|
+
# * *Returns* :
|
484
|
+
# - string, id of the created ace
|
485
|
+
# * *Raises* :
|
486
|
+
# - +nothing+
|
487
|
+
#
|
488
|
+
def create_ace(prin_name, acc_type, priv_name, res_ob_type, res_ob_adr, grand2children = false)
|
489
|
+
if(res_ob_adr[-2..-1] == "/*")
|
490
|
+
id = insert_ace(prin_name, acc_type, priv_name, res_ob_type, res_ob_adr)
|
491
|
+
else
|
492
|
+
id = insert_ace(prin_name, acc_type, priv_name, res_ob_type, res_ob_adr)
|
493
|
+
if(grand2children)
|
494
|
+
res_ob_adr = res_ob_adr + "/*"
|
495
|
+
insert_ace(prin_name, acc_type, priv_name, res_ob_type, res_ob_adr)
|
496
|
+
end
|
497
|
+
end
|
498
|
+
return id
|
499
|
+
rescue => e
|
500
|
+
raise e
|
501
|
+
end
|
502
|
+
|
503
|
+
#It creates principal with name and membership in groups.
|
504
|
+
#
|
505
|
+
# * *Args* :
|
506
|
+
# - +name+ -> name of the princpal
|
507
|
+
# - +groups+ -> array of groups where principal will be member.
|
508
|
+
# * *Returns* :
|
509
|
+
# - string, name of the principal
|
510
|
+
# * *Raises* :
|
511
|
+
# - +nothing+
|
512
|
+
#
|
513
|
+
def create_principal(name, groups = ["ALL"])
|
514
|
+
@indi.create_new(name, groups)
|
515
|
+
rescue => e
|
516
|
+
raise e
|
517
|
+
end
|
518
|
+
|
519
|
+
#Create group with name and membership in groups and members as groups or individual
|
520
|
+
#
|
521
|
+
#Note:
|
522
|
+
# members can be groups or individuals;
|
523
|
+
# At first method check if the name already exist. Or if groups and members exist at all
|
524
|
+
#
|
525
|
+
# * *Args* :
|
526
|
+
# - +name+ -> name of the new group
|
527
|
+
# - +member_of+ -> array of groups where new group will be member.
|
528
|
+
# - +members+ -> array of principals, who will be members of new group
|
529
|
+
# members can be groups or individuals;
|
530
|
+
# check if it the name already exist. Or if groups and members exist at all
|
531
|
+
# * *Returns* :
|
532
|
+
# - string, name of the group
|
533
|
+
# * *Raises* :
|
534
|
+
# - +nothing+
|
535
|
+
#
|
536
|
+
def create_group(name, member_of = ["ALL"], members = [])
|
537
|
+
@group.create_new(name, member_of, members)
|
538
|
+
rescue => e
|
539
|
+
raise e
|
540
|
+
end
|
541
|
+
|
542
|
+
#It creates privilege with name and membership in specified privileges.
|
543
|
+
#
|
544
|
+
# * *Args* :
|
545
|
+
# - +name+ -> name of the privilege
|
546
|
+
# - +member_of+ -> array of privileges where new privilege will be member.
|
547
|
+
# * *Returns* :
|
548
|
+
# - string, name of the privilege
|
549
|
+
# * *Raises* :
|
550
|
+
# - +nothing+
|
551
|
+
#
|
552
|
+
def create_privilege(name, member_of = ["ALL_PRIVILEGES"])
|
553
|
+
@priv.create_new(name, member_of)
|
554
|
+
rescue => e
|
555
|
+
raise e
|
556
|
+
end
|
557
|
+
|
558
|
+
#It creates resource object with type, address and owner.
|
559
|
+
#
|
560
|
+
# * *Args* :
|
561
|
+
# - +type+ -> type of resource object. e.g. doc, room, file, collection
|
562
|
+
# - +address+ -> address of the resource object. If it ends with /*, it means all children
|
563
|
+
# - +owner+ -> owner of the resource object
|
564
|
+
# * *Returns* :
|
565
|
+
# - string, id of the created resource object
|
566
|
+
# * *Raises* :
|
567
|
+
# - +nothing+
|
568
|
+
#
|
569
|
+
def create_resource_object(type, address, owner)
|
570
|
+
#puts "type #{type} add #{address}"
|
571
|
+
id = @res_obj.create_new(type, address, owner)
|
572
|
+
return id
|
573
|
+
rescue => e
|
574
|
+
raise e
|
575
|
+
end
|
576
|
+
|
577
|
+
#It changes resource object's type.
|
578
|
+
#Address and type must be specified to identify resource object.
|
579
|
+
#
|
580
|
+
# * *Args* :
|
581
|
+
# - +type+ -> type of resource object
|
582
|
+
# - +address+ -> address of resource object
|
583
|
+
# - +new_type+ -> new_type of resource object
|
584
|
+
# * *Returns* :
|
585
|
+
# - string, original type
|
586
|
+
# * *Raises* :
|
587
|
+
# - +nothing+
|
588
|
+
#
|
589
|
+
def change_res_ob_type(type, address, new_type)
|
590
|
+
@res_obj.change_type(type, address, new_type)
|
591
|
+
rescue => e
|
592
|
+
raise e
|
593
|
+
end
|
594
|
+
|
595
|
+
#It changes resource object's address.
|
596
|
+
#Address and type must be specified to identify resource object.
|
597
|
+
#
|
598
|
+
# * *Args* :
|
599
|
+
# - +type+ -> type of resource object
|
600
|
+
# - +address+ -> address of resource object
|
601
|
+
# - +new_address+ -> new address of resource object
|
602
|
+
# * *Returns* :
|
603
|
+
# - string, original address
|
604
|
+
# * *Raises* :
|
605
|
+
# - +nothing+
|
606
|
+
#
|
607
|
+
def change_of_res_ob_address(type, address, new_address)
|
608
|
+
@res_obj.change_address(type, address, new_address)
|
609
|
+
rescue => e
|
610
|
+
raise e
|
611
|
+
end
|
612
|
+
|
613
|
+
#It changes resource object's owner.
|
614
|
+
#Address and type must be specified to identify resource object.
|
615
|
+
#
|
616
|
+
# * *Args* :
|
617
|
+
# - +type+ -> type of resource object
|
618
|
+
# - +address+ -> address of resource object
|
619
|
+
# - +new_owner+ -> new owner of resource object
|
620
|
+
# * *Returns* :
|
621
|
+
# - string, original owner
|
622
|
+
# * *Raises* :
|
623
|
+
# - +nothing+
|
624
|
+
#
|
625
|
+
def change_of_res_ob_owner(type, address, new_owner)
|
626
|
+
@res_obj.change_owner(type, address, new_owner)
|
627
|
+
rescue => e
|
628
|
+
raise e
|
629
|
+
end
|
630
|
+
|
631
|
+
#It renames any principal. It means either individual or group.
|
632
|
+
#
|
633
|
+
# * *Args* :
|
634
|
+
# - +old_name+ -> old name of principal
|
635
|
+
# - +new_name+ -> new name of principal
|
636
|
+
# * *Returns* :
|
637
|
+
# - string, original name of the principal
|
638
|
+
# * *Raises* :
|
639
|
+
# - +nothing+
|
640
|
+
#
|
641
|
+
def rename_principal(old_name, new_name)
|
642
|
+
@prin.rename(old_name, new_name)
|
643
|
+
end
|
644
|
+
|
645
|
+
#It renames privilege.
|
646
|
+
#
|
647
|
+
# * *Args* :
|
648
|
+
# - +old_name+ -> old name of privilege
|
649
|
+
# - +new_name+ -> new name of privilege
|
650
|
+
# * *Returns* :
|
651
|
+
# - string, original name of the privilege
|
652
|
+
# * *Raises* :
|
653
|
+
# - +nothing+
|
654
|
+
#
|
655
|
+
def rename_privilege(old_name, new_name)
|
656
|
+
@priv.rename(old_name, new_name)
|
657
|
+
end
|
658
|
+
|
659
|
+
#It adds principal into group(s) as member.
|
660
|
+
#
|
661
|
+
# * *Args* :
|
662
|
+
# - +name+ -> name of the principal
|
663
|
+
# - +groups+ -> array of groups, where principal will be member.
|
664
|
+
# - +existance+ -> boolean. If you know that principal exists set true for existance.
|
665
|
+
# * *Returns* :
|
666
|
+
# - string, name of the principal
|
667
|
+
# * *Raises* :
|
668
|
+
# - +nothing+
|
669
|
+
#
|
670
|
+
def add_membership_principal(name, groups, existance = false)
|
671
|
+
@prin.add_membership(name, groups, existance)
|
672
|
+
rescue => e
|
673
|
+
raise e
|
674
|
+
end
|
675
|
+
|
676
|
+
#It adds privilege into privilege(s). So you can gather privileges into tree.
|
677
|
+
#
|
678
|
+
# * *Args* :
|
679
|
+
# - +name+ -> name of the privilege
|
680
|
+
# - +groups+ -> array of privileges, where privilege will be member.
|
681
|
+
# - +existance+ -> boolean. If you know that privielge exists set true for existance.
|
682
|
+
# * *Returns* :
|
683
|
+
# - string, name of the privilege
|
684
|
+
# * *Raises* :
|
685
|
+
# - +nothing+
|
686
|
+
#
|
687
|
+
def add_membership_privilege (name, groups, existance = false)
|
688
|
+
@priv.add_membership(name, groups, existance)
|
689
|
+
rescue => e
|
690
|
+
raise e
|
691
|
+
end
|
692
|
+
|
693
|
+
#It removes principal from group(s) where principal is member.
|
694
|
+
#
|
695
|
+
# * *Args* :
|
696
|
+
# - +name+ -> name of the principal
|
697
|
+
# - +groups+ -> array of groups, where principal is member.
|
698
|
+
# * *Returns* :
|
699
|
+
# - string, name of the principal
|
700
|
+
# * *Raises* :
|
701
|
+
# - +nothing+
|
702
|
+
#
|
703
|
+
def del_membership_principal(prin_name, groups) #deletes prin_name from group(s)
|
704
|
+
@prin.del_membership(prin_name, groups)
|
705
|
+
rescue => e
|
706
|
+
raise e
|
707
|
+
end
|
708
|
+
|
709
|
+
#It removes the privilege from parental privilege(s) where the privilege is member.
|
710
|
+
#
|
711
|
+
# * *Args* :
|
712
|
+
# - +name+ -> name of the privilege
|
713
|
+
# - +groups+ -> array of groups, where privilege is member.
|
714
|
+
# * *Returns* :
|
715
|
+
# - string, name of the privilege
|
716
|
+
# * *Raises* :
|
717
|
+
# - +nothing+
|
718
|
+
#
|
719
|
+
def del_membership_privilege(priv_name, groups) #deletes prin_name from group(s)
|
720
|
+
@priv.del_membership(priv_name, groups)
|
721
|
+
rescue => e
|
722
|
+
raise e
|
723
|
+
end
|
724
|
+
|
725
|
+
#It deletes principal from ACL. It also deletes all linked ACEs.
|
726
|
+
#
|
727
|
+
# * *Args* :
|
728
|
+
# - +name+ -> name of the principal
|
729
|
+
# * *Returns* :
|
730
|
+
# -string, name of the pricipal
|
731
|
+
# * *Raises* :
|
732
|
+
# - +nothing+
|
733
|
+
#
|
734
|
+
def delete_principal(name)
|
735
|
+
@prin.delete(name)
|
736
|
+
rescue => e
|
737
|
+
raise e
|
738
|
+
end
|
739
|
+
|
740
|
+
#It deletes privilege from ACL. It also deletes all linked ACEs.
|
741
|
+
#
|
742
|
+
# * *Args* :
|
743
|
+
# - +name+ -> name of the privilege
|
744
|
+
# * *Returns* :
|
745
|
+
# -string, name of the privilege
|
746
|
+
# * *Raises* :
|
747
|
+
# - +nothing+
|
748
|
+
#
|
749
|
+
def delete_privilege(name)
|
750
|
+
@priv.delete(name)
|
751
|
+
rescue => e
|
752
|
+
raise e
|
753
|
+
end
|
754
|
+
|
755
|
+
#It deletes resource object from ACL. It also deletes all linked ACEs.
|
756
|
+
#
|
757
|
+
# * *Args* :
|
758
|
+
# - +type+ -> type of the resource object
|
759
|
+
# - +address+ -> address of the resource object
|
760
|
+
# * *Returns* :
|
761
|
+
# -string, name of the resource object
|
762
|
+
# * *Raises* :
|
763
|
+
# - +nothing+
|
764
|
+
#
|
765
|
+
def delete_res_object(type, address)
|
766
|
+
res_ob_id = @res_obj.find_res_ob(type, address)
|
767
|
+
@res_obj.delete(res_ob_id)
|
768
|
+
return res_ob_id
|
769
|
+
rescue => e
|
770
|
+
raise e
|
771
|
+
end
|
772
|
+
|
773
|
+
#It deletes resource object from ACL by id. It also deletes all linked ACEs.
|
774
|
+
#
|
775
|
+
# * *Args* :
|
776
|
+
# - +id+ -> id of the resource object
|
777
|
+
# * *Returns* :
|
778
|
+
# -string, name of the resource object
|
779
|
+
# * *Raises* :
|
780
|
+
# - +nothing+
|
781
|
+
#
|
782
|
+
def delete_res_object_by_id(id)
|
783
|
+
@res_obj.delete(id)
|
784
|
+
rescue => e
|
785
|
+
raise e
|
786
|
+
end
|
787
|
+
|
788
|
+
#It deletes ACE from ACL.
|
789
|
+
#
|
790
|
+
# * *Args* :
|
791
|
+
# - +ace_id+ -> id of the ACE
|
792
|
+
# * *Returns* :
|
793
|
+
# -string, name of the
|
794
|
+
# * *Raises* :
|
795
|
+
# - +nothing+
|
796
|
+
#
|
797
|
+
def delete_ace(ace_id)
|
798
|
+
@ace.delete(ace_id)
|
799
|
+
rescue => e
|
800
|
+
raise e
|
801
|
+
end
|
802
|
+
|
803
|
+
|
804
|
+
end
|
805
|
+
|
806
|
+
#TODO Vzorovou tridu API s vyhazovanim vyjimek must be implemented
|
807
|
+
#TODO ptam se jestli nekdo kdo neexistuje ma pristup. Pozor na vyjimku, mel bych vratit rovnou false.
|
808
|
+
#TODO Lze pridat privilege do principal a naopak? test na to by byl peknej :)
|
809
|
+
|
810
|
+
##Usage example. Also very good source of information are test cases.
|
811
|
+
#puts "start"
|
812
|
+
#$:.unshift("../../eXistAPI/lib")
|
813
|
+
#require 'eXistAPI' #must require 'eXistAPI' to comunicated with eXist-db
|
814
|
+
#
|
815
|
+
##create instance of ExistAPI
|
816
|
+
#@db = ExistAPI.new("http://localhost:8080/exist/xmlrpc", "admin", "admin")
|
817
|
+
#@col_path = "/db/test_acl/" #sets the collection where you want to have ACL in db
|
818
|
+
#@src_files_path = "./src_files/" #path to source files
|
819
|
+
#if(@db.existscollection?(@col_path))
|
820
|
+
# @db.remove_collection(@col_path) #Deleting old ACL from db
|
821
|
+
#end
|
822
|
+
#report = false
|
823
|
+
#@my_acl = RubyACL.new("my_acl", @db, @col_path, @src_files_path, report)
|
824
|
+
#
|
825
|
+
##it's good to create some principals at the begging
|
826
|
+
#@my_acl.create_principal("Sheldon")
|
827
|
+
#@my_acl.create_principal("Leonard")
|
828
|
+
#@my_acl.create_principal("Rajesh")
|
829
|
+
#@my_acl.create_principal("Howarda")
|
830
|
+
#@my_acl.create_principal("Penny")
|
831
|
+
#@my_acl.create_principal("Kripkie")
|
832
|
+
#
|
833
|
+
##Besides given privileges you can create your owns
|
834
|
+
#@my_acl.create_privilege("WATCH")
|
835
|
+
#@my_acl.create_privilege("SIT")
|
836
|
+
#
|
837
|
+
##You can create resource object and get id of it.
|
838
|
+
#resource_id = @my_acl.create_resource_object("mov", "/Movies", "Sheldon")
|
839
|
+
#@my_acl.create_resource_object("couch", "/livingroom", "Sheldon")
|
840
|
+
#@my_acl.create_resource_object("seat", "/livingroom/couch/Sheldon's_spot", "Sheldon")
|
841
|
+
#
|
842
|
+
##Now we have everything we need to create a rule.
|
843
|
+
##Lets see what we must hand over
|
844
|
+
##1) One individual or group that (principal)
|
845
|
+
##2) will or won't have access (access type = {allow, deny})
|
846
|
+
##3) to do something with (privilege)
|
847
|
+
##4) which type of (resource type)
|
848
|
+
##5) resource. (resource object)
|
849
|
+
##6) And if we needs to grand all this to children of resource. (grant to children)
|
850
|
+
#@my_acl.create_ace("Sheldon", "allow", "DELETE", "mov", "/Movies", true)
|
851
|
+
#@my_acl.create_ace("Sheldon", "allow", "SIT", "seat", "/livingroom/couch/Sheldon's_spot")
|
852
|
+
#
|
853
|
+
#
|
854
|
+
##You can easily check e.g. if Penny may delete all movies.
|
855
|
+
#@my_acl.check("Penny", "DELETE", "mov", "/Movies")
|
856
|
+
#
|
857
|
+
##Next method call returns deny
|
858
|
+
#@my_acl.check("Penny", "SIT", "seat", "/livingroom/couch/Sheldon's_spot")
|
859
|
+
#
|
860
|
+
##You can create group and immidiatly insert members or do it later.
|
861
|
+
#@my_acl.create_group("4th_floor", ["ALL"], ["Sheldon","Leonard","Penny"])
|
862
|
+
##Here are other possible ways of creating group
|
863
|
+
##@my_acl.create_group("4th_floor")
|
864
|
+
##@my_acl.create_group("4th_floor", ["ALL"])
|
865
|
+
##
|
866
|
+
##Create access control entry with group as principal.
|
867
|
+
#ace_id = @my_acl.create_ace("4th_floor", "allow", "WATCH", "mov", "/Movies/*")
|
868
|
+
#
|
869
|
+
##You can show all privileges connected with principal
|
870
|
+
#perm = @my_acl.show_permissions_for("Penny")
|
871
|
+
#puts perm
|
872
|
+
#
|
873
|
+
##EXCEPTION EXAMPLE
|
874
|
+
#@my_acl.create_group("Scientists") #you must create group before you use it
|
875
|
+
#@my_acl.add_membership_principal("Sheldon", ["Scientists"])
|
876
|
+
#
|
877
|
+
##You also must create privileges before you use them
|
878
|
+
#@my_acl.create_privilege("TALK")
|
879
|
+
#@my_acl.create_privilege("COMUNICATE")
|
880
|
+
##You can gather privileges in treelike structure
|
881
|
+
#@my_acl.add_membership_privilege("TALK", ["COMUNICATE"])
|
882
|
+
#
|
883
|
+
##You can delete membership of principal and privilege,
|
884
|
+
##ace, principal, privilege, resource object, if exists.
|
885
|
+
##Otherwise you will get exception
|
886
|
+
#@my_acl.del_membership_principal("Sheldon", ["Scientists"])
|
887
|
+
#@my_acl.del_membership_privilege("TALK", ["COMUNICATE"])
|
888
|
+
#@my_acl.delete_ace(ace_id)
|
889
|
+
#@my_acl.delete_principal("Kripkie")
|
890
|
+
#@my_acl.delete_privilege("SIT")
|
891
|
+
#@my_acl.delete_res_object("couch", "/livingroom")
|
892
|
+
#@my_acl.delete_res_object_by_id(resource_id)
|
893
|
+
#
|
894
|
+
#@my_acl.create_resource_object("mov", "/Movies", "Sheldon") #create again for demonstration purposes
|
895
|
+
##You can rename principal, privilege and change every part of resource object.
|
896
|
+
#@my_acl.rename_principal("Kripkie", "Kwipkie")
|
897
|
+
#@my_acl.rename_privilege("TALK", "CHAT")
|
898
|
+
#@my_acl.change_of_res_ob_address("mov", "/Movies", "/Films")
|
899
|
+
#@my_acl.change_of_res_ob_owner("mov", "/Films", "Leonard")
|
900
|
+
#@my_acl.change_res_ob_type("mov", "/Films", "motion picture")
|
901
|
+
#
|
902
|
+
#You can save or load ACL
|
903
|
+
#@my_acl.save('C:\\storage')
|
904
|
+
#RubyACL.load(@db, "C:\\backup")
|
905
|
+
#
|
906
|
+
##You can rename ACL
|
907
|
+
#@my_acl.rename("my_beloved_acl")
|
908
|
+
#puts "finished"
|