[attribute_aggregator] application of attribute management extracted from acs

This commit is contained in:
Mikaël Ates 2011-09-21 18:44:19 +02:00
parent 4440d06315
commit aad109b9a4
7 changed files with 1217 additions and 0 deletions

View File

View File

@ -0,0 +1,191 @@
'''
VERIDIC Project - Towards a centralized access control system
Copyright (C) 2011 Mikael Ates
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
'''
import time
import datetime
import logging
import re
from django.db import transaction
from django.core.exceptions import ObjectDoesNotExist
from attribute_aggregator.xacml_constants import *
from attribute_aggregator.mapping import ATTRIBUTE_MAPPING
logger = logging.getLogger('attribute_aggregator')
def iso8601_to_datetime(date_string):
'''
Convert a string formatted as an ISO8601 date into a time_t value.
This function ignores the sub-second resolution.
'''
m = re.match(r'(\d+-\d+-\d+T\d+:\d+:\d+)(?:\.\d+)?Z?$', date_string)
if not m:
raise ValueError('Invalid ISO8601 date')
tm = time.strptime(m.group(1)+'Z', "%Y-%m-%dT%H:%M:%SZ")
return datetime.datetime.fromtimestamp(time.mktime(tm))
def get_def_name_from_name_and_ns_of_attribute(name, namespace):
if not name or not namespace:
return None
for def_name, content in ATTRIBUTE_MAPPING.items():
if namespace in content["definitions"].keys():
if name in content["definitions"][namespace]["identifiers"]:
return def_name
if name in content["definitions"][namespace]["friendly_name"]:
return def_name
return None
def get_attribute_name_in_namespace(definition, namespace):
if not definition or not namespace:
return None
if definition in ATTRIBUTE_MAPPING:
if namespace in ATTRIBUTE_MAPPING[definition]["definitions"]:
return ATTRIBUTE_MAPPING[definition]\
["definitions"][namespace]["identifiers"][0]
return None
def convert_from_string(definition_name, value):
if not definition_name in ATTRIBUTE_MAPPING:
return None
type_ = ATTRIBUTE_MAPPING[definition_name]['type']
if type_ == ACS_XACML_DATATYPE_STRING:
return value
elif type_ == ACS_XACML_DATATYPE_BOOLEAN:
if value in ('True', 'true', 'Vrai', 'vrai'):
return True
return False
elif type_ == ACS_XACML_DATATYPE_INTEGER:
try:
return int(value)
except:
return None
elif type_ == ACS_XACML_DATATYPE_DOUBLE:
try:
return float(value)
except:
return None
elif type_ == ACS_XACML_DATATYPE_TIME:
try:
return time.strptime(value,"%h:%m:%s") #12:15:00
except:
return None
elif type_ == ACS_XACML_DATATYPE_DATE:
try:
return time.strptime(value,"%d/%b/%Y") #28/01/1982
except:
return None
elif type_ == ACS_XACML_DATATYPE_DATETIME:
try:
return iso8601_to_datetime(value)
except:
return None
elif type_ == ACS_XACML_DATATYPE_RFC822NAME: # email
r = re.compile(\
'[a-zA-Z0-9+_\-\.]+@[0-9a-zA-Z][.-0-9a-zA-Z]*.[a-zA-Z]+')
if r.search(value):
return value
else:
return None
elif type_ == ACS_XACML_DATATYPE_IPADDRESS: # x.x.x.x
r = re.compile(\
'(?:[\d]{1,3})\.(?:[\d]{1,3})\.(?:[\d]{1,3})\.(?:[\d]{1,3})')
if r.search(value):
return value
else:
return None
return None
@transaction.commit_manually
def load_or_create_user_profile(user=None, no_cleanup=False):
'''
If the user has a profile, remove assertions outdated and return
profile, else create a new one.
If cleanup: expiration_date < now() remove assertion data from profile
If no_cleanup: return profile if any without removing outdated
assertions
'''
from attribute_aggregator.models import UserAttributeProfile
profile = None
try:
if user:
try:
logger.debug('load_or_create_user_profile: \
search profile for %s' \
% user)
profile = UserAttributeProfile.objects.get(user=user)
except ObjectDoesNotExist:
profile = UserAttributeProfile(user=user)
profile.save()
logger.info('load_or_create_user_profile: \
profile with id %s for user %s created' \
% (str(profile.id), user))
else:
if no_cleanup:
logger.debug('load_or_create_user_profile: Existing user \
profile %s for %s - No cleanup' % (profile, user))
else:
profile.cleanup()
profile.save()
elif not user:
profile = UserAttributeProfile()
profile.save()
logger.debug('load_or_create_user_profile: \
profile with id %s for an anonymous user created' \
% str(profile.id))
except Exception, err:
transaction.rollback()
logger.error('load_or_create_user_profile: An error occured %s' \
% str(err))
return None
else:
transaction.commit()
logger.debug('load_or_create_user_profile: everything successfully \
performed')
return profile
def get_user_alias_in_source(user, source):
from attribute_aggregator.models import UserAliasInSource
try:
alias = UserAliasInSource.objects.get(user=user, source=source)
return alias.name
except:
return None
def set_user_alias_in_source(user, source, name):
from attribute_aggregator.models import UserAliasInSource
try:
alias, c = UserAliasInSource.objects.get_or_create(user=user,
source=source, name=name)
alias.save()
return alias
except:
return None

View File

@ -0,0 +1,132 @@
'''
VERIDIC - Towards a centralized access control system
Copyright (C) 2011 Mikael Ates
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
'''
import logging
import ldap
from attribute_aggregator.core import get_user_alias_in_source, \
get_attribute_name_in_namespace
logger = logging.getLogger('acs')
def get_all_attributes(user, definitions=None, **kwargs):
'''
Dictionnary format:
attributes = dict()
data_from_source = list()
a1 = dict()
a1['definition'] = definition_name
a1['name'] = attribute_name_in_ns
a1['namespace'] = ns_name
a1['values'] = list_of_values
data_from_source.append(a1)
...
data_from_source.append(a2)
attributes[source_name] = data_from_source
First attempt on 'definition' key.
Else, definition is searched by 'name' and 'namespece' keys.
'''
if not user:
logger.error('get_all_attributes: No user provided')
return None
logger.debug('get_all_attributes: Searching attributes for user %s' % user)
from attribute_aggregator.models import LdapSource
sources = LdapSource.objects.all()
if not sources:
logger.debug('get_all_attributes: No LDAP source configured')
return None
attributes = {}
for source in sources:
logger.debug('get_all_attributes: The LDAP source is known as %s' \
% source.name)
identifier = get_user_alias_in_source(user, source)
if not identifier:
logger.error('get_all_attributes: No user identifier known into that \
source')
else:
logger.debug('get_all_attributes: the user is known as %s in source %s' \
% (identifier, source.name))
try:
l = ldap.open(source.server)
l.protocol_version = ldap.VERSION3
username = source.user
password = source.password
if username and password:
l.simple_bind(username, password)
except ldap.LDAPError, err:
logger.error('get_all_attributes: an error occured at binding due \
to %s' % err)
else:
base_dn = source.base
search_scope = ldap.SCOPE_SUBTREE
retrieve_attributes = None
if definitions:
retrieve_attributes = [\
get_attribute_name_in_namespace(definition,
'X500') for definition in definitions]
dn = ldap.dn.explode_dn(identifier,
flags=ldap.DN_FORMAT_LDAPV3)
search_filter = dn[0]
logger.debug('get_all_attributes: rdn is %s' % search_filter)
data = []
try:
ldap_result_id = l.search(base_dn, search_scope,
search_filter, retrieve_attributes)
result_type, result_data = l.result(ldap_result_id, 0)
logger.debug('get_all_attributes: result %s %s' % (result_type,
result_data))
for d, dic in result_data:
logger.debug('get_all_attributes: found %s' % d)
if d == identifier:
logger.debug('get_all_attributes: Attributes are %s' \
% dic)
for key in dic.keys():
attr = {}
attr['name'] = key
attr['values'] = [\
a.decode('utf-8'). \
encode('ascii', 'ignore') \
for a in dic[key]]
attr['namespace'] = 'X500'
data.append(attr)
except ldap.LDAPError, err:
logger.error('get_all_attributes: an error occured at searching \
due to %s' % err)
else:
if not data:
logger.error('get_all_attributes: no attribute found')
else:
attributes[source.name] = data
logger.debug('get_all_attributes: the attributes returned are %s' % attributes)
return attributes
def get_listed_attributes(user, definitions, **kwargs):
return get_all_attributes(user, definitions=definitions, **kwargs)

View File

@ -0,0 +1,171 @@
'''
VERIDIC Project - Towards a centralized access control system
Copyright (C) 2011 Mikael Ates
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
'''
from django.utils.translation import ugettext as _
ATTRIBUTE_MAPPING = {
"unique_ID": {
"type": "http://www.w3.org/2001/XMLSchema#string",
"friendly_name": _("Unique Identifier"),
"definitions": {
"X500": {
"identifiers":
[
"uid",
],
"friendly_name" :
[]
},
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims": {
"identifiers":
[
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/\
privatepersonalidentifier",
],
"friendly_name":
[],
}
}
},
"surname": {
"type": "http://www.w3.org/2001/XMLSchema#string",
"friendly_name": _("Surname"),
"definitions": {
"X500": {
"identifiers":
[
"sn",
"2.5.4.4",
],
"friendly_name" :
[]
},
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims": {
"identifiers":
[
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname",
"Last Name"
],
"friendly_name":
[],
}
}
},
"firstname": {
"type": "http://www.w3.org/2001/XMLSchema#string",
"friendly_name": _("First Name"),
"definitions": {
"X500": {
"identifiers":
[
"givenName",
],
"friendly_name" :
[]
},
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims": {
"identifiers":
[
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname",
],
"friendly_name":
[],
}
}
},
"displayname": {
"type": "http://www.w3.org/2001/XMLSchema#string",
"friendly_name": _("Display Name"),
"definitions": {
"X500": {
"identifiers":
[
"displayName",
],
"friendly_name" :
[]
},
}
},
"email": {
"type": "urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name",
"friendly_name": _("Email Address"),
"definitions": {
"X500": {
"identifiers":
[
"mail",
],
"friendly_name" :
[]
},
}
},
"title": {
"type": "http://www.w3.org/2001/XMLSchema#string",
"friendly_name": _("Title"),
"definitions": {
"X500": {
"identifiers":
[
"title",
],
"friendly_name" :
[]
},
}
},
"age": {
"type": "http://www.w3.org/2001/XMLSchema#integer",
"friendly_name": _("Title"),
"definitions": {
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims": {
"identifiers":
[
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/dateofbirth",
],
"friendly_name" :
[]
},
}
},
"nationality": {
"type": "http://www.w3.org/2001/XMLSchema#string",
"friendly_name": _("Nationality"),
"definitions": {
"ISO7501-1": {
"identifiers":
[
"Nationality",
],
"friendly_name" :
[]
},
}
},
}

View File

@ -0,0 +1,397 @@
'''
VERIDIC Project - Towards a centralized access control system
Copyright (C) 2011 Mikael Ates
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
'''
import datetime
import logging
from cPickle import loads, dumps
from django.utils.translation import ugettext as _
from django.db import models
from django.contrib.auth.models import User
from attribute_aggregator.signals import any_attributes_call, \
listed_attributes_call
from attribute_aggregator.mapping import ATTRIBUTE_MAPPING
from attribute_aggregator.core import convert_from_string, \
get_def_name_from_name_and_ns_of_attribute, iso8601_to_datetime
logger = logging.getLogger('attribute_aggregator')
class AttributeSource(models.Model):
name = models.CharField(max_length = 200, unique=True)
def __unicode__(self):
return self.name
def get_source_instance(self):
try:
return self.ldapsource
except:
pass
return None
def get_source_from_name(name):
try:
return AttributeSource.objects.get(name=name)
except:
return None
class LdapSource(AttributeSource):
server = models.CharField(max_length=200, unique=True)
user = models.CharField(max_length=200, blank=True, null=True)
password = models.CharField(max_length=200, blank=True, null=True)
base = models.CharField(max_length=200)
port = models.IntegerField(default=389)
ldaps = models.BooleanField(default=False)
certificate = models.TextField(blank=True)
is_auth_backend = models.BooleanField(default=False)
class UserAliasInSource(models.Model):
name = models.CharField(max_length = 200, unique=True)
source = models.ForeignKey(AttributeSource,
verbose_name = _('Attribute Source'))
user = models.ForeignKey(User, related_name='user_alias_in_source')
class AttributeData:
def __init__(self, definition, values=None, source=None,
expiration_date=None):
self.definition = definition
self.values = list()
for value in values:
self.values.append(value)
if isinstance(source, AttributeSource):
self.source_id = source.id
else:
self.source_id = -1
'''ISO8601'''
try:
iso8601_to_datetime(expiration_date)
self.expiration_date = expiration_date
except:
self.expiration_date = None
def get_definition(self):
return self.definition
def get_full_definition(self):
if not self.definition in ATTRIBUTE_MAPPING:
return None
return ATTRIBUTE_MAPPING[self.definition]
def get_exptime_in_iso8601(self):
return self.expiration_date
def get_exptime_in_datetime(self):
return iso8601_to_datetime(self.expiration_date)
def set_exptime_in_iso8601(self, expiration_date):
try:
iso8601_to_datetime(expiration_date)
self.expiration_date = expiration_date
except:
self.expiration_date = None
self.save()
return self.expiration_date
def set_exptime_in_datetime(self, expiration_date):
try:
self.expiration_date = expiration_date.isoformat()
except:
self.expiration_date = None
self.save()
return self.expiration_date
def get_values(self):
return self.values
def get_source(self):
try:
return AttributeSource.objects.get(pk=self.source_id)
except:
return None
def get_source_id(self):
return self.source_id
def add_value(self, value):
try:
self.values.append(value)
self.save()
return 0
except:
return -1
def remove_value(self, value):
try:
self.values.remove(value)
self.save()
return 0
except:
return -1
def does_expire(self):
if self.expiration_date:
return self.expiration_date
else:
return 0
def __unicode__(self):
s = "%s with values %s" % (self.get_definition(),
[v for v in self.get_values()])
source = self.get_source()
if source:
s += " from %s" % str(source)
if self.does_expire():
s += " (Expires on %s)" % self.does_expire()
return s
class UserAttributeProfile(models.Model):
user = models.OneToOneField(User, null=True, blank=True,
related_name='user_attribute_profile')
data = models.TextField(null=True, blank=True)
def add_data(self, data):
if not isinstance(data, AttributeData):
return -1
try:
l = None
if not self.data:
l = list()
else:
l = loads(str(self.data))
l.append(data)
self.data = dumps(l)
except:
return -1
return 0
def remove_data(self, position):
try:
l = loads(str(self.data))
res = l.pop(position)
self.data = dumps(l)
return res
except:
return None
def get_all_data(self):
try:
l = loads(str(self.data))
return l
except:
return None
def get_data_of_definition(self, definition, in_list=None):
l = None
if in_list:
l = in_list
else:
l = self.get_all_data()
if not l:
return None
return [d for d in l if d.get_definition() == definition]
def get_freshest_data_of_definition(self, definition):
l = self.get_data_of_definition(definition)
if not l:
return None
l.sort(key=lambda x: x.expiration_date, reverse=True)
return l[0]
def get_data_of_source(self, source, in_list=None):
l = None
if in_list:
l = in_list
else:
l = self.get_all_data()
if not l or not isinstance(source, AttributeSource):
return None
return [d for d in l if d.get_source_id() == source.id]
def get_data_of_source_by_name(self, source):
l = self.get_all_data()
if not l:
return None
s = None
try:
s = AttributeSource.objects.get(name=source)
except:
return None
return [d for d in l if d.get_source_id() == s.id]
def get_data_of_definition_and_source(self, definition, source):
return self.get_data_of_definition(definition,
in_list=self.get_data_of_source(source))
def get_data_of_definition_and_source_by_name(self, definition, source):
return self.get_data_of_definition(definition,
in_list=self.get_data_of_source_by_name(source))
def load_by_dic(self, dictionnary):
'''
Dictionnary format:
attributes = dict()
data_from_source = list()
a1 = dict()
a1['definition'] = definition_name
a1['name'] = attribute_name_in_ns
a1['namespace'] = ns_name
a1['values'] = list_of_values
data_from_source.append(a1)
...
data_from_source.append(a2)
attributes[source_name] = data_from_source
First attempt on 'definition' key.
Else, definition is searched by 'name' and 'namespece' keys.
'''
if not dictionnary:
logger.error('load_by_dic: \
Missing profile or dictionnary')
return -1
for source_name in dictionnary:
logger.debug('load_by_dic: loading from source with name: %s' \
% source_name)
source = get_source_from_name(source_name)
if source:
logger.debug('load_by_dic: attributes: %s' \
% str(dictionnary[source_name]))
for attribute in dictionnary[source_name]:
if (not ('definition' in attribute \
and attribute['definition'] \
in ATTRIBUTE_MAPPING) \
and not('name' in attribute \
and 'namespace' in attribute)) \
or not 'values' in attribute:
logger.warn('load_by_dic: \
missing data to treat %s' % str(attribute))
else:
definition = None
if 'definition' in attribute \
and attribute['definition'] \
in ATTRIBUTE_MAPPING:
definition = attribute['definition']
else:
definition = \
get_def_name_from_name_and_ns_of_attribute(\
attribute['name'],
attribute['namespace'])
if not definition:
logger.warn('load_by_dic: \
unable to find definition for %s' \
% str(attribute))
else:
logger.debug('load_by_dic: \
definition %s found' % definition)
expiration_date = None
if 'expiration_date' in attribute:
logger.debug('load_by_dic: expire at %s' \
% attribute['expiration_date'])
try:
iso8601_to_datetime(\
attribute['expiration_date'])
expiration_date = \
attribute['expiration_date']
logger.debug('load_by_dic: expiration \
date has the ISO8601 format')
except:
logger.warn('load_by_dic: expiration \
date has not the ISO8601 format')
if not expiration_date:
expiration_date = \
datetime.datetime.now().isoformat()
values = [value for value in attribute['values'] \
if convert_from_string(definition, value)]
if self.add_data(AttributeData(\
definition,
values=values,
source=source,
expiration_date=expiration_date)) == 0:
logger.debug('load_by_dic: \
attribute successfully added')
else:
logger.warn('load_by_dic: \
error addind attribute')
else:
logger.critical('load_by_dic: \
The source with name %s providing attributes %s \
is unknown of the system' \
% (str(source_name), str(dictionnary[source_name])))
self.save()
return 0
def load_greedy(self):
if self.user:
attributes_provided = any_attributes_call.send(sender=None,
user=self.user)
for attrs in attributes_provided:
logger.info('load_greedy: \
attributes_call connected to function %s' % \
attrs[0].__name__)
logger.info('load_greedy: \
attributes provided are %s' %str(attrs[1]))
self.load_by_dic(attrs[1])
def load_listed_attributes(self, definitions):
if self.user:
attributes_provided = listed_attributes_call.send(sender=None,
user=self.user, definitions=definitions)
for attrs in attributes_provided:
logger.info('load_listed_attributes: \
attributes_call connected to function %s' % \
attrs[0].__name__)
logger.info('load_listed_attributes: \
attributes provided are %s' %str(attrs[1]))
self.load_by_dic(attrs[1])
def cleanup(self):
l = self.get_all_data()
if not l:
return 0
now = datetime.datetime.now()
self.data = dumps([d for d in l if d.expiration_date \
and d.get_exptime_in_datetime() > now])
self.save()
def __unicode__(self):
s = None
if self.user:
s = "Profile of %s" % self.user
else:
s = "Anonymous profile"
if not self.get_all_data():
s += " is empty."
return s
s += " that contains:"
for d in self.get_all_data():
s = s + "\n\t" + d.__unicode__()
return s

View File

@ -0,0 +1,30 @@
'''
VERIDIC - Towards a centralized access control system
Copyright (C) 2011 Mikael Ates
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
'''
from django.dispatch import Signal
from attribute_aggregator.ldap_sources import get_all_attributes, \
get_listed_attributes
any_attributes_call = Signal(providing_args = ["user"])
listed_attributes_call = Signal(providing_args = ["user", "definitions"])
any_attributes_call.connect(get_all_attributes)
listed_attributes_call.connect(get_listed_attributes)

View File

@ -0,0 +1,296 @@
'''
VERIDIC - Towards a centralized access control system
Copyright (C) 2011 Mikael Ates
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
'''
'''
(Core - 3958) For the sake of improved interoperability, it is RECOMMENDED
that all time references be in UTC time.
(Core - 3960) For doubles, XACML SHALL use the conversions described in
[IEEE754]
'''
#RENAME me to XACML constants!
from django.utils.translation import ugettext as _
ACS_XACML_DATATYPE_STRING = "http://www.w3.org/2001/XMLSchema#string"
ACS_XACML_DATATYPE_BOOLEAN = "http://www.w3.org/2001/XMLSchema#boolean"
ACS_XACML_DATATYPE_INTEGER = "http://www.w3.org/2001/XMLSchema#integer"
ACS_XACML_DATATYPE_DOUBLE = "http://www.w3.org/2001/XMLSchema#double"
ACS_XACML_DATATYPE_TIME = "http://www.w3.org/2001/XMLSchema#time"
ACS_XACML_DATATYPE_DATE = "http://www.w3.org/2001/XMLSchema#date"
ACS_XACML_DATATYPE_DATETIME = "http://www.w3.org/2001/XMLSchema#dateTime"
#ACS_XACML_DATATYPE_ANYURI = "http://www.w3.org/2001/XMLSchema#anyURI"
#ACS_XACML_DATATYPE_HEXBINARY = "http://www.w3.org/2001/XMLSchema#hexBinary"
#ACS_XACML_DATATYPE_BASE64BINARY = \
# "http://www.w3.org/2001/XMLSchema#base64Binary"
#ACS_XACML_DATATYPE_DAYTIMEDURATION = \
# "http://www.w3.org/2001/XMLSchema#dayTimeDuration"
#ACS_XACML_DATATYPE_YEARMONTHDURATION = \
# "http://www.w3.org/2001/XMLSchema#yearMonthDuration"
'''
An ITU-T Rec.X.520 Distinguished Name.
The valid syntax for such a name is described in IETF RFC 2253
"Lightweight Directory Access Protocol (v3): UTF-8 String Representation of
Distinguished Names".
'''
ACS_XACML_DATATYPE_X500NAME = \
"urn:oasis:names:tc:xacml:1.0:data-type:x500Name"
'''
An electronic mail address. The valid syntax for such a name is described
in IETF RFC 2821, Section 4.1.2,
Command Argument Syntax, under the term "Mailbox".
'''
ACS_XACML_DATATYPE_RFC822NAME = \
"urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name"
'''
The syntax SHALL be:
ipAddress = address [ "/" mask ] [ ":" [ portrange ] ]
For an IPv4 address, the address and mask are formatted in accordance with the syntax for a
"host" in IETF RFC 2396 "Uniform Resource Identifiers (URI): Generic Syntax", section 3.2.
For an IPv6 address, the address and mask are formatted in accordance with the syntax for an
"ipv6reference" in IETF RFC 2732 "Format for Literal IPv6 Addresses in URL's". (Note that an
IPv6 address or mask, in this syntax, is enclosed in literal "[" "]" brackets.)
'''
ACS_XACML_DATATYPE_IPADDRESS = \
"urn:oasis:names:tc:xacml:2.0:data-type:ipAddress"
'''
The syntax SHALL be:
dnsName = hostname [ ":" portrange ]
The hostname is formatted in accordance with IETF RFC 2396 "Uniform Resource Identifiers
(URI): Generic Syntax", section 3.2, except that a wildcard "*" may be used in the left-most
component of the hostname to indicate "any subdomain" under the domain specified to its right.
For both the "urn:oasis:names:tc:xacml:2.0:data-type:ipAddress" and
"urn:oasis:names:tc:xacml:2.0:data-type:dnsName" data-types, the port or port range syntax
SHALL be
portrange = portnumber | "-"portnumber | portnumber"-"[portnumber]
where "portnumber" is a decimal port number. If the port number is of the form "-x", where "x" is
a port number, then the range is all ports numbered "x" and below. If the port number is of the
form "x-", then the range is all ports numbered "x" and above. [This syntax is taken from the Java
SocketPermission.]
'''
ACS_XACML_DATATYPE_DNSNAME = \
"urn:oasis:names:tc:xacml:2.0:data-type:dnsName"
ACS_XACML_DATATYPE_XPATHEXPRESSION = \
"urn:oasis:names:tc:xacml:3.0:data-type:xpathExpression"
XACML_DATA_TYPE = (
(ACS_XACML_DATATYPE_STRING, _('String')),
(ACS_XACML_DATATYPE_BOOLEAN, _('Boolean')),
(ACS_XACML_DATATYPE_INTEGER, _('Integer')),
(ACS_XACML_DATATYPE_DOUBLE, _('Double')),
(ACS_XACML_DATATYPE_TIME, _('Time')),
(ACS_XACML_DATATYPE_DATE, _('Date')),
(ACS_XACML_DATATYPE_DATETIME, _('Date and Time')),
# (ACS_XACML_DATATYPE_ANYURI, _('Any URI')),
# (ACS_XACML_DATATYPE_HEXBINARY, _('Hex Binary')),
# (ACS_XACML_DATATYPE_BASE64BINARY, _('Base64 Binary')),
# (ACS_XACML_DATATYPE_DAYTIMEDURATION, _('Day Time Duration')),
# (ACS_XACML_DATATYPE_YEARMONTHDURATION, _('Year Month Duration')),
# (ACS_XACML_DATATYPE_X500NAME, _('X500 name')),
(ACS_XACML_DATATYPE_RFC822NAME, _('email address')),
(ACS_XACML_DATATYPE_IPADDRESS, _('IP address')),
# (ACS_XACML_DATATYPE_DNSNAME, _('DNS name')),
# (ACS_XACML_DATATYPE_XPATHEXPRESSION, _('XPATH expression')),
)
ACS_XACML_COMPARISON_EQUALITY_STRING = \
"urn:oasis:names:tc:xacml:1.0:function:string-equal"
ACS_XACML_COMPARISON_EQUALITY_STRING_IGN_CASE = \
"urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case"
ACS_XACML_COMPARISON_EQUALITY_BOOLEAN = \
"urn:oasis:names:tc:xacml:1.0:function:boolean-equal"
ACS_XACML_COMPARISON_EQUALITY_INTEGER = \
"urn:oasis:names:tc:xacml:1.0:function:integer-equal"
ACS_XACML_COMPARISON_EQUALITY_DOUBLE = \
"urn:oasis:names:tc:xacml:1.0:function:double-equal"
ACS_XACML_COMPARISON_EQUALITY_DATE = \
"urn:oasis:names:tc:xacml:1.0:function:date-equal"
ACS_XACML_COMPARISON_EQUALITY_TIME = \
"urn:oasis:names:tc:xacml:1.0:function:time-equal"
ACS_XACML_COMPARISON_EQUALITY_DATETIME = \
"urn:oasis:names:tc:xacml:1.0:function:dateTime-equal"
ACS_XACML_COMPARISON_EQUALITY_DAYTIMEDURATION = \
"urn:oasis:names:tc:xacml:3.0:function:dayTimeDuration-equal"
ACS_XACML_COMPARISON_EQUALITY_YEARMONTHDURATION = \
"urn:oasis:names:tc:xacml:3.0:function:yearMonthDuration-equal"
ACS_XACML_COMPARISON_EQUALITY_ANYURI = \
"urn:oasis:names:tc:xacml:1.0:function:anyURI-equal"
ACS_XACML_COMPARISON_EQUALITY_X500NAME = \
"urn:oasis:names:tc:xacml:1.0:function:x500Name-equal"
ACS_XACML_COMPARISON_EQUALITY_RFC822NAME = \
"urn:oasis:names:tc:xacml:1.0:function:rfc822Name-equal"
ACS_XACML_COMPARISON_EQUALITY_IPADDRESS = \
"urn:oasis:names:tc:xacml:1.0:function:ipAddress-equal"
ACS_XACML_COMPARISON_EQUALITY_HEXBINARY = \
"urn:oasis:names:tc:xacml:1.0:function:hexBinary-equal"
ACS_XACML_COMPARISON_EQUALITY_BASE64BINARY = \
"urn:oasis:names:tc:xacml:1.0:function:base64Binary-equal"
XACML_COMPARISON_EQUALITY = (
ACS_XACML_COMPARISON_EQUALITY_STRING,
ACS_XACML_COMPARISON_EQUALITY_STRING_IGN_CASE,
ACS_XACML_COMPARISON_EQUALITY_BOOLEAN,
ACS_XACML_COMPARISON_EQUALITY_INTEGER,
ACS_XACML_COMPARISON_EQUALITY_DOUBLE,
ACS_XACML_COMPARISON_EQUALITY_DATE,
ACS_XACML_COMPARISON_EQUALITY_TIME,
ACS_XACML_COMPARISON_EQUALITY_DATETIME,
# ACS_XACML_COMPARISON_EQUALITY_DAYTIMEDURATION, _('Day Time Duration equality')),
# ACS_XACML_COMPARISON_EQUALITY_YEARMONTHDURATION, _('Year Month Duration equality')),
# ACS_XACML_COMPARISON_EQUALITY_ANYURI, _('Any URI equality')),
# ACS_XACML_COMPARISON_EQUALITY_X500NAME, _('X500 name equality')),
ACS_XACML_COMPARISON_EQUALITY_RFC822NAME,
ACS_XACML_COMPARISON_EQUALITY_IPADDRESS,
# ACS_XACML_COMPARISON_EQUALITY_HEXBINARY, _('Hex binary equality')),
# ACS_XACML_COMPARISON_EQUALITY_BASE64BINARY, _('base 64 binary equality')),
)
XACML_COMPARISON_EQUALITY_TYPE = (
(ACS_XACML_COMPARISON_EQUALITY_STRING, _('String equality')),
(ACS_XACML_COMPARISON_EQUALITY_STRING_IGN_CASE, _('String equality ignoring case')),
(ACS_XACML_COMPARISON_EQUALITY_BOOLEAN, _('Boolean equality')),
(ACS_XACML_COMPARISON_EQUALITY_INTEGER, _('Integer equality')),
(ACS_XACML_COMPARISON_EQUALITY_DOUBLE, _('Double equality')),
(ACS_XACML_COMPARISON_EQUALITY_DATE, _('Date equality')),
(ACS_XACML_COMPARISON_EQUALITY_TIME, _('Time equality')),
(ACS_XACML_COMPARISON_EQUALITY_DATETIME, _('DateTime equality')),
# (ACS_XACML_COMPARISON_EQUALITY_DAYTIMEDURATION, _('Day Time Duration equality')),
# (ACS_XACML_COMPARISON_EQUALITY_YEARMONTHDURATION, _('Year Month Duration equality')),
# (ACS_XACML_COMPARISON_EQUALITY_ANYURI, _('Any URI equality')),
# (ACS_XACML_COMPARISON_EQUALITY_X500NAME, _('X500 name equality')),
(ACS_XACML_COMPARISON_EQUALITY_RFC822NAME, _('email equality')),
(ACS_XACML_COMPARISON_EQUALITY_IPADDRESS, _('IP address equality')),
# (ACS_XACML_COMPARISON_EQUALITY_HEXBINARY, _('Hex binary equality')),
# (ACS_XACML_COMPARISON_EQUALITY_BASE64BINARY, _('base 64 binary equality')),
)
XACML_COMPARISON_EQUALITY_TYPE_DIC = {
ACS_XACML_COMPARISON_EQUALITY_STRING: _('String equality'),
ACS_XACML_COMPARISON_EQUALITY_STRING_IGN_CASE: _('String equality ignoring case'),
ACS_XACML_COMPARISON_EQUALITY_BOOLEAN: _('Boolean equality'),
ACS_XACML_COMPARISON_EQUALITY_INTEGER: _('Integer equality'),
ACS_XACML_COMPARISON_EQUALITY_DOUBLE: _('Double equality'),
ACS_XACML_COMPARISON_EQUALITY_DATE: _('Date equality'),
ACS_XACML_COMPARISON_EQUALITY_TIME: _('Time equality'),
ACS_XACML_COMPARISON_EQUALITY_DATETIME: _('DateTime equality'),
# ACS_XACML_COMPARISON_EQUALITY_DAYTIMEDURATION: _('Day Time Duration equality'),
# ACS_XACML_COMPARISON_EQUALITY_YEARMONTHDURATION: _('Year Month Duration equality'),
# ACS_XACML_COMPARISON_EQUALITY_ANYURI: _('Any URI equality'),
# ACS_XACML_COMPARISON_EQUALITY_X500NAME: _('X500 name equality'),
ACS_XACML_COMPARISON_EQUALITY_RFC822NAME: _('email equality'),
ACS_XACML_COMPARISON_EQUALITY_IPADDRESS: _('IP address equality'),
# ACS_XACML_COMPARISON_EQUALITY_HEXBINARY: _('Hex binary equality'),
# ACS_XACML_COMPARISON_EQUALITY_BASE64BINARY: _('base 64 binary equality'),
}
ACS_XACML_COMPARISON_INTEGER_GRT = \
"urn:oasis:names:tc:xacml:1.0:function:integer-greater-than"
ACS_XACML_COMPARISON_INTEGER_GRT_OE = \
"urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal"
ACS_XACML_COMPARISON_INTEGER_LT = \
"urn:oasis:names:tc:xacml:1.0:function:integer-less-than"
ACS_XACML_COMPARISON_INTEGER_LT_OE = \
"urn:oasis:names:tc:xacml:1.0:function:integer-less-than-or-equal"
ACS_XACML_COMPARISON_DOUBLE_GRT = \
"urn:oasis:names:tc:xacml:1.0:function:double-greater-than"
ACS_XACML_COMPARISON_DOUBLE_GRT_OE = \
"urn:oasis:names:tc:xacml:1.0:function:double-greater-than-or-equal"
ACS_XACML_COMPARISON_DOUBLE_LT = \
"urn:oasis:names:tc:xacml:1.0:function:double-less-than"
ACS_XACML_COMPARISON_DOUBLE_LT_OE = \
"urn:oasis:names:tc:xacml:1.0:function:double-less-than-or-equal"
ACS_XACML_COMPARISON_GRT = (
ACS_XACML_COMPARISON_INTEGER_GRT,
ACS_XACML_COMPARISON_DOUBLE_GRT,
)
ACS_XACML_COMPARISON_GRT_OE = (
ACS_XACML_COMPARISON_INTEGER_GRT_OE,
ACS_XACML_COMPARISON_DOUBLE_GRT_OE,
)
ACS_XACML_COMPARISON_LT = (
ACS_XACML_COMPARISON_INTEGER_LT,
ACS_XACML_COMPARISON_DOUBLE_LT,
)
ACS_XACML_COMPARISON_LT_OE = (
ACS_XACML_COMPARISON_INTEGER_LT_OE,
ACS_XACML_COMPARISON_DOUBLE_LT_OE,
)
ACS_XACML_COMPARISON = ACS_XACML_COMPARISON_GRT \
+ ACS_XACML_COMPARISON_GRT_OE \
+ ACS_XACML_COMPARISON_LT \
+ ACS_XACML_COMPARISON_LT_OE
XACML_COMPARISON_DIFF_TYPE = (
(ACS_XACML_COMPARISON_INTEGER_GRT, _('Integer 1 greater than integer 2')),
(ACS_XACML_COMPARISON_INTEGER_GRT_OE, _('Integer 1 greater than or equal integer 2')),
(ACS_XACML_COMPARISON_INTEGER_LT, _('Integer 1 less than integer 2')),
(ACS_XACML_COMPARISON_INTEGER_LT_OE, _('Integer 1 less than or equal integer 2')),
(ACS_XACML_COMPARISON_DOUBLE_GRT, _('Double 1 greater than double 2')),
(ACS_XACML_COMPARISON_DOUBLE_GRT_OE, _('Double 1 greater than or equal double 2')),
(ACS_XACML_COMPARISON_DOUBLE_LT, _('Double 1 less than double 2')),
(ACS_XACML_COMPARISON_DOUBLE_LT_OE, _('Double 1 less than or equal double 2')),
)
XACML_COMPARISON_DIFF_TYPE_DIC = {
ACS_XACML_COMPARISON_INTEGER_GRT: _('Integer 1 greater than integer 2'),
ACS_XACML_COMPARISON_INTEGER_GRT_OE: _('Integer 1 greater than or equal integer 2'),
ACS_XACML_COMPARISON_INTEGER_LT: _('Integer 1 less than integer 2'),
ACS_XACML_COMPARISON_INTEGER_LT_OE: _('Integer 1 less than or equal integer 2'),
ACS_XACML_COMPARISON_DOUBLE_GRT: _('Double 1 greater than double 2'),
ACS_XACML_COMPARISON_DOUBLE_GRT_OE: _('Double 1 greater than or equal double 2'),
ACS_XACML_COMPARISON_DOUBLE_LT: _('Double 1 less than double 2'),
ACS_XACML_COMPARISON_DOUBLE_LT_OE: _('Double 1 less than or equal double 2'),
}
XACML_COMPARISON_TYPE_DIC = dict(XACML_COMPARISON_EQUALITY_TYPE_DIC.items() \
+ XACML_COMPARISON_DIFF_TYPE_DIC.items())
XACML_COMPARISON_TYPE = XACML_COMPARISON_EQUALITY_TYPE + XACML_COMPARISON_DIFF_TYPE
ACS_COMP_TYPE = {
ACS_XACML_COMPARISON_INTEGER_GRT: ACS_XACML_DATATYPE_INTEGER,
ACS_XACML_COMPARISON_INTEGER_GRT_OE: ACS_XACML_DATATYPE_INTEGER,
ACS_XACML_COMPARISON_INTEGER_LT: ACS_XACML_DATATYPE_INTEGER,
ACS_XACML_COMPARISON_INTEGER_LT_OE: ACS_XACML_DATATYPE_INTEGER,
ACS_XACML_COMPARISON_DOUBLE_GRT: ACS_XACML_DATATYPE_DOUBLE,
ACS_XACML_COMPARISON_DOUBLE_GRT_OE: ACS_XACML_DATATYPE_DOUBLE,
ACS_XACML_COMPARISON_DOUBLE_LT: ACS_XACML_DATATYPE_DOUBLE,
ACS_XACML_COMPARISON_DOUBLE_LT_OE: ACS_XACML_DATATYPE_DOUBLE,
ACS_XACML_COMPARISON_EQUALITY_STRING: ACS_XACML_DATATYPE_STRING,
ACS_XACML_COMPARISON_EQUALITY_STRING_IGN_CASE: ACS_XACML_DATATYPE_STRING,
ACS_XACML_COMPARISON_EQUALITY_BOOLEAN: ACS_XACML_DATATYPE_BOOLEAN,
ACS_XACML_COMPARISON_EQUALITY_INTEGER: ACS_XACML_DATATYPE_INTEGER,
ACS_XACML_COMPARISON_EQUALITY_DOUBLE: ACS_XACML_DATATYPE_DOUBLE,
ACS_XACML_COMPARISON_EQUALITY_DATE: ACS_XACML_DATATYPE_DATE,
ACS_XACML_COMPARISON_EQUALITY_TIME: ACS_XACML_DATATYPE_TIME,
ACS_XACML_COMPARISON_EQUALITY_DATETIME: ACS_XACML_DATATYPE_DATETIME,
# ACS_XACML_COMPARISON_EQUALITY_DAYTIMEDURATION: ACS_XACML_DATATYPE_DAYTIMEDURATION,
# ACS_XACML_COMPARISON_EQUALITY_YEARMONTHDURATION: ACS_XACML_DATATYPE_YEARMONTHDURATION,
# ACS_XACML_COMPARISON_EQUALITY_ANYURI: ACS_XACML_DATATYPE_ANYURI,
# ACS_XACML_COMPARISON_EQUALITY_X500NAME: ACS_XACML_DATATYPE_X500NAME,
ACS_XACML_COMPARISON_EQUALITY_RFC822NAME: ACS_XACML_DATATYPE_RFC822NAME,
ACS_XACML_COMPARISON_EQUALITY_IPADDRESS: ACS_XACML_DATATYPE_IPADDRESS,
# ACS_XACML_COMPARISON_EQUALITY_HEXBINARY: ACS_XACML_DATATYPE_HEXBINARY,
# ACS_XACML_COMPARISON_EQUALITY_BASE64BINARY: ACS_XACML_DATATYPE_BASE64BINARY,
}