summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNico von Geyso <Nico.Geyso@FU-Berlin.de>2012-09-17 11:06:08 +0200
committerNico von Geyso <Nico.Geyso@FU-Berlin.de>2012-09-17 11:06:08 +0200
commit8d7faa398ff2cec41001e7c3cc069ced8deb1d8a (patch)
treea60af77543266ef65534955192bdbbb2a535f83a
parentd7e62d1166991c0c4c9fa1385ead2bd2058b5b86 (diff)
downloadweb-8d7faa398ff2cec41001e7c3cc069ced8deb1d8a.tar.gz
web-8d7faa398ff2cec41001e7c3cc069ced8deb1d8a.tar.bz2
web-8d7faa398ff2cec41001e7c3cc069ced8deb1d8a.zip
added basic account service functionality
To auth, register, update or delete an account you have to use the AccountService class. A basic usage could be the following: # Simple auth service = AccountService(LDAP_HOST, LDAP_BASE_DN, LDAP_ADMIN_USER, LDAP_ADMIN_PASS) acc = service.auth('test', 'secret') # Authenticate against some credentials print('Mail: %s' % acc.mail) # Account creation, updating and deletion a = Account('foo', 'foo@bar.de', password='foobar') service.register(a) # create a.mail = 'bar@foo.de' service.update(a) # update service.delete(a.uid) # deletete
-rw-r--r--account.py227
1 files changed, 148 insertions, 79 deletions
diff --git a/account.py b/account.py
index 76e3bf8..46356d5 100644
--- a/account.py
+++ b/account.py
@@ -1,84 +1,153 @@
# -*- coding: utf-8 -*-
import ldap
-import sys
-#LDAP_HOST = 'ldaps://bernd:6336'
-LDAP_HOST = 'ldap://bernd:3889'
-LDAP_BASE_DN = 'dc=nodomain'
-USER = 'cn=admin,dc=nodomain'
-PASS = 'blubb'
-
-class Account(object):
- def __init__(self, ldap_host, base_dn, user, password):
-
- self.con = ldap.initialize(ldap_host)
-
- self.base_dn = base_dn
-
- self.con.version = ldap.VERSION3
- self.con.start_tls_s()
-
- self.con.simple_bind(user, password)
-
-
- def list(self, *args, **kwargs):
- return self.con.search_s(
- self.base_dn, ldap.SCOPE_SUBTREE, *args, **kwargs
- )
-
-
- def register(self, name, attr):
- dn = 'uid=%s,%s' % (name, self.base_dn)
- try:
- self.con.add_s(dn, attr)
- except:
- return False
-
- return True
-
-
- def modify(self, name, attr):
- try:
- dn = self.find(name)[0]
- self.con.modify_s(dn, attr)
- except:
- return False
-
- return True
-
-
- def find(self, name, *args, **kwargs):
- try:
- dn = 'uid=%s,%s' % (name, self.base_dn)
- return self.con.search_s(
- dn, ldap.SCOPE_SUBTREE, *args, **kwargs
- )[0]
- except:
- pass
-
- return None
-
-
-
- def delete(self, name):
- try:
- dn = self.find(name)[0]
- self.con.delete_s(dn)
- except:
- return False
- return True
-
-
-a = Account(LDAP_HOST, LDAP_BASE_DN, USER, PASS)
-#print(a.register('test6',
-# [('objectClass', 'account'),('uid','test6')]
-#))
-#print(a.list())
-#a.delete('test3')
-#print(a.find('test3'))
-#print(a.list())
-#print("--")
-a.modify('test2', [(ldap.MOD_ADD, 'description','ldap ist_scheisse')])
-print(a.list())
+LDAP_HOST = 'ldap://localhost'
+LDAP_BASE_DN = 'dc=nodomain,dc=local'
+LDAP_ADMIN_USER = 'root'
+LDAP_ADMIN_PASS = 'root'
+
+
+
+class AccountService:
+ """
+ To simplify account management through ldap this class can be used.
+ """
+ def __init__(self, ldap_host, base_dn, admin_user, admin_pass):
+ self.ldap_host = ldap_host
+ self.base_dn = base_dn
+ self.admin_cn = 'cn=%s,%s' % (admin_user, self.base_dn)
+ self.admin_pass = admin_pass
+ self.binded = False
+
+ self.connection = ldap.initialize(ldap_host)
+ self.connection.version = ldap.VERSION3
+
+
+ def auth(self, username, password):
+ """
+ Tries to authenticate a user with a given password. If the
+ authentication is successful an Account object will be returned.
+ """
+ dn = 'uid=%s,%s' % (username, self.base_dn)
+ self._bind(dn, password)
+ dn, data = self.connection.search_s(dn, ldap.SCOPE_BASE)[0]
+ acc = Account(dn, data['cn'][0], data['sn'][0])
+ self._unbind()
+ return acc
+
+
+ def register(self, account):
+ """
+ Persists an account in the ldap backend
+ """
+ self._bind(self.admin_cn, self.admin_pass)
+ dn = 'uid=%s,%s' % (account.uid, self.base_dn)
+ self.connection.add_s(dn, account.to_ldif())
+ account.dn = dn
+ self._alter_passwords(account)
+ self._unbind()
+
+
+ def update(self, account):
+ """
+ Updates account informations like passwords or email.
+ """
+ self._bind(self.admin_cn, self.admin_pass)
+ attr = [(ldap.MOD_REPLACE, 'mail', account.mail)]
+ dn = 'uid=%s,%s' % (account.uid, self.base_dn)
+ self.connection.modify_s(dn, attr)
+ self._alter_passwords(account)
+ self._unbind()
+
+
+ def delete(self, uid):
+ """
+ Deletes an account permanently.
+ """
+ self._bind(self.admin_cn, self.admin_pass)
+ dn = 'uid=%s,%s' % (uid, self.base_dn)
+ self.connection.delete_s(dn)
+ self._unbind()
+
+
+ def _bind(self, dn, password):
+ if not self.binded:
+ self.connection.simple_bind_s(dn, password)
+ self.binded = True
+
+
+ def _unbind(self):
+ if self.binded:
+ self.connection.unbind_s()
+ self.binded = False
+
+
+ def _alter_passwords(self, account):
+ if self.binded and 'root' in account.passwords:
+ attr = [
+ (ldap.MOD_REPLACE, 'userPassword', account.passwords['root'])
+ ]
+ dn = 'uid=%s,%s' % (account.uid, self.base_dn)
+ self.connection.modify_s(dn, attr)
+
+
+
+class Account:
+ """
+ An Account represents a complex ldap tree entry for spline users.
+ For each service a spline user can have a different password.
+ """
+ def __init__(self, uid, mail, services = [], dn = None, password = None):
+ self.uid = uid
+ self.mail = mail
+ self.services = services
+ self.dn = dn
+ self.passwords = {}
+
+ if password:
+ self.change_password(password)
+
+
+ def __str__(self):
+ return "Account(uid=%s)" % self.uid
+
+
+ def change_password(self, new_password, service = None):
+ """
+ Changes a password for a given service. You have to use the Ldap class
+ to make the changes permanent. If no service is given, the root
+ password will be changed.
+ """
+ if not service:
+ service = 'root'
+
+ self.passwords[service] = new_password
+
+
+ def change_email(self, new_mail):
+ """
+ Changes the mail address of an account. You have to use the Ldap class
+ to make changes permanent.
+ """
+ self.mail = new_mail
+
+
+ def to_ldif(self):
+ """
+ Returns basic account data as a list of tuples (ldif format)
+ """
+ return [
+ ('objectClass', ['top','inetOrgPerson']), ('uid',self.uid),
+ ('sn', self.uid), ('cn', self.uid), ('mail', self.mail)
+ ]
+
+
+service = AccountService(LDAP_HOST, LDAP_BASE_DN, LDAP_ADMIN_USER, LDAP_ADMIN_PASS)
+#print(service.auth('testaccountt6', 'secret'))
+#service.delete('testaccountt5')
+#a = Account('testaccountt6', 'test@test.de', password='secret')
+a = Account('testaccount4', 'mail@mail.de', password='secret')
+service.update(a)
+#print(service.register(a))