<s> import logging <EOL> import ldap <EOL> from ldap . ldapobject import LDAPObject <EOL> from ldap . controls import SimplePagedResultsControl <EOL> from django . conf import settings <EOL> from django . core . management . base import NoArgsCommand <EOL> from django . contrib . auth import get_user_model <EOL> from django . contrib . auth . models import Group <EOL> from django . core . exceptions import ImproperlyConfigured <EOL> from django . db import IntegrityError , DataError <EOL> logger = logging . getLogger ( __name__ ) <EOL> class Command ( NoArgsCommand ) : <EOL> help = "<STR_LIT>" <EOL> def handle_noargs ( self , ** options ) : <EOL> ldap_groups = self . get_ldap_groups ( ) <EOL> if ldap_groups : <EOL> self . sync_ldap_groups ( ldap_groups ) <EOL> ldap_users = self . get_ldap_users ( ) <EOL> if ldap_users : <EOL> self . sync_ldap_users ( ldap_users ) <EOL> def get_ldap_users ( self ) : <EOL> """<STR_LIT>""" <EOL> user_filter = getattr ( settings , '<STR_LIT>' , None ) <EOL> if not user_filter : <EOL> msg = "<STR_LIT>" <EOL> logger . info ( msg ) <EOL> return None <EOL> attributes = getattr ( settings , '<STR_LIT>' , None ) <EOL> if not attributes : <EOL> error_msg = ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> raise ImproperlyConfigured ( error_msg ) <EOL> user_attributes = attributes . keys ( ) <EOL> users = self . ldap_search ( user_filter , user_attributes ) <EOL> logger . debug ( "<STR_LIT>" % len ( users ) ) <EOL> return users <EOL> def sync_ldap_users ( self , ldap_users ) : <EOL> """<STR_LIT>""" <EOL> model = get_user_model ( ) <EOL> attributes = getattr ( settings , '<STR_LIT>' , None ) <EOL> username_field = getattr ( settings , '<STR_LIT>' , None ) <EOL> if username_field is None : <EOL> username_field = getattr ( model , '<STR_LIT>' , '<STR_LIT:username>' ) <EOL> if not model . _meta . get_field ( username_field ) . unique : <EOL> error_msg = ( "<STR_LIT>" % username_field ) <EOL> raise ImproperlyConfigured ( error_msg ) <EOL> if username_field not in attributes . values ( ) : <EOL> error_msg = ( "<STR_LIT>" <EOL> "<STR_LIT>" % username_field ) <EOL> raise ImproperlyConfigured ( error_msg ) <EOL> for cname , attrs in ldap_users : <EOL> try : <EOL> items = attrs . items ( ) <EOL> except AttributeError : <EOL> continue <EOL> user_attr = { } <EOL> for name , attr in items : <EOL> user_attr [ attributes [ name ] ] = attr [ <NUM_LIT:0> ] . decode ( '<STR_LIT:utf-8>' ) <EOL> try : <EOL> username = user_attr [ username_field ] <EOL> user_attr [ username_field ] = username . lower ( ) <EOL> except KeyError : <EOL> logger . warning ( "<STR_LIT>" % <EOL> username_field ) <EOL> continue <EOL> kwargs = { <EOL> username_field + '<STR_LIT>' : username , <EOL> '<STR_LIT>' : user_attr , <EOL> } <EOL> try : <EOL> user , created = model . objects . get_or_create ( ** kwargs ) <EOL> except ( IntegrityError , DataError ) as e : <EOL> logger . error ( "<STR_LIT>" % ( username , e ) ) <EOL> else : <EOL> updated_fields = [ ] <EOL> if created : <EOL> logger . debug ( "<STR_LIT>" % username ) <EOL> user . set_unusable_password ( ) <EOL> updated_fields . append ( '<STR_LIT:password>' ) <EOL> else : <EOL> for name , attr in user_attr . items ( ) : <EOL> current_attr = getattr ( user , name ) <EOL> if current_attr != attr : <EOL> setattr ( user , name , attr ) <EOL> updated_fields . append ( name ) <EOL> user . save ( update_fields = updated_fields ) <EOL> logger . info ( "<STR_LIT>" ) <EOL> def get_ldap_groups ( self ) : <EOL> """<STR_LIT>""" <EOL> group_filter = getattr ( settings , '<STR_LIT>' , None ) <EOL> if not group_filter : <EOL> msg = "<STR_LIT>" <EOL> logger . info ( msg ) <EOL> return None <EOL> attributes = getattr ( settings , '<STR_LIT>' , None ) <EOL> if not attributes : <EOL> error_msg = ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> raise ImproperlyConfigured ( error_msg ) <EOL> group_attributes = attributes . keys ( ) <EOL> groups = self . ldap_search ( group_filter , group_attributes ) <EOL> logger . debug ( "<STR_LIT>" % len ( groups ) ) <EOL> return groups <EOL> def sync_ldap_groups ( self , ldap_groups ) : <EOL> """<STR_LIT>""" <EOL> attributes = getattr ( settings , '<STR_LIT>' , None ) <EOL> groupname_field = '<STR_LIT:name>' <EOL> if groupname_field not in attributes . values ( ) : <EOL> error_msg = ( "<STR_LIT>" <EOL> "<STR_LIT>" % groupname_field ) <EOL> raise ImproperlyConfigured ( error_msg ) <EOL> for cname , attrs in ldap_groups : <EOL> try : <EOL> items = attrs . items ( ) <EOL> except AttributeError : <EOL> continue <EOL> group_attr = { } <EOL> for name , attr in items : <EOL> group_attr [ attributes [ name ] ] = attr [ <NUM_LIT:0> ] . decode ( '<STR_LIT:utf-8>' ) <EOL> try : <EOL> groupname = group_attr [ groupname_field ] <EOL> group_attr [ groupname_field ] = groupname . lower ( ) <EOL> except KeyError : <EOL> logger . warning ( "<STR_LIT>" % <EOL> groupname_field ) <EOL> continue <EOL> kwargs = { <EOL> groupname_field + '<STR_LIT>' : groupname , <EOL> '<STR_LIT>' : group_attr , <EOL> } <EOL> try : <EOL> group , created = Group . objects . get_or_create ( ** kwargs ) <EOL> except IntegrityError as e : <EOL> logger . error ( "<STR_LIT>" % e ) <EOL> else : <EOL> if created : <EOL> logger . debug ( "<STR_LIT>" % groupname ) <EOL> logger . info ( "<STR_LIT>" ) <EOL> def ldap_search ( self , filter , attributes ) : <EOL> """<STR_LIT>""" <EOL> uri = getattr ( settings , '<STR_LIT>' , None ) <EOL> if not uri : <EOL> error_msg = ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> raise ImproperlyConfigured ( error_msg ) <EOL> base_user = getattr ( settings , '<STR_LIT>' , None ) <EOL> if not base_user : <EOL> error_msg = ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> raise ImproperlyConfigured ( error_msg ) <EOL> base_pass = getattr ( settings , '<STR_LIT>' , None ) <EOL> if not base_pass : <EOL> error_msg = ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> raise ImproperlyConfigured ( error_msg ) <EOL> base = getattr ( settings , '<STR_LIT>' , None ) <EOL> if not base : <EOL> error_msg = ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> raise ImproperlyConfigured ( error_msg ) <EOL> ldap . set_option ( ldap . OPT_REFERRALS , <NUM_LIT:0> ) <EOL> l = PagedLDAPObject ( uri ) <EOL> l . protocol_version = <NUM_LIT:3> <EOL> try : <EOL> l . simple_bind_s ( base_user , base_pass ) <EOL> except ldap . LDAPError : <EOL> logger . error ( "<STR_LIT>" % uri ) <EOL> raise <EOL> results = l . paged_search_ext_s ( base , <EOL> ldap . SCOPE_SUBTREE , <EOL> filter , <EOL> attrlist = attributes , <EOL> serverctrls = None ) <EOL> l . unbind_s ( ) <EOL> return results <EOL> class PagedResultsSearchObject : <EOL> """<STR_LIT>""" <EOL> page_size = getattr ( settings , '<STR_LIT>' , <NUM_LIT:100> ) <EOL> def paged_search_ext_s ( self , base , scope , filterstr = '<STR_LIT>' , <EOL> attrlist = None , attrsonly = <NUM_LIT:0> , serverctrls = None , <EOL> clientctrls = None , timeout = - <NUM_LIT:1> , sizelimit = <NUM_LIT:0> ) : <EOL> """<STR_LIT>""" <EOL> req_ctrl = SimplePagedResultsControl ( True , size = self . page_size , <EOL> cookie = '<STR_LIT>' ) <EOL> msgid = self . search_ext ( base , ldap . SCOPE_SUBTREE , filterstr , <EOL> attrlist = attrlist , <EOL> serverctrls = ( serverctrls or [ ] ) + [ req_ctrl ] ) <EOL> results = [ ] <EOL> while True : <EOL> rtype , rdata , rmsgid , rctrls = self . result3 ( msgid ) <EOL> results . extend ( rdata ) <EOL> pctrls = [ c for c in rctrls if c . controlType == <EOL> SimplePagedResultsControl . controlType ] <EOL> if pctrls : <EOL> if pctrls [ <NUM_LIT:0> ] . cookie : <EOL> req_ctrl . cookie = pctrls [ <NUM_LIT:0> ] . cookie <EOL> msgid = self . search_ext ( base , ldap . SCOPE_SUBTREE , <EOL> filterstr , attrlist = attrlist , <EOL> serverctrls = ( serverctrls or [ ] ) + <EOL> [ req_ctrl ] ) <EOL> else : <EOL> break <EOL> return results <EOL> class PagedLDAPObject ( LDAPObject , PagedResultsSearchObject ) : <EOL> pass </s>
