From 17d8fd8b7c16ed4410385b10e342a5f08468732e Mon Sep 17 00:00:00 2001
From: srosse <none@none>
Date: Wed, 19 Jul 2017 11:06:51 +0200
Subject: [PATCH] OO-2899: allow webdav login with email

---
 .../admin/user/imp/TransientIdentity.java     |   5 +
 .../olat/admin/user/imp/UpdateIdentity.java   |   5 +
 .../org/olat/basesecurity/BaseSecurity.java   |   5 +
 .../basesecurity/BaseSecurityManager.java     |  26 +++
 .../webdav/manager/WebDAVAuthManager.java     | 197 ++++++++++++------
 src/main/java/org/olat/core/id/User.java      |   2 +
 .../olat/core/util/mail/ui/EMailIdentity.java |   5 +
 .../course/run/preview/PreviewIdentity.java   |   5 +
 .../org/olat/login/auth/OLATAuthManager.java  |   4 +-
 src/main/java/org/olat/user/UserImpl.java     |  11 +
 .../olat/user/WebDAVPasswordController.java   |  11 +-
 11 files changed, 212 insertions(+), 64 deletions(-)

diff --git a/src/main/java/org/olat/admin/user/imp/TransientIdentity.java b/src/main/java/org/olat/admin/user/imp/TransientIdentity.java
index fad7b247052..c10747776e9 100644
--- a/src/main/java/org/olat/admin/user/imp/TransientIdentity.java
+++ b/src/main/java/org/olat/admin/user/imp/TransientIdentity.java
@@ -85,6 +85,11 @@ public class TransientIdentity implements Identity, User {
 		return properties.get(UserConstants.EMAIL);
 	}
 
+	@Override
+	public String getInstitutionalEmail() {
+		return properties.get(UserConstants.INSTITUTIONALEMAIL);
+	}
+
 	public String getPassword() {
 		return password;
 	}
diff --git a/src/main/java/org/olat/admin/user/imp/UpdateIdentity.java b/src/main/java/org/olat/admin/user/imp/UpdateIdentity.java
index 60b9c43c0fc..bcfaf150e09 100644
--- a/src/main/java/org/olat/admin/user/imp/UpdateIdentity.java
+++ b/src/main/java/org/olat/admin/user/imp/UpdateIdentity.java
@@ -168,6 +168,11 @@ public class UpdateIdentity implements Identity {
 			return updatedProperties.get(UserConstants.EMAIL);
 		}
 
+		@Override
+		public String getInstitutionalEmail() {
+			return updatedProperties.get(UserConstants.INSTITUTIONALEMAIL);
+		}
+
 		@Override
 		public Date getCreationDate() {
 			return user.getCreationDate();
diff --git a/src/main/java/org/olat/basesecurity/BaseSecurity.java b/src/main/java/org/olat/basesecurity/BaseSecurity.java
index c2445becd78..e37f2d1bc73 100644
--- a/src/main/java/org/olat/basesecurity/BaseSecurity.java
+++ b/src/main/java/org/olat/basesecurity/BaseSecurity.java
@@ -367,6 +367,8 @@ public interface BaseSecurity {
 	 */
 	public Authentication findAuthentication(IdentityRef identity, String provider);
 	
+	public List<Authentication> findAuthentications(IdentityRef identity, List<String> providers);
+	
 	public String findAuthenticationName(IdentityRef identity, String provider);
 	
 	
@@ -526,6 +528,9 @@ public interface BaseSecurity {
 	 *         found
 	 */
 	public Authentication findAuthenticationByAuthusername(String authusername, String provider);
+	
+
+	public List<Authentication> findAuthenticationByAuthusername(String authusername, List<String> providers);
 
 
 	/**
diff --git a/src/main/java/org/olat/basesecurity/BaseSecurityManager.java b/src/main/java/org/olat/basesecurity/BaseSecurityManager.java
index d71ffa54508..8cd688ad74d 100644
--- a/src/main/java/org/olat/basesecurity/BaseSecurityManager.java
+++ b/src/main/java/org/olat/basesecurity/BaseSecurityManager.java
@@ -1,4 +1,5 @@
 /**
+
 * OLAT - Online Learning and Training<br>
 * http://www.olat.org
 * <p>
@@ -1384,6 +1385,18 @@ public class BaseSecurityManager implements BaseSecurity {
 		return results.get(0);
 	}
 	
+	@Override
+	public List<Authentication> findAuthentications(IdentityRef identity, List<String> providers) {
+		StringBuilder sb = new StringBuilder();
+		sb.append("select auth from ").append(AuthenticationImpl.class.getName())
+		  .append(" as auth where auth.identity.key=:identityKey and auth.provider in (:providers)");
+		return dbInstance.getCurrentEntityManager()
+				.createQuery(sb.toString(), Authentication.class)
+				.setParameter("identityKey", identity.getKey())
+				.setParameter("providers", providers)
+				.getResultList();
+	}
+
 	@Override
 	public String findAuthenticationName(IdentityRef identity, String provider) {
 		if (identity==null) {
@@ -1518,6 +1531,19 @@ public class BaseSecurityManager implements BaseSecurity {
 		}
 		return results.get(0);
 	}
+	
+	@Override
+	public List<Authentication> findAuthenticationByAuthusername(String authusername, List<String> providers) {
+		StringBuilder sb = new StringBuilder();
+		sb.append("select auth from ").append(AuthenticationImpl.class.getName()).append(" as auth")
+		  .append(" inner join fetch auth.identity ident")
+		  .append(" where auth.provider in (:providers) and auth.authusername=:authusername");
+		return dbInstance.getCurrentEntityManager()
+				.createQuery(sb.toString(), Authentication.class)
+				.setParameter("providers", providers)
+				.setParameter("authusername", authusername)
+				.getResultList();
+	}
 
 	/**
 	 * @see org.olat.basesecurity.Manager#getVisibleIdentitiesByPowerSearch(java.lang.String, java.util.Map, boolean, org.olat.basesecurity.SecurityGroup[], org.olat.basesecurity.PermissionOnResourceable[], java.lang.String[], java.util.Date, java.util.Date)
diff --git a/src/main/java/org/olat/core/commons/services/webdav/manager/WebDAVAuthManager.java b/src/main/java/org/olat/core/commons/services/webdav/manager/WebDAVAuthManager.java
index ec28f37f574..589bb4e4844 100644
--- a/src/main/java/org/olat/core/commons/services/webdav/manager/WebDAVAuthManager.java
+++ b/src/main/java/org/olat/core/commons/services/webdav/manager/WebDAVAuthManager.java
@@ -20,6 +20,9 @@
 
 package org.olat.core.commons.services.webdav.manager;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import org.olat.basesecurity.Authentication;
 import org.olat.basesecurity.BaseSecurity;
 import org.olat.core.commons.services.webdav.WebDAVModule;
@@ -49,7 +52,11 @@ import org.springframework.stereotype.Service;
 public class WebDAVAuthManager implements AuthenticationSPI {
 	
 	public static final String PROVIDER_WEBDAV = "WEBDAV";
+	public static final String PROVIDER_WEBDAV_EMAIL = "WEBDAV-E";
+	public static final String PROVIDER_WEBDAV_INSTITUTIONAL_EMAIL = "WEBDAV-I";
 	public static final String PROVIDER_HA1 = "HA1";
+	public static final String PROVIDER_HA1_EMAIL = "HA1-E";
+	public static final String PROVIDER_HA1_INSTITUTIONAL_EMAIL = "HA1-I";
 	
 	private static final OLog log = Tracing.createLoggerFor(WebDAVAuthManager.class);
 
@@ -65,25 +72,31 @@ public class WebDAVAuthManager implements AuthenticationSPI {
 	public Identity digestAuthentication(String httpMethod, DigestAuthentication digestAuth) {
 		String username = digestAuth.getUsername();
 		
-		Authentication olatAuth = securityManager.findAuthenticationByAuthusername(username, WebDAVAuthManager.PROVIDER_HA1);
-		if(olatAuth != null) {
-			if("auth".equals(digestAuth.getQop())) {
-				String nonce = digestAuth.getNonce();
-				String response = digestAuth.getResponse();
-
-				String ha1 = olatAuth.getCredential();
-				
-				String a2 = httpMethod + ":" + digestAuth.getUri();
-				String ha2 = Encoder.md5hash(a2);
-				
-				String ver = ha1 + ":" + nonce + ":" + digestAuth.getNc() + ":" + digestAuth.getCnonce() + ":" + digestAuth.getQop() + ":" + ha2;
-				String verity = Encoder.md5hash(ver);
-				if(verity.equals(response)) {
-					Identity identity = olatAuth.getIdentity();
-					return identity;
-				} else if(log.isDebug()) {
-					// don't log as error, happens all the time with certain clients, e.g. Microsoft-WebDAV-MiniRedir
-					log.debug("Verity::" + verity + " doesn't equals response::" + response);
+		List<String> providers = new ArrayList<>(3);
+		providers.add(PROVIDER_HA1);
+		providers.add(PROVIDER_HA1_EMAIL);
+		providers.add(PROVIDER_HA1_INSTITUTIONAL_EMAIL);
+		
+		List<Authentication> authentications = securityManager.findAuthenticationByAuthusername(username, providers);
+		if(authentications != null && authentications.size() > 0) {
+			for(Authentication authentication:authentications) {
+				if("auth".equals(digestAuth.getQop())) {
+					String nonce = digestAuth.getNonce();
+					String response = digestAuth.getResponse();
+	
+					String ha1 = authentication.getCredential();
+					
+					String a2 = httpMethod + ":" + digestAuth.getUri();
+					String ha2 = Encoder.md5hash(a2);
+					
+					String ver = ha1 + ":" + nonce + ":" + digestAuth.getNc() + ":" + digestAuth.getCnonce() + ":" + digestAuth.getQop() + ":" + ha2;
+					String verity = Encoder.md5hash(ver);
+					if(verity.equals(response)) {
+						return authentication.getIdentity();
+					} else if(log.isDebug()) {
+						// don't log as error, happens all the time with certain clients, e.g. Microsoft-WebDAV-MiniRedir
+						log.debug("Verity::" + verity + " doesn't equals response::" + response);
+					}
 				}
 			}
 		}
@@ -92,30 +105,37 @@ public class WebDAVAuthManager implements AuthenticationSPI {
 
 	@Override
 	public Identity authenticate(Identity identity, String login, String password) {
-		Authentication authentication = null;
+		List<String> providers = new ArrayList<>(3);
+		providers.add(PROVIDER_WEBDAV);
+		providers.add(PROVIDER_WEBDAV_EMAIL);
+		providers.add(PROVIDER_WEBDAV_INSTITUTIONAL_EMAIL);
+		
+		List<Authentication> authentications = null;
 		if (identity != null) {
-			authentication = securityManager.findAuthentication(identity, PROVIDER_WEBDAV);
+			authentications = securityManager.findAuthentications(identity, providers);
 		} else {
-			authentication = securityManager.findAuthenticationByAuthusername(login, PROVIDER_WEBDAV);
+			authentications = securityManager.findAuthenticationByAuthusername(login, providers);
 		}
 
-		if(authentication == null) {
+		if(authentications == null || authentications.isEmpty()) {
 			//fallback to standard OLAT authentication
 			return olatAuthenticationSpi.authenticate(identity, login, password);
 		}
 		
-		Identity authenticatedIdentity = authentication.getIdentity();
+		Identity authenticatedIdentity = authentications.get(0).getIdentity();
 		boolean visible = securityManager.isIdentityVisible(authenticatedIdentity);
 		if (!visible) {
 			return null;
 		}
 		
-		if (securityManager.checkCredentials(authentication, password))	{
-			Algorithm algorithm = Algorithm.find(authentication.getAlgorithm());
-			if(Algorithm.md5.equals(algorithm)) {
-				authentication = securityManager.updateCredentials(authentication, password, loginModule.getDefaultHashAlgorithm());
+		for(Authentication authentication:authentications) {
+			if (securityManager.checkCredentials(authentication, password))	{
+				Algorithm algorithm = Algorithm.find(authentication.getAlgorithm());
+				if(Algorithm.md5.equals(algorithm)) {
+					authentication = securityManager.updateCredentials(authentication, password, loginModule.getDefaultHashAlgorithm());
+				}
+				return authentication.getIdentity();
 			}
-			return authentication.getIdentity();
 		}
 		return null;
 	}
@@ -123,12 +143,8 @@ public class WebDAVAuthManager implements AuthenticationSPI {
 	@Override
 	public void upgradePassword(Identity identity, String login, String password) {
 		if(webDAVModule.isEnabled() && webDAVModule.isDigestAuthenticationEnabled()) {
-			Authentication digestAuth = securityManager.findAuthentication(identity, PROVIDER_HA1);
-			if(digestAuth == null) {
-				String digestToken = login + ":" + WebDAVManagerImpl.BASIC_AUTH_REALM + ":" + password;
-				Identity reloadedIdentity = securityManager.loadIdentityByKey(identity.getKey());
-				securityManager.createAndPersistAuthentication(reloadedIdentity, PROVIDER_HA1, login, digestToken, Encoder.Algorithm.md5_noSalt);
-			}
+			List<Authentication> digestAuths = securityManager.getAuthentications(identity);
+			updateDigestPasswords(identity, identity, password, digestAuths);
 		}
 	}
 
@@ -140,27 +156,51 @@ public class WebDAVAuthManager implements AuthenticationSPI {
 	 * @return True upon success.
 	 */
 	public boolean changePassword(Identity doer, Identity identity, String newPwd) {
-		if (doer==null) throw new AssertException("password changing identity cannot be undefined!");
-		if (identity == null || identity.getKey() == null)
+		if (doer==null) {
+			throw new AssertException("password changing identity cannot be undefined!");
+		}
+		if (identity == null || identity.getKey() == null) {
 			throw new AssertException("cannot change password on a nonpersisted identity");
+		}
 
 		//For Basic
-		Authentication auth = securityManager.findAuthentication(identity, PROVIDER_WEBDAV);
-		if (auth == null) { // create new authentication for provider OLAT
+		List<Authentication> auths = securityManager.getAuthentications(identity);
+		updateWebdavPassword(doer, identity, newPwd, auths);
+		//For Digest
+		changeDigestPassword(doer, identity,  newPwd);
+		return true;
+	}
+	
+	private void updateWebdavPassword(Identity doer, Identity identity, String password, List<Authentication> authentications) {
+		updateWebDAVPassword(doer, identity, identity.getName(), password, PROVIDER_WEBDAV, authentications);
+		if(identity.getUser().getEmail() != null) {
+			updateWebDAVPassword(doer, identity, identity.getUser().getEmail(), password, PROVIDER_WEBDAV_EMAIL, authentications);
+		}
+		if(identity.getUser().getInstitutionalEmail() != null) {
+			updateWebDAVPassword(doer, identity, identity.getUser().getEmail(), password, PROVIDER_WEBDAV_INSTITUTIONAL_EMAIL, authentications);
+		}
+
+		for(Authentication authentication:authentications) {
+			if(authentication.getProvider().startsWith(PROVIDER_WEBDAV)) {
+				securityManager.deleteAuthentication(authentication);
+			}
+		}
+	}
+	
+	private void updateWebDAVPassword(Identity doer, Identity identity, String authUsername, String password,
+			String provider, List<Authentication> authentications) {
+		Authentication authentication = getAndRemoveAuthentication(provider, authentications);
+		if (authentication == null) { // create new authentication for provider OLAT
 			Identity reloadedIdentity = securityManager.loadIdentityByKey(identity.getKey());
-			auth = securityManager.createAndPersistAuthentication(reloadedIdentity, PROVIDER_WEBDAV, identity.getName(), newPwd, loginModule.getDefaultHashAlgorithm());
-			log.audit(doer.getName() + " created new WebDAV authentication for identity: " + identity.getName());
+			securityManager.createAndPersistAuthentication(reloadedIdentity, provider, authUsername, password, loginModule.getDefaultHashAlgorithm());
+			log.audit(doer.getName() + " created new WebDAV authentication for identity: " + identity.getKey() + " (" + authUsername + ")");
 		} else {
-			auth = securityManager.updateCredentials(auth, newPwd, loginModule.getDefaultHashAlgorithm());
-			log.audit(doer.getName() + " set new WebDAV password for identity: " +identity.getName());
+			securityManager.updateCredentials(authentication, password, loginModule.getDefaultHashAlgorithm());
+			log.audit(doer.getName() + " set new WebDAV password for identity: " + identity.getKey() + " (" + authUsername + ")");
 		}
-
-		//For Digest
-		changeDigestPassword(doer, identity, identity.getName(), newPwd);
-		return true;
 	}
 	
-	public boolean changeDigestPassword(Identity doer, Identity identity, String username, String newPwd) {
+	public boolean changeDigestPassword(Identity doer, Identity identity, String newPwd) {
 		if (doer == null) {
 			throw new AssertException("password changing identity cannot be undefined!");
 		}
@@ -170,22 +210,57 @@ public class WebDAVAuthManager implements AuthenticationSPI {
 
 		//For Digest
 		if(webDAVModule.isDigestAuthenticationEnabled()) {
-			Authentication authHa1 = securityManager.findAuthentication(identity, PROVIDER_HA1);
-			String digestToken = username + ":" + WebDAVManagerImpl.BASIC_AUTH_REALM + ":" + newPwd;
+			List<Authentication> ha1Authentications = securityManager.getAuthentications(identity);
+			updateDigestPasswords(doer, identity, newPwd, ha1Authentications);
+		}
+		return true;
+	}
+	
+	private void updateDigestPasswords(Identity doer, Identity identity, String newPwd,
+			List<Authentication> authentications) {
+		updateDigestPassword(doer, identity, identity.getName(), newPwd, PROVIDER_HA1, authentications);
+		if(identity.getUser().getEmail() != null) {
+			updateDigestPassword(doer, identity, identity.getUser().getEmail(), newPwd, PROVIDER_HA1_EMAIL, authentications);
+		}
+		if(identity.getUser().getInstitutionalEmail() != null) {
+			updateDigestPassword(doer, identity, identity.getUser().getEmail(), newPwd, PROVIDER_HA1_INSTITUTIONAL_EMAIL, authentications);
+		}
+		
+		for(Authentication authentication:authentications) {
+			if(authentication.getProvider().startsWith(PROVIDER_HA1)) {
+				securityManager.deleteAuthentication(authentication);
+			}
+		}
+	}
+	
+	private void updateDigestPassword(Identity doer, Identity identity, String authUsername, String password,
+			String provider, List<Authentication> authentications) {
+		String digestToken = authUsername + ":" + WebDAVManagerImpl.BASIC_AUTH_REALM + ":" + password;
+		Authentication authHa1 = getAndRemoveAuthentication(provider, authentications);
+		if (authHa1 == null) { // create new authentication for provider OLAT
+			Identity reloadedIdentity = securityManager.loadIdentityByKey(identity.getKey());
+			securityManager.createAndPersistAuthentication(reloadedIdentity, provider, authUsername, digestToken, Encoder.Algorithm.md5_noSalt);
+			log.audit(doer.getName() + " created new WebDAV (HA1) authentication for identity: " + identity.getKey() + " (" + authUsername + ")");
+		} else {
 			String md5DigestToken = Encoder.encrypt(digestToken, null, Encoder.Algorithm.md5_noSalt);
-			
-			if (authHa1 == null) { // create new authentication for provider OLAT
-				Identity reloadedIdentity = securityManager.loadIdentityByKey(identity.getKey());
-				authHa1 = securityManager.createAndPersistAuthentication(reloadedIdentity, PROVIDER_HA1, username, digestToken, Encoder.Algorithm.md5_noSalt);
-				log.audit(doer.getName() + " created new WebDAV (HA1) authenticatin for identity: " + identity.getName());
-			} else if (username != null && (!username.equals(authHa1.getAuthusername()) || !md5DigestToken.equals(authHa1.getCredential()))) {
+			if (!md5DigestToken.equals(authHa1.getCredential()) || !authHa1.getAuthusername().equals(authUsername)) {
 				authHa1.setCredential(md5DigestToken);
-				authHa1.setAuthusername(username);
-				authHa1 = securityManager.updateAuthentication(authHa1);
-				log.audit(doer.getName() + " set new WebDAV (HA1) password for identity: " +identity.getName());
+				authHa1.setAuthusername(authUsername);
+				securityManager.updateAuthentication(authHa1);
+				log.audit(doer.getName() + " set new WebDAV (HA1) password for identity: " + identity.getKey() + " (" + authUsername + ")");
 			}
 		}
-		
-		return true;
+	}
+	
+	private Authentication getAndRemoveAuthentication(String provider, List<Authentication> authentications) {
+		if(authentications != null && authentications.size() > 0) {
+			for(Authentication authentication:authentications) {
+				if(provider.equals(authentication.getProvider())) {
+					authentications.remove(authentication);
+					return authentication;
+				}
+			}
+		}
+		return null;
 	}
 }
diff --git a/src/main/java/org/olat/core/id/User.java b/src/main/java/org/olat/core/id/User.java
index 6ae56a24694..a91134f158d 100644
--- a/src/main/java/org/olat/core/id/User.java
+++ b/src/main/java/org/olat/core/id/User.java
@@ -49,6 +49,8 @@ public interface User extends CreateInfo, Persistable {
 	public String getLastName();
 	
 	public String getEmail();
+	
+	public String getInstitutionalEmail();
 
 	/**
 	 * Get the users prefereces object
diff --git a/src/main/java/org/olat/core/util/mail/ui/EMailIdentity.java b/src/main/java/org/olat/core/util/mail/ui/EMailIdentity.java
index 031897abccb..655aef4d8a1 100644
--- a/src/main/java/org/olat/core/util/mail/ui/EMailIdentity.java
+++ b/src/main/java/org/olat/core/util/mail/ui/EMailIdentity.java
@@ -121,6 +121,11 @@ public class EMailIdentity implements Identity {
 			return data.get(UserConstants.EMAIL);
 		}
 
+		@Override
+		public String getInstitutionalEmail() {
+			return data.get(UserConstants.INSTITUTIONALEMAIL);
+		}
+
 		@Override
 		public Date getLastModified() {
 			return null;
diff --git a/src/main/java/org/olat/course/run/preview/PreviewIdentity.java b/src/main/java/org/olat/course/run/preview/PreviewIdentity.java
index 8ec50a0f737..f1053729bc1 100644
--- a/src/main/java/org/olat/course/run/preview/PreviewIdentity.java
+++ b/src/main/java/org/olat/course/run/preview/PreviewIdentity.java
@@ -85,6 +85,11 @@ public final class PreviewIdentity implements Identity, User {
 		return data.get(UserConstants.EMAIL);
 	}
 
+	@Override
+	public String getInstitutionalEmail() {
+		return data.get(UserConstants.INSTITUTIONALEMAIL);
+	}
+
 	@Override
 	public String getFirstName() {
 		return data.get(UserConstants.FIRSTNAME);
diff --git a/src/main/java/org/olat/login/auth/OLATAuthManager.java b/src/main/java/org/olat/login/auth/OLATAuthManager.java
index db0509ecbcf..bb6028877c8 100644
--- a/src/main/java/org/olat/login/auth/OLATAuthManager.java
+++ b/src/main/java/org/olat/login/auth/OLATAuthManager.java
@@ -269,7 +269,7 @@ public class OLATAuthManager extends BasicManager implements AuthenticationSPI {
 		}
 		
 		if(identity != null && StringHelper.containsNonWhitespace(username) && webDAVAuthManager != null) {
-			webDAVAuthManager.changeDigestPassword(doer, identity, username, newPwd);
+			webDAVAuthManager.changeDigestPassword(doer, identity, newPwd);
 		}
 		return true;
 	}
@@ -294,7 +294,7 @@ public class OLATAuthManager extends BasicManager implements AuthenticationSPI {
 		}
 		
 		if(identity != null && StringHelper.containsNonWhitespace(username) && webDAVAuthManager != null) {
-			webDAVAuthManager.changeDigestPassword(doer, identity, username, newPwd);
+			webDAVAuthManager.changeDigestPassword(doer, identity, newPwd);
 		}
 		return true;
 	}
diff --git a/src/main/java/org/olat/user/UserImpl.java b/src/main/java/org/olat/user/UserImpl.java
index 97bd673daf3..7b0fba26c4a 100644
--- a/src/main/java/org/olat/user/UserImpl.java
+++ b/src/main/java/org/olat/user/UserImpl.java
@@ -318,6 +318,7 @@ public class UserImpl implements Persistable, User {
 		this.firstName = firstName;
 	}
 
+	@Override
 	public String getLastName() {
 		return lastName;
 	}
@@ -326,6 +327,7 @@ public class UserImpl implements Persistable, User {
 		this.lastName = lastName;
 	}
 
+	@Override
 	public String getEmail() {
 		return email;
 	}
@@ -334,6 +336,15 @@ public class UserImpl implements Persistable, User {
 		this.email = email;
 	}
 	
+	@Override
+	public String getInstitutionalEmail() {
+		return institutionalEmail;
+	}
+	
+	public void setInstitutionalEmail(String institutionalEmail) {
+		this.institutionalEmail = institutionalEmail;
+	}
+	
 	public boolean isWebdav() {
 		return webdav;
 	}
diff --git a/src/main/java/org/olat/user/WebDAVPasswordController.java b/src/main/java/org/olat/user/WebDAVPasswordController.java
index 517e67822ee..0527c7a643d 100644
--- a/src/main/java/org/olat/user/WebDAVPasswordController.java
+++ b/src/main/java/org/olat/user/WebDAVPasswordController.java
@@ -87,7 +87,16 @@ public class WebDAVPasswordController extends FormBasicController {
 			
 			accessDataFlc = FormLayoutContainer.createDefaultFormLayout("flc_access_data", getTranslator());
 			layoutContainer.add(accessDataFlc);
-			uifactory.addStaticTextElement("pwdav.username", "pwdav.username", ureq.getIdentity().getName(), accessDataFlc);
+			
+			StringBuilder sb = new StringBuilder();
+			sb.append(getIdentity().getName());
+			if(StringHelper.containsNonWhitespace(getIdentity().getUser().getEmail())) {
+				sb.append(", ").append(getIdentity().getUser().getEmail());
+			}
+			if(StringHelper.containsNonWhitespace(getIdentity().getUser().getInstitutionalEmail())) {
+				sb.append(", ").append(getIdentity().getUser().getInstitutionalEmail());
+			}
+			uifactory.addStaticTextElement("pwdav.username", "pwdav.username", sb.toString(), accessDataFlc);
 
 			boolean hasOlatToken = false;
 			boolean hasWebDAVToken = false;
-- 
GitLab