Changeset f395ef in indico


Ignore:
Timestamp:
02/24/11 14:38:38 (2 years ago)
Author:
Pedro Ferreira <jose.pedro.ferreira@…>
Branches:
master, burotel, hello-world-walkthrough, ipv6, v0.98-series, v0.98.2, v0.98.3, v0.98b1, v0.98b2, v0.99, 051b2622c51afb171a1dedb46a0df4fbb0cbd02e, 0da0c1403bae8e51d8229f460181c71b9e6dda72
Children:
5f7a6d
Parents:
6b3931
git-author:
Pedro Ferreira <jose.pedro.ferreira@…> (02/24/11 14:29:09)
git-committer:
Pedro Ferreira <jose.pedro.ferreira@…> (02/24/11 14:38:38)
Message:

[IMP] LDAP Authentication

  • Integrated Martin Kuba's patch (thanks Martin!);
  • Added escaping of LDAP special chars, in order to avoid injection attacks;
  • Added some extra customization options, so that the mechanism can interact with services that follow different conventions;
  • Renamed some structures, including 'Ldap' -> 'LDAP';
  • Changed operations to synchronous;
  • Added preliminary login step that can be needed in servers that do not provide anonymous read access;
  • Changed group membership strategy - faster and easier;
  • Adapted code to inetOrgPerson fields;
  • Improved the overall formatting and code quality (pylint and PEP8);
  • closes #600 and makes many server admins happier ;)
  • TODO: pluginize the whole thing (implies refactoring of auth mechanism);
  • TODO: Caching - right now server calls are performed every time;
Files:
1 added
10 edited

Legend:

Unmodified
Added
Removed
  • etc/indico.conf.sample

    r06a6d9 rf395ef  
    194194# to right): 
    195195# 
    196 #     AuthenticatorList = ['Local', 'MyAuthSystem'] 
     196#     AuthenticatorList = ['Local', 'LDAP', 'MyAuthSystem'] 
    197197# 
    198198# The default configuration will use only Indico's authentication system. 
     
    200200AuthenticatorList    = ['Local'] 
    201201 
     202# Uncomment/customize the following lines if you want to use LDAP authentication 
     203# 
     204# LDAPConfig = {'host': 'myldapserver.example.com', 
     205# 
     206#               # filter parameters for users, base DN to use 
     207#               'peopleDNQuery': ('uid={0}', 'DC=example,DC=com'), 
     208# 
     209#               # filter parameters for groups, base DN to use 
     210#               'groupDNQuery': ('cn={0}', 'OU=Groups,DC=example,DC=com'), 
     211# 
     212#               # query used to infer membership of a group 
     213#               'membershipQuery': 'memberof={0}', 
     214# 
     215#               # access credentials of a user with read access 
     216#               'accessCredentials': ('CN=user,OU=Users,DC=example,DC=com','secret_password') 
     217# } 
    202218 
    203219#------------------------------------------------------------------------------ 
  • indico/MaKaC/accessControl.py

    r96edb4 rf395ef  
    123123        """grants read access for the related resource to the specified 
    124124            principal""" 
    125         if principal not in self.allowed and (isinstance(principal, MaKaC.user.Avatar) or isinstance(principal, MaKaC.user.CERNGroup) or isinstance(principal, MaKaC.user.Group)): 
     125 
     126        # TODO: make this extensible 
     127        if principal not in self.allowed and \ 
     128               (isinstance(principal, MaKaC.user.Avatar) or \ 
     129                isinstance(principal, MaKaC.user.CERNGroup) or \ 
     130                isinstance(principal, MaKaC.user.Group) or \ 
     131                isinstance(principal, MaKaC.user.LDAPGroup)): 
    126132            self.allowed.append( principal ) 
    127133            self._p_changed = 1 
  • indico/MaKaC/authentication/AuthenticationMgr.py

    r912b9a rf395ef  
    3838                from MaKaC.authentication.NiceAuthentication import NiceAuthenticator 
    3939                self.AuthenticatorList.append( NiceAuthenticator() ) 
     40            if auth == "LDAP": 
     41                from MaKaC.authentication.LDAPAuthentication import LDAPAuthenticator 
     42                self.AuthenticatorList.append(LDAPAuthenticator()) 
    4043        self.create = True 
    4144 
  • indico/MaKaC/common/Configuration.py

    r06a6d9 rf395ef  
    440440            'AuthenticatedEnforceSecure': 'yes', 
    441441 
     442            # Authentication 
     443            'LDAPConfig': {'host': 'myldapserver.example.com', 
     444                           'peopleDNQuery': ('uid={0}', 'DC=example,DC=com'), 
     445                           'groupDNQuery': ('cn={0}', 
     446                                            'OU=Groups,DC=example,DC=com'), 
     447                           'membershipQuery': 'memberof={0}', 
     448                           'accessCredentials': ('CN=user,OU=Users,' 
     449                                                 'DC=example,DC=com', 
     450                                                 'secret_password')}, 
    442451            # Room Booking Related 
    443452            'LightboxCssStylesheetName' : "lightbox/lightbox.css", 
    444453            'LightboxJavascriptName'    : "lightbox/lightbox.js" 
    445454            } 
    446  
    447455 
    448456        if sys.platform == 'win32': 
  • indico/MaKaC/common/ObjectHolders.py

    rbdd862 rf395ef  
    5252            index. 
    5353    """ 
    54     __allowedIdxs = ["conferences", "avatars", "groups", "counters",  
    55                     "identities", "principals", "categories",  
    56                     "localidentities", "niceidentities", "groupsregistration",  
    57                     "fieldsregistration", "registrationform", "domains", "indexes", 
    58                     "trashcan", "roomsmapping", "deletedobject", "shorturl", "modules", "plugins"] 
     54    __allowedIdxs = ["conferences", "avatars", "groups", "counters", 
     55                     "identities", "principals", "categories", 
     56                     "localidentities", "niceidentities", "groupsregistration", 
     57                     "ldapidentities", "fieldsregistration", "registrationform", 
     58                     "domains", "indexes", "trashcan", "roomsmapping", 
     59                     "deletedobject", "shorturl", "modules", "plugins"] 
    5960    idxName = None 
    6061    counterName = None 
    6162 
    62     def __init__(self):  
     63    def __init__(self): 
    6364        """Class constructor. Gets an opened DB storage and initializes the  
    6465           DB connection so it's available for later requests. 
  • indico/MaKaC/externUsers.py

    r8dee82 rf395ef  
    2929from MaKaC.errors import MaKaCError 
    3030from MaKaC.common.logger import Logger 
     31from MaKaC.authentication.LDAPAuthentication import LDAPAuthenticator, LDAPUser 
     32 
    3133 
    3234class ExtUserHolder: 
    3335    def __init__(self): 
    34         self.extUserList = {"Nice":NiceUser} 
     36        self.extUserList = {"Nice": NiceUser, 
     37                            LDAPAuthenticator.getId(): LDAPUser} 
    3538 
    3639    def getById(self, id): 
  • indico/MaKaC/user.py

    r2ed6e4 rf395ef  
    1919## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 
    2020 
     21 
    2122from MaKaC.fossils.user import IAvatarFossil, IAvatarAllDetailsFossil,\ 
    2223                            IGroupFossil, IPersonalInfoFossil, IAvatarMinimalFossil 
     
    3940import MaKaC.common.info as info 
    4041from MaKaC.i18n import _ 
     42from MaKaC.authentication.LDAPAuthentication import LDAPAuthenticator, ldapFindGroups, ldapUserInGroup 
    4143 
    4244from datetime import datetime, timedelta 
     
    325327 
    326328 
     329class LDAPGroup(Group): 
     330    groupType = "LDAP" 
     331 
     332    def __str__(self): 
     333        return "<LDAPGroup id: %s name: %s desc: %s>" % (self.getId(), 
     334                                                         self.getName(), 
     335                                                         self.getDescription()) 
     336 
     337    def addMember(self, newMember): 
     338        pass 
     339 
     340    def removeMember(self, member): 
     341        pass 
     342 
     343    def getMemberList(self): 
     344        uidList = ldapFindGroupMemberUids(self.getName()) 
     345        avatarLists = [] 
     346        for uid in uidList: 
     347            # First, try locally (fast) 
     348            lst = AvatarHolder().match({'login': uid }, exact=1, 
     349                                       forceWithoutExtAuth=True) 
     350            if not lst: 
     351                # If not found, try external 
     352                lst = AvatarHolder().match({'login': uid}, exact=1) 
     353            avatarLists.append(lst) 
     354        return [avList[0] for avList in avatarLists if avList] 
     355 
     356    def containsUser(self, avatar): 
     357 
     358        # used when checking acces to private events restricted for certain groups 
     359        if not avatar: 
     360            return False 
     361        login = None 
     362        for aid in avatar.getIdentityList(): 
     363            if aid.getAuthenticatorTag() == 'LDAP': 
     364                login = aid.getLogin() 
     365        if not login: 
     366            return False 
     367        return ldapUserInGroup(login, self.getName()) 
     368 
     369    def containsMember(self, avatar): 
     370        return 0 
     371 
     372 
    327373class GroupHolder(ObjectHolder): 
    328374    """ 
     
    384430        if "Nice" in Config.getInstance().getAuthenticatorList() and not forceWithoutExtAuth: 
    385431            self.updateCERNGroupMatch(crit["name"][0],exact) 
     432        if "LDAP" in Config.getInstance().getAuthenticatorList() and not forceWithoutExtAuth: 
     433            self.updateLDAPGroupMatch(crit["name"][0],exact) 
    386434        match = self.getIndex().matchGroup(crit["name"][0], exact=exact) 
    387435 
     
    392440                    result.append(gr) 
    393441        return result 
     442 
     443    def updateLDAPGroupMatch(self, name, exact=False): 
     444        logger.Logger.get('GroupHolder').debug( 
     445            "updateLDAPGroupMatch(name=" + name + ")") 
     446 
     447        for grDict in ldapFindGroups(name, exact): 
     448            grName = grDict['cn'] 
     449            if not self.hasKey(grName): 
     450                gr = LDAPGroup() 
     451                gr.setId(grName) 
     452                gr.setName(grName) 
     453                gr.setDescription('LDAP group: ' + grDict['description']) 
     454                self.add(gr) 
     455                logger.Logger.get('GroupHolder').debug( 
     456                    "updateLDAPGroupMatch() added" + str(gr)) 
    394457 
    395458    def updateCERNGroupMatch(self, name, exact=False): 
     
    13951458            euh = ExtUserHolder() 
    13961459            from MaKaC.authentication import NiceAuthentication 
     1460            from MaKaC.authentication import LDAPAuthentication 
    13971461            for authId in Config.getInstance().getAuthenticatorList(): 
    13981462                if not authId == "Local": 
    13991463                    dict = euh.getById(authId).match(criteria, exact=exact) 
    1400                     auth = NiceAuthentication.NiceAuthenticator() 
    1401  
    1402  
     1464                    if authId == "Nice": 
     1465                        auth = NiceAuthentication.NiceAuthenticator() 
     1466                    elif authId == "LDAP": 
     1467                        auth = LDAPAuthentication.LDAPAuthenticator() 
     1468                    else: 
     1469                       raise MaKaCError( 
     1470                           _("Authentication type " + authId + " is not known.")) 
    14031471                    for email in dict.keys(): 
    14041472                        # TODO and TOSTUDY: result.keys should be replace it with 
  • indico/MaKaC/webinterface/pages/admins.py

    r2ed6e4 rf395ef  
    18431843            self.__setGroupVars( self._group, vars ) 
    18441844            vars["locator"] = self._group.getLocator().getWebForm() 
    1845             if isinstance(self._group, CERNGroup): 
     1845            if isinstance(self._group, CERNGroup) or \ 
     1846                   isinstance(self._group, user.LDAPGroup): 
    18461847                vars["allowModif"] = False 
    18471848        return vars 
  • indico/MaKaC/webinterface/rh/base.py

    r64824a rf395ef  
    495495                        self._reqParams = copy.copy( params ) 
    496496                        self._checkParams( self._reqParams ) 
     497 
    497498                        self._checkProtection() 
    498499                        security.Sanitization.sanitizationCheck(self._target, 
  • indico/MaKaC/webinterface/rh/conferenceDisplay.py

    r50cb7d rf395ef  
    390390 
    391391    def _checkProtection( self ): 
     392 
    392393        from MaKaC.webinterface.rh.collaboration import RCCollaborationAdmin, RCCollaborationPluginAdmin 
    393394        if not RCCollaborationAdmin.hasRights(self, None) and \ 
Note: See TracChangeset for help on using the changeset viewer.