Add possibility to login via email address

Message ID 20171029120902.8677-1-jonatan.schlag@ipfire.org
State New
Headers show
Series
  • Add possibility to login via email address
Related show

Commit Message

Jonatan Schlag Oct. 29, 2017, 11:09 p.m. UTC
This patch to login via email address for normal users and for ldap
users. This is for ldap user also possible on the the first login.

Signed-off-by: Jonatan Schlag <jonatan.schlag@ipfire.org>
---
 src/buildservice/ldap.py  | 30 ++++++++++++++++++++++++++----
 src/buildservice/users.py | 19 ++++++++++++-------
 2 files changed, 38 insertions(+), 11 deletions(-)

Patch

diff --git a/src/buildservice/ldap.py b/src/buildservice/ldap.py
index 9f5019e..44f7c7c 100644
--- a/src/buildservice/ldap.py
+++ b/src/buildservice/ldap.py
@@ -34,9 +34,9 @@  class LDAP(base.Object):
 	def auth(self, username, password):
 		log.debug("Checking credentials for %s" % username)
 
-		dn = self.get_dn_by_uid(username)
+		dn = self.get_dn(username)
 		if not dn:
-			log.debug("Could not resolve username %s to dn" % username)
+			log.debug("Could not resolve  %s to dn" % username)
 			return False
 
 		return self.bind(dn, password)
@@ -61,9 +61,31 @@  class LDAP(base.Object):
 		log.debug("DN for uid %s is: %s" % (uid, dn))
 		return dn
 
-	def get_user(self, uid, **kwargs):
+	def get_dn_by_mail(self, mail):
+		result = self.search("(&(objectClass=posixAccount)(mail=%s))" % mail, limit=1, attrlist=["uid"])
+
+		for dn, attrs in result:
+			return dn
+
+		log.debug("DN for mail %s is: %s" % (mail, dn))
+		return None
+
+	def get_dn(self, name):
+		return self.get_dn_by_uid(name) or self.get_dn_by_mail(name)
+
+	def get_user_by_mail(self, mail, **kwargs):
+		result = self.search("(&(objectClass=posixAccount)(mail=%s))" % mail, limit=1, **kwargs)
+		for dn, attrs in result:
+			return (dn, attrs)
+
+		return None
+
+	def get_user_by_dn(self, uid, **kwargs):
 		result = self.search("(&(objectClass=posixAccount)(uid=%s))" % uid, limit=1, **kwargs)
 		for dn, attrs in result:
 			return (dn, attrs)
 
-		return (None, None)
\ No newline at end of file
+		return None
+
+	def get_user(self, name, **kwargs):
+		return self.get_user_by_dn(name, **kwargs) or self.get_user_by_mail(name, **kwargs)
diff --git a/src/buildservice/users.py b/src/buildservice/users.py
index 8d731d8..005a2e0 100644
--- a/src/buildservice/users.py
+++ b/src/buildservice/users.py
@@ -150,20 +150,21 @@  class Users(base.Object):
 		if None in (name, password):
 			return
 
-		# Search for the username in the database.
-		# The user must not be deleted and must be activated.
-		user = self._get_user("SELECT * FROM users WHERE name = %s AND \
-			activated IS TRUE AND deleted IS FALSE", name)
+		# usually we will get an email address as name
+		user = self.get_by_email(name) or self.get_by_name(name)
 
-		# If no user could be found, we search for a matching user in
-		# the LDAP database
 		if not user:
+			# If no user could be found, we search for a matching user in
+			# the LDAP database
 			if not self.ldap.auth(name, password):
 				return
 
 			# If a LDAP user is found (and password matches), we will
 			# create a new local user with the information from LDAP.
-			user = self.register_from_ldap(name)
+			user = self.create_from_ldap(name)
+
+		if not user.activated or user.deleted:
+			return
 
 		# Check if the password matches
 		if user.check_password(password):
@@ -416,6 +417,10 @@  class User(base.DataObject):
 		return self.data.activated
 
 	@property
+	def deleted(self):
+		return self.data.deleted
+
+	@property
 	def registered(self):
 		return self.data.registered