[Abac] Use a unique persistent object to store a rule, core update.

This commit is contained in:
Mikaël Ates 2012-03-21 17:27:07 +01:00
parent 6b3b67b243
commit 69f91f28b4
1 changed files with 41 additions and 121 deletions

View File

@ -30,8 +30,8 @@ from acs.models import Namespace, UserAlias
from acs.abac.models import *
from attribute_aggregator.xacml_constants import *
from attribute_aggregator.core import get_attribute_type_of_definition
from acs.attribute_aggregator.xacml_constants import *
from acs.attribute_aggregator.core import get_attribute_type_of_definition
from acs.core import get_alias_in_policy_from_namespace, \
stack_of_roles_from_user
@ -54,15 +54,15 @@ def extract_predicate_ids(expression):
def check_predicate(predicate, profile):
logger.debug("check_predicate: predicate id %s" % predicate.id)
logger.debug("check_predicate: predicate %s" % predicate.__unicode__())
if isinstance(predicate, PredicateRequired):
logger.debug("check_predicate: PredicateRequired %s" % predicate)
logger.debug("check_predicate: PredicateRequired %s" % predicate.__unicode__())
return check_predicate_required(predicate, profile)
if isinstance(predicate, PredicateComparison):
logger.debug("check_predicate: PredicateComparison %s" % predicate)
logger.debug("check_predicate: PredicateComparison %s" % predicate.__unicode__())
return check_predicate_comparison(predicate, profile)
if isinstance(predicate, PredicateRole):
logger.debug("check_predicate: PredicateRole %s" % predicate)
logger.debug("check_predicate: PredicateRole %s" % predicate.__unicode__())
return check_predicate_role(predicate, profile)
return False
@ -86,32 +86,36 @@ def check_predicate(predicate, profile):
def check_predicate_comparison(predicate, profile):
#operand1
l_data1 = []
data1 = predicate.operand1.get_assertion_instance()
data1 = predicate.get_operand1()
if isinstance(data1, AssertionDefinition):
'''
find in profile the data corresponding to this definition
'''
for source in data1.sources.all():
for source in data1.get_sources():
l_data1 += profile.get_data_of_definition_and_source(\
data1.get_definition(), source)
else:
l_data1 = [data1.get_attribute_data()]
#operand2
l_data2 = []
data2 = predicate.operand2.get_assertion_instance()
data2 = predicate.get_operand2()
if isinstance(data2, AssertionDefinition):
'''
find in profile the data corresponding to this definition
'''
for source in data2.sources.all():
for source in data2.get_sources():
l_data2 += profile.get_data_of_definition_and_source(\
data2.get_definition(), source)
else:
l_data2 = [data2.get_attribute_data()]
logger.debug("check_predicate_comparison: l_data1 %s" % str([x.__unicode__() for x in l_data1]))
logger.debug("check_predicate_comparison: l_data2 %s" % str([x.__unicode__() for x in l_data2]))
for d1 in l_data1:
for d2 in l_data2:
if compare_two_data(predicate, d1, d2):
logger.debug("check_predicate_comparison: satisfied")
return True
logger.debug("check_predicate_comparison: not satisfied")
return False
@ -192,24 +196,26 @@ def compare_two_data(predicate, data1, data2):
logger.debug("compare_two_data: convert values...")
data1_values = data1.get_converted_values()
data2_values = data2.get_converted_values()
logger.debug("compare_two_data: data1_values %s" % data1_values)
logger.debug("compare_two_data: data2_values %s" % data2_values)
if not data1_values or not data2_values:
logger.debug("compare_two_data: \
Return False because no values was found for predicate %s" \
% predicate)
% predicate.__unicode__())
return False
if predicate.operand1_single_value and len(data1_values) > 1:
logger.debug("compare_two_data: \
Return False because a single value is required for operand one \
and multiple were found %s for predicate %s" \
% ([x for x in data1_values], predicate))
% ([x for x in data1_values], predicate.__unicode__()))
return False
if predicate.operand2_single_value and len(data2_values) > 1:
logger.debug("compare_two_data: \
Return False because a single value is required for operand two \
and multiple were found %s for predicate %s" \
% ([x for x in data2_values], predicate))
% ([x for x in data2_values], predicate.__unicode__()))
return False
@ -229,11 +235,11 @@ def compare_two_data(predicate, data1, data2):
logger.debug("compare_two_data: \
Return False because multivalued attributes are accepted and no \
suitable management option has been selected for predicate %s" \
% str(predicate))
% predicate.__unicode__())
return False
logger.debug("compare_two_data: \
Evaluation of predicate %s" % str(predicate))
Evaluation of predicate %s" % predicate.__unicode__())
if predicate.comparison_type in XACML_COMPARISON_EQUALITY:
return test_equality_of_values(data1_values, data2_values,
get_attribute_type_of_definition(data1.get_definition()),
@ -249,7 +255,7 @@ def compare_two_data(predicate, data1, data2):
logger.debug("compare_two_data: \
Return False because of unknown comparison type \
for predicate %s" \
% predicate)
% predicate.__unicode__())
return False
@ -443,7 +449,7 @@ def check_predicate_required(predicate, profile):
If it is expected to check a unique value with multiple sources
it is required to use multiple required predicates and NOT operators
'''
logger.debug("check_predicate_required: check %s" % predicate)
logger.debug("check_predicate_required: check %s" % predicate.__unicode__())
if not predicate.single_value:
logger.debug("check_predicate_required: single value not required")
for source in predicate.get_sources():
@ -476,24 +482,25 @@ def check_predicate_role(predicate, profile):
'''
if not predicate or not profile \
or not isinstance(predicate, PredicateRole) \
or not predicate.role \
or not predicate.get_role() \
or not profile.user:
return False
role = predicate.get_role()
alias = get_alias_in_policy_from_namespace(profile.user,
predicate.role.namespace)
role.namespace)
if not alias:
logger.debug("check_predicate_role: no alias found for user: %s \
in namespace %s" % (profile.user, predicate.role.namespace))
in namespace %s" % (profile.user, role.namespace))
return False
logger.debug("check_predicate_role: check if user %s has role %s" \
% (alias, predicate.role))
% (alias, role))
stack = stack_of_roles_from_user(alias)
logger.debug("check_predicate_role: roles of the user: %s" \
% stack)
if predicate.role in stack:
logger.debug("check_predicate_role: success")
if role in stack:
logger.debug("check_predicate_role: satisfied")
return True
logger.debug("check_predicate_role: failure")
logger.debug("check_predicate_role: not satisfied")
return False
@ -503,92 +510,14 @@ def check_predicates(rule, profile):
Check presence, source, values...
'''
if not rule or not profile or not rule.expression:
return {}
predicates = []
dic = {}
for p in Predicate.objects.filter(rule=rule):
p_t = p.get_predicate_instance()
predicates.append(p_t)
dic[str(p.id)] = check_predicate(p_t, profile)
logger.debug("check_predicates: found %s" \
% [str(x) for x in predicates])
logger.debug("check_predicates: computed %s" % dic)
return dic
@transaction.commit_manually
def remove_predicate(predicate):
try:
if not predicate:
raise Exception(_('No predicate provided'))
else:
logger.debug(\
'remove_predicate: Begin deletion of predicate %s with id %s' \
% (predicate, predicate.id))
'''
Objects to delete for predicate required:
- AssertionDefinition
Objects to delete for predicate role:
- None
Objects to delete for predicate comparisons:
- AssertionDefinition
- AssertionData
'''
instance = predicate.get_predicate_instance()
if isinstance(instance, PredicateRole):
pass
elif isinstance(instance, PredicateRequired):
logger.debug('remove_predicate: predicate required found')
instance.assertion_definition.delete()
elif isinstance(instance, PredicateComparison):
logger.debug('remove_predicate: predicate comparison found')
assertion = instance.operand1.get_assertion_instance()
if isinstance(assertion, AssertionDefinition):
logger.debug('remove_predicate: \
operand one is an assertion definition')
logger.debug('remove_predicate: \
remove assertion definition with id %s' %assertion.id)
assertion.delete()
elif isinstance(assertion, AssertionData):
logger.debug('remove_predicate: \
operand one is an assertion data')
logger.debug('remove_predicate: \
remove assertion data with id %s' % assertion.id)
assertion.delete()
else:
raise Exception(_('Unknown operand one'))
assertion = instance.operand2.get_assertion_instance()
if isinstance(assertion, AssertionDefinition):
logger.debug('remove_predicate: \
operand two is an assertion definition')
logger.debug('remove_predicate: \
remove assertion definition with id %s' %assertion.id)
assertion.delete()
elif isinstance(assertion, AssertionData):
logger.debug('remove_predicate: \
operand two is an assertion data')
logger.debug('remove_predicate: \
remove assertion data with id %s' % assertion.id)
assertion.delete()
else:
raise Exception(_('Unknown operand two'))
else:
raise Exception(_('Unknown predicate type'))
logger.debug('remove_predicate: deletion of the predicate')
predicate.delete()
except Exception, err:
transaction.rollback()
logger.critical('remove_predicate: error deleting predicate due to %s'
% err)
raise err
else:
transaction.commit()
logger.debug('remove_predicate: predicate deleted')
return None
result = {}
count = 1
for predicate in rule.get_predicates():
result[str(count)] = check_predicate(predicate, profile)
count = count + 1
logger.debug("check_predicates: computed %s" % result)
return result
@transaction.commit_manually
@ -596,21 +525,12 @@ def remove_rule(rule):
try:
if not rule:
raise Exception(_('No rule provided'))
else:
logger.debug(\
'remove_rule: Begin deletion of rule %s with id %s' \
logger.debug('remove_rule: deletion of the rule %s with id %s' \
% (rule, rule.id))
for p in Predicate.objects.filter(rule=rule):
logger.debug('remove_rule: found predicate %s' % p)
remove_predicate(p)
logger.debug('remove_rule: deletion of the rule')
rule.delete()
except Exception, err:
transaction.rollback()
logger.critical('remove_rule: error deleting rule due to %s'
% err)
logger.critical('remove_rule: error deleting rule due to %s' % err)
raise err
else:
transaction.commit()