From b9249a71bc4fd6323f2ec879018f497027a4545a Mon Sep 17 00:00:00 2001 From: rautenberg Date: Thu, 22 Mar 2012 12:21:31 +0100 Subject: retry opensso if connection fails (1x) log error if fails twice --- lib/authorization.rb | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/authorization.rb b/lib/authorization.rb index 4d54c41..470ecd8 100644 --- a/lib/authorization.rb +++ b/lib/authorization.rb @@ -5,7 +5,7 @@ module OpenTox #@example Authentication # require "opentox-client" # OpenTox::Authorization::AA = "https://opensso.in-silico.ch" #if not set in .opentox/conf/[environment].yaml - # token = OpenTox::Authorization.authenticate("benutzer", "passwort") + # token = OpenTox::Authorization.authenticate("username", "password") #@see http://www.opentox.org/dev/apis/api-1.2/AA OpenTox A&A API 1.2 specification module Authorization @@ -42,11 +42,12 @@ module OpenTox xml = get_xml(uri) ret = false ret = Authorization.create_policy(xml, @subjectid) + $logger.warn "Create policy on openSSO failed for URI: #{uri} subjectid: #{@subjectid}. Will try again." if !ret + ret = Authorization.create_policy(xml, @subjectid) if !ret $logger.debug "Policy send with subjectid: #{@subjectid}" - $logger.warn "Not created Policy is: #{xml}" if !ret + $logger.error "Not created Policy is: #{xml}" if !ret ret end - end #Returns the open-sso server set in the config file .opentox/config/[environment].yaml -- cgit v1.2.3 From 3bf0e33c86cd4cd460412c01eed9a37afacad4d5 Mon Sep 17 00:00:00 2001 From: rautenberg Date: Thu, 22 Mar 2012 12:23:09 +0100 Subject: add policy-lib mods from feature/policy and add policy tests --- lib/policy.rb | 331 +++++++++++++++++++++++++++++++++++---------------------- test/policy.rb | 120 +++++++++++++++++++++ 2 files changed, 324 insertions(+), 127 deletions(-) create mode 100644 test/policy.rb 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 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=,ou=people,dc=opentox,dc=org' + # @param [String]uri URI + # @param [String]group groupname in LDAP string of group policy: 'cn=,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 + # @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 -- cgit v1.2.3