opentox-ruby 0.0.2 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +41 -0
- data/Rakefile +4 -0
- data/VERSION +1 -1
- data/lib/algorithm.rb +15 -2
- data/lib/authorization.rb +381 -0
- data/lib/compound.rb +6 -0
- data/lib/config/config_ru.rb +1 -0
- data/lib/dataset.rb +98 -43
- data/lib/environment.rb +9 -18
- data/lib/error.rb +99 -0
- data/lib/feature.rb +30 -2
- data/lib/helper.rb +90 -17
- data/lib/model.rb +81 -34
- data/lib/ontology_service.rb +43 -0
- data/lib/opentox-ruby.rb +3 -2
- data/lib/opentox.rb +9 -4
- data/lib/overwrite.rb +87 -28
- data/lib/parser.rb +117 -22
- data/lib/policy.rb +261 -0
- data/lib/rest_client_wrapper.rb +110 -99
- data/lib/serializer.rb +130 -1
- data/lib/task.rb +179 -42
- data/lib/templates/config.yaml +45 -0
- data/lib/templates/default_guest_policy.xml +53 -0
- data/lib/templates/default_policy.xml +53 -0
- data/lib/to-html.rb +112 -0
- data/lib/validation.rb +183 -57
- metadata +31 -94
- data/README.rdoc +0 -23
data/lib/parser.rb
CHANGED
@@ -29,22 +29,37 @@ module OpenTox
|
|
29
29
|
|
30
30
|
# Read metadata from opentox service
|
31
31
|
# @return [Hash] Object metadata
|
32
|
-
def load_metadata
|
33
|
-
|
34
|
-
|
35
|
-
|
32
|
+
def load_metadata(subjectid=nil)
|
33
|
+
# avoid using rapper directly because of 2 reasons:
|
34
|
+
# * http errors wont be noticed
|
35
|
+
# * subjectid cannot be sent as header
|
36
|
+
##uri += "?subjectid=#{CGI.escape(subjectid)}" if subjectid
|
37
|
+
## `rapper -i rdfxml -o ntriples #{uri} 2>/dev/null`.each_line do |line|
|
38
|
+
if File.exist?(@uri)
|
39
|
+
file = File.new(@uri)
|
36
40
|
else
|
37
|
-
|
41
|
+
file = Tempfile.new("ot-rdfxml")
|
42
|
+
if @dataset
|
43
|
+
# do not concat /metadata to uri string, this would not work for dataset/R401577?max=3
|
44
|
+
uri = URI::parse(@uri)
|
45
|
+
uri.path = File.join(uri.path,"metadata")
|
46
|
+
uri = uri.to_s
|
47
|
+
else
|
48
|
+
uri = @uri
|
49
|
+
end
|
50
|
+
file.puts OpenTox::RestClientWrapper.get uri,{:subjectid => subjectid,:accept => "application/rdf+xml"},nil,false
|
51
|
+
file.close
|
52
|
+
to_delete = file.path
|
38
53
|
end
|
39
|
-
|
40
54
|
statements = []
|
41
55
|
parameter_ids = []
|
42
|
-
`rapper -i rdfxml -o ntriples #{
|
56
|
+
`rapper -i rdfxml -o ntriples #{file.path} 2>/dev/null`.each_line do |line|
|
43
57
|
triple = line.to_triple
|
44
58
|
@metadata[triple[1]] = triple[2].split('^^').first if triple[0] == @uri and triple[1] != RDF['type']
|
45
59
|
statements << triple
|
46
60
|
parameter_ids << triple[2] if triple[1] == OT.parameters
|
47
61
|
end
|
62
|
+
File.delete(to_delete) if to_delete
|
48
63
|
unless parameter_ids.empty?
|
49
64
|
@metadata[OT.parameters] = []
|
50
65
|
parameter_ids.each do |p|
|
@@ -55,10 +70,45 @@ module OpenTox
|
|
55
70
|
end
|
56
71
|
@metadata
|
57
72
|
end
|
58
|
-
|
73
|
+
|
74
|
+
# creates owl object from rdf-data
|
75
|
+
# @param [String] rdf
|
76
|
+
# @param [String] type of the info (e.g. OT.Task, OT.ErrorReport) needed to get the subject-uri
|
77
|
+
# @return [Owl] with uri and metadata set
|
78
|
+
def self.from_rdf( rdf, type )
|
79
|
+
# write to file and read convert with rapper into tripples
|
80
|
+
file = Tempfile.new("ot-rdfxml")
|
81
|
+
file.puts rdf
|
82
|
+
file.close
|
83
|
+
#puts "cmd: rapper -i rdfxml -o ntriples #{file} 2>/dev/null"
|
84
|
+
triples = `rapper -i rdfxml -o ntriples #{file.path} 2>/dev/null`
|
85
|
+
|
86
|
+
# load uri via type
|
87
|
+
uri = nil
|
88
|
+
triples.each_line do |line|
|
89
|
+
triple = line.to_triple
|
90
|
+
if triple[1] == RDF['type'] and triple[2]==type
|
91
|
+
raise "uri already set, two uris found with type: "+type.to_s if uri
|
92
|
+
uri = triple[0]
|
93
|
+
end
|
94
|
+
end
|
95
|
+
File.delete(file.path)
|
96
|
+
# load metadata
|
97
|
+
metadata = {}
|
98
|
+
triples.each_line do |line|
|
99
|
+
triple = line.to_triple
|
100
|
+
metadata[triple[1]] = triple[2].split('^^').first if triple[0] == uri and triple[1] != RDF['type']
|
101
|
+
end
|
102
|
+
owl = Owl::Generic.new(uri)
|
103
|
+
owl.metadata = metadata
|
104
|
+
owl
|
105
|
+
end
|
106
|
+
|
59
107
|
# Generic parser for all OpenTox classes
|
60
108
|
class Generic
|
61
109
|
include Owl
|
110
|
+
|
111
|
+
attr_accessor :uri, :metadata
|
62
112
|
end
|
63
113
|
|
64
114
|
# OWL-DL parser for datasets
|
@@ -71,9 +121,9 @@ module OpenTox
|
|
71
121
|
# Create a new OWL-DL dataset parser
|
72
122
|
# @param uri Dataset URI
|
73
123
|
# @return [OpenTox::Parser::Owl::Dataset] OWL-DL parser
|
74
|
-
def initialize(uri)
|
124
|
+
def initialize(uri, subjectid=nil)
|
75
125
|
super uri
|
76
|
-
@dataset = ::OpenTox::Dataset.new(@uri)
|
126
|
+
@dataset = ::OpenTox::Dataset.new(@uri, subjectid)
|
77
127
|
end
|
78
128
|
|
79
129
|
# Read data from dataset service. Files can be parsed by setting #uri to a filename (after initialization with a real URI)
|
@@ -87,12 +137,27 @@ module OpenTox
|
|
87
137
|
# dataset = parser.load_uri
|
88
138
|
# dataset.save
|
89
139
|
# @return [Hash] Internal dataset representation
|
90
|
-
def load_uri
|
140
|
+
def load_uri(subjectid=nil)
|
141
|
+
|
142
|
+
# avoid using rapper directly because of 2 reasons:
|
143
|
+
# * http errors wont be noticed
|
144
|
+
# * subjectid cannot be sent as header
|
145
|
+
##uri += "?subjectid=#{CGI.escape(subjectid)}" if subjectid
|
146
|
+
##`rapper -i rdfxml -o ntriples #{file} 2>/dev/null`.each_line do |line|
|
147
|
+
if File.exist?(@uri)
|
148
|
+
file = File.new(@uri)
|
149
|
+
else
|
150
|
+
file = Tempfile.new("ot-rdfxml")
|
151
|
+
file.puts OpenTox::RestClientWrapper.get @uri,{:subjectid => subjectid,:accept => "application/rdf+xml"},nil,false
|
152
|
+
file.close
|
153
|
+
to_delete = file.path
|
154
|
+
end
|
155
|
+
|
91
156
|
data = {}
|
92
157
|
feature_values = {}
|
93
158
|
feature = {}
|
94
159
|
other_statements = {}
|
95
|
-
`rapper -i rdfxml -o ntriples #{
|
160
|
+
`rapper -i rdfxml -o ntriples #{file.path} 2>/dev/null`.each_line do |line|
|
96
161
|
triple = line.chomp.split(' ',3)
|
97
162
|
triple = triple[0..2].collect{|i| i.sub(/\s+.$/,'').gsub(/[<>"]/,'')}
|
98
163
|
case triple[1]
|
@@ -105,32 +170,62 @@ module OpenTox
|
|
105
170
|
data[triple[0]] = {:compound => "", :values => []} unless data[triple[0]]
|
106
171
|
data[triple[0]][:compound] = triple[2]
|
107
172
|
when /#{OT.feature}/i
|
108
|
-
feature[triple[0]] = triple[2]
|
173
|
+
feature[triple[0]] = triple[2]
|
174
|
+
when /#{RDF.type}/i
|
175
|
+
if triple[2]=~/#{OT.Compound}/i and !data[triple[0]]
|
176
|
+
data[triple[0]] = {:compound => triple[0], :values => []}
|
177
|
+
end
|
109
178
|
else
|
110
179
|
end
|
111
180
|
end
|
181
|
+
File.delete(to_delete) if to_delete
|
112
182
|
data.each do |id,entry|
|
113
|
-
entry[:values].
|
114
|
-
|
115
|
-
@dataset.
|
183
|
+
if entry[:values].size==0
|
184
|
+
# no feature values add plain compounds
|
185
|
+
@dataset.add_compound(entry[:compound])
|
186
|
+
else
|
187
|
+
entry[:values].each do |value_id|
|
188
|
+
split = feature_values[value_id].split(/\^\^/)
|
189
|
+
case split[-1]
|
190
|
+
when XSD.double, XSD.float
|
191
|
+
value = split.first.to_f
|
192
|
+
when XSD.boolean
|
193
|
+
value = split.first=~/(?i)true/ ? true : false
|
194
|
+
else
|
195
|
+
value = split.first
|
196
|
+
end
|
197
|
+
@dataset.add entry[:compound],feature[value_id],value
|
198
|
+
end
|
116
199
|
end
|
117
200
|
end
|
118
|
-
load_features
|
119
|
-
@dataset.metadata = load_metadata
|
201
|
+
load_features subjectid
|
202
|
+
@dataset.metadata = load_metadata(subjectid)
|
120
203
|
@dataset
|
121
204
|
end
|
122
205
|
|
123
206
|
# Read only features from a dataset service.
|
124
207
|
# @return [Hash] Internal features representation
|
125
|
-
def load_features
|
126
|
-
|
208
|
+
def load_features(subjectid=nil)
|
209
|
+
if File.exist?(@uri)
|
210
|
+
file = File.new(@uri)
|
211
|
+
else
|
212
|
+
file = Tempfile.new("ot-rdfxml")
|
213
|
+
# do not concat /features to uri string, this would not work for dataset/R401577?max=3
|
214
|
+
uri = URI::parse(@uri)
|
215
|
+
uri.path = File.join(uri.path,"features")
|
216
|
+
uri = uri.to_s
|
217
|
+
file.puts OpenTox::RestClientWrapper.get uri,{:subjectid => subjectid,:accept => "application/rdf+xml"},nil,false
|
218
|
+
file.close
|
219
|
+
to_delete = file.path
|
220
|
+
end
|
127
221
|
statements = []
|
128
222
|
features = Set.new
|
129
|
-
`rapper -i rdfxml -o ntriples #{
|
223
|
+
`rapper -i rdfxml -o ntriples #{file.path} 2>/dev/null`.each_line do |line|
|
130
224
|
triple = line.chomp.split('> ').collect{|i| i.sub(/\s+.$/,'').gsub(/[<>"]/,'')}[0..2]
|
131
225
|
statements << triple
|
132
|
-
features << triple[0] if triple[1] == RDF['type'] and triple[2] == OT.Feature
|
226
|
+
features << triple[0] if triple[1] == RDF['type'] and (triple[2] == OT.Feature || triple[2] == OT.NumericFeature)
|
133
227
|
end
|
228
|
+
File.delete(to_delete) if to_delete
|
134
229
|
statements.each do |triple|
|
135
230
|
if features.include? triple[0]
|
136
231
|
@dataset.features[triple[0]] = {} unless @dataset.features[triple[0]]
|
data/lib/policy.rb
ADDED
@@ -0,0 +1,261 @@
|
|
1
|
+
module OpenTox
|
2
|
+
require "rexml/document"
|
3
|
+
|
4
|
+
#Module for policy-processing
|
5
|
+
# @see also http://www.opentox.org/dev/apis/api-1.2/AA for opentox API specs
|
6
|
+
# Class Policies corresponds to <policies> container of an xml-policy-fle
|
7
|
+
class Policies
|
8
|
+
|
9
|
+
attr_accessor :name, :policies
|
10
|
+
|
11
|
+
def initialize()
|
12
|
+
@policies = {}
|
13
|
+
end
|
14
|
+
|
15
|
+
#create new policy instance with name
|
16
|
+
# @param [String]name of the policy
|
17
|
+
def new_policy(name)
|
18
|
+
@policies[name] = Policy.new(name)
|
19
|
+
end
|
20
|
+
|
21
|
+
#drop a specific policy in a policies instance
|
22
|
+
# @param [String]name of the policy
|
23
|
+
# @return [Boolean]
|
24
|
+
def drop_policy(name)
|
25
|
+
return true if @policies.delete(name)
|
26
|
+
end
|
27
|
+
|
28
|
+
#drop all policies in a policies instance
|
29
|
+
def drop_policies
|
30
|
+
@policies.each do |name, policy|
|
31
|
+
drop_policy(name)
|
32
|
+
end
|
33
|
+
return true
|
34
|
+
end
|
35
|
+
|
36
|
+
# @return [Array] set of arrays affected by policies
|
37
|
+
def uris
|
38
|
+
@policies.collect{ |k,v| v.uris }.flatten.uniq
|
39
|
+
end
|
40
|
+
|
41
|
+
#drop all policies in a policies instance
|
42
|
+
def names
|
43
|
+
out = []
|
44
|
+
@policies.each do |name, policy|
|
45
|
+
out << name
|
46
|
+
end
|
47
|
+
return out
|
48
|
+
end
|
49
|
+
|
50
|
+
#loads a default policy template in policies instance
|
51
|
+
def load_default_policy(user, uri, group="member")
|
52
|
+
template = case user
|
53
|
+
when "guest", "anonymous" then "default_guest_policy"
|
54
|
+
else "default_policy"
|
55
|
+
end
|
56
|
+
xml = File.read(File.join(File.dirname(__FILE__), "templates/#{template}.xml"))
|
57
|
+
self.load_xml(xml)
|
58
|
+
datestring = Time.now.strftime("%Y-%m-%d-%H-%M-%S-x") + rand(1000).to_s
|
59
|
+
|
60
|
+
@policies["policy_user"].name = "policy_user_#{user}_#{datestring}"
|
61
|
+
@policies["policy_user"].rules["rule_user"].uri = uri
|
62
|
+
@policies["policy_user"].rules["rule_user"].name = "rule_user_#{user}_#{datestring}"
|
63
|
+
@policies["policy_user"].subjects["subject_user"].name = "subject_user_#{user}_#{datestring}"
|
64
|
+
@policies["policy_user"].subjects["subject_user"].value = "uid=#{user},ou=people,dc=opentox,dc=org"
|
65
|
+
@policies["policy_user"].subject_group = "subjects_user_#{user}_#{datestring}"
|
66
|
+
|
67
|
+
@policies["policy_group"].name = "policy_group_#{group}_#{datestring}"
|
68
|
+
@policies["policy_group"].rules["rule_group"].uri = uri
|
69
|
+
@policies["policy_group"].rules["rule_group"].name = "rule_group_#{group}_#{datestring}"
|
70
|
+
@policies["policy_group"].subjects["subject_group"].name = "subject_group_#{group}_#{datestring}"
|
71
|
+
@policies["policy_group"].subjects["subject_group"].value = "cn=#{group},ou=groups,dc=opentox,dc=org"
|
72
|
+
@policies["policy_group"].subject_group = "subjects_#{group}_#{datestring}"
|
73
|
+
return true
|
74
|
+
end
|
75
|
+
|
76
|
+
#loads a xml template
|
77
|
+
def load_xml(xml)
|
78
|
+
rexml = REXML::Document.new(xml)
|
79
|
+
rexml.elements.each("Policies/Policy") do |pol| #Policies
|
80
|
+
policy_name = pol.attributes["name"]
|
81
|
+
new_policy(policy_name)
|
82
|
+
#@policies[policy_name] = Policy.new(policy_name)
|
83
|
+
rexml.elements.each("Policies/Policy[@name='#{policy_name}']/Rule") do |r| #Rules
|
84
|
+
rule_name = r.attributes["name"]
|
85
|
+
uri = rexml.elements["Policies/Policy[@name='#{policy_name}']/Rule[@name='#{rule_name}']/ResourceName"].attributes["name"]
|
86
|
+
@policies[policy_name].rules[rule_name] = @policies[policy_name].new_rule(rule_name, uri)
|
87
|
+
rexml.elements.each("Policies/Policy[@name='#{policy_name}']/Rule[@name='#{rule_name}']/AttributeValuePair") do |attribute_pairs|
|
88
|
+
action=nil; value=nil;
|
89
|
+
attribute_pairs.each_element do |elem|
|
90
|
+
action = elem.attributes["name"] if elem.attributes["name"]
|
91
|
+
value = elem.text if elem.text
|
92
|
+
end
|
93
|
+
if action and value
|
94
|
+
case action
|
95
|
+
when "GET"
|
96
|
+
@policies[policy_name].rules[rule_name].get = value
|
97
|
+
when "POST"
|
98
|
+
@policies[policy_name].rules[rule_name].post = value
|
99
|
+
when "PUT"
|
100
|
+
@policies[policy_name].rules[rule_name].put = value
|
101
|
+
when "DELETE"
|
102
|
+
@policies[policy_name].rules[rule_name].delete = value
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
rexml.elements.each("Policies/Policy[@name='#{policy_name}']/Subjects") do |subjects| #Subjects
|
108
|
+
@policies[policy_name].subject_group = subjects.attributes["name"]
|
109
|
+
rexml.elements.each("Policies/Policy[@name='#{policy_name}']/Subjects[@name='#{@policies[policy_name].subject_group}']/Subject") do |s| #Subject
|
110
|
+
subject_name = s.attributes["name"]
|
111
|
+
subject_type = s.attributes["type"]
|
112
|
+
subject_value = rexml.elements["Policies/Policy[@name='#{policy_name}']/Subjects[@name='#{@policies[policy_name].subject_group}']/Subject[@name='#{subject_name}']/AttributeValuePair/Value"].text
|
113
|
+
@policies[policy_name].new_subject(subject_name, subject_type, subject_value) if subject_name and subject_type and subject_value
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
#generates xml from policies instance
|
120
|
+
def to_xml
|
121
|
+
doc = REXML::Document.new()
|
122
|
+
doc << REXML::DocType.new("Policies", "PUBLIC \"-//Sun Java System Access Manager7.1 2006Q3\n Admin CLI DTD//EN\" \"jar://com/sun/identity/policy/policyAdmin.dtd\"")
|
123
|
+
doc.add_element(REXML::Element.new("Policies"))
|
124
|
+
|
125
|
+
@policies.each do |name, pol|
|
126
|
+
policy = REXML::Element.new("Policy")
|
127
|
+
policy.attributes["name"] = pol.name
|
128
|
+
policy.attributes["referralPolicy"] = false
|
129
|
+
policy.attributes["active"] = true
|
130
|
+
@policies[name].rules.each do |r,rl|
|
131
|
+
rule = @policies[name].rules[r]
|
132
|
+
out_rule = REXML::Element.new("Rule")
|
133
|
+
out_rule.attributes["name"] = rule.name
|
134
|
+
servicename = REXML::Element.new("ServiceName")
|
135
|
+
servicename.attributes["name"]="iPlanetAMWebAgentService"
|
136
|
+
out_rule.add_element(servicename)
|
137
|
+
rescourcename = REXML::Element.new("ResourceName")
|
138
|
+
rescourcename.attributes["name"] = rule.uri
|
139
|
+
out_rule.add_element(rescourcename)
|
140
|
+
|
141
|
+
["get","post","delete","put"].each do |act|
|
142
|
+
if rule.method(act).call
|
143
|
+
attribute = REXML::Element.new("Attribute")
|
144
|
+
attribute.attributes["name"] = act.upcase
|
145
|
+
attributevaluepair = REXML::Element.new("AttributeValuePair")
|
146
|
+
attributevaluepair.add_element(attribute)
|
147
|
+
attributevalue = REXML::Element.new("Value")
|
148
|
+
attributevaluepair.add_element(attributevalue)
|
149
|
+
attributevalue.add_text REXML::Text.new(rule.method(act).call)
|
150
|
+
out_rule.add_element(attributevaluepair)
|
151
|
+
|
152
|
+
end
|
153
|
+
end
|
154
|
+
policy.add_element(out_rule)
|
155
|
+
end
|
156
|
+
|
157
|
+
subjects = REXML::Element.new("Subjects")
|
158
|
+
subjects.attributes["name"] = pol.subject_group
|
159
|
+
subjects.attributes["description"] = ""
|
160
|
+
@policies[name].subjects.each do |subj, subjs|
|
161
|
+
subject = REXML::Element.new("Subject")
|
162
|
+
subject.attributes["name"] = pol.subjects[subj].name
|
163
|
+
subject.attributes["type"] = pol.subjects[subj].type
|
164
|
+
subject.attributes["includeType"] = "inclusive"
|
165
|
+
attributevaluepair = REXML::Element.new("AttributeValuePair")
|
166
|
+
attribute = REXML::Element.new("Attribute")
|
167
|
+
attribute.attributes["name"] = "Values"
|
168
|
+
attributevaluepair.add_element(attribute)
|
169
|
+
attributevalue = REXML::Element.new("Value")
|
170
|
+
attributevalue.add_text REXML::Text.new(pol.subjects[subj].value)
|
171
|
+
attributevaluepair.add_element(attributevalue)
|
172
|
+
subject.add_element(attributevaluepair)
|
173
|
+
subjects.add_element(subject)
|
174
|
+
end
|
175
|
+
policy.add_element(subjects)
|
176
|
+
doc.root.add_element(policy)
|
177
|
+
end
|
178
|
+
out = ""
|
179
|
+
doc.write(out, 2)
|
180
|
+
return out
|
181
|
+
end
|
182
|
+
|
183
|
+
end
|
184
|
+
|
185
|
+
#single policy in a policies instance
|
186
|
+
class Policy
|
187
|
+
|
188
|
+
attr_accessor :name, :rules, :subject_group, :subjects
|
189
|
+
|
190
|
+
def initialize(name)
|
191
|
+
@name = name
|
192
|
+
@rules = {}
|
193
|
+
@subject_group = ""
|
194
|
+
@subjects = {}
|
195
|
+
end
|
196
|
+
|
197
|
+
#create a new rule instance for the policy
|
198
|
+
def new_rule(name, uri)
|
199
|
+
@rules[name] = Rule.new(name, uri)
|
200
|
+
end
|
201
|
+
|
202
|
+
#create a new subject instance for the policy
|
203
|
+
def new_subject(name, type, value)
|
204
|
+
@subjects[name] = Subject.new(name, type, value)
|
205
|
+
end
|
206
|
+
|
207
|
+
# @return [Array] set of uris affected by policy
|
208
|
+
def uris
|
209
|
+
@rules.collect{ |k,v| v.uri }.uniq
|
210
|
+
end
|
211
|
+
|
212
|
+
#rule inside a policy
|
213
|
+
class Rule
|
214
|
+
|
215
|
+
attr_accessor :name, :uri, :get, :post, :put, :delete
|
216
|
+
|
217
|
+
def initialize(name, uri)
|
218
|
+
@name = name
|
219
|
+
@uri = uri
|
220
|
+
end
|
221
|
+
|
222
|
+
def rename(new, old)
|
223
|
+
self[new] = self.delete(old)
|
224
|
+
self[new].name = new
|
225
|
+
end
|
226
|
+
|
227
|
+
def get=(value)
|
228
|
+
@get = check_value(value, @get)
|
229
|
+
end
|
230
|
+
|
231
|
+
def post=(value)
|
232
|
+
@post = check_value(value, @post)
|
233
|
+
end
|
234
|
+
|
235
|
+
def delete=(value)
|
236
|
+
@delete = check_value(value, @delete)
|
237
|
+
end
|
238
|
+
|
239
|
+
def put=(value)
|
240
|
+
@put = check_value(value, @put)
|
241
|
+
end
|
242
|
+
|
243
|
+
private
|
244
|
+
#checks if value is allow or deny. returns old value if not valid.
|
245
|
+
def check_value(new_value, old_value)
|
246
|
+
return (new_value=="allow" || new_value=="deny" || new_value==nil) ? new_value : old_value
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
class Subject
|
251
|
+
|
252
|
+
attr_accessor :name, :type, :value
|
253
|
+
|
254
|
+
def initialize(name, type, value)
|
255
|
+
@name = name
|
256
|
+
@type = type
|
257
|
+
@value = value
|
258
|
+
end
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|