[Abac] Use a unique persistent object to store a rule, core update.
This commit is contained in:
parent
6b3b67b243
commit
69f91f28b4
162
acs/abac/core.py
162
acs/abac/core.py
|
@ -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()
|
||||
|
|
Reference in New Issue