Advertisement
Guest User

Untitled

a guest
Jun 1st, 2017
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 33.40 KB | None | 0 0
  1. import ldap
  2. import logging
  3. import random
  4. import sys
  5. import traceback
  6. import os
  7. import hashlib
  8. from base64 import urlsafe_b64encode as encode
  9. from base64 import urlsafe_b64decode as decode
  10.  
  11. LOG_FILENAME = '/tmp/logging_example.out'
  12. log = logging
  13. logging.basicConfig(filename=LOG_FILENAME,level=logging.DEBUG)
  14.  
  15. #log = logging.getLogger('atrium.auth.backends')
  16.  
  17. from django.conf import settings
  18. from django.contrib.auth.models import User
  19. from django.db import transaction
  20.  
  21. class LDAPBackendError(Exception):
  22. pass
  23.  
  24. #need to map all of our user attributes to a LDAP attr for commit to work
  25. #CHANGE THIS FOR INETORG, JWUSER
  26. _DEFAULTS = {
  27. 'bindname': None,
  28. 'binddn': None,
  29. 'bindpw': None,
  30. 'group': None,
  31. 'groupdn': None,
  32. 'groupsu': None,
  33. 'groupstaff': None,
  34. 'groupactive': None,
  35. 'replicas': True,
  36. 'email': 'mail',
  37. 'first_name': 'cn',
  38. 'last_name': 'sn',
  39. 'username' : 'uid',
  40. 'objectClass' : ['jwUser' ,'inetOrgPerson', 'organizationalPerson', 'person', 'top'] ,
  41. 'timeout': 3,
  42. 'disable_update': False,
  43. 'all_attr' : ('username', 'first_name', 'last_name', 'email' ),
  44. }
  45.  
  46. _REQUIRED = ('url', 'userdn')
  47. _TO_ITERABLE = ('url', 'group', 'groupsu', 'groupstaff', 'groupactive')
  48.  
  49. class LDAPBackend():
  50. def changePasswd(self, user, newpassword):
  51. log.debug('LDAPBackend.changePasswd(%s,%s)' % (user, newpassword) )
  52. self._modifyPasswd(user, None, newpassword)
  53.  
  54. def authenticate(self, username=None, password=None):
  55. log.debug('LDAPBackend.authenticate(%s,%s)' % (username, password))
  56. if username is None or password is None:
  57. log.debug('Username or password is None, automatically returning None')
  58. return None
  59. blocks = self._buildBlocks()
  60. for block in blocks:
  61. log.debug('Processing block, settings: %s' % str(block))
  62. for opt in ('NETWORK_TIMEOUT', 'TIMELIMIT', 'TIMEOUT'):
  63. ldap.set_option(getattr(ldap, 'OPT_%s' % opt), block['timeout'])
  64.  
  65. for uri in block['url']:
  66. conn = self._buildConn(uri)
  67. if not conn:
  68. log.error('Could not initialize connection to %s' % uri)
  69. continue
  70.  
  71. try:
  72. try:
  73. conn.simple_bind_s('uid=%s,%s' % (username, block['userdn']), password)
  74. except ldap.INVALID_CREDENTIALS:
  75. log.debug('%s returned invalid credentials' % uri)
  76. if block['replicas'] is True:
  77. return None
  78. break
  79. except ldap.LDAPError, e:
  80. log.error('Got error from LDAP library: %s' % str(e))
  81. break
  82. if block['group'] is None:
  83. log.info('%s authenticated successfully against %s' % (username, uri))
  84. return self._return_user(username, conn, block)
  85. # If your directory is setup such that this user couldn't search (for whatever reason)
  86. # switch to an account that can so we can check the group
  87. if block['bindname'] is not None:
  88. log.debug('Rebinding to check group membership')
  89. conn.unbind()
  90. del conn
  91. conn = self._buildConn(uri)
  92. try:
  93. conn.simple_bind_s('cn=%s,%s' % (block['bindname'], block['binddn']), block['bindpw'])
  94. except ldap.LDAPError, e:
  95. log.error('Error during rebind: %s' % str(e))
  96. break
  97. for group in block['group']:
  98. log.debug('Checking if %s is a member of %s' % (username, group))
  99. try:
  100. result = conn.search_s('cn=%s,%s' % (group, block['groupdn']), ldap.SCOPE_SUBTREE, '(objectclass=*)', ['memberUid'])
  101. except ldap.NO_SUCH_OBJECT:
  102. log.error('Could not find user object cn=%s,%s' % (group, block['groupdn']) )
  103. continue
  104. print result
  105. # If there's more than one result, it gets ignored (there shouldn't be more than one
  106. # group with the same name anyway)
  107. if not result:
  108. log.debug('No group found with name %s' % group)
  109. continue
  110. if 'memberUid' not in result[0][1]:
  111. log.debug('No memberUid in group %s' % group)
  112. continue
  113. else:
  114. log.debug('memberUid in group %s found!' % group)
  115. result = result[0][1]['memberUid']
  116. #print result[0]
  117. #print username
  118. uid = 'uid=' + username + ',' + block['userdn']
  119. if uid in result[0]:
  120. log.info('%s authenticated successfully against %s' % (username, uri))
  121. return self._return_user(username, conn, block)
  122.  
  123. if block['replicas'] is True:
  124. break
  125. finally:
  126. del conn
  127. log.info('User %s could not be authenticated' % username)
  128. return None
  129.  
  130. def checkPassword(self, user, password):
  131. log.debug('LDAPBackend.checkPassword(%s,%s)' % (user,password) )
  132. blocks = self._buildBlocks()
  133. for block in blocks:
  134. for uri in block['url']:
  135. #we only compare the current changes, rather than changes between servers (this will put their state into sync incidentaly)
  136. conn = self._buildConn(uri)
  137. try:
  138. conn.simple_bind_s('cn=%s,%s' % (user.username, block['userdn']), password)
  139. except ldap.INVALID_CREDENTIALS:
  140. log.info('%s user could not bind, password is incorrect' % user.username)
  141. continue
  142. except ldap.LDAPError, e:
  143. log.error('Got error from LDAP library: %s' % str(e))
  144. continue
  145. return True
  146. #since one server has validated the authentication, we allow the user to proceed.
  147. return False
  148.  
  149. def commitUser(self, user):
  150. log.debug('LDAPBackend.commitUser(%s)' % user)
  151. #log.debug('Refernece from %s to modify user')
  152. blocks = self._buildBlocks()
  153. update = False
  154. for block in blocks:
  155. for uri in block['url']:
  156. #we only compare the current changes, rather than changes between servers (this will put their state into sync incidentaly)
  157. conn = self._buildConn(uri)
  158. try:
  159. conn.simple_bind_s('cn=%s,%s' % (block['bindname'], block['binddn']), block['bindpw'])
  160. except ldap.INVALID_CREDENTIALS:
  161. log.error('%s Admin user could not bind. something is wrong...' % uri)
  162. continue
  163. except ldap.LDAPError, e:
  164. log.error('Got error from LDAP library: %s' % str(e))
  165. continue
  166. #ldap_data = self._getUserByName(user.username, user, conn, block)
  167. ldap_data = 'hacks'
  168. try:
  169. r = conn.search_s('uid=%s,%s' % (user.username, block['userdn']), ldap.SCOPE_SUBTREE,'(objectclass=*)', [block['email'], block['first_name'], block['last_name']])
  170. except ldap.NO_SUCH_OBJECT, e:
  171. log.warning('Could not get user information for %s, LDAP user likely does not exist' % user.username)
  172. ldap_data = None
  173. except ldap.LDAPError, e:
  174. log.error('Got error from LDAP library, returning our user: %s' % str(e))
  175. continue
  176. if ldap_data == None:
  177. result = self._createUser(conn, block, user, uri)
  178. log.debug('User create returned %s' % result)
  179. else:
  180. result = self._modifyUser(conn, block, user, uri)
  181. log.debug('User modify returned %s' % result)
  182. conn.unbind()
  183. log.debug('Unbound from cn=%s,%s' % (block['bindname'], block['binddn']) )
  184. del conn
  185. if result:
  186. update = True
  187. #this means our update has occured on at least one server, so we can continue
  188. if update == False:
  189. log.error('%s was enabled to be (completely) saved!' % user.username)
  190. raise LDAPUserCreateError('%s was unabled to be saved/modified to the LDAP system. please view the logs' % user.username)
  191.  
  192. def get_user(self, user_id):
  193. log.debug('LDAPBackend.get_user(%s)' % user_id )
  194. try:
  195. return LDAP_User.objects.get(pk=user_id)
  196. except User.DoesNotExist:
  197. return None
  198.  
  199. ################
  200. #private methods
  201. ################
  202.  
  203. def _buildBlocks(self):
  204. log.debug('LDAPBackend._buildBlocks()')
  205. if isinstance(settings.LDAP_AUTH_SETTINGS[0], dict):
  206. log.debug('Using complex settings')
  207. blocks = settings.LDAP_AUTH_SETTINGS
  208. else:
  209. log.debug('Using simple settings')
  210. blocks = (self._parse_simple_config(),)
  211. # First get our configuration into a standard format
  212. for block in blocks:
  213. for r in _REQUIRED:
  214. if r not in block:
  215. raise LDAPBackendError('Missing required configuration option: %s' % r)
  216. for d in _DEFAULTS:
  217. if d not in block:
  218. block[d] = _DEFAULTS[d]
  219. for i in _TO_ITERABLE:
  220. if isinstance(block[i], str):
  221. block[i] = (block[i],)
  222. #Dont make our access random, we want to access servers in the order in the config
  223. block['url'] = list(block['url'])
  224. return blocks
  225.  
  226. def _buildConn(self, uri):
  227. log.debug('LDAPBackend._buildConn(%s)' % uri)
  228. log.debug('Attempting to authenticate to %s' % uri)
  229. conn = ldap.initialize(uri)
  230. try:
  231. conn.start_tls_s()
  232. except ldap.LDAPError, e:
  233. log.error("Could not start TLS")
  234. return conn
  235.  
  236. def _createUser(self, conn, block, user, uri):
  237. log.debug('LDAPBackend._createUser(%s,%s,%s,%s)' % (conn,block,user,uri))
  238. log.debug('Choosing to create user %s' % user.username)
  239. exist = True
  240. #CHANGE THIS FOR INETORG
  241. try:
  242. conn.search_s('uid=%s,%s' % (user.username, block['userdn']), ldap.SCOPE_ONELEVEL, '(objectclass=jwUser)', ['uid'])
  243. except ldap.NO_SUCH_OBJECT, e:
  244. log.debug('User %s does not exist, time to insert them' % user.username)
  245. exist = False
  246. except ldap.LDAPError, e:
  247. log.error('Got error from LDAP library: %s' % str(e))
  248. return False
  249. if exist:
  250. log.debug('User %s already exists, migrating to %s' % (user.username, uri) )
  251. #if they exist, we should be adding the group membership
  252. try:
  253. r = self._migrateUser(conn, block, user, uri)
  254. except:
  255. log.debug(sys.exc_info()[0])
  256. return r
  257. #with this, since user creates are handled by the UserManage module, we can be pretty safe we are adding a new user, not overiding one.
  258. #we need to iterate over all our user values.
  259. stack = []
  260. #for oc in block['objectClass']:
  261. stack.append( ('objectClass', block['objectClass'] ) )
  262. #add some defaults to our stack
  263. password= user.password
  264. user.password = self._makeSecret(password)
  265. stack.append( ('userPassword' , user.password) )
  266. for attr in block['all_attr']:
  267. #we need a way to skip some attributes like username and password etc.
  268. stack.append( (block[attr] , str(getattr(user, attr)) ), )
  269. #now we push out our user, and hope nothing bad happens .....
  270. try:
  271. log.debug(stack)
  272. conn.add_s('uid=%s,%s' % (user.username, block['userdn']) , stack)
  273. log.debug('Succesfully created user %s' % user.username)
  274. except ldap.LDAPError, e:
  275. log.error('Error attempting to create user %s to %s' % (user.username, uri))
  276. #now we want to call our actually user password change method so the new user can *actually* bind and atuhenticate
  277. #we also want to make our userpassword ! to force validation against the LDAP
  278. self.adminChangePasswd(user, password)
  279. user.set_unusable_password()
  280. #we also need to add groups from the user_is active etc
  281. r = self._modifyUserGroup(conn, user, block)
  282. if r == False:
  283. #shit has gone down, fix it in our create
  284. conn.delete_s('uid=%s,%s' % (user.username, block['userdn']) )
  285. return True
  286.  
  287. def _getUserByName(self, username, user, conn, block):
  288. log.debug('LDAPBackend._getUserByName(%s,%s,%s,%s)' % (username,user,conn,block))
  289. #CHANGE HERE FOR INETORG
  290. try:
  291. r = conn.search_s('uid=%s,%s' % (username, block['userdn']), ldap.SCOPE_SUBTREE,
  292. '(objectclass=*)', [block['email'], block['first_name'], block['last_name']])
  293. except ldap.NO_SUCH_OBJECT, e:
  294. log.warning('Could not get user information for %s, LDAP user does not exist returning possibly stale user object' % username)
  295. return user
  296. except ldap.LDAPError, e:
  297. log.error('Got error from LDAP library, returning our user: %s' % str(e))
  298. return user
  299. #log.debug('Got back results %s' % r)
  300. results = r[0][1]
  301. ldap_data = {}
  302. if block['email'] is not None:
  303. ldap_data['email'] = results[block['email']][0] if block['email'] in results else ''
  304. if block['first_name'] is not None:
  305. ldap_data['first_name'] = results[block['first_name']][0] if block['first_name'] in results else ''
  306. if block['last_name'] is not None:
  307. ldap_data['last_name'] = results[block['last_name']][0] if block['last_name'] in results else ''
  308. for g, attr in (('groupsu', 'is_superuser'), ('groupstaff', 'is_staff'), ('groupactive', 'is_active')):
  309. if block[g] is not None:
  310. ldap_data[attr] = False
  311. for group in block[g]:
  312. #these groups MUST exist, but if not we want to log this error.
  313. try:
  314. result = conn.search_s('cn=%s,%s' % (group, block['groupdn']), ldap.SCOPE_SUBTREE,
  315. '(objectclass=*)', ['memberuid'])
  316. except ldap.NO_SUCH_OBJECT:
  317. log.error('Group object %s does not exist %s!' % (group, str(e)) )
  318. continue
  319. if not result or 'memberUid' not in result[0][1]:
  320. continue
  321. log.debug(result)
  322. result = result[0][1]['memberUid']
  323. if 'uid=%s,%s' % (username, block['userdn']) in result:
  324. ldap_data[attr] = True
  325. #break
  326. log.debug(ldap_data)
  327. return ldap_data
  328.  
  329. def _makeSecret(self, password):
  330. log.debug('LDAPBackend._makeSecret(%s)' % password)
  331. salt = os.urandom(4)
  332. h = hashlib.sha1(password)
  333. h.update(salt)
  334. return "{SSHA}" + encode(h.digest() + salt)
  335.  
  336. def _migrateUser(self, conn, block, user, uri):
  337. log.debug('LDAPBackend._migrateUser(%s,%s,%s,%s)' % (conn,block,user,uri))
  338. #we know our user already exists, so we need to check they have a JW user attribute
  339. log.debug('Checking if %s has JW attrs' % user.username)
  340. try:
  341. result = conn.search_s('uid=%s,%s' % (str(user.username), block['userdn']), ldap.SCOPE_SUBTREE, '(objectclass=*)')
  342. except ldap.NO_SUCH_OBJECT:
  343. log.error('Could not find user object, this isnt correct, uid=%s,%s' % (user.username, block['userdn']) )
  344. return False
  345. stack = []
  346. if result:
  347. if 'jwUser' not in result[0][1]['objectClass']:
  348. #we should make it so that we delete the other object classes, then add them back with the jwUser, providded that they are compatible.
  349. log.error('Cannot add %s, this would create an object class violation!' % user.username)
  350. return False
  351. #technically this section should never be called, but it will be useful to 'resync' a broken user profile that lacks the attributes it needs.
  352. for oclass in block['objectClass']:
  353. if oclass not in result[0][1]['objectClass']:
  354. stack.append( (ldap.MOD_ADD, 'objectClass', str(oclass) ) )
  355. log.debug('User %s does not have %s objectClass, adding' % (str(user.username) , oclass))
  356. #check that we have all of our needed attributes. if not push them to the stack to be added
  357. for attr in block['all_attr']:
  358. if block[attr] not in result[0][1]:
  359. stack.append( (ldap.MOD_ADD, block[attr] , str(getattr(user, attr)) ) )
  360. Result = self._modifyUserGroup(conn, user, block)
  361. if Result:
  362. #since we don't depend on the user migrate working, we wait till we knows groups have worked, then we commit our user.
  363. try:
  364. conn.modify_s('uid=%s,%s' % (user.username, block['userdn']), stack)
  365. log.debug('%s migrated succesfully' % user.username)
  366. except ldap.LDAPError, e:
  367. log.error('%s at %s migrate command failed. %s %s' % (user.username, uri, stack, str(e) ) )
  368. return False
  369. return Result
  370.  
  371. def _modifyPasswd(self, user, oldpassword, newpassword):
  372. log.debug('LDAPBackend._modifyPassword(%s,%s,%s)' % (user, oldpassword, newpassword))
  373. blocks = self._buildBlocks()
  374. for block in blocks:
  375. for uri in block['url']:
  376. conn = self._buildConn(uri)
  377. try:
  378. conn.simple_bind_s('cn=%s,%s' % (block['bindname'], block['binddn']), block['bindpw'])
  379. conn.passwd_s('uid=%s,%s' % (user.username, block['userdn']), oldpassword, newpassword)
  380. except ldap.INVALID_CREDENTIALS:
  381. log.error('%s returned invalid admin credentials on attempt to change passwd by %s' % (uri,user.username))
  382. break
  383. except ldap.LDAPError, e:
  384. log.error('Got error from LDAP library: %s' % str(e))
  385. break
  386. try:
  387. conn.simple_bind_s('uid=%s,%s' % (user.username, block['userdn']), newpassword)
  388. log.debug('New password for %s authenticated succesfully' % user.username)
  389. except ldap.INVALID_CREDENTIALS:
  390. log.error('%s error binding as changed %s password - holy fucking shit something is bad!' % (uri, user.username))
  391. except ldap.LDAPError, e:
  392. log.error('Got error from LDAP library: %s' % str(e))
  393. conn.unbind()
  394.  
  395. def _modifyUser(self, conn, block, user, uri):
  396. log.debug('LDAPBackend._modifyUser(%s,%s,%s,%s)' % (conn,block,user,uri))
  397. log.debug('Choosing to modify user %s' % user.username)
  398. user_stack = []
  399. ldap_data = self._getUserByName(user.username, user, conn, block)
  400. #if we dont find our user, we get the original object back and no update will occur.
  401. #if we do, add our uri to the stack of servers to modify / add
  402. #we need to work out if it is a group change or a attr change, and act accordingly
  403. for attr in ldap_data:
  404. if attr != 'username' or attr != 'password': #this allows us to skip values that should be immutable
  405. if getattr(user, attr) != ldap_data[attr]:
  406. #push our changed attr to a stack, ready to be modified
  407. if not (ldap.MOD_ADD, block[attr], getattr(user, attr)) in user_stack or not (ldap.MOD_REPLACE, block[attr], getattr(user, attr)) in user_stack:
  408. #work out if its a replace or add operation (we can have many emails etc but likely not)
  409. if ldap_data[attr] == None:
  410. user_stack.append( (ldap.MOD_ADD, block[attr], getattr(user, attr)) )
  411. else:
  412. user_stack.append( (ldap.MOD_REPLACE, block[attr], getattr(user, attr)) )
  413. #once we know the changes, we save them to the ldap in a single hit.
  414. try:
  415. conn.modify_s('uid=%s,%s' % (user.username, block['userdn']), user_stack)
  416. log.debug('%s modified succesfully' % user.username)
  417. except ldap.LDAPError, e:
  418. log.error('%s at %s modify command failed. %s %s' % (user.username, uri, user_stack, str(e) ) )
  419. return False
  420. r = self._modifyUserGroup(conn, user, block)
  421. return r
  422. #we should consider checking that it worked .....
  423.  
  424. def _modifyUserGroup(self, conn, user, block):
  425. log.debug('LDAPBackend._modifyUserGroup(%s,%s,%s)' % (conn,user,block))
  426. #check that our membership exists
  427. try:
  428. member_stack = [ (ldap.MOD_ADD, 'memberUid', 'uid=%s,%s' % (str(user.username), block['userdn']) ) ]
  429. conn.modify_s('cn=%s,%s' % (block['group'][0], block['groupdn']), member_stack)
  430. except ldap.TYPE_OR_VALUE_EXISTS:
  431. log.error('%s already exists in %s' % (user.username, block['group']) )
  432. except ldap.LDAPError, e:
  433. #we hit an error, so we revent our change to the user, this one is the bad error to hit.
  434. log.error('Error adding %s to %s %s' % (user.username, block['group'], str(e) ) )
  435. return False
  436. for g, attr in (('groupsu', 'is_superuser'), ('groupstaff', 'is_staff'), ('groupactive', 'is_active')):
  437. if block[g] is not None:
  438. for group in block[g]:
  439. #now we check that our user, and add them to the group
  440. try:
  441. if getattr(user, attr) == True:
  442. mod_attrs = [ (ldap.MOD_ADD, 'memberUid', 'uid=%s,%s' % (str(user.username), block['userdn']) ) ]
  443. else:
  444. mod_attrs = [ (ldap.MOD_DELETE, 'memberUid', 'uid=%s,%s' % (str(user.username), block['userdn']) ) ]
  445. conn.modify_s('cn=%s,%s' % (group, block['groupdn']), mod_attrs)
  446. log.debug('Successfully modified %s with user %s' % (group, user.username) )
  447. except ldap.NO_SUCH_ATTRIBUTE:
  448. continue
  449. except ldap.TYPE_OR_VALUE_EXISTS:
  450. continue
  451. except ldap.LDAPError, e:
  452. log.error('Error adding %s to %s %s' % (user.username, group, str(e) ) )
  453. #we hit an error, but, in the schema of things a group error isnt to big of a deal and is easy to correct, and also extremely unlikely to occur.
  454. #in the majority of cases, this will only result in a user having no ablitiy to login, or permissions not granted, both of which are not bad situations
  455. return True
  456.  
  457. def _parse_simple_config(self):
  458. log.debug('LDAPBackend._parse_simple_config()')
  459. if len(settings.LDAP_AUTH_SETTINGS) < 2:
  460. raise LDAPBackendError('In a minimal configuration, you must at least specify url and user DN')
  461. ret = {'url': settings.LDAP_AUTH_SETTINGS[0], 'userdn': settings.LDAP_AUTH_SETTINGS[1]}
  462.  
  463. if len(settings.LDAP_AUTH_SETTINGS) < 3:
  464. return ret
  465.  
  466. if len(settings.LDAP_AUTH_SETTINGS) < 4:
  467. raise LDAPBackendError('If you specify a required group, you must specify the group DN as well')
  468. ret['group'] = settings.LDAP_AUTH_SETTINGS[2]
  469. ret['groupdn'] = settings.LDAP_AUTH_SETTINGS[3]
  470. return ret
  471.  
  472. def _return_user(self, username, conn, block):
  473. log.debug('LDAPBackend._return_user(%s,%s,%s)' % (username,conn,block))
  474. try:
  475. user = LDAP_User.objects.get(username=username)
  476. except User.DoesNotExist:
  477. log.info('User %s did not exist in Django database, creating' % username)
  478. user = LDAP_User(username=username, password='')
  479. user.set_unusable_password()
  480. user.save()
  481.  
  482. if block['disable_update']:
  483. return user
  484.  
  485. for p in ('first_name', 'last_name', 'email', 'groupsu', 'groupstaff', 'groupactive'):
  486. if block[p] is not None:
  487. break
  488. else:
  489. return user
  490. ldap_data = self._getUserByName(username, user, conn, block)
  491.  
  492. log.debug(ldap_data)
  493. for attr in ldap_data:
  494. if getattr(user, attr) != ldap_data[attr]:
  495. break
  496. else:
  497. return user
  498.  
  499. log.info('Data for user %s has changed, updating Django database' % username)
  500. log.debug('Setting attributes: %s' % str(ldap_data))
  501. for attr in ldap_data:
  502. setattr(user, attr, ldap_data[attr])
  503. #conviniently, this will pull our other servers into sync with the data our user has here.
  504. user.save()
  505. return user
  506.  
  507. #we define our custom error handlers.
  508. class Error(Exception):
  509. pass
  510.  
  511. class LDAPUserCreateError(Error):
  512. def __init__(self, expr, msg):
  513. self.msg = msg
  514.  
  515. class LDAP_User(User):
  516. class Meta:
  517. proxy = True
  518.  
  519. """
  520. Users within the Django authentication system are represented by this model.
  521.  
  522. Username and password are required. Other fields are optional.
  523. """
  524. #username = models.CharField(_('username'), max_length=30, unique=True, help_text=_("Required. 30 characters or fewer. Letters, numbers and @/./+/-/_ characters"))
  525. #first_name = models.CharField(_('first name'), max_length=30, blank=True)
  526. #last_name = models.CharField(_('last name'), max_length=30, blank=True)
  527. #email = models.EmailField(_('e-mail address'), blank=True)
  528. #always query password checks
  529. #password = models.CharField(_('password'), max_length=128, help_text=_("Use '[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change password form</a>."))
  530. #is_staff = models.BooleanField(_('staff status'), default=False, help_text=_("Designates whether the user can log into this admin site."))
  531. #is_active = models.BooleanField(_('active'), default=True, help_text=_("Designates whether this user should be treated as active. Unselect this instead of deleting accounts."))
  532. #is_superuser = models.BooleanField(_('superuser status'), default=False, help_text=_("Designates that this user has all permissions without explicitly assigning them."))
  533. #last_login = models.DateTimeField(_('last login'), default=datetime.datetime.now)
  534. #date_joined = models.DateTimeField(_('date joined'), default=datetime.datetime.now)
  535. #groups = models.ManyToManyField(Group, verbose_name=_('groups'), blank=True,
  536. # help_text=_("In addition to the permissions manually assigned, this user will also get all permissions granted to each group he/she is in."))
  537. #user_permissions = models.ManyToManyField(Permission, verbose_name=_('user permissions'), blank=True)
  538. #objects = UserManager()
  539.  
  540. #Always query for passwork checks
  541. #We want to cache user data, but on modify we want to force a reload, then modify the data, and update our cache
  542.  
  543.  
  544. def save(self,*args,**kwargs):
  545. log.debug('LDAP_User.save()' )
  546. try:
  547. sid = transaction.savepoint()
  548. super(User,self).save(*args,**kwargs)
  549. #save to ldap here
  550. ldapbackend = LDAPBackend()
  551. # we dont want to catch this raised exception, we want to use it to hook our roll back.
  552. ldapbackend.commitUser(self)
  553. del ldapbackend
  554. transaction.savepoint_commit(sid)
  555. except:
  556. log.debug('Error saving user: %s' % sys.exc_info()[0] )
  557. transaction.savepoint_rollback(sid)
  558.  
  559. def set_password(self, rawpassword):
  560. log,debug('LDAP_User.set_password(%s)' % rawpassword)
  561. ldapbackend = LDAPBackend()
  562. ldapbackend.changePasswd(self, rawpassword)
  563. #we should be checking if our user exists before saving, and set the unusable password anyway
  564. #since the user model already exists, it must have come out of the lday system, so we dont need to check.
  565. #we dont need to do a self.save() because it is not in the original models method, its also saved to ldap internal to the methods.
  566.  
  567. def check_password(self, rawpassword):
  568. log.debug('LDAP_User.check_password(%s)' % rawpassword)
  569. #return a boolean of true or false if we can bind.
  570. ldapbackend = LDAPBackend()
  571. return ldapbackend.checkPasswd(self.username, rawpassword)
  572. #do a bind operation
  573. # LDAP_AUTH_SETTINGS = ('ldap://10.0.44.2', 'cn=users,dc=example,dc=com')
  574. #
  575. # LDAP_AUTH_SETTINGS = ('ldap://10.0.44.2', 'cn=users,dc=example,dc=com', 'django_login',
  576. # 'cn=groups,dc=example,dc=com')
  577. #
  578. # LDAP_AUTH_SETTINGS = (('ldap://10.0.44.2', 'ldaps://10.0.44.200'), 'cn=users,dc=example,dc=com',
  579. # ('django_login', 'staff', 'web_users'), 'cn=groups,dc=example,dc=com')
  580. #
  581. # -*> means required
  582. # --> means optional
  583. # LDAP_AUTH_SETTINGS = (
  584. # {'url': ('ldap://10.0.44.2', 'ldaps://10.0.44.200'), -*> can be string or iterable of strings
  585. # 'userdn': 'cn=users,dc=example,dc=com', -*> ldap subtree in which users are stored
  586. # 'bindname': 'diradmin', --> admin name if users are not allowed to search
  587. # 'bindpw': 'supersecret', --> password for bindname
  588. # 'group': ('django_users', 'web_users', 'staff'), --> can be None, string, or iterable of group names
  589. # if set, user must be in one of these groups
  590. # also, must set groupdn
  591. # 'groupdn': 'cn=groups,dc=example,dc=com', --> ldap subtree in which groups are stored
  592. # 'groupsu': ('wheel', 'admin', 'django_superusers'), --> can be None, string or iterable of group names
  593. # if set, users in these groups will be Django
  594. # "superusers"
  595. # 'groupstaff': ('staff', 'django_staff'), --> can be None, string or iterable of group names
  596. # if set, users in these groups will be Django
  597. # "staff"
  598. # 'groupactive': 'active_users', --> can be None, string or iterable of group names
  599. # if set, users in these groups will be "active"
  600. # in Django
  601. # users not in any group will be "inactive" in
  602. # Django
  603. # 'replicas': False, --> If True, will stop querying this block's
  604. # servers on the first response, positive or
  605. # negative. If False, it will try to authenticate
  606. # against each server before moving onto the next
  607. # block
  608. # 'use_for_data': True, --> If True, the Django User object first_name,
  609. # last_name, and email fields will be taken from
  610. # LDAP. See *_field settings.
  611. # 'email': 'mail', --> The LDAP attribute of the person object that
  612. # holds the user's email address
  613. # 'first_name': 'givenName', --> The LDAP attribute of the person object that
  614. # holds the user's first name
  615. # 'last_name': 'sn' --> The LDAP attribute of the person object that
  616. # holds the user's last name
  617. # }
  618. # # Can repeat with totally different set of authentication servers/settings
  619. # # Useful for a situation where you have multiple masters with multiple replicas that are all possibly
  620. # # valid authentication points
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement