def verify(request): # Connect to LDAP try: conn = ldap.initialize(Config.ldap_uri) conn.bind_s(Config.ldap_bind_dn, Config.ldap_bind_password) except Exception as e: return request.response_json({'success': False, 'msg': "Can't bind to LDAP: %s" % e.message['desc']}) # # Grab the entryUUID for the newly created object, this is the unique identifier for account email verification # res = conn.search_s(Config.ldap_base_dn, ldap.SCOPE_SUBTREE, '(&(entryUUID=%s)(uid=%s))' % (escape_filter(request.post['entryUUID'][0]), escape_filter(request.post['username'][0]))) if len(res) != 1: return request.response_json({'success': False, 'errors': { 'entryUUID': 'Cannot find this UUID with this username'}}) dn = res[0][0] ldif = [( ldap.MOD_REPLACE, 'accountStatus', '2' )] try: conn.modify_s(dn, ldif) except Exception as e: return request.response_json({'success': False, 'msg': "Can't modify account: %s" % e.message['desc']}) return request.response_json({'success': True, 'msg': 'Your account is activated' })
def users(request): # Connect to LDAP try: conn = ldap.initialize(Config.ldap_uri) conn.bind_s(Config.ldap_bind_dn, Config.ldap_bind_password) except Exception as e: return request.response_json({'success': False, 'msg': "Can't bind to LDAP: %s" % e.message['desc']}) if request.method == "GET": # GET requests a user tree, but only one level deep # Determine the DN for the current depth dn_prepend = "" for url_part in request.url_parts[-1:0:-1]: dn_prepend += "ou=%s," % escape_dn(url_part) search_dn = "%s%s" % (dn_prepend, Config.ldap_base_dn) # Perform LDAP search try: res = conn.search_s(search_dn, ldap.SCOPE_ONELEVEL, "(|(objectclass=sambaSamAccount)(objectClass=organizationalUnit))", attrlist=[ '*', 'entryUUID' ]) except Exception as e: return request.response_json({'success': False, 'msg': 'Search failed: %s' % e.message['desc']}, status='404 Not Found') # Determine the depth for the search dn, needed for reference when building the tree # This also works with DNs with escaped characters mysplit = shlex.shlex(search_dn, posix=True) mysplit.escape = '\\' mysplit.quotes = '' mysplit.whitespace = ',' mysplit.whitespace_split = True search_dn_length = len(list(mysplit)) # Build an attribute tree tree = {} for dn, attrs in res: mysplit = shlex.shlex(dn, posix=True) mysplit.escape = '\\' mysplit.quotes = '' mysplit.whitespace = ',' mysplit.whitespace_split = True add_to_indexed_tree(tree, list(mysplit)[-search_dn_length-1::-1], dn, attrs) # Parse the attribute tree to convert it to something ExtJS can parse output_tree = parse_subtree({'children': tree }, "root") return request.response_json({'success': True, 'data': output_tree['children'] }) else: if request.method == 'PUT': try: existing_attrs = conn.search_s(Config.ldap_base_dn, ldap.SCOPE_SUBTREE, "(entryUUID=%s)" % escape_filter(request.url_parts[0])) except: return request.response_json({'success': False, 'message': 'Failed to locate object in LDAP directory'}) # TODO: Handle 'sambaAcctFlags': '[U ]', (samba Disabled, workstation, user, etc) # TODO: Handle password changes attrs = {} if 'first' in request.put: attrs['givenName'] = request.put['first'] if 'last' in request.put: attrs['sn'] = request.put['last'] if 'first' in request.put and 'last' in request.put: attrs['cn'] = "%s %s" % (request.put['first'], request.put['last']) attrs['displayName'] = attrs['cn'] attrs['description'] = attrs['cn'] attrs['gecos'] = "%s %s,,," % (request.put['first'], request.put['last']) request.put['displayname'] = attrs['cn'] if 'email' in request.put: attrs['mail'] = request.put['email'] if 'uidNumber' in request.put: attrs['uidNumber'] = request.put['uidNumber'] if 'gidNumber' in request.put: attrs['gidNumber'] = request.put['gidNumber'] if 'sambaSID' in request.put: attrs['sambaSID'] = request.put['sambaSID'] if 'homeDirectory' in request.put: attrs['homeDirectory'] = request.put['homeDirectory'] if 'loginShell' in request.put: attrs['loginShell'] = request.put['loginShell'] if 'accountStatus' in request.put: attrs['accountStatus'] = request.put['accountStatus'] ldif = modlist.modifyModlist(existing_attrs[0][1], attrs, ignore_oldexistent=True) if len(ldif): conn.modify_s(existing_attrs[0][0], ldif) if 'username' in request.put and existing_attrs[0][1]['uid'][0] != request.put['username'].lower(): conn.rename_s(existing_attrs[0][0], "uid=%s" % escape_dn(request.put['username'].lower())) return request.response_json({'success': True, 'message': "User info has been saved.", 'data': request.put }) else: return request.response_json({'success': False, 'msg': 'Feature not implemented', 'more': request.url_parts})