backends.py 2.38 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
# -*- coding: utf-8 -*-
# Copyright 2014 Budapest University of Technology and Economics (BME IK)
#
# This file is part of CIRCLE Cloud.
#
# CIRCLE is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# CIRCLE 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 General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along
# with CIRCLE.  If not, see <http://www.gnu.org/licenses/>.

import re
20
import logging
21
import sha
22

23
from django.conf import settings
24 25
from djangosaml2.backends import Saml2Backend as Saml2BackendBase

26 27
logger = logging.getLogger(__name__)

28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45

class Saml2Backend(Saml2BackendBase):
    u"""
    >>> b = Saml2Backend()
    >>> b.clean_user_main_attribute(u'Ékezetes Enikő')
    u'+00c9kezetes+0020Enik+0151'
    >>> b.clean_user_main_attribute(u'Cé++')
    u'C+00e9+002b+002b'
    >>> b.clean_user_main_attribute(u'test')
    u'test'
    >>> b.clean_user_main_attribute(u'3+4')
    u'3+002b4'
    """
    def clean_user_main_attribute(self, main_attribute):
        def replace(match):
            match = match.group()
            return '+%04x' % ord(match)

46 47
        if isinstance(main_attribute, str):
            main_attribute = main_attribute.decode('UTF-8')
48
        assert isinstance(main_attribute, unicode)
49 50 51
        attr = re.sub(r'[^\w.@-]', replace, main_attribute)
        max_length = settings.SAML_MAIN_ATTRIBUTE_MAX_LENGTH
        if max_length > 0 and len(attr) > max_length:
52 53
            logger.info("Main attribute '%s' is too long." % attr)
            hashed = sha.new(attr).hexdigest()
54
            if "@" in attr:
55 56 57
                domain = attr.rsplit("@", 1)[1]
                attr = "%s@%s" % (hashed[:max_length-1-len(domain)],
                                  domain)
58
            else:
59 60
                attr = hashed[:max_length]
            logger.info("New main attribute: %s" % attr)
61
        return attr
62 63 64 65 66

    def _set_attribute(self, obj, attr, value):
        if attr == 'username':
            value = self.clean_user_main_attribute(value)
        return super(Saml2Backend, self)._set_attribute(obj, attr, value)