# -*- coding: utf-8 -*- # vim:set expandtab tabstop=4 shiftwidth=4: # # The MIT License (MIT) # LdapCherry # Copyright (c) 2014 Carpentier Pierre-Francois import os import sys import re from ldapcherry.pyyamlwrapper import loadNoDump from ldapcherry.pyyamlwrapper import DumplicatedKey from ldapcherry.exceptions import * import yaml if sys.version < '3': from sets import Set as set # List of available types for form types = ['string', 'textfield', 'email', 'int', 'stringlist', 'fix', 'password'] class Attributes: def __init__(self, attributes_file): self.attributes_file = attributes_file self.backends = set([]) self.self_attributes = {} self.backend_attributes = {} self.displayed_attributes = {} self.key = None try: stream = open(attributes_file, 'r') except Exception as e: raise MissingAttributesFile(attributes_file) try: self.attributes = loadNoDump(stream) except DumplicatedKey as e: raise DumplicateAttributesKey(e.key) for attrid in self.attributes: self._mandatory_check(attrid) attr = self.attributes[attrid] if not attr['type'] in types: raise WrongAttributeType( attr['type'], attrid, attributes_file ) if attr['type'] == 'password': if attrid + '1' in self.attributes or \ attrid + '2' in self.attributes: raise PasswordAttributesCollision(attrid) if 'self' in attr and attr['self']: self.self_attributes[attrid] = attr if 'key' in attr and attr['key']: if self.key is not None: raise DumplicateUserKey(attrid, self.key) self.key = attrid for b in attr['backends']: self.backends.add(b) if b not in self.backend_attributes: self.backend_attributes[b] = {} self.backend_attributes[b][attr['backends'][b]] = attrid if 'search_displayed' in attr and attr['search_displayed']: self.displayed_attributes[attrid] = attr if self.key is None: raise MissingUserKey() def _is_email(self, email): pattern = r'[\.\w]{1,}[@]\w+[.]\w+' if re.match(pattern, email): return True else: return False def check_attr(self, attr, value): attrid = attr if attrid not in self.attributes: raise AttrNotDefined(attrid) attr_type = self.attributes[attrid]['type'] if attr_type == 'string': return elif attr_type == 'textfield': return elif attr_type == 'email': if self._is_email(value): return else: raise WrongAttrValue(attrid, attr_type) elif attr_type == 'int': try: int(value) return except ValueError: raise WrongAttrValue(attrid, attr_type) elif attr_type == 'stringlist': if value in self.attributes[attrid]['values']: return else: raise WrongAttrValue(attrid, attr_type) elif attr_type == 'fix': if value != self.attributes[attrid]['value']: raise WrongAttrValue(attrid, attr_type) elif attr_type == 'password': return def get_search_attributes(self): return self.displayed_attributes def get_key(self): return self.key def _mandatory_check(self, attr): for m in ['description', 'display_name', 'type', 'backends', 'weight']: if m not in self.attributes[attr]: raise MissingKey(m, attr, self.attributes_file) def get_selfattributes(self): """get the list of groups from roles""" return self.self_attributes def get_backends(self): """return the list of backends in roles file""" return self.backends def get_backend_attributes(self, backend): if backend not in self.backends: raise WrongBackend(backend) ret = list(self.backend_attributes[backend].keys()) ret.sort() return ret def get_backend_key(self, backend): if backend not in self.backends: raise WrongBackend(backend) return self.attributes[self.key]['backends'][backend] def get_attributes(self): """get the list of groups from roles""" return self.attributes.keys() def get_backends_attributes(self, attribute): return self.attributes[attribute]['backends']