ldapcherry/ldapcherry/attributes.py

148 lines
4.7 KiB
Python

# -*- 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']