summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrautenberg <rautenberg@in-silico.ch>2012-03-22 12:23:09 +0100
committerrautenberg <rautenberg@in-silico.ch>2012-03-22 12:23:09 +0100
commit3bf0e33c86cd4cd460412c01eed9a37afacad4d5 (patch)
treecfea007af3a8ae883117ed2beeb4ed4bdf34920c
parentb9249a71bc4fd6323f2ec879018f497027a4545a (diff)
add policy-lib mods from feature/policy and add policy tests
-rw-r--r--lib/policy.rb331
-rw-r--r--test/policy.rb120
2 files changed, 324 insertions, 127 deletions
diff --git a/lib/policy.rb b/lib/policy.rb
index 8591d52..56a90b7 100644
--- a/lib/policy.rb
+++ b/lib/policy.rb
@@ -1,28 +1,29 @@
module OpenTox
require "rexml/document"
- #Module for policy-processing
+ #Module for policy-processing
# @see also http://www.opentox.org/dev/apis/api-1.2/AA for opentox API specs
# Class Policies corresponds to <policies> container of an xml-policy-fle
- class Policies
-
- attr_accessor :name, :policies
-
+ class Policies
+
+ #Hash for policy objects see {Policy Policy}
+ attr_accessor :policies, :name
+
def initialize()
@policies = {}
end
-
+
#create new policy instance with name
# @param [String]name of the policy
def new_policy(name)
@policies[name] = Policy.new(name)
end
-
+
#drop a specific policy in a policies instance
# @param [String]name of the policy
# @return [Boolean]
def drop_policy(name)
- return true if @policies.delete(name)
+ return true if @policies.delete(name)
end
#drop all policies in a policies instance
@@ -32,58 +33,63 @@ module OpenTox
end
return true
end
-
+
# @return [Array] set of arrays affected by policies
def uris
- @policies.collect{ |k,v| v.uris }.flatten.uniq
+ @policies.collect{ |k,v| v.uri }.flatten.uniq
end
- #drop all policies in a policies instance
+ #list all policy names in a policies instance
+ # @return [Array]
def names
out = []
@policies.each do |name, policy|
- out << name
+ out << name
end
return out
end
- #loads a default policy template in policies instance
- def load_default_policy(user, uri, group="member")
+ # Loads a default policy template in a policies instance
+ # @param [String]user username in LDAP string of user policy: 'uid=<user>,ou=people,dc=opentox,dc=org'
+ # @param [String]uri URI
+ # @param [String]group groupname in LDAP string of group policy: 'cn=<group>,ou=groups,dc=opentox,dc=org'
+ def load_default_policy(user, uri, group="member")
template = case user
when "guest", "anonymous" then "default_guest_policy"
- else "default_policy"
+ else "default_policy"
end
xml = File.read(File.join(File.dirname(__FILE__), "templates/#{template}.xml"))
self.load_xml(xml)
datestring = Time.now.strftime("%Y-%m-%d-%H-%M-%S-x") + rand(1000).to_s
-
+
@policies["policy_user"].name = "policy_user_#{user}_#{datestring}"
- @policies["policy_user"].rules["rule_user"].uri = uri
- @policies["policy_user"].rules["rule_user"].name = "rule_user_#{user}_#{datestring}"
- @policies["policy_user"].subjects["subject_user"].name = "subject_user_#{user}_#{datestring}"
- @policies["policy_user"].subjects["subject_user"].value = "uid=#{user},ou=people,dc=opentox,dc=org"
+ @policies["policy_user"].rule.uri = uri
+ @policies["policy_user"].rule.name = "rule_user_#{user}_#{datestring}"
+ @policies["policy_user"].subject.name = "subject_user_#{user}_#{datestring}"
+ @policies["policy_user"].subject.value = "uid=#{user},ou=people,dc=opentox,dc=org"
@policies["policy_user"].subject_group = "subjects_user_#{user}_#{datestring}"
-
- @policies["policy_group"].name = "policy_group_#{group}_#{datestring}"
- @policies["policy_group"].rules["rule_group"].uri = uri
- @policies["policy_group"].rules["rule_group"].name = "rule_group_#{group}_#{datestring}"
- @policies["policy_group"].subjects["subject_group"].name = "subject_group_#{group}_#{datestring}"
- @policies["policy_group"].subjects["subject_group"].value = "cn=#{group},ou=groups,dc=opentox,dc=org"
- @policies["policy_group"].subject_group = "subjects_#{group}_#{datestring}"
+
+ @policies["policy_group"].name = "policy_group_#{group}_#{datestring}"
+ @policies["policy_group"].rule.uri = uri
+ @policies["policy_group"].rule.name = "rule_group_#{group}_#{datestring}"
+ @policies["policy_group"].subject.name = "subject_group_#{group}_#{datestring}"
+ @policies["policy_group"].subject.value = "cn=#{group},ou=groups,dc=opentox,dc=org"
+ @policies["policy_group"].subject_group = "subjects_#{group}_#{datestring}"
return true
- end
+ end
- #loads a xml template
+ #loads a xml template
def load_xml(xml)
rexml = REXML::Document.new(xml)
rexml.elements.each("Policies/Policy") do |pol| #Policies
policy_name = pol.attributes["name"]
new_policy(policy_name)
- #@policies[policy_name] = Policy.new(policy_name)
+ #@policies[policy_name] = Policy.new(policy_name)
rexml.elements.each("Policies/Policy[@name='#{policy_name}']/Rule") do |r| #Rules
- rule_name = r.attributes["name"]
+ rule_name = r.attributes["name"]
uri = rexml.elements["Policies/Policy[@name='#{policy_name}']/Rule[@name='#{rule_name}']/ResourceName"].attributes["name"]
- @policies[policy_name].rules[rule_name] = @policies[policy_name].new_rule(rule_name, uri)
+ @policies[policy_name].rule.name = rule_name
+ @policies[policy_name].uri = uri
rexml.elements.each("Policies/Policy[@name='#{policy_name}']/Rule[@name='#{rule_name}']/AttributeValuePair") do |attribute_pairs|
action=nil; value=nil;
attribute_pairs.each_element do |elem|
@@ -93,163 +99,234 @@ module OpenTox
if action and value
case action
when "GET"
- @policies[policy_name].rules[rule_name].get = value
+ @policies[policy_name].rule.get = value
when "POST"
- @policies[policy_name].rules[rule_name].post = value
+ @policies[policy_name].rule.post = value
when "PUT"
- @policies[policy_name].rules[rule_name].put = value
- when "DELETE"
- @policies[policy_name].rules[rule_name].delete = value
+ @policies[policy_name].rule.put = value
+ when "DELETE"
+ @policies[policy_name].rule.delete = value
end
end
- end
+ end
end
rexml.elements.each("Policies/Policy[@name='#{policy_name}']/Subjects") do |subjects| #Subjects
- @policies[policy_name].subject_group = subjects.attributes["name"]
+ @policies[policy_name].subject_group = subjects.attributes["name"]
rexml.elements.each("Policies/Policy[@name='#{policy_name}']/Subjects[@name='#{@policies[policy_name].subject_group}']/Subject") do |s| #Subject
subject_name = s.attributes["name"]
subject_type = s.attributes["type"]
subject_value = rexml.elements["Policies/Policy[@name='#{policy_name}']/Subjects[@name='#{@policies[policy_name].subject_group}']/Subject[@name='#{subject_name}']/AttributeValuePair/Value"].text
- @policies[policy_name].new_subject(subject_name, subject_type, subject_value) if subject_name and subject_type and subject_value
+ if subject_name and subject_type and subject_value
+ @policies[policy_name].subject.name = subject_name
+ @policies[policy_name].type = subject_type
+ @policies[policy_name].value = subject_value
+ end
end
- end
- end
+ end
+ end
end
-
+
#generates xml from policies instance
def to_xml
doc = REXML::Document.new()
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\"")
doc.add_element(REXML::Element.new("Policies"))
-
+
@policies.each do |name, pol|
policy = REXML::Element.new("Policy")
policy.attributes["name"] = pol.name
policy.attributes["referralPolicy"] = false
policy.attributes["active"] = true
- @policies[name].rules.each do |r,rl|
- rule = @policies[name].rules[r]
- out_rule = REXML::Element.new("Rule")
- out_rule.attributes["name"] = rule.name
- servicename = REXML::Element.new("ServiceName")
- servicename.attributes["name"]="iPlanetAMWebAgentService"
- out_rule.add_element(servicename)
- rescourcename = REXML::Element.new("ResourceName")
- rescourcename.attributes["name"] = rule.uri
- out_rule.add_element(rescourcename)
-
- ["get","post","delete","put"].each do |act|
- if rule.method(act).call
- attribute = REXML::Element.new("Attribute")
- attribute.attributes["name"] = act.upcase
- attributevaluepair = REXML::Element.new("AttributeValuePair")
- attributevaluepair.add_element(attribute)
- attributevalue = REXML::Element.new("Value")
- attributevaluepair.add_element(attributevalue)
- attributevalue.add_text REXML::Text.new(rule.method(act).call)
- out_rule.add_element(attributevaluepair)
-
- end
+ rule = @policies[name].rule
+ out_rule = REXML::Element.new("Rule")
+ out_rule.attributes["name"] = rule.name
+ servicename = REXML::Element.new("ServiceName")
+ servicename.attributes["name"]="iPlanetAMWebAgentService"
+ out_rule.add_element(servicename)
+ rescourcename = REXML::Element.new("ResourceName")
+ rescourcename.attributes["name"] = rule.uri
+ out_rule.add_element(rescourcename)
+
+ ["get","post","delete","put"].each do |act|
+ if rule.method(act).call
+ attribute = REXML::Element.new("Attribute")
+ attribute.attributes["name"] = act.upcase
+ attributevaluepair = REXML::Element.new("AttributeValuePair")
+ attributevaluepair.add_element(attribute)
+ attributevalue = REXML::Element.new("Value")
+ attributevaluepair.add_element(attributevalue)
+ attributevalue.add_text REXML::Text.new(rule.method(act).call)
+ out_rule.add_element(attributevaluepair)
end
- policy.add_element(out_rule)
- end
+ end
+ policy.add_element(out_rule)
subjects = REXML::Element.new("Subjects")
subjects.attributes["name"] = pol.subject_group
subjects.attributes["description"] = ""
- @policies[name].subjects.each do |subj, subjs|
- subject = REXML::Element.new("Subject")
- subject.attributes["name"] = pol.subjects[subj].name
- subject.attributes["type"] = pol.subjects[subj].type
- subject.attributes["includeType"] = "inclusive"
- attributevaluepair = REXML::Element.new("AttributeValuePair")
- attribute = REXML::Element.new("Attribute")
- attribute.attributes["name"] = "Values"
- attributevaluepair.add_element(attribute)
- attributevalue = REXML::Element.new("Value")
- attributevalue.add_text REXML::Text.new(pol.subjects[subj].value)
- attributevaluepair.add_element(attributevalue)
- subject.add_element(attributevaluepair)
- subjects.add_element(subject)
- end
+ subj = @policies[name].subject.name
+ subject = REXML::Element.new("Subject")
+ subject.attributes["name"] = pol.subject.name
+ subject.attributes["type"] = pol.subject.type
+ subject.attributes["includeType"] = "inclusive"
+ attributevaluepair = REXML::Element.new("AttributeValuePair")
+ attribute = REXML::Element.new("Attribute")
+ attribute.attributes["name"] = "Values"
+ attributevaluepair.add_element(attribute)
+ attributevalue = REXML::Element.new("Value")
+ attributevalue.add_text REXML::Text.new(pol.subject.value)
+ attributevaluepair.add_element(attributevalue)
+ subject.add_element(attributevaluepair)
+ subjects.add_element(subject)
policy.add_element(subjects)
doc.root.add_element(policy)
- end
+ end
out = ""
doc.write(out, 2)
return out
- end
-
+ end
+
end
-
- #single policy in a policies instance
- class Policy
-
- attr_accessor :name, :rules, :subject_group, :subjects
-
+
+ #single policy in a {Policies Policies} instance
+ class Policy
+
+ attr_accessor :name, :rule, :subject_group, :subject, :value, :type, :uri, :group, :user
+
def initialize(name)
@name = name
- @rules = {}
- @subject_group = ""
- @subjects = {}
+ @rule = Rule.new("#{name}_rule", nil)
+ @subject_group = "#{name}_subjects"
+ @subject = Subject.new("#{name}_subject", nil, nil)
end
-
- #create a new rule instance for the policy
- def new_rule(name, uri)
- @rules[name] = Rule.new(name, uri)
+
+ # Subject type LDAPUsers or LDAPGroups
+ def type
+ @subject.type
end
-
- #create a new subject instance for the policy
- def new_subject(name, type, value)
- @subjects[name] = Subject.new(name, type, value)
+
+ # Set subject type <LDAPUsers, LDAPGroups>
+ # @param [String],type
+ def type=(type)
+ @subject.type = type
end
-
- # @return [Array] set of uris affected by policy
- def uris
- @rules.collect{ |k,v| v.uri }.uniq
+
+ # returns LDAP Distinguished Name (DN) e.g. uid=username,ou=people,dc=opentox,dc=org or cn=membergroup,ou=groups,dc=opentox,dc=org
+ def value
+ @subject.value
+ end
+
+ # sets LDAP Distinguished Name (DN) for policy e.g.
+ # @param [String],LDAPString
+ def value=(value)
+ @subject.value = value
+ end
+
+ # uri affected by policy
+ # @return uri affected by policy
+ def uri
+ @rule.uri
+ end
+
+ # sets uri affected by policy
+ # @param [String] set URI
+ def uri=(uri)
+ @rule.uri = uri
+ end
+
+ # Get the groupname from within the LDAP Distinguished Name (DN)
+ def group
+ return false if !value && type != "LDAPGroups"
+ value.split(",").each{|part| return part.gsub("cn=","") if part.match("cn=")}
+ end
+
+ # Get the username from within the LDAP Distinguished Name (DN)
+ def user
+ return false if !value && type != "LDAPUsers"
+ value.split(",").each{|part| return part.gsub("uid=","") if part.match("uid=")}
+ end
+
+ # helper method sets value and type to opentox LDAP Distinguished Name (DN) of a user
+ def set_ot_user(username)
+ self.value = "uid=#{username},ou=people,dc=opentox,dc=org"
+ self.type = "LDAPUsers"
+ true
+ end
+
+ def set_ot_group(groupname)
+ self.value = "cn=#{groupname},ou=groups,dc=opentox,dc=org"
+ self.type = "LDAPGroups"
+ true
end
-
+
#rule inside a policy
class Rule
-
- attr_accessor :name, :uri, :get, :post, :put, :delete
-
+
+ attr_accessor :name, :uri, :get, :post, :put, :delete, :read, :readwrite
+
def initialize(name, uri)
@name = name
@uri = uri
end
-
- def rename(new, old)
- self[new] = self.delete(old)
- self[new].name = new
- end
-
+
+ #Set Rule attribute for request-method GET
+ # @param [String]value (allow,deny,nil)
def get=(value)
@get = check_value(value, @get)
end
-
+
+ #Set Rule attribute for request-method POST
+ # @param [String]value (allow,deny,nil)
def post=(value)
@post = check_value(value, @post)
end
-
+
+ #Set Rule attribute for request-method DELETE
+ # @param [String]value (allow,deny,nil)
def delete=(value)
@delete = check_value(value, @delete)
end
-
+
+ #Set Rule attribute for request-method PUT
+ # @param [String]value (allow,deny,nil)
def put=(value)
@put = check_value(value, @put)
end
-
+
+ def read
+ return true if @get == "allow" && (@put == "deny" || !@put) && (@post == "deny" || !@post)
+ end
+
+ def readwrite
+ return true if @get == "allow" && @put == "allow" && @post == "allow"
+ end
+
+ def read=(value)
+ if value
+ @get = "allow"; @put = nil; @post = nil
+ else
+ @get = nil; @put = nil; @post = nil
+ end
+ end
+
+ def readwrite=(value)
+ if value
+ @get = "allow"; @put = "allow"; @post = "allow"
+ else
+ @get = nil; @put = nil; @post = nil
+ end
+ end
+
private
- #checks if value is allow or deny. returns old value if not valid.
+ #checks if value is allow, deny or nil. returns old value if not valid.
def check_value(new_value, old_value)
- return (new_value=="allow" || new_value=="deny" || new_value==nil) ? new_value : old_value
+ return (new_value=="allow" || new_value=="deny" || new_value==nil) ? new_value : old_value
end
end
-
+
class Subject
- attr_accessor :name, :type, :value
+ attr_accessor :name, :type, :value
def initialize(name, type, value)
@name = name
@@ -258,4 +335,4 @@ module OpenTox
end
end
end
-end \ No newline at end of file
+end
diff --git a/test/policy.rb b/test/policy.rb
new file mode 100644
index 0000000..eb7e2b6
--- /dev/null
+++ b/test/policy.rb
@@ -0,0 +1,120 @@
+require 'test/unit'
+$LOAD_PATH << File.join(File.dirname(__FILE__),'..','lib')
+require File.expand_path(File.join(File.dirname(__FILE__),'..','lib','opentox-client.rb'))
+
+TEST_URI = "http://only_a_test/test/" + rand(1000000).to_s
+USER_TYPE = "LDAPUsers"
+USER_VALUE = "uid=guest,ou=people,dc=opentox,dc=org"
+USER_GROUP = "member"
+GROUP_TYPE = "LDAPGroups"
+GROUP_VALUE = "cn=member,ou=groups,dc=opentox,dc=org"
+POLICY_NAME = "test_policy_#{rand(100000)}"
+RULE_NAME = "test_rule_#{rand(100000)}"
+SUBJECT_NAME = "test_subject_#{rand(100000)}"
+
+AA ||= "https://opensso.in-silico.ch"
+AA_USER = "guest"
+AA_PASS = "guest"
+
+@@subjectid = OpenTox::Authorization.authenticate(AA_USER,AA_PASS)
+
+class PolicyTest < Test::Unit::TestCase
+
+ def test_01_class
+ policies = OpenTox::Policies.new()
+ assert_equal(policies.class, OpenTox::Policies)
+ assert_kind_of Array, policies.names
+ assert_kind_of Array, policies.uris
+ assert_kind_of Array, policies.names
+ end
+
+ def test_02_subclasses
+ policies = OpenTox::Policies.new()
+ policies.new_policy(POLICY_NAME)
+ assert_equal(policies.names[0], POLICY_NAME)
+ assert_equal(policies.policies[policies.names[0]].class, OpenTox::Policy)
+ policy = policies.policies[policies.names[0]]
+ policy.rule.name = RULE_NAME
+ policy.uri = TEST_URI
+ assert_equal(policy.rule.class, OpenTox::Policy::Rule)
+ assert_equal(policy.rule.name, RULE_NAME)
+ assert_equal(policy.rule.uri, TEST_URI)
+ assert_equal(policy.uri, TEST_URI)
+ policy.subject.name = SUBJECT_NAME
+ policy.type = USER_TYPE
+ policy.value = USER_VALUE
+ assert_equal(policy.subject.class, OpenTox::Policy::Subject)
+ assert_equal(policy.subject.name, SUBJECT_NAME)
+ assert_equal(policy.subject.type, USER_TYPE)
+ assert_equal(policy.type, USER_TYPE)
+ assert_equal(policy.subject.value, USER_VALUE)
+ assert_equal(policy.value, USER_VALUE)
+ end
+
+ def test_03_read_readwrite
+ policies = OpenTox::Policies.new()
+ policies.new_policy(POLICY_NAME)
+ policy = policies.policies[policies.names[0]]
+ policy.rule.name = RULE_NAME
+ policy.uri = TEST_URI
+ policy.rule.get = "allow"
+ assert policy.rule.read
+ assert !policy.rule.readwrite
+ policy.rule.post = "allow"
+ policy.rule.put = "allow"
+ assert !policy.rule.read
+ assert policy.rule.readwrite
+ end
+
+ def test_04_group_user
+ policies = OpenTox::Policies.new()
+ policies.load_default_policy(AA_USER, TEST_URI, "member")
+ assert_equal "member", policies.policies["policy_group"].group
+ assert_equal AA_USER, policies.policies["policy_user"].user
+ end
+
+ def test_05_DN
+ policies = OpenTox::Policies.new()
+ policies.new_policy(POLICY_NAME)
+ policy = policies.policies[policies.names[0]]
+ policy.set_ot_user(AA_USER)
+ assert_equal USER_VALUE, policy.value
+ assert_equal USER_TYPE, policy.type
+ policy.set_ot_group(USER_GROUP)
+ assert_equal GROUP_VALUE, policy.value
+ assert_equal GROUP_TYPE, policy.type
+ end
+
+ def test_06_load_xml_and_check_defaults
+ policies = OpenTox::Policies.new()
+ xml = File.read(File.join(File.dirname(__FILE__), "../lib/templates/default_policy.xml"))
+ policies.load_xml(xml)
+ # check user policy
+ policy = policies.policies["policy_user"]
+ assert policy.name == "policy_user"
+ assert policy.rule.name == "rule_user"
+ assert policy.rule.uri == "uri"
+ assert policy.rule.get == "allow"
+ assert policy.rule.post == "allow"
+ assert policy.rule.delete == "allow"
+ assert policy.rule.put == "allow"
+ assert policy.subject_group == "subjects_user"
+ assert policy.subject.name == "subject_user"
+ assert policy.subject.type == USER_TYPE
+ assert policy.subject.value == USER_VALUE
+ # check group policy
+ policy = policies.policies["policy_group"]
+ assert policy.name == "policy_group"
+ assert policy.rule.name == "rule_group"
+ assert policy.rule.uri == "uri"
+ assert policy.rule.get == "allow"
+ assert !policy.rule.post
+ assert !policy.rule.delete
+ assert !policy.rule.put
+ assert policy.subject_group == "subjects_group"
+ assert policy.subject.name == "subject_group"
+ assert policy.subject.type == GROUP_TYPE
+ assert policy.subject.value == GROUP_VALUE
+ end
+
+end \ No newline at end of file