diff --git a/src/main/java/de/bps/course/nodes/vc/provider/adobe/AdobeConnectProvider.java b/src/main/java/de/bps/course/nodes/vc/provider/adobe/AdobeConnectProvider.java index e0441173a2094ce992edca0148bd28fa4210d9ac..0d9f6e37466707670dfdaf22b55decfc52175f49 100644 --- a/src/main/java/de/bps/course/nodes/vc/provider/adobe/AdobeConnectProvider.java +++ b/src/main/java/de/bps/course/nodes/vc/provider/adobe/AdobeConnectProvider.java @@ -373,7 +373,7 @@ public class AdobeConnectProvider extends LogDelegator implements VCProvider { parameters.put("first-name", identity.getUser().getProperty(UserConstants.FIRSTNAME, null)); parameters.put("last-name", identity.getUser().getProperty(UserConstants.LASTNAME, null)); parameters.put("login", PREFIX + identity.getName()); - parameters.put("password", Encoder.encrypt(identity.getName() + "@" + Settings.getApplicationName())); + parameters.put("password", Encoder.md5hash(identity.getName() + "@" + Settings.getApplicationName())); parameters.put("type", userType); parameters.put("has-children", "false"); Document responseDoc = getResponseDocument(sendRequest(parameters)); @@ -453,7 +453,7 @@ public class AdobeConnectProvider extends LogDelegator implements VCProvider { parameters.put("action", "login"); if(accountId != null) parameters.put("account-id", accountId); parameters.put("login", PREFIX + identity.getName()); - parameters.put("password", Encoder.encrypt(identity.getName() + "@" + Settings.getApplicationName())); + parameters.put("password", Encoder.md5hash(identity.getName() + "@" + Settings.getApplicationName())); Document responseDoc = getResponseDocument(sendRequest(parameters)); return evaluateOk(responseDoc); diff --git a/src/main/java/de/bps/course/nodes/vc/provider/wimba/WimbaClassroomProvider.java b/src/main/java/de/bps/course/nodes/vc/provider/wimba/WimbaClassroomProvider.java index 876ffc61eae374516405dfab0f41c0ad1133d255..2a15adad9256647e358d8e8e61cc9c3b59f80623 100644 --- a/src/main/java/de/bps/course/nodes/vc/provider/wimba/WimbaClassroomProvider.java +++ b/src/main/java/de/bps/course/nodes/vc/provider/wimba/WimbaClassroomProvider.java @@ -226,7 +226,7 @@ public class WimbaClassroomProvider extends LogDelegator implements VCProvider { // first delete recordings Map<String, String> mapRecordings = listRecordings(roomId); for(String key : mapRecordings.keySet()) { - removeClassroomRecording(key, config); + removeClassroomRecording(key); } Map<String, String> parameters = new HashMap<String, String>(); @@ -410,7 +410,7 @@ public class WimbaClassroomProvider extends LogDelegator implements VCProvider { parameters.put("function", "createUser"); parameters.put("target", PREFIX + identity.getKey()); parameters.put("password_type", "P");// specified password, see Wimba Classroom 6.0 API Guide, page 8 - parameters.put("password", Encoder.encrypt(identity.getName() + "@" + Settings.getApplicationName())); + parameters.put("password", Encoder.md5hash(identity.getName() + "@" + Settings.getApplicationName())); parameters.put("first_name", identity.getUser().getProperty(UserConstants.FIRSTNAME, null)); parameters.put("last_name", identity.getUser().getProperty(UserConstants.LASTNAME, null)); String raw = sendRequest(parameters); @@ -519,7 +519,7 @@ public class WimbaClassroomProvider extends LogDelegator implements VCProvider { return mapKeyName; } - public URL createClassroomRecordingUrl(String recordingId, Identity identity, VCConfiguration config) { + public URL createClassroomRecordingUrl(String recordingId, Identity identity) { URL url = null; /* Notice: This is a very special and wimba specific case, the recordingId must not prefixed! */ URI uri = UriBuilder.fromUri(protocol + "://" + baseUrl).port(port) @@ -533,7 +533,7 @@ public class WimbaClassroomProvider extends LogDelegator implements VCProvider { return url; } - public boolean removeClassroomRecording(String recordingId, VCConfiguration config) { + public boolean removeClassroomRecording(String recordingId) { if(!loginAdmin()) throw new AssertException("Cannot login to Wimba Classroom. Please check module configuration and Wimba Classroom connectivity"); Map<String, String> parameters = new HashMap<String, String>(); diff --git a/src/main/java/de/bps/course/nodes/vc/provider/wimba/WimbaDisplayController.java b/src/main/java/de/bps/course/nodes/vc/provider/wimba/WimbaDisplayController.java index 303559af35522804cf755727fd7d15ff23bb8064..e50bc9d5c3ef8ceec9f9fb065cdc3c0313754060 100644 --- a/src/main/java/de/bps/course/nodes/vc/provider/wimba/WimbaDisplayController.java +++ b/src/main/java/de/bps/course/nodes/vc/provider/wimba/WimbaDisplayController.java @@ -265,7 +265,7 @@ public class WimbaDisplayController extends BasicController { String key = (String) recTable.getTableDataModel().getValueAt(row, 0); if(action.equals(COMMAND_OPEN_RECORDING)) { wimba.login(ureq.getIdentity(), null); - URL url = wimba.createClassroomRecordingUrl(key, ureq.getIdentity(), config); + URL url = wimba.createClassroomRecordingUrl(key, ureq.getIdentity()); RedirectMediaResource rmr = new RedirectMediaResource(url.toString()); ureq.getDispatchResult().setResultingMediaResource(rmr); return; @@ -283,7 +283,7 @@ public class WimbaDisplayController extends BasicController { getWindowControl().setError(translate(text)); } } else if(action.equals(COMMAND_DELETE_RECORDING)) { - if(wimba.removeClassroomRecording(key, config)) { + if(wimba.removeClassroomRecording(key)) { getWindowControl().setInfo(translate("table.recordings.delete.success")); recTableModel.removeRecording(row); recTable.modelChanged(); @@ -340,7 +340,7 @@ public class WimbaDisplayController extends BasicController { } -class RecordingsTableModel implements TableDataModel { +class RecordingsTableModel implements TableDataModel<Object[]> { private List<Object[]> recordings = new ArrayList<Object[]>(); private Translator translator; @@ -376,12 +376,12 @@ class RecordingsTableModel implements TableDataModel { } @Override - public Object getObject(int row) { + public Object[] getObject(int row) { return recordings.get(row); } @Override - public void setObjects(List objects) { + public void setObjects(List<Object[]> objects) { this.recordings = objects; } diff --git a/src/main/java/org/olat/admin/user/SendTokenToUserForm.java b/src/main/java/org/olat/admin/user/SendTokenToUserForm.java index 1553e266ebc576408ef2c82ce7adbc49abb12635..776364bde82f94043206e1779a983104bc17a2e2 100644 --- a/src/main/java/org/olat/admin/user/SendTokenToUserForm.java +++ b/src/main/java/org/olat/admin/user/SendTokenToUserForm.java @@ -119,7 +119,7 @@ public class SendTokenToUserForm extends FormBasicController { Locale locale = I18nManager.getInstance().getLocaleOrDefault(prefs.getLanguage()); String emailAdress = user.getUser().getProperty(UserConstants.EMAIL, locale); if (emailAdress != null) { - dummyKey = Encoder.encrypt(emailAdress); + dummyKey = Encoder.md5hash(emailAdress); String serverpath = Settings.getServerContextPathURI(); Translator userTrans = Util.createPackageTranslator(RegistrationManager.class, locale) ; diff --git a/src/main/java/org/olat/admin/user/UserChangePasswordController.java b/src/main/java/org/olat/admin/user/UserChangePasswordController.java index bdf903a018523e8243dd7d330c192f1012a4fc12..c8b05421334f8b7a72c086f4e42681577db62711 100644 --- a/src/main/java/org/olat/admin/user/UserChangePasswordController.java +++ b/src/main/java/org/olat/admin/user/UserChangePasswordController.java @@ -26,8 +26,8 @@ package org.olat.admin.user; import org.olat.basesecurity.BaseSecurity; -import org.olat.basesecurity.BaseSecurityManager; import org.olat.basesecurity.Constants; +import org.olat.core.CoreSpringFactory; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; import org.olat.core.gui.components.velocity.VelocityContainer; @@ -57,6 +57,8 @@ public class UserChangePasswordController extends BasicController { private SendTokenToUserForm tokenForm; private VelocityContainer mainVC; private Identity user; + + private final OLATAuthManager olatAuthenticationSpi; /** * @param ureq @@ -66,7 +68,8 @@ public class UserChangePasswordController extends BasicController { public UserChangePasswordController(UserRequest ureq, WindowControl wControl, Identity changeableUser) { super(ureq, wControl); - BaseSecurity mgr = BaseSecurityManager.getInstance(); + olatAuthenticationSpi = CoreSpringFactory.getImpl(OLATAuthManager.class); + BaseSecurity mgr = CoreSpringFactory.getImpl(BaseSecurity.class); if (!mgr.isIdentityPermittedOnResourceable( ureq.getIdentity(), Constants.PERMISSION_ACCESS, @@ -94,7 +97,7 @@ public class UserChangePasswordController extends BasicController { @Override public void event(UserRequest ureq, Controller source, Event event) { if (source == chPwdForm && event.equals(Event.DONE_EVENT)) { - if (OLATAuthManager.changePassword(ureq.getIdentity(), user, chPwdForm.getNewPassword())) { + if (olatAuthenticationSpi.changePassword(ureq.getIdentity(), user, chPwdForm.getNewPassword())) { showInfo("changeuserpwd.successful"); logAudit ("user password changed successfully of " +user.getName(), this.getClass().getName()); } else { diff --git a/src/main/java/org/olat/admin/user/UsermanagerUserSearchController.java b/src/main/java/org/olat/admin/user/UsermanagerUserSearchController.java index 05919f373dd464a674f08d17082fbb591270be70..8feea6498fe8dba8dd77dabe789cacc0459a4cec 100644 --- a/src/main/java/org/olat/admin/user/UsermanagerUserSearchController.java +++ b/src/main/java/org/olat/admin/user/UsermanagerUserSearchController.java @@ -483,11 +483,11 @@ public class UsermanagerUserSearchController extends BasicController implements HashMap<String, String> roleChangeMap = (HashMap<String, String>) runContext.get("roleChangeMap"); List<Long> ownGroups = (List<Long>) runContext.get("ownerGroups"); List<Long> partGroups = (List<Long>) runContext.get("partGroups"); - List<Long> mailGroups = (List<Long>) runContext.get("mailGroups"); + //List<Long> mailGroups = (List<Long>) runContext.get("mailGroups"); if (attributeChangeMap.size() != 0 || roleChangeMap.size() != 0 || ownGroups.size() != 0 || partGroups.size() != 0){ Identity addingIdentity = ureq1.getIdentity(); ubcMan.changeSelectedIdentities(selectedIdentities, attributeChangeMap, roleChangeMap, notUpdatedIdentities, - isAdministrativeUser, ownGroups, partGroups, mailGroups, getTranslator(), addingIdentity); + isAdministrativeUser, ownGroups, partGroups, getTranslator(), addingIdentity); hasChanges = true; } } diff --git a/src/main/java/org/olat/admin/user/bulkChange/UserBulkChangeManager.java b/src/main/java/org/olat/admin/user/bulkChange/UserBulkChangeManager.java index 0b774e70714141bb6f67b1482b0a2d42a287a95c..ba7fd1259b6b488407778ac3a42c87b368ef994c 100644 --- a/src/main/java/org/olat/admin/user/bulkChange/UserBulkChangeManager.java +++ b/src/main/java/org/olat/admin/user/bulkChange/UserBulkChangeManager.java @@ -100,7 +100,8 @@ public class UserBulkChangeManager extends BasicManager { } public void changeSelectedIdentities(List<Identity> selIdentities, HashMap<String, String> attributeChangeMap, - HashMap<String, String> roleChangeMap, ArrayList<String> notUpdatedIdentities, boolean isAdministrativeUser, List<Long> ownGroups, List<Long> partGroups, List<Long> mailGroups, Translator trans, Identity addingIdentity) { + HashMap<String, String> roleChangeMap, ArrayList<String> notUpdatedIdentities, boolean isAdministrativeUser, List<Long> ownGroups, List<Long> partGroups, + Translator trans, Identity addingIdentity) { Translator transWithFallback = UserManager.getInstance().getPropertyHandlerTranslator(trans); String usageIdentifyer = UserBulkChangeStep00.class.getCanonicalName(); @@ -129,8 +130,11 @@ public class UserBulkChangeManager extends BasicManager { errorDesc = transWithFallback.translate("error.password"); updateError = true; } - } else newPwd = null; - OLATAuthManager.changePasswordAsAdmin(identity, newPwd); + } else { + newPwd = null; + } + OLATAuthManager olatAuthenticationSpi = CoreSpringFactory.getImpl(OLATAuthManager.class); + olatAuthenticationSpi.changePasswordAsAdmin(identity, newPwd); } // set language diff --git a/src/main/java/org/olat/admin/user/bulkChange/UserBulkChangePasswordController.java b/src/main/java/org/olat/admin/user/bulkChange/UserBulkChangePasswordController.java index d7d2f131c640afe92741c9577070715395447021..5894a43182777c7cfce75aa60415cf8a20fb1f76 100644 --- a/src/main/java/org/olat/admin/user/bulkChange/UserBulkChangePasswordController.java +++ b/src/main/java/org/olat/admin/user/bulkChange/UserBulkChangePasswordController.java @@ -26,6 +26,7 @@ package org.olat.admin.user.bulkChange; import org.olat.basesecurity.BaseSecurity; import org.olat.basesecurity.BaseSecurityManager; +import org.olat.core.CoreSpringFactory; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; import org.olat.core.gui.components.form.flexible.FormItemContainer; @@ -60,16 +61,20 @@ import org.olat.user.UserManager; public class UserBulkChangePasswordController extends BasicController { private static final OLog log = Tracing.createLoggerFor(UserBulkChangePasswordController.class); + private ChangePasswordForm changePasswordForm; + private final OLATAuthManager olatAuthenticationSpi; public UserBulkChangePasswordController(UserRequest ureq, WindowControl wControl) { super(ureq, wControl); + + olatAuthenticationSpi = CoreSpringFactory.getImpl(OLATAuthManager.class); Panel main = new Panel("changePsw"); VelocityContainer mainVC = createVelocityContainer("index"); changePasswordForm = new ChangePasswordForm(ureq, wControl); - this.listenTo(changePasswordForm); + listenTo(changePasswordForm); mainVC.put("form", changePasswordForm.getInitialComponent()); main.setContent(mainVC); @@ -106,7 +111,7 @@ public class UserBulkChangePasswordController extends BasicController { Identity identity = identityManager.findIdentityByName(username); if(identity!=null) { if (password!=null && password.trim().length()>0) { - OLATAuthManager.changePassword(ureq.getIdentity(), identity, password); + olatAuthenticationSpi.changePassword(ureq.getIdentity(), identity, password); log.info("changePassword for username: " + username); } if (autodisc) { diff --git a/src/main/java/org/olat/basesecurity/AuthHelper.java b/src/main/java/org/olat/basesecurity/AuthHelper.java index 2c56eae6c0675318f53ddca5c788fbace9186240..81c2efda55a3b5b842a8e784b5d27dc56a23ff56 100644 --- a/src/main/java/org/olat/basesecurity/AuthHelper.java +++ b/src/main/java/org/olat/basesecurity/AuthHelper.java @@ -65,7 +65,6 @@ import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; import org.olat.core.logging.activity.OlatLoggingAction; import org.olat.core.logging.activity.ThreadLocalUserActivityLogger; -import org.olat.core.util.Encoder; import org.olat.core.util.SessionInfo; import org.olat.core.util.UserSession; import org.olat.core.util.WebappHelper; @@ -362,10 +361,10 @@ public class AuthHelper { if (pwd == null) { // when no password is used the provider must be set to null to not generate // an OLAT authentication token. See method doku. - ident = BaseSecurityManager.getInstance().createAndPersistIdentityAndUser(loginName, newUser, null, null, null); + ident = BaseSecurityManager.getInstance().createAndPersistIdentityAndUser(loginName, newUser, null, null); } else { ident = BaseSecurityManager.getInstance().createAndPersistIdentityAndUser(loginName, newUser, - BaseSecurityModule.getDefaultAuthProviderIdentifier(), loginName, Encoder.encrypt(pwd)); + BaseSecurityModule.getDefaultAuthProviderIdentifier(), loginName, pwd); } // TODO: Tracing message return ident; diff --git a/src/main/java/org/olat/basesecurity/Authentication.java b/src/main/java/org/olat/basesecurity/Authentication.java index fa75301ca60a6d2a7af19c3751a75f1ecf049cf4..522ee46ffcc5fafaf674edc44723d2fd2228fb39 100644 --- a/src/main/java/org/olat/basesecurity/Authentication.java +++ b/src/main/java/org/olat/basesecurity/Authentication.java @@ -55,6 +55,18 @@ public interface Authentication extends CreateInfo, Persistable { * @return */ public String getCredential(); + + /** + * Salt used to hash the password + * @return + */ + public String getSalt(); + + /** + * Algoritm used to hash the password + * @return + */ + public String getAlgorithm(); /** * @param identity @@ -75,6 +87,18 @@ public interface Authentication extends CreateInfo, Persistable { * @param credential */ public void setCredential(String credential); + + /** + * + * @param salt + */ + public void setSalt(String salt); + + /** + * + * @param algorithm + */ + public void setAlgorithm(String algorithm); } diff --git a/src/main/java/org/olat/basesecurity/AuthenticationImpl.hbm.xml b/src/main/java/org/olat/basesecurity/AuthenticationImpl.hbm.xml index d82b1a094b924ced6ce56bdf7877a55b61476366..be1f99bd0f94bc9827384bbbda57595bef8b731b 100644 --- a/src/main/java/org/olat/basesecurity/AuthenticationImpl.hbm.xml +++ b/src/main/java/org/olat/basesecurity/AuthenticationImpl.hbm.xml @@ -26,6 +26,9 @@ <property name="credential" type="string" not-null="false"> <column name="credential" length="255" index="credential_idx"/> </property> + + <property name="salt" column="salt" type="string" not-null="false"/> + <property name="algorithm" column="hashalgorithm" type="string" not-null="false"/> </class> </hibernate-mapping> diff --git a/src/main/java/org/olat/basesecurity/AuthenticationImpl.java b/src/main/java/org/olat/basesecurity/AuthenticationImpl.java index b9cd42e99b34ae853e1d72ceb67ad238f5d86aaf..2b36aac750f3c66472264e2c110de96651f1f633 100644 --- a/src/main/java/org/olat/basesecurity/AuthenticationImpl.java +++ b/src/main/java/org/olat/basesecurity/AuthenticationImpl.java @@ -36,10 +36,13 @@ import org.olat.core.logging.AssertException; */ public class AuthenticationImpl extends PersistentObject implements Authentication { + private static final long serialVersionUID = 7969409958077836798L; private Identity identity; private String provider; private String authusername; private String credential; + private String salt; + private String algorithm; /** * for hibernate only @@ -47,8 +50,22 @@ public class AuthenticationImpl extends PersistentObject implements Authenticati protected AuthenticationImpl() { // } + + AuthenticationImpl(Identity identity, String provider, String authusername, String credentials) { + + if (provider.length() > 8) { + // this implementation allows only 8 characters, as defined in hibernate file + throw new AssertException("Authentication provider '" + provider + "' to long, only 8 characters supported!"); + } + this.identity = identity; + this.provider = provider; + this.authusername = authusername; + this.credential = credentials; + } - AuthenticationImpl(Identity identity, String provider, String authusername, String credential) { + AuthenticationImpl(Identity identity, String provider, String authusername, + String credential, String salt, String algorithm) { + if (provider.length() > 8) { // this implementation allows only 8 characters, as defined in hibernate file throw new AssertException("Authentication provider '" + provider + "' to long, only 8 characters supported!"); @@ -57,11 +74,14 @@ public class AuthenticationImpl extends PersistentObject implements Authenticati this.provider = provider; this.authusername = authusername; this.credential = credential; + this.salt = salt; + this.algorithm = algorithm; } /** * @return */ + @Override public String getAuthusername() { return authusername; } @@ -69,6 +89,7 @@ public class AuthenticationImpl extends PersistentObject implements Authenticati /** * @return */ + @Override public String getProvider() { return provider; } @@ -78,6 +99,7 @@ public class AuthenticationImpl extends PersistentObject implements Authenticati * * @param string */ + @Override public void setAuthusername(String string) { authusername = string; } @@ -87,6 +109,7 @@ public class AuthenticationImpl extends PersistentObject implements Authenticati * * @param string */ + @Override public void setProvider(String string) { provider = string; } @@ -96,6 +119,7 @@ public class AuthenticationImpl extends PersistentObject implements Authenticati * * @return */ + @Override public String getCredential() { return credential; } @@ -103,13 +127,35 @@ public class AuthenticationImpl extends PersistentObject implements Authenticati /** * @param string */ + @Override public void setCredential(String string) { credential = string; } + @Override + public String getSalt() { + return salt; + } + + @Override + public void setSalt(String salt) { + this.salt = salt; + } + + @Override + public String getAlgorithm() { + return algorithm; + } + + @Override + public void setAlgorithm(String algorithm) { + this.algorithm = algorithm; + } + /** * @see java.lang.Object#toString() */ + @Override public String toString() { return "auth: provider:" + provider + " ,authusername:" + authusername + ", hashpwd:" + credential + " ," + super.toString(); } @@ -117,6 +163,7 @@ public class AuthenticationImpl extends PersistentObject implements Authenticati /** * @see org.olat.basesecurity.Authentication#getIdentity() */ + @Override public Identity getIdentity() { return identity; } @@ -124,6 +171,7 @@ public class AuthenticationImpl extends PersistentObject implements Authenticati /** * @see org.olat.basesecurity.Authentication#setIdentity(org.olat.core.id.Identity) */ + @Override public void setIdentity(Identity identity) { this.identity = identity; } diff --git a/src/main/java/org/olat/basesecurity/BaseSecurity.java b/src/main/java/org/olat/basesecurity/BaseSecurity.java index fe8c73a75ff6a36678d7c54fbe2e1c967d38b854..9f66ce9d285432fa41a72f64215247ed8099a848 100644 --- a/src/main/java/org/olat/basesecurity/BaseSecurity.java +++ b/src/main/java/org/olat/basesecurity/BaseSecurity.java @@ -35,6 +35,7 @@ import org.olat.core.id.Identity; import org.olat.core.id.OLATResourceable; import org.olat.core.id.Roles; import org.olat.core.id.User; +import org.olat.core.util.Encoder; import org.olat.resource.OLATResource; /** @@ -272,6 +273,8 @@ public interface BaseSecurity { * @return nr of members in the securitygroup */ public int countIdentitiesOfSecurityGroup(SecurityGroup secGroup); + + /** * @param username the username @@ -283,8 +286,8 @@ public interface BaseSecurity { * @param credential the credentials or null if not used * @return the new identity */ - public Identity createAndPersistIdentity(String username, User user, String provider, String authusername, String credential); - + public Identity createAndPersistIdentity(String username, User user, String provider, String authusername, String password); + /** * @param username the username * @param user the unpresisted User @@ -295,7 +298,19 @@ public interface BaseSecurity { * @param credential the credentials or null if not used * @return the new identity */ - public Identity createAndPersistIdentityAndUser(String username, User user, String provider, String authusername, String credential); + public Identity createAndPersistIdentityAndUser(String username, User user, String provider, String authusername); + + /** + * @param username the username + * @param user the unpresisted User + * @param provider the provider of the authentication ("OLAT" or "AAI"). If + * null, no authentication token is generated. + * @param authusername the username used as authentication credential + * (=username for provider "OLAT") + * @param password The password which will be used as credentials (not hashed it) + * @return the new identity + */ + public Identity createAndPersistIdentityAndUser(String username, User user, String provider, String authusername, String password); /** * Return the List of associated Authentications. @@ -313,32 +328,22 @@ public interface BaseSecurity { */ public Authentication findAuthentication(Identity identity, String provider); - /** - * - * @param identity - * @param creationDate - * @return - */ - public List<Authentication> findOldAuthentication(String provider, Date creationDate); /** - * - * @param provider - * @param token + * Find authentication which are older than a specific date. + * @param provider The provider + * @param creationDate The date's limit * @return */ - public List<Authentication> findAuthentication(String provider, String credential); + public List<Authentication> findOldAuthentication(String provider, Date creationDate); /** - * Return the credential or null - * @param identity - * @param provider + * Authentication with a security token + * @param provider The provider + * @param securityToken The security token * @return */ - public String findCredentials(Identity identity, String provider); - - //fxdiff: FXOLAT-219 decrease the load for synching groups - public boolean hasAuthentication(Long identityKey, String provider); + public List<Authentication> findAuthenticationByToken(String provider, String securityToken); /** * @param identity @@ -347,7 +352,7 @@ public interface BaseSecurity { * @param credential * @return an Authentication */ - public Authentication createAndPersistAuthentication(Identity identity, String provider, String authUsername, String credential); + public Authentication createAndPersistAuthentication(Identity identity, String provider, String authUsername, String password, Encoder.Algorithm algoritm); /** * @param authentication @@ -359,6 +364,24 @@ public interface BaseSecurity { * @param authentication */ public Authentication updateAuthentication(Authentication authentication); + + /** + * + * @param authentication + * @param password + * @param algorithm + * @return + */ + public boolean checkCredentials(Authentication authentication, String password); + + /** + * Updated the hashed password to a new one + * @param authentication + * @param password + * @param algorithm + * @return + */ + public Authentication updateCredentials(Authentication authentication, String password, Encoder.Algorithm algorithm); // --- SecGroup management diff --git a/src/main/java/org/olat/basesecurity/BaseSecurityManager.java b/src/main/java/org/olat/basesecurity/BaseSecurityManager.java index b12779e93eda0c4f0dbb0452b6fb077d6765e7b4..1c0511cba0630b4d83adbfb84a47413892daab42 100644 --- a/src/main/java/org/olat/basesecurity/BaseSecurityManager.java +++ b/src/main/java/org/olat/basesecurity/BaseSecurityManager.java @@ -62,11 +62,13 @@ import org.olat.core.id.User; import org.olat.core.id.UserConstants; import org.olat.core.logging.AssertException; import org.olat.core.manager.BasicManager; -import org.olat.core.util.StringHelper; +import org.olat.core.util.Encoder.Algorithm; +import org.olat.core.util.Encoder; import org.olat.core.util.Util; import org.olat.core.util.coordinate.CoordinatorManager; import org.olat.core.util.coordinate.SyncerCallback; import org.olat.core.util.resource.OresHelper; +import org.olat.login.LoginModule; import org.olat.resource.OLATResource; import org.olat.resource.OLATResourceImpl; import org.olat.resource.OLATResourceManager; @@ -933,11 +935,31 @@ public class BaseSecurityManager extends BasicManager implements BaseSecurity { * @param credential the credentials or null if not used * @return Identity */ + @Override public Identity createAndPersistIdentity(String username, User user, String provider, String authusername, String credential) { IdentityImpl iimpl = new IdentityImpl(username, user); dbInstance.getCurrentEntityManager().persist(iimpl); if (provider != null) { - createAndPersistAuthentication(iimpl, provider, authusername, credential); + createAndPersistAuthentication(iimpl, provider, authusername, credential, LoginModule.getDefaultHashAlgorithm()); + } + notifyNewIdentityCreated(iimpl); + return iimpl; + } + + /** + * @param username The username + * @param user The unpresisted User + * @param provider The provider of the authentication ("OLAT" or "AAI"). If null, no authentication token is generated. + * @param authusername The username used as authentication credential (=username for provider "OLAT") + * @return Identity + */ + @Override + public Identity createAndPersistIdentityAndUser(String username, User user, String provider, String authusername) { + dbInstance.getCurrentEntityManager().persist(user); + IdentityImpl iimpl = new IdentityImpl(username, user); + dbInstance.getCurrentEntityManager().persist(iimpl); + if (provider != null) { + createAndPersistAuthentication(iimpl, provider, authusername, null, null); } notifyNewIdentityCreated(iimpl); return iimpl; @@ -953,12 +975,13 @@ public class BaseSecurityManager extends BasicManager implements BaseSecurity { * @param credential the credentials or null if not used * @return Identity */ + @Override public Identity createAndPersistIdentityAndUser(String username, User user, String provider, String authusername, String credential) { dbInstance.getCurrentEntityManager().persist(user); IdentityImpl iimpl = new IdentityImpl(username, user); dbInstance.getCurrentEntityManager().persist(iimpl); if (provider != null) { - createAndPersistAuthentication(iimpl, provider, authusername, credential); + createAndPersistAuthentication(iimpl, provider, authusername, credential, LoginModule.getDefaultHashAlgorithm()); } notifyNewIdentityCreated(iimpl); return iimpl; @@ -1383,13 +1406,20 @@ public class BaseSecurityManager extends BasicManager implements BaseSecurity { * @see org.olat.basesecurity.Manager#createAndPersistAuthentication(org.olat.core.id.Identity, java.lang.String, java.lang.String, java.lang.String) */ @Override - public Authentication createAndPersistAuthentication(final Identity ident, final String provider, final String authUserName, final String credential) { + public Authentication createAndPersistAuthentication(final Identity ident, final String provider, final String authUserName, + final String credentials, final Encoder.Algorithm algorithm) { OLATResourceable resourceable = OresHelper.createOLATResourceableInstanceWithoutCheck(provider, ident.getKey()); return CoordinatorManager.getInstance().getCoordinator().getSyncer().doInSync(resourceable, new SyncerCallback<Authentication>(){ public Authentication execute() { Authentication auth = findAuthentication(ident, provider); if(auth == null) { - auth = new AuthenticationImpl(ident, provider, authUserName, credential); + if(algorithm != null) { + String salt = Encoder.getSalt(); + String hash = Encoder.encrypt(credentials, salt, algorithm); + auth = new AuthenticationImpl(ident, provider, authUserName, hash, salt, algorithm.name()); + } else { + auth = new AuthenticationImpl(ident, provider, authUserName, credentials); + } dbInstance.getCurrentEntityManager().persist(auth); } return auth; @@ -1424,8 +1454,8 @@ public class BaseSecurityManager extends BasicManager implements BaseSecurity { * @see org.olat.basesecurity.Manager#findAuthentication(org.olat.core.id.Identity, java.lang.String) */ @Override - public List<Authentication> findAuthentication(String provider, String credential) { - if (provider==null || credential==null) { + public List<Authentication> findAuthenticationByToken(String provider, String securityToken) { + if (provider==null || securityToken==null) { throw new IllegalArgumentException("provider and token must not be null"); } @@ -1435,7 +1465,7 @@ public class BaseSecurityManager extends BasicManager implements BaseSecurity { List<Authentication> results = dbInstance.getCurrentEntityManager() .createQuery(sb.toString(), Authentication.class) - .setParameter("credential", credential) + .setParameter("credential", securityToken) .setParameter("provider", provider) .getResultList(); return results; @@ -1460,63 +1490,55 @@ public class BaseSecurityManager extends BasicManager implements BaseSecurity { } @Override - public String findCredentials(Identity identity, String provider) { - if (identity==null) { - throw new IllegalArgumentException("identity must not be null"); - } - - StringBuilder sb = new StringBuilder(); - sb.append("select auth.credential from ").append(AuthenticationImpl.class.getName()) - .append(" as auth where auth.identity.key=:identityKey and auth.provider=:provider"); - - List<String> results = dbInstance.getCurrentEntityManager() - .createQuery(sb.toString(), String.class) - .setParameter("identityKey", identity.getKey()) - .setParameter("provider", provider) - .getResultList(); - if (results == null || results.size() == 0) return null; - if (results.size() > 1) throw new AssertException("Found more than one Authentication for a given subject and a given provider."); - return results.get(0); + public Authentication updateAuthentication(Authentication authentication) { + return dbInstance.getCurrentEntityManager().merge(authentication); } @Override - //fxdiff: FXOLAT-219 decrease the load for synching groups - public boolean hasAuthentication(Long identityKey, String provider) { - if (identityKey == null || !StringHelper.containsNonWhitespace(provider)) return false; - - String queryStr = "select count(auth) from org.olat.basesecurity.AuthenticationImpl as auth where auth.identity.key=:key and auth.provider=:provider"; - DBQuery query = DBFactory.getInstance().createQuery(queryStr); - query.setLong("key", identityKey); - query.setString("provider", provider); - - Number count = (Number)query.uniqueResult(); - return count.intValue() > 0; + public boolean checkCredentials(Authentication authentication, String password) { + Algorithm algorithm = Algorithm.find(authentication.getAlgorithm()); + String hash = Encoder.encrypt(password, authentication.getSalt(), algorithm); + return authentication.getCredential() != null && authentication.getCredential().equals(hash); } @Override - public Authentication updateAuthentication(Authentication authentication) { - return dbInstance.getCurrentEntityManager().merge(authentication); + public Authentication updateCredentials(Authentication authentication, String password, Algorithm algorithm) { + String salt = Encoder.getSalt(); + String newCredentials = Encoder.encrypt(password, salt, algorithm); + authentication.setSalt(salt); + authentication.setCredential(newCredentials); + authentication.setAlgorithm(algorithm.name()); + return updateAuthentication(authentication); } /** * @see org.olat.basesecurity.Manager#deleteAuthentication(org.olat.basesecurity.Authentication) */ + @Override public void deleteAuthentication(Authentication auth) { - DBFactory.getInstance().deleteObject(auth); + dbInstance.getCurrentEntityManager().remove(auth); } /** * @see org.olat.basesecurity.Manager#findAuthenticationByAuthusername(java.lang.String, java.lang.String) */ + @Override public Authentication findAuthenticationByAuthusername(String authusername, String provider) { - List results = DBFactory.getInstance().find( - "from org.olat.basesecurity.AuthenticationImpl as auth where auth.provider = ? and auth.authusername = ?", - new Object[] { provider, authusername }, new Type[] { StandardBasicTypes.STRING, StandardBasicTypes.STRING }); + 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=:provider and auth.authusername=:authusername"); + + List<Authentication> results = dbInstance.getCurrentEntityManager() + .createQuery(sb.toString(), Authentication.class) + .setParameter("provider", provider) + .setParameter("authusername", authusername) + .getResultList(); if (results.size() == 0) return null; - if (results.size() != 1) throw new AssertException( - "more than one entry for the a given authusername and provider, should never happen (even db has a unique constraint on those columns combined) "); - Authentication auth = (Authentication) results.get(0); - return auth; + if (results.size() != 1) { + throw new AssertException("more than one entry for the a given authusername and provider, should never happen (even db has a unique constraint on those columns combined) "); + } + return results.get(0); } /** diff --git a/src/main/java/org/olat/commons/lifecycle/LifeCycleManager.java b/src/main/java/org/olat/commons/lifecycle/LifeCycleManager.java index bc266543a6d9f5ab6862c45ac0fe5d789ae9fcb5..fc98cf2bafb94e994881afb542787d949c5e9b38 100644 --- a/src/main/java/org/olat/commons/lifecycle/LifeCycleManager.java +++ b/src/main/java/org/olat/commons/lifecycle/LifeCycleManager.java @@ -162,7 +162,7 @@ public class LifeCycleManager extends BasicManager { public static String getShortTypeName(String standardTypeName) { if (standardTypeName.length() > LifeCycleEntry.PERSISTENTTYPENAME_MAXLENGTH) { //encode into an md5 hash with fixed length of 32 characters otherwise the sting may get too long for locks or db fields - return Encoder.encrypt(standardTypeName); + return Encoder.md5hash(standardTypeName); } else { return standardTypeName; } diff --git a/src/main/java/org/olat/commons/rss/RSSUtil.java b/src/main/java/org/olat/commons/rss/RSSUtil.java index d27c14b8e547acb67d583df6346f8a998397d7cf..e8d7b7191c21c52467b929e5f653a65d8a074dea 100644 --- a/src/main/java/org/olat/commons/rss/RSSUtil.java +++ b/src/main/java/org/olat/commons/rss/RSSUtil.java @@ -80,7 +80,7 @@ public class RSSUtil { if (auth == null) { // no token found - create one token = RandomStringUtils.randomAlphanumeric(6); - auth = secManager.createAndPersistAuthentication(identity, RSSUtil.RSS_AUTH_PROVIDER, identity.getName(), token); + auth = secManager.createAndPersistAuthentication(identity, RSSUtil.RSS_AUTH_PROVIDER, identity.getName(), token, null); } else { token = auth.getCredential(); } diff --git a/src/main/java/org/olat/core/commons/editor/htmleditor/HTMLEditorController.java b/src/main/java/org/olat/core/commons/editor/htmleditor/HTMLEditorController.java index 07707fee3e87b8a288a80d2ec42fc8e2ec42bcae..aefbda2c63c94712c7ffebfc19e0ab77da2a1e9f 100644 --- a/src/main/java/org/olat/core/commons/editor/htmleditor/HTMLEditorController.java +++ b/src/main/java/org/olat/core/commons/editor/htmleditor/HTMLEditorController.java @@ -165,7 +165,7 @@ public class HTMLEditorController extends FormBasicController { // OLAT-5066: the use of "fileName" gives users the (false) impression that the file they wish to access // is already locked by someone else. Since the lock token must be smaller than 50 characters we us an // MD5 hash of the absolute file path which will always be 32 characters long and virtually unique. - String lockToken = Encoder.encrypt(getFileDebuggingPath(baseContainer, relFilePath)); + String lockToken = Encoder.md5hash(getFileDebuggingPath(baseContainer, relFilePath)); this.lock = CoordinatorManager.getInstance().getCoordinator().getLocker().acquireLock(lockResourceable, ureq.getIdentity(), lockToken); VelocityContainer vc = (VelocityContainer) flc.getComponent(); if (!lock.isSuccess()) { diff --git a/src/main/java/org/olat/core/commons/services/webdav/DefaultServlet.java b/src/main/java/org/olat/core/commons/services/webdav/DefaultServlet.java index b9f38d918d6468044301302f48133bc43d990df6..babd1ac6f292bdabe0b8385efc574b962d3589cc 100644 --- a/src/main/java/org/olat/core/commons/services/webdav/DefaultServlet.java +++ b/src/main/java/org/olat/core/commons/services/webdav/DefaultServlet.java @@ -125,9 +125,9 @@ import javax.servlet.http.HttpServletResponse; import org.apache.naming.resources.Resource; import org.apache.naming.resources.ResourceAttributes; import org.olat.core.helpers.Settings; +import org.olat.core.util.MD5Encoder; import org.olat.core.util.servlets.FastHttpDateFormat; import org.olat.core.util.servlets.Globals; -import org.olat.core.util.servlets.MD5Encoder; import org.olat.core.util.servlets.URLEncoder; diff --git a/src/main/java/org/olat/core/commons/services/webdav/_spring/webdavContext.xml b/src/main/java/org/olat/core/commons/services/webdav/_spring/webdavContext.xml index e24e6ea68a60fe384f7f894b7eb5b94953648ffe..bd9493d46b11e0816b3201b4d1ab97a7ed3098dc 100644 --- a/src/main/java/org/olat/core/commons/services/webdav/_spring/webdavContext.xml +++ b/src/main/java/org/olat/core/commons/services/webdav/_spring/webdavContext.xml @@ -10,7 +10,13 @@ <!-- set to false to disable the WebDAV support and remove the WebDAV Link from the GUI --> <property name="enabled" value="${webdav.links.enabled}" /> <property name="sessionManager" ref="userSessionManager" /> - </bean> + <property name="webDAVAuthManager" ref="webDAVAuthenticationSpi" /> + </bean> + + <bean id="webDAVAuthenticationSpi" class="org.olat.core.commons.services.webdav.manager.WebDAVAuthManager" > + <property name="securityManager" ref="baseSecurityManager" /> + <property name="olatAuthenticationSpi" ref="olatAuthenticationSpi" /> + </bean> <!-- WebDAV provider factory --> 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 56db6a7b680efb2e51af94a8aad7b515a2654a99..a9b84b57432de8bc22ee7c80aae7690236b5cb68 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 @@ -22,14 +22,14 @@ package org.olat.core.commons.services.webdav.manager; import org.olat.basesecurity.Authentication; import org.olat.basesecurity.BaseSecurity; -import org.olat.basesecurity.BaseSecurityManager; -import org.olat.core.commons.persistence.DBFactory; import org.olat.core.id.Identity; import org.olat.core.logging.AssertException; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; -import org.olat.core.util.Encoder; -import org.olat.login.OLATAuthenticationController; +import org.olat.core.util.Encoder.Algorithm; +import org.olat.login.LoginModule; +import org.olat.login.auth.AuthenticationSPI; +import org.olat.login.auth.OLATAuthManager; /** @@ -41,68 +41,82 @@ import org.olat.login.OLATAuthenticationController; * Initial Date: 13 apr. 2010 <br> * @author srosse, stephane.rosse@frentix.com */ -public class WebDAVAuthManager { +public class WebDAVAuthManager implements AuthenticationSPI { public static final String PROVIDER_WEBDAV = "WEBDAV"; private static final OLog log = Tracing.createLoggerFor(WebDAVAuthManager.class); + private BaseSecurity securityManager; + private OLATAuthManager olatAuthenticationSpi; /** - * Change the WEBDAV-Password of an identity - * @param doer Identity who is changing the password - * @param identity Identity who's password is being changed. - * @param newPwd New password. - * @return True upon success. + * [used by Spring] + * @param securityManager */ - public static boolean changePassword(Identity doer, Identity identity, String newPwd) { - if (doer==null) throw new AssertException("password changing identity cannot be undefined!"); - - if (identity.getKey() == null) throw new AssertException("cannot change password on a nonpersisted identity"); - // password's length is limited to 128 chars. - // The 128 bit MD5 hash is converted into a 32 character long String - String hashedPwd = Encoder.encrypt(newPwd); - - identity = (Identity) DBFactory.getInstance().loadObject(identity); - - return changeWebDAVPassword(doer, identity, hashedPwd); + public void setSecurityManager(BaseSecurity securityManager) { + this.securityManager = securityManager; } - - private static boolean changeWebDAVPassword(Identity doer, Identity identity, String hashedPwd) { - Authentication auth = BaseSecurityManager.getInstance().findAuthentication(identity, PROVIDER_WEBDAV); - if (auth == null) { // create new authentication for provider OLAT - auth = BaseSecurityManager.getInstance().createAndPersistAuthentication(identity, PROVIDER_WEBDAV, identity.getName(), hashedPwd); - log.audit(doer.getName() + " created new WebDAV authenticatin for identity: " + identity.getName()); - } - auth.setCredential(hashedPwd); - DBFactory.getInstance().updateObject(auth); - log.audit(doer.getName() + " set new WebDAV password for identity: " +identity.getName()); - return true; - } - /** - * Authenticate against the WEBDAV Authentication provider. - * @param login - * @param pass - * @return Identity if authentication was successful, null otherwise. + * [used by Spring] + * @param olatAuthenticationSpi */ - public static Identity authenticate(String login, String pass) { - BaseSecurity securityManager = BaseSecurityManager.getInstance(); + public void setOlatAuthenticationSpi(OLATAuthManager olatAuthenticationSpi) { + this.olatAuthenticationSpi = olatAuthenticationSpi; + } + + @Override + public Identity authenticate(Identity identity, String login, String password) { + Authentication authentication = null; + if (identity != null) { + authentication = securityManager.findAuthentication(identity, PROVIDER_WEBDAV); + } else { + authentication = securityManager.findAuthenticationByAuthusername(login, PROVIDER_WEBDAV); + } + + if(authentication == null) { + //fallback to standard OLAT authentication + return olatAuthenticationSpi.authenticate(identity, login, password); + } - Identity ident = securityManager.findIdentityByName(login); - if (ident == null) return null; - boolean visible = securityManager.isIdentityVisible(ident); + Identity authenticatedIdentity = authentication.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()); + } + return authentication.getIdentity(); + } + return null; + } + + /** + * Change the WEBDAV-Password of an identity + * @param doer Identity who is changing the password + * @param identity Identity who's password is being changed. + * @param newPwd New password. + * @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) + throw new AssertException("cannot change password on a nonpersisted identity"); - //find WEBDAV authentication provider - String auth = securityManager.findCredentials(ident, PROVIDER_WEBDAV); - if (auth != null && auth.equals(Encoder.encrypt(pass))) { - return ident; + Authentication auth = securityManager.findAuthentication(identity, PROVIDER_WEBDAV); + if (auth == 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 authenticatin for identity: " + identity.getName()); + } else { + auth = securityManager.updateCredentials(auth, newPwd, LoginModule.getDefaultHashAlgorithm()); + log.audit(doer.getName() + " set new WebDAV password for identity: " +identity.getName()); } - //fallback to OLAT authentication provider - return OLATAuthenticationController.authenticate(ident, login, pass); + return true; } } diff --git a/src/main/java/org/olat/core/commons/services/webdav/manager/WebDAVManagerImpl.java b/src/main/java/org/olat/core/commons/services/webdav/manager/WebDAVManagerImpl.java index 2544bd64220fe308c12cb9087d5724a167794fa8..cfa2499dba68bb09045b7de795519d085ef53bfe 100644 --- a/src/main/java/org/olat/core/commons/services/webdav/manager/WebDAVManagerImpl.java +++ b/src/main/java/org/olat/core/commons/services/webdav/manager/WebDAVManagerImpl.java @@ -66,6 +66,7 @@ public class WebDAVManagerImpl extends WebDAVManager { private CacheWrapper<String,UserSession> timedSessionCache; private UserSessionManager sessionManager; + private WebDAVAuthManager webDAVAuthManager; /** * [spring] @@ -82,6 +83,14 @@ public class WebDAVManagerImpl extends WebDAVManager { public void setSessionManager(UserSessionManager sessionManager) { this.sessionManager = sessionManager; } + + /** + * [used by Spring] + * @param webDAVAuthManager + */ + public void setWebDAVAuthManager(WebDAVAuthManager webDAVAuthManager) { + this.webDAVAuthManager = webDAVAuthManager; + } /** * @see org.olat.core.commons.services.webdav.WebDAVManager#handleAuthentication(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) @@ -171,7 +180,7 @@ public class WebDAVManagerImpl extends WebDAVManager { // and set valid true if valid. // In this example, we simply check // that neither field is blank - Identity identity = WebDAVAuthManager.authenticate(userID, password); + Identity identity = webDAVAuthManager.authenticate(null, userID, password); if (identity != null) { UserSession usess = sessionManager.getUserSession(request); synchronized(usess) { diff --git a/src/main/java/org/olat/core/dispatcher/mapper/manager/MapperServiceImpl.java b/src/main/java/org/olat/core/dispatcher/mapper/manager/MapperServiceImpl.java index b3fe4175171f48794dfca766982f8c7f1d424b3e..4f5746d2c80b254cb44b0af1db911686cc04aea7 100644 --- a/src/main/java/org/olat/core/dispatcher/mapper/manager/MapperServiceImpl.java +++ b/src/main/java/org/olat/core/dispatcher/mapper/manager/MapperServiceImpl.java @@ -84,7 +84,7 @@ public class MapperServiceImpl implements MapperService { @Override public String register(UserSession session, Mapper mapper) { String mapid = UUID.randomUUID().toString().replace("-", ""); - mapid = Encoder.encrypt(mapid); + mapid = Encoder.md5hash(mapid); MapperKey mapperKey = new MapperKey(session, mapid); mapperKeyToMapper.put(mapperKey, mapper); @@ -118,7 +118,7 @@ public class MapperServiceImpl implements MapperService { @Override public String register(UserSession session, String mapperId, Mapper mapper, int expirationTime) { - String encryptedMapId = Encoder.encrypt(mapperId); + String encryptedMapId = Encoder.md5hash(mapperId); MapperKey mapperKey = new MapperKey(session, encryptedMapId); boolean alreadyLoaded = mapperKeyToMapper.containsKey(mapperKey); if(mapper instanceof Serializable) { diff --git a/src/main/java/org/olat/core/util/Encoder.java b/src/main/java/org/olat/core/util/Encoder.java index 0114decc1fb3661433001c99c70e6151dcefefbb..e5370a00942cdccb7a1972ac0a675b0cd564d764 100644 --- a/src/main/java/org/olat/core/util/Encoder.java +++ b/src/main/java/org/olat/core/util/Encoder.java @@ -26,19 +26,67 @@ package org.olat.core.util; +import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.KeySpec; -import org.olat.core.logging.AssertException; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.PBEKeySpec; + +import org.olat.core.logging.OLog; +import org.olat.core.logging.Tracing; + +import com.oreilly.servlet.Base64Encoder; /** - * Description: + * Description: it's our hash factory + * * * @author Sabina Jeger + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com */ public class Encoder { - private static final String HASH_ALGORITHM = "MD5"; + + private static final OLog log = Tracing.createLoggerFor(Encoder.class); + + public enum Algorithm { + md5("MD5", 1), + sha1("SHA-1", 100), + sha256("SHA-256", 100), + sha512("SHA-512", 100), + pbkdf2("PBKDF2WithHmacSHA1", 20000); + + private final int iterations; + private final String algorithm; + + private Algorithm(String algorithm, int iterations) { + this.algorithm = algorithm; + this.iterations = iterations; + } + + public String getAlgorithm() { + return algorithm; + } + + public int getIterations() { + return iterations; + } + + public static final Algorithm find(String str) { + if(StringHelper.containsNonWhitespace(str)) { + for(Algorithm value:values()) { + if(value.name().equals(str)) { + return value; + } + } + } + return md5; + } + } /** * The MD5 helper object for this class. @@ -51,26 +99,91 @@ public class Encoder { * @param s * @return MD5 encrypted string */ - public static String encrypt(String s) { - byte[] inbytes = s.getBytes(); + public static String md5hash(String s) { + return md5(s, null); + } + + public static String encrypt(String s, String salt, Algorithm algorithm) { + switch(algorithm) { + case md5: return md5(s, salt); + case sha1: + case sha256: + case sha512: + return digest(s, salt, algorithm); + case pbkdf2: + return secretKey(s, salt, algorithm); + default: return md5(s, salt); + } + } + + protected static String md5(String s, String salt) { try { - MessageDigest md5Helper = MessageDigest.getInstance(HASH_ALGORITHM); - byte[] outbytes = md5Helper.digest(inbytes); - String out = md5Encoder.encode(outbytes); - return out; + byte[] inbytes = s.getBytes(); + MessageDigest digest = MessageDigest.getInstance(Algorithm.md5.algorithm); + digest.reset(); + if(salt != null) { + digest.update(salt.getBytes()); + } + byte[] outbytes = digest.digest(inbytes); + return md5Encoder.encode(outbytes); } catch (NoSuchAlgorithmException e) { - throw new AssertException("Cannot load MD5 Message Digest ," + HASH_ALGORITHM + " not supported"); + log.error("", e); + return null; } } - - /** - * encrypt the first argument and show the result on the console - * - * @param args - */ - public static void main(String[] args) { - String result = encrypt(args[0]); - System.out.println("MD5-Hash of " + args[0] + ": " + result); + + protected static String digest(String password, String salt, Algorithm algorithm) { + try { + MessageDigest digest = MessageDigest.getInstance(algorithm.getAlgorithm()); + digest.reset(); + if(salt != null) { + digest.update(salt.getBytes()); + } + byte[] input = password.getBytes("UTF-8"); + for(int i=algorithm.getIterations(); i-->0; ) { + input = digest.digest(input); + } + return byteToBase64(input); + } catch (NoSuchAlgorithmException e) { + log.error("", e); + return null; + } catch (UnsupportedEncodingException e) { + log.error("", e); + return null; + } + } + + protected static String secretKey(String password, String salt, Algorithm algorithm) { + try { + KeySpec spec = new PBEKeySpec(password.toCharArray(), salt.getBytes(), algorithm.getIterations(), 160); + SecretKeyFactory f = SecretKeyFactory.getInstance(algorithm.getAlgorithm()); + return byteToBase64(f.generateSecret(spec).getEncoded()); + } catch (NoSuchAlgorithmException e) { + log.error("", e); + return null; + } catch (InvalidKeySpecException e) { + log.error("", e); + return null; + } + } + + public static String getSalt() { + try { + //Always use a SecureRandom generator + SecureRandom sr = SecureRandom.getInstance("SHA1PRNG"); + //Create array for salt + byte[] salt = new byte[16]; + //Get a random salt + sr.nextBytes(salt); + //return salt + return byteToBase64(salt); + } catch (NoSuchAlgorithmException e) { + log.error("", e); + return null; + } } + public static String byteToBase64(byte[] data){ + return Base64Encoder.encode(data); + } } \ No newline at end of file diff --git a/src/main/java/org/olat/core/util/mail/manager/MailManager.java b/src/main/java/org/olat/core/util/mail/manager/MailManager.java index e67bea37764d90bbdb64a8a3ef975444039ea498..3980db0290f9207d74576352514176328060f548 100644 --- a/src/main/java/org/olat/core/util/mail/manager/MailManager.java +++ b/src/main/java/org/olat/core/util/mail/manager/MailManager.java @@ -225,7 +225,7 @@ public class MailManager extends BasicManager { return hasSibling; } - String uuid = Encoder.encrypt(name + checksum); + String uuid = Encoder.md5hash(name + checksum); String dir = attachmentStorage.generateDir(uuid, false); VFSContainer container = attachmentStorage.getContainer(dir); String uniqueName = VFSManager.similarButNonExistingName(container, name); @@ -733,7 +733,7 @@ public class MailManager extends BasicManager { createAddress(toAddress, recipientTo, true, result, true); } if(makeRealMail && StringHelper.containsNonWhitespace(to)) { - createAddress(toAddress, to, result); + createAddress(toAddress, to); } if(cc != null) { @@ -1016,7 +1016,7 @@ public class MailManager extends BasicManager { } } - private boolean createAddress(List<Address> addressList, String address, MailerResult result) throws AddressException { + private boolean createAddress(List<Address> addressList, String address) throws AddressException { Address add = createAddress(address); if(add != null) { addressList.add(add); diff --git a/src/main/java/org/olat/core/util/resource/OresHelper.java b/src/main/java/org/olat/core/util/resource/OresHelper.java index fd45b9cb75286aedea70faf563cab2585277b888..89c6e6efefd0a40b9dee3981b3cb7f42b70eae68 100644 --- a/src/main/java/org/olat/core/util/resource/OresHelper.java +++ b/src/main/java/org/olat/core/util/resource/OresHelper.java @@ -99,7 +99,7 @@ public class OresHelper { String resourcableTypeName = ores.getResourceableTypeName(); if (resourcableTypeName.length() > 80) { //encode into an md5 hash with fixed length of 32 characters otherwise the sting may get too long for locks or db fields - resourcableTypeName = Encoder.encrypt(resourcableTypeName); + resourcableTypeName = Encoder.md5hash(resourcableTypeName); } String derivedString = resourcableTypeName+"::"+ores.getResourceableId(); if (subKey != null) { diff --git a/src/main/java/org/olat/core/util/servlets/MD5Encoder.java b/src/main/java/org/olat/core/util/servlets/MD5Encoder.java deleted file mode 100644 index e376c83290bbdcc23d821b61074f45ed41b47ced..0000000000000000000000000000000000000000 --- a/src/main/java/org/olat/core/util/servlets/MD5Encoder.java +++ /dev/null @@ -1,79 +0,0 @@ -/** -* OLAT - Online Learning and Training<br> -* http://www.olat.org -* <p> -* Licensed under the Apache License, Version 2.0 (the "License"); <br> -* you may not use this file except in compliance with the License.<br> -* You may obtain a copy of the License at -* <p> -* http://www.apache.org/licenses/LICENSE-2.0 -* <p> -* Unless required by applicable law or agreed to in writing,<br> -* software distributed under the License is distributed on an "AS IS" BASIS, <br> -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> -* See the License for the specific language governing permissions and <br> -* limitations under the License. -* <p> -* Copyright (c) since 2004 at Multimedia- & E-Learning Services (MELS),<br> -* University of Zurich, Switzerland. -* <hr> -* <a href="http://www.openolat.org"> -* OpenOLAT - Online Learning and Training</a><br> -* This file has been modified by the OpenOLAT community. Changes are licensed -* under the Apache 2.0 license as the original file. -*/ -package org.olat.core.util.servlets; - - - -/** - * Encode an MD5 digest into a String. - * <p> - * The 128 bit MD5 hash is converted into a 32 character long String. - * Each character of the String is the hexadecimal representation of 4 bits - * of the digest. - * - * @author Remy Maucherat - */ - -public final class MD5Encoder { - - - // ----------------------------------------------------- Instance Variables - - - private static final char[] hexadecimal = - {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - 'a', 'b', 'c', 'd', 'e', 'f'}; - - - // --------------------------------------------------------- Public Methods - - - /** - * Encodes the 128 bit (16 bytes) MD5 into a 32 character String. - * - * @param binaryData Array containing the digest - * @return Encoded MD5, or null if encoding failed - */ - public String encode( byte[] binaryData ) { - - if (binaryData.length != 16) - return null; - - char[] buffer = new char[32]; - - for (int i=0; i<16; i++) { - int low = (binaryData[i] & 0x0f); - int high = ((binaryData[i] & 0xf0) >> 4); - buffer[i*2] = hexadecimal[high]; - buffer[i*2 + 1] = hexadecimal[low]; - } - - return new String(buffer); - - } - - -} - diff --git a/src/main/java/org/olat/course/nodes/basiclti/LTIRunController.java b/src/main/java/org/olat/course/nodes/basiclti/LTIRunController.java index 7f79fd366168fbc300de44e31496f951c72f3b25..5c68c5897b139112cfa9330c99bac4fc1dbdf2ef 100644 --- a/src/main/java/org/olat/course/nodes/basiclti/LTIRunController.java +++ b/src/main/java/org/olat/course/nodes/basiclti/LTIRunController.java @@ -266,7 +266,7 @@ public class LTIRunController extends BasicController { } } if (data.length() > 0) { - hash = Encoder.encrypt(data); + hash = Encoder.md5hash(data); } if (isLogDebugEnabled()) { logDebug("Create accept hash::" + hash + " for data::" + data, null); diff --git a/src/main/java/org/olat/course/statistic/export/LogLineConverter.java b/src/main/java/org/olat/course/statistic/export/LogLineConverter.java index 7fdcad46ac3248bec95dce5afc55a9043961734b..9a5ca06e7d6393084438fdadce4997bcad723dc3 100644 --- a/src/main/java/org/olat/course/statistic/export/LogLineConverter.java +++ b/src/main/java/org/olat/course/statistic/export/LogLineConverter.java @@ -172,7 +172,7 @@ public class LogLineConverter { private String makeAnonymous(String s, Long courseResId) { String encodeValue = s + "-" + Long.toString(courseResId); // encode with MD5 - return Encoder.encrypt(encodeValue); + return Encoder.md5hash(encodeValue); } } diff --git a/src/main/java/org/olat/dispatcher/RemoteLoginformDispatcher.java b/src/main/java/org/olat/dispatcher/RemoteLoginformDispatcher.java index cb2c7d666aa2c01f8a097a34b7421e6392943917..b858bd29774a3e866ab08e75cf56e3665cdc8d7e 100644 --- a/src/main/java/org/olat/dispatcher/RemoteLoginformDispatcher.java +++ b/src/main/java/org/olat/dispatcher/RemoteLoginformDispatcher.java @@ -28,6 +28,7 @@ import javax.servlet.http.HttpServletResponse; import org.olat.admin.user.delete.service.UserDeletionManager; import org.olat.basesecurity.AuthHelper; import org.olat.basesecurity.BaseSecurityModule; +import org.olat.core.CoreSpringFactory; import org.olat.core.dispatcher.Dispatcher; import org.olat.core.dispatcher.DispatcherAction; import org.olat.core.gui.UserRequest; @@ -46,6 +47,7 @@ import org.olat.core.util.StringHelper; import org.olat.core.util.UserSession; import org.olat.core.util.WebappHelper; import org.olat.login.OLATAuthenticationController; +import org.olat.login.auth.OLATAuthManager; /** * <h3>Description:</h3> @@ -123,7 +125,8 @@ public class RemoteLoginformDispatcher implements Dispatcher { } // Authenticate user - Identity identity = OLATAuthenticationController.authenticate(userName, pwd); + OLATAuthManager olatAuthenticationSpi = CoreSpringFactory.getImpl(OLATAuthManager.class); + Identity identity = olatAuthenticationSpi.authenticate(null, userName, pwd); if (identity == null) { log.info("Could not authenticate user '" + userName + "', wrong password or user name"); // redirect to OLAT loginscreen, add error parameter so that the loginform can mark itself as errorfull diff --git a/src/main/java/org/olat/ims/cp/ContentPackage.java b/src/main/java/org/olat/ims/cp/ContentPackage.java index 06d52fca68447b0de955cce5f022ef720e2cb3e4..1240bea3c81ac690ef5ac88176c0a5a8e7c902d2 100644 --- a/src/main/java/org/olat/ims/cp/ContentPackage.java +++ b/src/main/java/org/olat/ims/cp/ContentPackage.java @@ -210,7 +210,7 @@ public class ContentPackage { String orgaIdentifier = getFirstOrganizationInManifest().getIdentifier(); // For the root node id of the ext-js tree we use an md5 hash. This is to // make sure that no unwanted characters are handed over to JS. - String rootNodeId = Encoder.encrypt(orgaIdentifier); + String rootNodeId = Encoder.md5hash(orgaIdentifier); return new CPTreeDataModel(orgaIdentifier, rootNodeId, this); } diff --git a/src/main/java/org/olat/ims/cp/ui/VFSCPContainer.java b/src/main/java/org/olat/ims/cp/ui/VFSCPContainer.java index f7b9a4d2f9f27b45f3f3d42babbe32be7c91c168..5fa74059cb652f555009638379655d15a9226b21 100644 --- a/src/main/java/org/olat/ims/cp/ui/VFSCPContainer.java +++ b/src/main/java/org/olat/ims/cp/ui/VFSCPContainer.java @@ -64,7 +64,7 @@ public class VFSCPContainer extends AbstractVirtualContainer implements VFSConta super(name); String orgaIdentifier = cp.getFirstOrganizationInManifest().getIdentifier(); - rootNodeId = Encoder.encrypt(orgaIdentifier); + rootNodeId = Encoder.md5hash(orgaIdentifier); this.cp = cp; cpMgm = (CPManagerImpl) CPManager.getInstance(); diff --git a/src/main/java/org/olat/ldap/LDAPLoginManagerImpl.java b/src/main/java/org/olat/ldap/LDAPLoginManagerImpl.java index ae5fbac12d154f7c37b6588ae312e418cac72b28..0fd6bd939e107a3f9a2d360c58d8e2fd72d5c870 100644 --- a/src/main/java/org/olat/ldap/LDAPLoginManagerImpl.java +++ b/src/main/java/org/olat/ldap/LDAPLoginManagerImpl.java @@ -544,7 +544,7 @@ public class LDAPLoginManagerImpl extends LDAPLoginManager implements GenericEve } // Create Identity - Identity identity = securityManager.createAndPersistIdentityAndUser(uid, user, LDAPAuthenticationController.PROVIDER_LDAP, uid, null); + Identity identity = securityManager.createAndPersistIdentityAndUser(uid, user, LDAPAuthenticationController.PROVIDER_LDAP, uid); // Add to SecurityGroup LDAP SecurityGroup secGroup = securityManager.findSecurityGroupByName(LDAPConstants.SECURITY_GROUP_LDAP); securityManager.addIdentityToSecurityGroup(identity, secGroup); @@ -662,14 +662,14 @@ public class LDAPLoginManagerImpl extends LDAPLoginManager implements GenericEve Authentication ldapAuth = securityManager.findAuthentication(identity, LDAPAuthenticationController.PROVIDER_LDAP); if(ldapAuth == null) { //BUG Fixe: update the user and test if it has a ldap provider - securityManager.createAndPersistAuthentication(identity, LDAPAuthenticationController.PROVIDER_LDAP, identity.getName(), null); + securityManager.createAndPersistAuthentication(identity, LDAPAuthenticationController.PROVIDER_LDAP, identity.getName(), null, null); } return identity; } else { if (LDAPLoginModule.isConvertExistingLocalUsersToLDAPUsers()) { // Add user to LDAP security group and add the ldap provider - securityManager.createAndPersistAuthentication(identity, LDAPAuthenticationController.PROVIDER_LDAP, identity.getName(), null); + securityManager.createAndPersistAuthentication(identity, LDAPAuthenticationController.PROVIDER_LDAP, identity.getName(), null, null); securityManager.addIdentityToSecurityGroup(identity, ldapGroup); logInfo("Found identity by LDAP username that was not yet in LDAP security group. Converted user::" + uid + " to be an LDAP managed user"); diff --git a/src/main/java/org/olat/ldap/ui/LDAPAuthenticationController.java b/src/main/java/org/olat/ldap/ui/LDAPAuthenticationController.java index d251501d7c0d956d77e37eb770cd61d2eb292dd9..637c401a5f9a27352c28bdd0261222efeec30635 100644 --- a/src/main/java/org/olat/ldap/ui/LDAPAuthenticationController.java +++ b/src/main/java/org/olat/ldap/ui/LDAPAuthenticationController.java @@ -32,7 +32,6 @@ import org.olat.basesecurity.BaseSecurity; import org.olat.basesecurity.BaseSecurityManager; import org.olat.basesecurity.BaseSecurityModule; import org.olat.core.CoreSpringFactory; -import org.olat.core.commons.persistence.DBFactory; import org.olat.core.dispatcher.DispatcherAction; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; @@ -49,7 +48,6 @@ import org.olat.core.id.context.ContextEntry; import org.olat.core.id.context.StateEntry; import org.olat.core.logging.OLATRuntimeException; import org.olat.core.logging.OLATSecurityException; -import org.olat.core.util.Encoder; import org.olat.core.util.StringHelper; import org.olat.core.util.UserSession; import org.olat.core.util.Util; @@ -59,8 +57,8 @@ import org.olat.ldap.LDAPError; import org.olat.ldap.LDAPLoginManager; import org.olat.ldap.LDAPLoginModule; import org.olat.login.LoginModule; -import org.olat.login.OLATAuthenticationController; import org.olat.login.auth.AuthenticationController; +import org.olat.login.auth.OLATAuthManager; import org.olat.login.auth.OLATAuthentcationForm; import org.olat.registration.DisclaimerController; import org.olat.registration.PwChangeController; @@ -80,10 +78,14 @@ public class LDAPAuthenticationController extends AuthenticationController imple private String provider = null; private CloseableModalController cmc; + + private final OLATAuthManager olatAuthenticationSpi; public LDAPAuthenticationController(UserRequest ureq, WindowControl control) { // use fallback translator to login and registration package super(ureq, control, Util.createPackageTranslator(LoginModule.class, ureq.getLocale(), Util.createPackageTranslator(RegistrationManager.class, ureq.getLocale()))); + + olatAuthenticationSpi = CoreSpringFactory.getImpl(OLATAuthManager.class); loginComp = createVelocityContainer("ldaplogin"); @@ -173,7 +175,7 @@ protected void event(UserRequest ureq, Component source, Event event) { } else { // try fallback to OLAT provider if configured if (LDAPLoginModule.isCacheLDAPPwdAsOLATPwdOnLogin()) { - authenticatedIdentity = OLATAuthenticationController.authenticate(login, pass); + authenticatedIdentity = olatAuthenticationSpi.authenticate(null, login, pass); } if (authenticatedIdentity != null) { provider = BaseSecurityModule.getDefaultAuthProviderIdentifier(); @@ -287,15 +289,13 @@ protected void event(UserRequest ureq, Component source, Event event) { } // Add or update an OLAT authentication token for this user if configured in the module if (identity != null && LDAPLoginModule.isCacheLDAPPwdAsOLATPwdOnLogin()) { - Authentication auth = secMgr.findAuthentication(identity, BaseSecurityModule.getDefaultAuthProviderIdentifier()); if (auth == null) { // Create new authentication token - secMgr.createAndPersistAuthentication(identity, BaseSecurityModule.getDefaultAuthProviderIdentifier(), username, Encoder.encrypt(pwd)); + secMgr.createAndPersistAuthentication(identity, BaseSecurityModule.getDefaultAuthProviderIdentifier(), username, pwd, LoginModule.getDefaultHashAlgorithm()); } else { // Reuse existing authentication token - auth.setCredential(Encoder.encrypt(pwd)); - DBFactory.getInstance().updateObject(auth); + secMgr.updateCredentials(auth, pwd, LoginModule.getDefaultHashAlgorithm()); } } return identity; diff --git a/src/main/java/org/olat/login/GuestBFWCParts.java b/src/main/java/org/olat/login/GuestBFWCParts.java index 13fc7daf0d0d724640f25a3fbadd7b32deceae2c..aba6a98b917ac8ce6471b4aa4d6bc50d45a912c7 100644 --- a/src/main/java/org/olat/login/GuestBFWCParts.java +++ b/src/main/java/org/olat/login/GuestBFWCParts.java @@ -123,7 +123,7 @@ public class GuestBFWCParts implements BaseFullWebappControllerParts { // let all extensions add sitedefinitions ExtManager extm = ExtManager.getInstance(); - Class extensionPointSites = DTabs.class; + Class<?> extensionPointSites = DTabs.class; int cnt = extm.getExtensionCnt(); for (int i = 0; i < cnt; i++) { Extension anExt = extm.getExtension(i); diff --git a/src/main/java/org/olat/login/LoginAuthprovidersController.java b/src/main/java/org/olat/login/LoginAuthprovidersController.java index 0d3ccbe2a3808def3caf416b6831489cb74e805c..ce5dbceb5623b1fb3f6dce76fc44f632ba95f989 100644 --- a/src/main/java/org/olat/login/LoginAuthprovidersController.java +++ b/src/main/java/org/olat/login/LoginAuthprovidersController.java @@ -145,7 +145,7 @@ public class LoginAuthprovidersController extends MainLayoutBasicController impl showAccessibilityPage(); olatMenuTree.setSelectedNodeId(accessibilityNode.getIdent()); } else if ("about".equals(type)) { - showAboutPage(ureq); + showAboutPage(); olatMenuTree.setSelectedNodeId(aboutNode.getIdent()); } else if ("registration".equals(type)) { // make sure the OLAT authentication controller is activated as only this one can handle registration requests @@ -272,7 +272,7 @@ public class LoginAuthprovidersController extends MainLayoutBasicController impl } else if (cmd.equals(ACTION_COOKIES)) { dmzPanel.pushContent(createVelocityContainer("cookies")); } else if (cmd.equals(ACTION_ABOUT)) { - showAboutPage(ureq);//fxdiff FXOLAT-113: business path in DMZ + showAboutPage();//fxdiff FXOLAT-113: business path in DMZ } else if (cmd.equals(ACTION_ACCESSIBILITY)) { showAccessibilityPage();//fxdiff FXOLAT-113: business path in DMZ } @@ -296,7 +296,7 @@ public class LoginAuthprovidersController extends MainLayoutBasicController impl dmzPanel.pushContent(browserCheck); } //fxdiff FXOLAT-113: business path in DMZ - protected void showAboutPage(UserRequest ureq) { + protected void showAboutPage() { //fxdiff FXOLAT-139 VelocityContainer aboutVC = createVelocityContainer("about"); // Add version info and licenses diff --git a/src/main/java/org/olat/login/LoginModule.java b/src/main/java/org/olat/login/LoginModule.java index 3e1187e5ffb3d4bab5fd48c0a0b673d519944a9b..65b794d12902ff94e2fd71d6adab028cbd3b94ed 100644 --- a/src/main/java/org/olat/login/LoginModule.java +++ b/src/main/java/org/olat/login/LoginModule.java @@ -32,6 +32,7 @@ import java.util.Map; import org.olat.core.configuration.AbstractOLATModule; import org.olat.core.configuration.PersistedProperties; import org.olat.core.logging.StartupException; +import org.olat.core.util.Encoder; import org.olat.core.util.cache.CacheWrapper; import org.olat.core.util.coordinate.CoordinatorManager; import org.olat.login.auth.AuthenticationProvider; @@ -124,6 +125,10 @@ public class LoginModule extends AbstractOLATModule { return defaultProviderName; } + public static Encoder.Algorithm getDefaultHashAlgorithm() { + return Encoder.Algorithm.sha512; + } + /** * @param provider * @return AuthenticationProvider implementation. diff --git a/src/main/java/org/olat/login/OLATAuthenticationController.java b/src/main/java/org/olat/login/OLATAuthenticationController.java index 2cc24fa1e6201cb981374dc254fe99f8dde1d5d9..1e0809b32d8368bf6e95e2edaa89055c77580dae 100644 --- a/src/main/java/org/olat/login/OLATAuthenticationController.java +++ b/src/main/java/org/olat/login/OLATAuthenticationController.java @@ -25,13 +25,10 @@ package org.olat.login; -import java.util.HashMap; import java.util.List; import java.util.Locale; import org.olat.basesecurity.AuthHelper; -import org.olat.basesecurity.BaseSecurityManager; -import org.olat.basesecurity.BaseSecurityModule; import org.olat.core.CoreSpringFactory; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; @@ -47,27 +44,21 @@ import org.olat.core.id.Identity; import org.olat.core.id.context.ContextEntry; import org.olat.core.id.context.StateEntry; import org.olat.core.logging.OLATSecurityException; -import org.olat.core.logging.Tracing; -import org.olat.core.util.Encoder; import org.olat.core.util.StringHelper; import org.olat.core.util.UserSession; import org.olat.core.util.Util; import org.olat.core.util.WebappHelper; import org.olat.core.util.i18n.I18nManager; -import org.olat.core.util.mail.MailHelper; import org.olat.login.auth.AuthenticationController; +import org.olat.login.auth.OLATAuthManager; import org.olat.login.auth.OLATAuthentcationForm; import org.olat.registration.DisclaimerController; import org.olat.registration.PwChangeController; import org.olat.registration.RegistrationController; import org.olat.registration.RegistrationManager; import org.olat.registration.RegistrationModule; -import org.olat.registration.TemporaryKey; -import org.olat.user.UserManager; import org.olat.user.UserModule; -import com.thoughtworks.xstream.XStream; - /** * Initial Date: 04.08.2004 * @@ -89,6 +80,8 @@ public class OLATAuthenticationController extends AuthenticationController imple private Link registerLink; private Link anoLink; + private final OLATAuthManager olatAuthenticationSpi; + /** * @see org.olat.login.auth.AuthenticationController#init(org.olat.core.gui.UserRequest, org.olat.core.gui.control.WindowControl) */ @@ -96,6 +89,8 @@ public class OLATAuthenticationController extends AuthenticationController imple // use fallback translator to registration module super(ureq, winControl, Util.createPackageTranslator(RegistrationManager.class, ureq.getLocale())); + olatAuthenticationSpi = CoreSpringFactory.getImpl(OLATAuthManager.class); + loginComp = createVelocityContainer("olat_log", "olatlogin"); if(UserModule.isPwdchangeallowed(null)) { @@ -203,7 +198,7 @@ public class OLATAuthenticationController extends AuthenticationController imple getLogger().audit("Login attempt on already blocked login for " + login + ". IP::" + ureq.getHttpReq().getRemoteAddr(), null); return; } - authenticatedIdentity = authenticate(login, pass); + authenticatedIdentity = olatAuthenticationSpi.authenticate(null, login, pass); if (authenticatedIdentity == null) { if (LoginModule.registerFailedLoginAttempt(login)) { getLogger().audit("Too many failed login attempts for " + login + ". Login blocked. IP::" + ureq.getHttpReq().getRemoteAddr(), null); @@ -288,19 +283,19 @@ public class OLATAuthenticationController extends AuthenticationController imple * @param pass * @return Identity if authentication was successfull, null otherwise. * @deprecated should not be part of the controller - */ + *//* public static Identity authenticate(String login, String pass) { if (pass == null) return null; // do never accept empty passwords Identity ident = BaseSecurityManager.getInstance().findIdentityByName(login); return authenticate(ident, login, pass); - } + }*/ /** * @param login * @param pass * @return Identity if authentication was successfull, null otherwise. * @deprecated should not be part of the controller - */ + *//* public static Identity authenticate(Identity ident, String login, String pass) { // check for email instead of username if ident is null if (ident == null && LoginModule.allowLoginUsingEmail()) { @@ -342,7 +337,7 @@ public class OLATAuthenticationController extends AuthenticationController imple } } return null; - } + }*/ /** * @see org.olat.core.gui.control.DefaultController#doDispose(boolean) diff --git a/src/main/java/org/olat/login/_spring/loginContext.xml b/src/main/java/org/olat/login/_spring/loginContext.xml index d0b6290d588eae44f85648fa37c4f98ffa2e3db7..0abeac4ddac7d955b71200e1262ecfb6fc9d12b0 100644 --- a/src/main/java/org/olat/login/_spring/loginContext.xml +++ b/src/main/java/org/olat/login/_spring/loginContext.xml @@ -3,10 +3,9 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans - http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> + http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="loginModule" class="org.olat.login.LoginModule"> - <property name="persistedProperties"> <bean class="org.olat.core.configuration.PersistedProperties" scope="prototype" init-method="init" destroy-method="destroy"> <constructor-arg index="0" ref="coordinatorManager"/> @@ -88,6 +87,8 @@ </bean> <bean id="afterLoginInterceptionManager" class="org.olat.login.AfterLoginInterceptionManager" /> +<bean id="olatAuthenticationSpi" class="org.olat.login.auth.OLATAuthManager" /> + </beans> \ No newline at end of file diff --git a/src/main/java/org/olat/login/auth/AuthenticationEvent.java b/src/main/java/org/olat/login/auth/AuthenticationEvent.java index c57ce4cfaceae2bfda7f3c2a637fcb34ee98ce03..748f8dcfdbfaef93f1cce67c28df40a18709004d 100644 --- a/src/main/java/org/olat/login/auth/AuthenticationEvent.java +++ b/src/main/java/org/olat/login/auth/AuthenticationEvent.java @@ -35,6 +35,7 @@ import org.olat.core.id.Identity; */ public class AuthenticationEvent extends Event { + private static final long serialVersionUID = -5353574564474813721L; Identity identity; /** @@ -48,5 +49,7 @@ public class AuthenticationEvent extends Event { /** * @return the identity that was authenticated. */ - public Identity getIdentity() { return identity; } + public Identity getIdentity() { + return identity; + } } diff --git a/src/main/java/org/olat/login/auth/AuthenticationProvider.java b/src/main/java/org/olat/login/auth/AuthenticationProvider.java index 3b3ed83f917593a90e177505b29209198a164080..954c18574d7a27550e6c1a4cd467f5c072fc6ba8 100644 --- a/src/main/java/org/olat/login/auth/AuthenticationProvider.java +++ b/src/main/java/org/olat/login/auth/AuthenticationProvider.java @@ -94,7 +94,6 @@ public class AuthenticationProvider implements ControllerCreator{ * @param language * @return Description text. */ - @SuppressWarnings("unchecked") public String getDescription(Locale locale) { Translator trans = getPackageTranslatorForLocale(locale); String desc = trans.translate("authentication.provider.description"); @@ -123,7 +122,7 @@ public class AuthenticationProvider implements ControllerCreator{ * @return a translator for the package matching the authenticationProvider */ private Translator getPackageTranslatorForLocale (Locale locale) { - Class authProvClass = null; + Class<?> authProvClass = null; try { authProvClass = Class.forName(clazz); } catch (ClassNotFoundException e) { diff --git a/src/main/java/org/olat/login/auth/AuthenticationSPI.java b/src/main/java/org/olat/login/auth/AuthenticationSPI.java new file mode 100644 index 0000000000000000000000000000000000000000..2d838872a25704314d9e247ab4f32c72ffbb2f00 --- /dev/null +++ b/src/main/java/org/olat/login/auth/AuthenticationSPI.java @@ -0,0 +1,34 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.login.auth; + +import org.olat.core.id.Identity; + +/** + * + * Initial date: 23.08.2013<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public interface AuthenticationSPI { + + public Identity authenticate(Identity identity, String login, String password); + +} diff --git a/src/main/java/org/olat/login/auth/OLATAuthManager.java b/src/main/java/org/olat/login/auth/OLATAuthManager.java index 8035f1a465cdb76274d4446d0c0f2f0001fb155e..f34f98f5db25cf199390c4717cc400f5297fba1a 100644 --- a/src/main/java/org/olat/login/auth/OLATAuthManager.java +++ b/src/main/java/org/olat/login/auth/OLATAuthManager.java @@ -25,13 +25,14 @@ package org.olat.login.auth; import java.util.Collections; +import java.util.List; import java.util.Locale; +import java.util.Map; import org.apache.velocity.VelocityContext; import org.olat.basesecurity.Authentication; import org.olat.basesecurity.BaseSecurity; import org.olat.basesecurity.BaseSecurityManager; -import org.olat.basesecurity.BaseSecurityModule; import org.olat.core.CoreSpringFactory; import org.olat.core.gui.translator.Translator; import org.olat.core.id.Identity; @@ -42,21 +43,29 @@ import org.olat.core.logging.AssertException; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; import org.olat.core.manager.BasicManager; -import org.olat.core.util.Encoder; +import org.olat.core.util.Encoder.Algorithm; import org.olat.core.util.Util; import org.olat.core.util.WebappHelper; import org.olat.core.util.i18n.I18nManager; import org.olat.core.util.mail.MailContext; import org.olat.core.util.mail.MailContextImpl; +import org.olat.core.util.mail.MailHelper; import org.olat.core.util.mail.MailTemplate; import org.olat.core.util.mail.MailerWithTemplate; import org.olat.core.util.resource.OresHelper; +import org.olat.core.util.xml.XStreamHelper; import org.olat.ldap.LDAPError; import org.olat.ldap.LDAPLoginManager; import org.olat.ldap.LDAPLoginModule; import org.olat.ldap.ui.LDAPAuthenticationController; +import org.olat.login.LoginModule; import org.olat.login.OLATAuthenticationController; +import org.olat.registration.RegistrationManager; +import org.olat.registration.TemporaryKey; import org.olat.user.UserManager; +import org.springframework.beans.factory.annotation.Autowired; + +import com.thoughtworks.xstream.XStream; /** * Description:<br> @@ -66,10 +75,81 @@ import org.olat.user.UserManager; * Initial Date: 26.09.2007 <br> * @author Felix Jost, http://www.goodsolutions.ch */ -public class OLATAuthManager extends BasicManager { +public class OLATAuthManager extends BasicManager implements AuthenticationSPI { private static OLog log = Tracing.createLoggerFor(OLATAuthenticationController.class); + @Autowired + private UserManager userManager; + @Autowired + private BaseSecurity securityManager; + + /** + * + * @param identity + * @param password + * @param provider + * @return + */ + @Override + public Identity authenticate(Identity ident, String login, String password) { + Authentication authentication; + if (ident == null) { + // check for email instead of username if ident is null + if(LoginModule.allowLoginUsingEmail()) { + if (MailHelper.isValidEmailAddress(login)){ + ident = userManager.findIdentityByEmail(login); + // check for email changed with verification workflow + if (ident == null) { + ident = findIdentInChangingEmailWorkflow(login); + } + } + } + + if(ident == null) { + authentication = securityManager.findAuthenticationByAuthusername(login, "OLAT"); + } else { + authentication = securityManager.findAuthentication(ident, "OLAT"); + } + } else { + authentication = securityManager.findAuthentication(ident, "OLAT"); + } + + if (authentication == null) { + log.audit("Error authenticating user "+login+" via provider OLAT", OLATAuthenticationController.class.getName()); + return null; + } + + // find OLAT authentication provider + 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(); + } + log.audit("Error authenticating user "+login+" via provider OLAT", OLATAuthenticationController.class.getName()); + return null; + } + + private Identity findIdentInChangingEmailWorkflow(String login){ + XStream xml = XStreamHelper.createXStreamInstance(); + + RegistrationManager rm = RegistrationManager.getInstance(); + List<TemporaryKey> tk = rm.loadTemporaryKeyByAction(RegistrationManager.EMAIL_CHANGE); + if (tk != null) { + for (TemporaryKey temporaryKey : tk) { + @SuppressWarnings("unchecked") + Map<String, String> mails = (Map<String, String>)xml.fromXML(temporaryKey.getEmailAddress()); + if (login.equals(mails.get("changedEMail"))) { + return securityManager.findIdentityByName(mails.get("currentEMail")); + } + } + } + return null; + } + + /** * Change the password of an identity. if the given identity is a LDAP-User, * the pw-change is propagated to LDAP (according to config) NOTE: caller of @@ -85,16 +165,10 @@ public class OLATAuthManager extends BasicManager { * New password. * @return True upon success. */ - public static boolean changePassword(Identity doer, Identity identity, String newPwd) { - + public boolean changePassword(Identity doer, Identity identity, String newPwd) { if (doer==null) throw new AssertException("password changing identity cannot be undefined!"); - if (identity.getKey() == null) throw new AssertException("cannot change password on a nonpersisted identity"); - // password's length is limited to 128 chars. - // The 128 bit MD5 hash is converted into a 32 character long String - String hashedPwd = Encoder.encrypt(newPwd); - BaseSecurity securityManager = BaseSecurityManager.getInstance(); - + //o_clusterREVIEW identity = securityManager.loadIdentityByKey(identity.getKey()); @@ -110,21 +184,19 @@ public class OLATAuthManager extends BasicManager { allOk = ldapError.isEmpty(); if(allOk && LDAPLoginModule.isCacheLDAPPwdAsOLATPwdOnLogin()) { - allOk &= changeOlatPassword(doer, identity, hashedPwd); + allOk &= changeOlatPassword(doer, identity, newPwd); } } - } - else { - allOk =changeOlatPassword(doer, identity, hashedPwd); + } else { + allOk = changeOlatPassword(doer, identity, newPwd); } if(allOk) { sendConfirmationEmail(doer, identity); } - return allOk; } - private static void sendConfirmationEmail(Identity doer, Identity identity) { + private void sendConfirmationEmail(Identity doer, Identity identity) { String prefsLanguage = identity.getUser().getPreferences().getLanguage(); Locale locale = I18nManager.getInstance().getLocaleOrDefault(prefsLanguage); Translator translator = Util.createPackageTranslator(OLATAuthenticationController.class, locale); @@ -151,16 +223,15 @@ public class OLATAuthManager extends BasicManager { mailer.sendMailAsSeparateMails(context, Collections.singletonList(identity), null, template, null, null); } - private static boolean changeOlatPassword(Identity doer, Identity identity, String hashedPwd) { - Authentication auth = BaseSecurityManager.getInstance().findAuthentication(identity, BaseSecurityModule.getDefaultAuthProviderIdentifier()); + private boolean changeOlatPassword(Identity doer, Identity identity, String newPwd) { + Authentication auth = securityManager.findAuthentication(identity, "OLAT"); if (auth == null) { // create new authentication for provider OLAT - auth = BaseSecurityManager.getInstance().createAndPersistAuthentication(identity, BaseSecurityModule.getDefaultAuthProviderIdentifier(), identity.getName(), hashedPwd); + auth = securityManager.createAndPersistAuthentication(identity, "OLAT", identity.getName(), newPwd, LoginModule.getDefaultHashAlgorithm()); log.audit(doer.getName() + " created new authenticatin for identity: " + identity.getName()); + } else { + auth = securityManager.updateCredentials(auth, newPwd, LoginModule.getDefaultHashAlgorithm()); + log.audit(doer.getName() + " set new password for identity: " + identity.getName()); } - - auth.setCredential(hashedPwd); - auth = BaseSecurityManager.getInstance().updateAuthentication(auth); - log.audit(doer.getName() + " set new password for identity: " +identity.getName()); return true; } @@ -170,7 +241,7 @@ public class OLATAuthManager extends BasicManager { * @param newPwd * @return */ - public static boolean changePasswordAsAdmin(Identity identity, String newPwd) { + public boolean changePasswordAsAdmin(Identity identity, String newPwd) { Identity adminUserIdentity = BaseSecurityManager.getInstance().findIdentityByName("administrator"); return changePassword(adminUserIdentity, identity, newPwd); } @@ -181,7 +252,7 @@ public class OLATAuthManager extends BasicManager { * @param newPwd * @return */ - public static boolean changePasswordByPasswordForgottenLink(Identity identity, String newPwd) { + public boolean changePasswordByPasswordForgottenLink(Identity identity, String newPwd) { return changePassword(identity, identity, newPwd); } diff --git a/src/main/java/org/olat/modules/vitero/manager/ViteroManager.java b/src/main/java/org/olat/modules/vitero/manager/ViteroManager.java index 1d5206635edf6a1b5293278d915c4bfdb510d7b2..a7caaf968fe377c2b2b65abc1be9fd156885f9f0 100644 --- a/src/main/java/org/olat/modules/vitero/manager/ViteroManager.java +++ b/src/main/java/org/olat/modules/vitero/manager/ViteroManager.java @@ -484,7 +484,7 @@ public class ViteroManager extends BasicManager implements UserDataDeletable { created = true; userId = createVmsUser(identity); if(userId > 0) { - securityManager.createAndPersistAuthentication(identity, VMS_PROVIDER, Integer.toString(userId), ""); + securityManager.createAndPersistAuthentication(identity, VMS_PROVIDER, Integer.toString(userId), null, null); } } else { userId = -1; @@ -1297,7 +1297,7 @@ public class ViteroManager extends BasicManager implements UserDataDeletable { Identity identity = securityManager.findIdentityByName(olatUsername); if(identity != null) { authenticationCreated++; - securityManager.createAndPersistAuthentication(identity, VMS_PROVIDER, Integer.toString(user.getId()), ""); + securityManager.createAndPersistAuthentication(identity, VMS_PROVIDER, Integer.toString(user.getId()), null, null); logInfo("Recreate VMS authentication for: " + identity.getName()); } } diff --git a/src/main/java/org/olat/modules/webFeed/dispatching/Path.java b/src/main/java/org/olat/modules/webFeed/dispatching/Path.java index fb750a44ef7c00c2825aa87f79493a381b06b47b..833892391ffbf5ea16a16cc9d6c1f1979dcd5b6c 100644 --- a/src/main/java/org/olat/modules/webFeed/dispatching/Path.java +++ b/src/main/java/org/olat/modules/webFeed/dispatching/Path.java @@ -513,7 +513,7 @@ public class Path { if (authentication == null) { // Create an authentication String token = RandomStringUtils.randomAlphanumeric(6); - authentication = manager.createAndPersistAuthentication(identity, TOKEN_PROVIDER, idKey, token); + authentication = manager.createAndPersistAuthentication(identity, TOKEN_PROVIDER, idKey, token, null); } // If the repository entry allows guest access it is public, thus not // private. diff --git a/src/main/java/org/olat/modules/webFeed/managers/FeedManagerImpl.java b/src/main/java/org/olat/modules/webFeed/managers/FeedManagerImpl.java index 35d29327b0d6f0a885ceb8532d282a3f0803d504..ede557ea5cd6afcc5f98cc49bd29e17bc7f85aaf 100644 --- a/src/main/java/org/olat/modules/webFeed/managers/FeedManagerImpl.java +++ b/src/main/java/org/olat/modules/webFeed/managers/FeedManagerImpl.java @@ -107,7 +107,7 @@ public class FeedManagerImpl extends FeedManager { private final XStream xstream; // Better performance when protected (apparently) - protected CacheWrapper feedCache; + protected CacheWrapper<String,Feed> feedCache; private OLog log; @@ -185,7 +185,7 @@ public class FeedManagerImpl extends FeedManager { * * @return The feed cache */ - protected CacheWrapper initFeedCache() { + protected CacheWrapper<String,Feed> initFeedCache() { if (feedCache == null) { OLATResourceable ores = OresHelper.createOLATResourceableType(Feed.class); coordinator.getSyncer().doInSync(ores, new SyncerExecutor() { @@ -521,7 +521,7 @@ public class FeedManagerImpl extends FeedManager { e.setTitle(entry.getTitle()); e.setDescription(entry.getDescription() != null ? entry.getDescription().getValue() : null); // Extract content objects from syndication item - StringBuffer sb = new StringBuffer(); + StringBuilder sb = new StringBuilder(); for (SyndContent content : (List<SyndContent>) entry.getContents()) { // we don't check for type, assume it is html or txt if (sb.length() > 0) { @@ -1234,7 +1234,7 @@ public class FeedManagerImpl extends FeedManager { public LockResult acquireLock(OLATResourceable feed, Item item, Identity identity) { String key = itemKey(item, feed); if (key.length() >= OresHelper.ORES_TYPE_LENGTH) { - key = Encoder.encrypt(key); + key = Encoder.md5hash(key); } OLATResourceable itemResource = OresHelper.createOLATResourceableType(key); LockResult lockResult = coordinator.getLocker().acquireLock(itemResource, identity, key); diff --git a/src/main/java/org/olat/registration/PwChangeForm.java b/src/main/java/org/olat/registration/PwChangeForm.java index d403ab5032a6a391114041f6ea2908675d0f53d9..9efcc534637aeaf6cdce9e2decf9a81ed27badb7 100644 --- a/src/main/java/org/olat/registration/PwChangeForm.java +++ b/src/main/java/org/olat/registration/PwChangeForm.java @@ -25,6 +25,7 @@ package org.olat.registration; +import org.olat.core.CoreSpringFactory; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.FormItemContainer; import org.olat.core.gui.components.form.flexible.elements.TextElement; @@ -48,12 +49,17 @@ public class PwChangeForm extends FormBasicController { private TextElement newpass1; private TextElement newpass2; // confirm + private final OLATAuthManager olatAuthenticationSpi; + /** * Password change form. * @param name */ public PwChangeForm(UserRequest ureq, WindowControl wControl) { super(ureq, wControl, null, Util.createPackageTranslator(ChangePasswordForm.class, ureq.getLocale())); + + olatAuthenticationSpi = CoreSpringFactory.getImpl(OLATAuthManager.class); + initForm(ureq); } @@ -79,7 +85,7 @@ public class PwChangeForm extends FormBasicController { * @param s The identity to change the password. */ public boolean saveFormData(Identity s) { - return OLATAuthManager.changePasswordByPasswordForgottenLink(s, newpass1.getValue()); + return olatAuthenticationSpi.changePasswordByPasswordForgottenLink(s, newpass1.getValue()); } @Override diff --git a/src/main/java/org/olat/registration/RegistrationManager.java b/src/main/java/org/olat/registration/RegistrationManager.java index 1eb978c9f8a376024e9f17d0b8bceb473e2d0e31..dcbd7a8865ae90365f863ca2a848b1334abd6c43 100644 --- a/src/main/java/org/olat/registration/RegistrationManager.java +++ b/src/main/java/org/olat/registration/RegistrationManager.java @@ -305,7 +305,7 @@ public class RegistrationManager extends BasicManager { */ public TemporaryKeyImpl register(String emailaddress, String ipaddress, String action) { String today = new Date().toString(); - String encryptMe = Encoder.encrypt(emailaddress + ipaddress + today); + String encryptMe = Encoder.md5hash(emailaddress + ipaddress + today); TemporaryKeyImpl tk = new TemporaryKeyImpl(emailaddress, ipaddress, encryptMe, action); DBFactory.getInstance().saveObject(tk); return tk; diff --git a/src/main/java/org/olat/restapi/security/Authentication.java b/src/main/java/org/olat/restapi/security/Authentication.java index cc2c1850edc23ebc485842171cf44a6e25d0f7f6..1da83467760addd11b675bb9bc5704422d219cd4 100644 --- a/src/main/java/org/olat/restapi/security/Authentication.java +++ b/src/main/java/org/olat/restapi/security/Authentication.java @@ -38,7 +38,7 @@ import org.olat.core.CoreSpringFactory; import org.olat.core.gui.UserRequest; import org.olat.core.id.Identity; import org.olat.core.util.StringHelper; -import org.olat.login.OLATAuthenticationController; +import org.olat.login.auth.OLATAuthManager; /** * @@ -123,7 +123,8 @@ public class Authentication { private Response loginWithPassword(String username, String password, HttpServletRequest httpRequest) { UserRequest ureq = RestSecurityHelper.getUserRequest(httpRequest); - Identity identity = OLATAuthenticationController.authenticate(username, password); + OLATAuthManager olatAuthenticationSpi = CoreSpringFactory.getImpl(OLATAuthManager.class); + Identity identity = olatAuthenticationSpi.authenticate(null, username, password); if(identity == null) { return Response.serverError().status(Status.UNAUTHORIZED).build(); } diff --git a/src/main/java/org/olat/restapi/security/RestApiLoginFilter.java b/src/main/java/org/olat/restapi/security/RestApiLoginFilter.java index 77b562c1caaacadaea2bad00293dd828f03c857a..aa83547c82b12865cc6937a6255f0abcbccc838c 100644 --- a/src/main/java/org/olat/restapi/security/RestApiLoginFilter.java +++ b/src/main/java/org/olat/restapi/security/RestApiLoginFilter.java @@ -55,7 +55,7 @@ import org.olat.core.util.UserSession; import org.olat.core.util.WebappHelper; import org.olat.core.util.i18n.I18nManager; import org.olat.core.util.session.UserSessionManager; -import org.olat.login.OLATAuthenticationController; +import org.olat.login.auth.OLATAuthManager; import org.olat.restapi.RestModule; import com.oreilly.servlet.Base64Decoder; @@ -168,7 +168,9 @@ public class RestApiLoginFilter implements Filter { if (p != -1) { String username = userPass.substring(0, p); String password = userPass.substring(p + 1); - Identity identity = OLATAuthenticationController.authenticate(username, password); + + OLATAuthManager olatAuthenticationSpi = CoreSpringFactory.getImpl(OLATAuthManager.class); + Identity identity = olatAuthenticationSpi.authenticate(null, username, password); if(identity == null) { return false; } diff --git a/src/main/java/org/olat/restapi/security/RestSecurityBeanImpl.java b/src/main/java/org/olat/restapi/security/RestSecurityBeanImpl.java index 8688b8305aa9852000c14d1a4e775beb64729ec5..b575790b292be5903ed6b36d7924cd111379a191 100644 --- a/src/main/java/org/olat/restapi/security/RestSecurityBeanImpl.java +++ b/src/main/java/org/olat/restapi/security/RestSecurityBeanImpl.java @@ -71,7 +71,7 @@ public class RestSecurityBeanImpl implements RestSecurityBean { Authentication auth = securityManager.findAuthentication(identity, REST_AUTH_PROVIDER); if(auth == null) { - auth = securityManager.createAndPersistAuthentication(identity, REST_AUTH_PROVIDER, identity.getName(), token); + auth = securityManager.createAndPersistAuthentication(identity, REST_AUTH_PROVIDER, identity.getName(), token, null); } else { auth.setCredential(token); auth = securityManager.updateAuthentication(auth); @@ -89,7 +89,7 @@ public class RestSecurityBeanImpl implements RestSecurityBean { if(!StringHelper.containsNonWhitespace(token)) return false; boolean registrated = tokenToIdentity.containsKey(token); if(!registrated) { - List<Authentication> auths = securityManager.findAuthentication(REST_AUTH_PROVIDER, token); + List<Authentication> auths = securityManager.findAuthenticationByToken(REST_AUTH_PROVIDER, token); if(auths.size() == 1) { Authentication auth = auths.get(0); tokenToIdentity.put(token, auth.getIdentity().getKey()); diff --git a/src/main/java/org/olat/shibboleth/ShibbolethMigrationForm.java b/src/main/java/org/olat/shibboleth/ShibbolethMigrationForm.java index 0030d8ce68270524688f37c9718a55473be1e068..56f8f7cb5ba9767ca42b5da00e0b164d881c835a 100644 --- a/src/main/java/org/olat/shibboleth/ShibbolethMigrationForm.java +++ b/src/main/java/org/olat/shibboleth/ShibbolethMigrationForm.java @@ -26,6 +26,8 @@ package org.olat.shibboleth; import org.olat.basesecurity.Authentication; +import org.olat.basesecurity.BaseSecurity; +import org.olat.core.CoreSpringFactory; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.FormItemContainer; import org.olat.core.gui.components.form.flexible.elements.TextElement; @@ -36,7 +38,6 @@ import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; -import org.olat.core.util.Encoder; import org.olat.login.LoginModule; /** @@ -49,24 +50,25 @@ import org.olat.login.LoginModule; */ public class ShibbolethMigrationForm extends FormBasicController { + private static final OLog log = Tracing.createLoggerFor(ShibbolethMigrationForm.class); + - private Authentication authentication; + private final Authentication authentication; private TextElement login; private TextElement password; - private OLog log = Tracing.createLoggerFor(this.getClass()); + private BaseSecurity securityManager; public ShibbolethMigrationForm(UserRequest ureq, WindowControl wControl, Authentication authentication) { super(ureq, wControl); + securityManager = CoreSpringFactory.getImpl(BaseSecurity.class); this.authentication = authentication; initForm(ureq); } @Override protected boolean validateFormLogic(UserRequest ureq) { - String credential = authentication.getCredential(); - if (credential == null) return false; - if (!credential.equals(Encoder.encrypt(password.getValue()))) { + if (!securityManager.checkCredentials(authentication, password.getValue())) { if (LoginModule.registerFailedLoginAttempt(login.getValue())) { password.setErrorKey("smf.error.blocked", null); log.audit("Too many failed login attempts for " + login.getValue() + ". Login blocked."); @@ -78,7 +80,6 @@ public class ShibbolethMigrationForm extends FormBasicController { } return true; } - /** * @return Authentication diff --git a/src/main/java/org/olat/shibboleth/ShibbolethRegistrationController.java b/src/main/java/org/olat/shibboleth/ShibbolethRegistrationController.java index 572e754fdf1e749eea97cf96c34a8015702f4a2b..9d7d9c6499b6048020aff966e8cff5961d99ccbb 100644 --- a/src/main/java/org/olat/shibboleth/ShibbolethRegistrationController.java +++ b/src/main/java/org/olat/shibboleth/ShibbolethRegistrationController.java @@ -353,7 +353,7 @@ public class ShibbolethRegistrationController extends DefaultController implemen user.setProperty(UserConstants.INSTITUTIONALEMAIL, institutionalEmail); } user.setProperty(UserConstants.INSTITUTIONALUSERIDENTIFIER, shibbolethAttributesMap.get(ShibbolethModule.getInstitutionalUserIdentifier())); - identity = secMgr.createAndPersistIdentityAndUser(choosenLogin, user, ShibbolethDispatcher.PROVIDER_SHIB, shibbolethUniqueID, null); + identity = secMgr.createAndPersistIdentityAndUser(choosenLogin, user, ShibbolethDispatcher.PROVIDER_SHIB, shibbolethUniqueID); SecurityGroup olatUserGroup = secMgr.findSecurityGroupByName(Constants.GROUP_OLATUSERS); secMgr.addIdentityToSecurityGroup(identity, olatUserGroup); // tell system that this user did accept the disclaimer @@ -365,7 +365,7 @@ public class ShibbolethRegistrationController extends DefaultController implemen Authentication auth = migrationForm.getAuthentication(); Identity authenticationedIdentity = auth.getIdentity(); BaseSecurity secMgr = BaseSecurityManager.getInstance(); - secMgr.createAndPersistAuthentication(authenticationedIdentity, ShibbolethDispatcher.PROVIDER_SHIB, shibbolethUniqueID, null); + secMgr.createAndPersistAuthentication(authenticationedIdentity, ShibbolethDispatcher.PROVIDER_SHIB, shibbolethUniqueID, null, null); // update user profile User user = authenticationedIdentity.getUser(); diff --git a/src/main/java/org/olat/user/ChangePasswordController.java b/src/main/java/org/olat/user/ChangePasswordController.java index 90c5dd32474087f36235951e406f048c25b2c7f9..3d83f89cd72c16deb952f3084ed4b70e25cf1622 100644 --- a/src/main/java/org/olat/user/ChangePasswordController.java +++ b/src/main/java/org/olat/user/ChangePasswordController.java @@ -29,10 +29,11 @@ import java.util.Iterator; import java.util.List; import org.olat.basesecurity.Authentication; -import org.olat.basesecurity.BaseSecurityModule; -import org.olat.basesecurity.Constants; import org.olat.basesecurity.BaseSecurity; import org.olat.basesecurity.BaseSecurityManager; +import org.olat.basesecurity.BaseSecurityModule; +import org.olat.basesecurity.Constants; +import org.olat.core.CoreSpringFactory; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; import org.olat.core.gui.components.velocity.VelocityContainer; @@ -47,7 +48,6 @@ import org.olat.core.util.resource.OresHelper; import org.olat.ldap.LDAPError; import org.olat.ldap.LDAPLoginModule; import org.olat.ldap.ui.LDAPAuthenticationController; -import org.olat.login.OLATAuthenticationController; import org.olat.login.SupportsAfterLoginInterceptor; import org.olat.login.auth.OLATAuthManager; @@ -72,6 +72,8 @@ public class ChangePasswordController extends BasicController implements Support private VelocityContainer myContent; private ChangePasswordForm chPwdForm; + + private final OLATAuthManager olatAuthenticationSpi; /** * @param ureq @@ -79,6 +81,8 @@ public class ChangePasswordController extends BasicController implements Support */ public ChangePasswordController(UserRequest ureq, WindowControl wControl) { super(ureq, wControl); + + olatAuthenticationSpi = CoreSpringFactory.getImpl(OLATAuthManager.class); // if a user is not allowed to change his/her own password, say it here if (!UserModule.isPwdchangeallowed(ureq.getIdentity())) { @@ -141,14 +145,14 @@ public class ChangePasswordController extends BasicController implements Support //fallback to OLAT if enabled happen automatically in LDAPAuthenticationController provenIdent = LDAPAuthenticationController.authenticate(ureq.getIdentity().getName(), oldPwd, ldapError); } else if(BaseSecurityManager.getInstance().findAuthentication(ureq.getIdentity(), BaseSecurityModule.getDefaultAuthProviderIdentifier()) != null) { - provenIdent = OLATAuthenticationController.authenticate(ureq.getIdentity().getName(), oldPwd); + provenIdent = olatAuthenticationSpi.authenticate(ureq.getIdentity(), ureq.getIdentity().getName(), oldPwd); } if (provenIdent == null) { showError("error.password.noauth"); } else { String newPwd = chPwdForm.getNewPasswordValue(); - if(OLATAuthManager.changePassword(ureq.getIdentity(), provenIdent, newPwd)) { + if(olatAuthenticationSpi.changePassword(ureq.getIdentity(), provenIdent, newPwd)) { //TODO: verify that we are NOT in a transaction (changepwd should be commited immediately) // fxdiff: we need this event for the afterlogin-controller fireEvent(ureq, Event.DONE_EVENT); diff --git a/src/main/java/org/olat/user/UserModule.java b/src/main/java/org/olat/user/UserModule.java index 020a37422ea26bdeabaa02400f9694f52ebffbdd..2d301c45a0242f93cd151891f92a916b38b673dd 100644 --- a/src/main/java/org/olat/user/UserModule.java +++ b/src/main/java/org/olat/user/UserModule.java @@ -26,7 +26,6 @@ package org.olat.user; import java.util.ArrayList; -import java.util.Iterator; import java.util.List; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; @@ -49,7 +48,6 @@ import org.olat.core.logging.OLATRuntimeException; import org.olat.core.logging.OLog; import org.olat.core.logging.StartupException; import org.olat.core.logging.Tracing; -import org.olat.core.util.Encoder; import org.olat.ldap.LDAPLoginManager; import org.olat.login.AfterLoginConfig; import org.olat.login.AfterLoginInterceptionManager; @@ -114,8 +112,7 @@ public class UserModule extends AbstractOLATModule { */ public static boolean isLoginOnBlacklist(String login) { login = login.toLowerCase(); - for (Iterator iter = getLoginBlacklist().iterator(); iter.hasNext();) { - String regexp = (String) iter.next(); + for (String regexp: getLoginBlacklist()) { if (login.matches(regexp)) { log.audit("Blacklist entry match for login '" + login + "' with regexp '" + regexp + "'."); return true; @@ -142,7 +139,7 @@ public class UserModule extends AbstractOLATModule { count ++; } - Tracing.logInfo("Successfully added " + count + " entries to login blacklist.", UserModule.class); + logInfo("Successfully added " + count + " entries to login blacklist."); // Autogeneration of test users @@ -159,16 +156,14 @@ public class UserModule extends AbstractOLATModule { // read user editable fields configuration if (defaultUsers != null) { - for (Iterator iter = defaultUsers.iterator(); iter.hasNext();) { - DefaultUser user = (DefaultUser) iter.next(); + for (DefaultUser user:defaultUsers) { createUser(user); } } if (hasTestUsers) { // read user editable fields configuration if (testUsers != null) { - for (Iterator iter = testUsers.iterator(); iter.hasNext();) { - DefaultUser user = (DefaultUser) iter.next(); + for (DefaultUser user :testUsers) { createUser(user); } } @@ -250,7 +245,7 @@ public class UserModule extends AbstractOLATModule { // Now finally create that user thing on the database with all // credentials, person etc. in one transation context! identity = BaseSecurityManager.getInstance().createAndPersistIdentityAndUser(user.getUserName(), newUser, authenticationProviderConstant, - user.getUserName(), Encoder.encrypt(user.getPassword())); + user.getUserName(), user.getPassword()); if (identity == null) { throw new OLATRuntimeException(this.getClass(), "Error, could not create user and subject with name " + user.getUserName(), null); } else { @@ -288,7 +283,7 @@ public class UserModule extends AbstractOLATModule { /** * @return List of logins on blacklist. */ - public static List getLoginBlacklist() { + public static List<String> getLoginBlacklist() { return loginBlacklistChecked; } diff --git a/src/main/java/org/olat/user/WebDAVPasswordController.java b/src/main/java/org/olat/user/WebDAVPasswordController.java index 7e4c3131489797c6f3dc976bf0a4ae135c1af67a..83f517bc7c60c9138b576801361f4d0faa42533c 100644 --- a/src/main/java/org/olat/user/WebDAVPasswordController.java +++ b/src/main/java/org/olat/user/WebDAVPasswordController.java @@ -23,8 +23,9 @@ package org.olat.user; import java.util.List; import org.olat.basesecurity.Authentication; -import org.olat.basesecurity.BaseSecurityManager; +import org.olat.basesecurity.BaseSecurity; import org.olat.basesecurity.BaseSecurityModule; +import org.olat.core.CoreSpringFactory; import org.olat.core.commons.modules.bc.FolderManager; import org.olat.core.commons.services.webdav.manager.WebDAVAuthManager; import org.olat.core.gui.UserRequest; @@ -63,8 +64,15 @@ public class WebDAVPasswordController extends FormBasicController { private FormLayoutContainer accessDataFlc; private FormLayoutContainer buttonGroupLayout; + private final WebDAVAuthManager webDAVAuthManager; + private final BaseSecurity securityManager; + public WebDAVPasswordController(UserRequest ureq, WindowControl wControl) { super(ureq,wControl, "pwdav"); + + webDAVAuthManager = CoreSpringFactory.getImpl(WebDAVAuthManager.class); + securityManager = CoreSpringFactory.getImpl(BaseSecurity.class); + initForm(ureq); } @@ -82,7 +90,7 @@ public class WebDAVPasswordController extends FormBasicController { boolean hasOlatToken = false; boolean hasWebDAVToken = false; - List<Authentication> authentications = BaseSecurityManager.getInstance().getAuthentications(ureq.getIdentity()); + List<Authentication> authentications = securityManager.getAuthentications(ureq.getIdentity()); for(Authentication auth : authentications) { if(BaseSecurityModule.getDefaultAuthProviderIdentifier().equals(auth.getProvider())) { hasOlatToken = true; @@ -161,7 +169,7 @@ public class WebDAVPasswordController extends FormBasicController { protected void formOK(UserRequest ureq) { if(passwordEl != null && passwordEl.isVisible()) { String newPassword = passwordEl.getValue(); - if(WebDAVAuthManager.changePassword(ureq.getIdentity(), ureq.getIdentity(), newPassword)) { + if(webDAVAuthManager.changePassword(ureq.getIdentity(), ureq.getIdentity(), newPassword)) { showInfo("pwdav.password.successful"); toogleChangePassword(ureq); } else { @@ -189,12 +197,14 @@ public class WebDAVPasswordController extends FormBasicController { passwordEl.setVisible(visible); confirmPasswordEl.setVisible(visible); - Authentication auth = BaseSecurityManager.getInstance().findAuthentication(ureq.getIdentity(), WebDAVAuthManager.PROVIDER_WEBDAV); + Authentication auth = securityManager.findAuthentication(ureq.getIdentity(), WebDAVAuthManager.PROVIDER_WEBDAV); String passwordPlaceholderKey = auth == null ? "pwdav.password.not_set" : "pwdav.password.set"; String passwordPlaceholder = getTranslator().translate(passwordPlaceholderKey); passwordStaticEl.setValue(passwordPlaceholder); String buttonPlaceholderKey = auth == null ? "pwdav.password.new" : "pwdav.password.change"; newButton.setI18nKey(buttonPlaceholderKey); + + flc.setDirty(true); } } diff --git a/src/main/java/org/olat/user/restapi/UserAuthenticationWebService.java b/src/main/java/org/olat/user/restapi/UserAuthenticationWebService.java index 3ee1301ea6b2ea0a9b0f769599d58bb959286806..be1985d3760f6f9c56a8039f2d4cd28ae0ecc4ab 100644 --- a/src/main/java/org/olat/user/restapi/UserAuthenticationWebService.java +++ b/src/main/java/org/olat/user/restapi/UserAuthenticationWebService.java @@ -141,7 +141,7 @@ public class UserAuthenticationWebService { String provider = authenticationVO.getProvider(); String authUsername = authenticationVO.getAuthUsername(); String credentials = authenticationVO.getCredential(); - Authentication authentication = baseSecurity.createAndPersistAuthentication(identity, provider, authUsername, credentials); + Authentication authentication = baseSecurity.createAndPersistAuthentication(identity, provider, authUsername, credentials, null); if(authentication == null) { return Response.serverError().status(Status.NOT_ACCEPTABLE).build(); } diff --git a/src/main/resources/database/mysql/alter_9_0_0_to_9_1_0.sql b/src/main/resources/database/mysql/alter_9_0_0_to_9_1_0.sql new file mode 100644 index 0000000000000000000000000000000000000000..d20bd44fcbf4f3d04a21bcb56ae34577845dfab0 --- /dev/null +++ b/src/main/resources/database/mysql/alter_9_0_0_to_9_1_0.sql @@ -0,0 +1,3 @@ +-- salted password +alter table o_bs_authentication add column salt varchar(255) default null; +alter table o_bs_authentication add column hashalgorithm varchar(16) default null; diff --git a/src/main/resources/database/mysql/setupDatabase.sql b/src/main/resources/database/mysql/setupDatabase.sql index 5c6caf39f72a1436ac7830ebcb5197285490c8cb..ebf63ab0a24abb80b5dda6863887dfdc7a2548b9 100644 --- a/src/main/resources/database/mysql/setupDatabase.sql +++ b/src/main/resources/database/mysql/setupDatabase.sql @@ -78,6 +78,8 @@ create table if not exists o_bs_authentication ( provider varchar(8), authusername varchar(255), credential varchar(255), + salt varchar(255) default null, + hashalgorithm varchar(16) default null, primary key (id), unique (provider, authusername) ); diff --git a/src/main/resources/database/oracle/alter_9_0_0_to_9_1_0.sql b/src/main/resources/database/oracle/alter_9_0_0_to_9_1_0.sql new file mode 100644 index 0000000000000000000000000000000000000000..3df574818a9baf40033195d1a031a9bd21e65360 --- /dev/null +++ b/src/main/resources/database/oracle/alter_9_0_0_to_9_1_0.sql @@ -0,0 +1,3 @@ +-- salted password +alter table o_bs_authentication add (salt varchar(255)); +alter table o_bs_authentication add (hashalgorithm varchar(16)); diff --git a/src/main/resources/database/oracle/setupDatabase.sql b/src/main/resources/database/oracle/setupDatabase.sql index 17a7f501a389996bac9ad16532e2b6acf6bac790..db0de6b77b66c472ccf23715a6cab12bd523c08a 100644 --- a/src/main/resources/database/oracle/setupDatabase.sql +++ b/src/main/resources/database/oracle/setupDatabase.sql @@ -85,6 +85,8 @@ CREATE TABLE o_bs_authentication ( provider varchar2(8 char), authusername varchar2(255 char), credential varchar2(255 char), + salt varchar2(255 char), + hashalgorithm varchar2(16 char), PRIMARY KEY (id), CONSTRAINT u_o_bs_authentication UNIQUE (provider, authusername) ); diff --git a/src/main/resources/database/postgresql/alter_9_0_0_to_9_1_0.sql b/src/main/resources/database/postgresql/alter_9_0_0_to_9_1_0.sql new file mode 100644 index 0000000000000000000000000000000000000000..d20bd44fcbf4f3d04a21bcb56ae34577845dfab0 --- /dev/null +++ b/src/main/resources/database/postgresql/alter_9_0_0_to_9_1_0.sql @@ -0,0 +1,3 @@ +-- salted password +alter table o_bs_authentication add column salt varchar(255) default null; +alter table o_bs_authentication add column hashalgorithm varchar(16) default null; diff --git a/src/main/resources/database/postgresql/setupDatabase.sql b/src/main/resources/database/postgresql/setupDatabase.sql index 958f197b43b792834093c8502da5bfd726e3895e..23f1872ffd5ddf0ff9eae715a946ac6b898dd6aa 100644 --- a/src/main/resources/database/postgresql/setupDatabase.sql +++ b/src/main/resources/database/postgresql/setupDatabase.sql @@ -76,6 +76,8 @@ create table o_bs_authentication ( provider varchar(8), authusername varchar(255), credential varchar(255), + salt varchar(255) default null, + hashalgorithm varchar(16) default null, primary key (id), unique (provider, authusername) ); diff --git a/src/test/java/org/olat/basesecurity/BaseSecurityManagerTest.java b/src/test/java/org/olat/basesecurity/BaseSecurityManagerTest.java index 479b27c95a0c68d293931e7c5883b230ccd4b450..d538a6d41bc102bcc546a247ce5fb16daa659223 100644 --- a/src/test/java/org/olat/basesecurity/BaseSecurityManagerTest.java +++ b/src/test/java/org/olat/basesecurity/BaseSecurityManagerTest.java @@ -38,7 +38,6 @@ import org.olat.core.id.Identity; import org.olat.core.id.Roles; import org.olat.core.id.User; import org.olat.core.id.UserConstants; -import org.olat.core.util.Encoder; import org.olat.resource.OLATResource; import org.olat.test.JunitTestHelper; import org.olat.test.OlatTestCase; @@ -64,7 +63,7 @@ public class BaseSecurityManagerTest extends OlatTestCase { public void testCreateIdentity() { String name = "createid-" + UUID.randomUUID().toString(); User user = userManager.createUser("first" + name, "last" + name, name + "@frentix.com"); - Identity identity = securityManager.createAndPersistIdentityAndUser(name, user, BaseSecurityModule.getDefaultAuthProviderIdentifier(), name, Encoder.encrypt("secret")); + Identity identity = securityManager.createAndPersistIdentityAndUser(name, user, BaseSecurityModule.getDefaultAuthProviderIdentifier(), name, "secret"); dbInstance.commitAndCloseSession(); Assert.assertNotNull(identity); @@ -86,7 +85,7 @@ public class BaseSecurityManagerTest extends OlatTestCase { User user = userManager.createUser("first" + name, "last" + name, name + "@frentix.com"); user.setProperty(UserConstants.COUNTRY, ""); user.setProperty(UserConstants.CITY, "Basel"); - Identity identity = securityManager.createAndPersistIdentityAndUser(name, user, BaseSecurityModule.getDefaultAuthProviderIdentifier(), name, Encoder.encrypt("secret")); + Identity identity = securityManager.createAndPersistIdentityAndUser(name, user, BaseSecurityModule.getDefaultAuthProviderIdentifier(), name, "secret"); dbInstance.commitAndCloseSession(); //reload and update @@ -836,15 +835,4 @@ public class BaseSecurityManagerTest extends OlatTestCase { Assert.assertTrue(permissions.contains("test.gpor-1_2")); Assert.assertFalse(permissions.contains("test.gpor-1_3")); } - - @Test - public void findCredentials() { - //create a user with the default provider - Identity id = JunitTestHelper.createAndPersistIdentityAsUser("find-cred-" + UUID.randomUUID().toString()); - - dbInstance.commitAndCloseSession(); - - String credential = securityManager.findCredentials(id, BaseSecurityModule.getDefaultAuthProviderIdentifier()); - Assert.assertNotNull(credential); - } } diff --git a/src/test/java/org/olat/basesecurity/BaseSecurityTest.java b/src/test/java/org/olat/basesecurity/BaseSecurityTest.java index 7ee5f0a4faa0206584b8367869e4018e9a62d323..f51fffaab029c42f30d8e0e00e64b3ba6c3a547a 100644 --- a/src/test/java/org/olat/basesecurity/BaseSecurityTest.java +++ b/src/test/java/org/olat/basesecurity/BaseSecurityTest.java @@ -46,7 +46,6 @@ import org.olat.core.id.User; import org.olat.core.id.UserConstants; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; -import org.olat.core.util.Encoder; import org.olat.test.JunitTestHelper; import org.olat.test.OlatTestCase; import org.olat.user.UserManager; @@ -482,13 +481,13 @@ public class BaseSecurityTest extends OlatTestCase { try { User onePropUser = UserManager.getInstance().createUser("onepropuser", "onepropuser", "onepropuser@lustig.com"); onePropUser.setProperty(UserConstants.FIRSTNAME, "one"); - Identity onePropeIdentity = baseSecurityManager.createAndPersistIdentityAndUser("onePropUser", onePropUser, BaseSecurityModule.getDefaultAuthProviderIdentifier(), "onepropuser", Encoder.encrypt("ppp")); + Identity onePropeIdentity = baseSecurityManager.createAndPersistIdentityAndUser("onePropUser", onePropUser, BaseSecurityModule.getDefaultAuthProviderIdentifier(), "onepropuser", "ppp"); Assert.assertNotNull(onePropeIdentity); User twoPropUser = UserManager.getInstance().createUser("twopropuser", "twopropuser", "twopropuser@lustig.com"); twoPropUser.setProperty(UserConstants.FIRSTNAME, "two"); twoPropUser.setProperty(UserConstants.LASTNAME, "prop"); - Identity twoPropeIdentity = baseSecurityManager.createAndPersistIdentityAndUser("twopropuser", twoPropUser, BaseSecurityModule.getDefaultAuthProviderIdentifier(), "twopropuser", Encoder.encrypt("ppp")); + Identity twoPropeIdentity = baseSecurityManager.createAndPersistIdentityAndUser("twopropuser", twoPropUser, BaseSecurityModule.getDefaultAuthProviderIdentifier(), "twopropuser", "ppp"); Assert.assertNotNull(twoPropeIdentity); // commit DBFactory.getInstance().closeSession(); @@ -575,7 +574,7 @@ public class BaseSecurityTest extends OlatTestCase { multiPropUser.setProperty(UserConstants.INSTITUTIONALEMAIL, "multiinst@lustig.com"); multiPropUser.setProperty(UserConstants.INSTITUTIONALUSERIDENTIFIER, "multiinst"); multiPropUser.setProperty(UserConstants.CITY, "züri"); - Identity onePropeIdentity = baseSecurityManager.createAndPersistIdentityAndUser("multiPropUser", multiPropUser, BaseSecurityModule.getDefaultAuthProviderIdentifier(), "multipropuser", Encoder.encrypt("ppp")); + Identity onePropeIdentity = baseSecurityManager.createAndPersistIdentityAndUser("multiPropUser", multiPropUser, BaseSecurityModule.getDefaultAuthProviderIdentifier(), "multipropuser", "ppp"); Assert.assertNotNull(onePropeIdentity); // commit @@ -752,7 +751,7 @@ public class BaseSecurityTest extends OlatTestCase { User user = UserManager.getInstance().createUser(name+"_Firstname", name + "_Lastname", name + "@lustig.com"); user.setProperty(UserConstants.INSTITUTIONALNAME, "unizh2"); user.setProperty(UserConstants.INSTITUTIONALUSERIDENTIFIER, "12-345-678-908"); - ident = baseSecurityManager.createAndPersistIdentityAndUser(name, user, authProvider, name, Encoder.encrypt("ppp")); + ident = baseSecurityManager.createAndPersistIdentityAndUser(name, user, authProvider, name, "ppp"); return ident; } } diff --git a/src/test/java/org/olat/basesecurity/SecurityManagerTest.java b/src/test/java/org/olat/basesecurity/SecurityManagerTest.java index 0ae7b08444e51c48a51013e2db625f269b52d847..6b36385ecf16e909009080a46716a4009eed7b08 100644 --- a/src/test/java/org/olat/basesecurity/SecurityManagerTest.java +++ b/src/test/java/org/olat/basesecurity/SecurityManagerTest.java @@ -50,6 +50,7 @@ import org.olat.core.id.Identity; import org.olat.core.id.UserConstants; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; +import org.olat.core.util.Encoder; import org.olat.test.JunitTestHelper; import org.olat.test.OlatTestCase; @@ -156,7 +157,7 @@ public class SecurityManagerTest extends OlatTestCase { assertEquals(1, userList.size()); // 3) two fields wheras only one matches to one single user - sm.createAndPersistAuthentication(s1, "mytest_p", s1.getName(), "sdf"); + sm.createAndPersistAuthentication(s1, "mytest_p", s1.getName(), "sdf", Encoder.Algorithm.sha512); String[] myProviders = new String[] {"mytest_p", "non-prov"}; for (int i = 0; i < myProviders.length; i++) { assertTrue("Provider name.length must be <= 8", myProviders[i].length() <= 8); diff --git a/src/test/java/org/olat/core/util/EncoderTest.java b/src/test/java/org/olat/core/util/EncoderTest.java new file mode 100644 index 0000000000000000000000000000000000000000..3a31c4745af36dfc546f2765fe3205638515cb8a --- /dev/null +++ b/src/test/java/org/olat/core/util/EncoderTest.java @@ -0,0 +1,87 @@ +package org.olat.core.util; + +import java.util.HashSet; +import java.util.Set; + +import junit.framework.Assert; + +import org.junit.Test; +import org.olat.core.util.Encoder.Algorithm; + +/** + * + * Initial date: 23.08.2013<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class EncoderTest { + + @Test + public void testCompatibility() { + //the openolat password as saved on our database + String openolat = "c14c4d01c090a065eaa619ca92f8cbc0"; + + String hashedOpenolat_1 = Encoder.md5("openolat", null); + Assert.assertEquals(openolat, hashedOpenolat_1); + + String encryptedOpenolat_1 = Encoder.md5hash("openolat"); + Assert.assertEquals(openolat, encryptedOpenolat_1); + + String encryptedOpenolat_2 = Encoder.encrypt("openolat", null, Algorithm.md5); + Assert.assertEquals(openolat, encryptedOpenolat_2); + } + + /** + * Dummy test which check that the salts are not always equals. + */ + @Test + public void testSalt() { + Set<String> history = new HashSet<String>(); + for(int i=0; i<100; i++) { + String salt = Encoder.getSalt(); + Assert.assertFalse(history.contains(salt)); + history.add(salt); + } + Assert.assertEquals(100, history.size()); + } + + @Test + public void testSHA1() { + String password = "openolat#19"; + String salt = "FEHq1hZYqd54/iCoboHvBQ=="; + String hash = "dkpoYSfn3uz6UcwdFhauuOFgX7Q="; + + String shaOutput = Encoder.encrypt(password, salt, Algorithm.sha1); + Assert.assertEquals(hash, shaOutput); + } + + @Test + public void testSHA256() { + String password = "openolat#19"; + String salt = "dbStjLmL2av7LObcN/69ww=="; + String hash = "+iTqibtIuur1t1IBYJ3P1i/iq6Xx2cb38wHc7LXHLHQ="; + + String shaOutput = Encoder.encrypt(password, salt, Algorithm.sha256); + Assert.assertEquals(hash, shaOutput); + } + + @Test + public void testSHA512() { + String password = "openolat#19"; + String salt = "Y4nY4VFWaiSnM6qe88ZxbQ=="; + String hash = "3+OTGOdnladWlLOY71DNnYa1YpaNmrDyefCvp/LM7d417frbjabdJnWkxK6JLOwxzJkpSfyjg3LY\nY8I0Mnq8PA=="; + + String shaOutput = Encoder.encrypt(password, salt, Algorithm.sha512); + Assert.assertEquals(hash, shaOutput); + } + + @Test + public void testPBKDF2() { + String password = "openolat#19"; + String salt = "lji1/YS8rEwv/ML0JUV2OQ=="; + String hash = "kUUaki27mueSEkrFeAFQoLfs1k8="; + + String shaOutput = Encoder.encrypt(password, salt, Algorithm.pbkdf2); + Assert.assertEquals(hash, shaOutput); + } +} diff --git a/src/test/java/org/olat/group/test/BusinessGroupServiceTest.java b/src/test/java/org/olat/group/test/BusinessGroupServiceTest.java index d82d36fd99c7540a5333d4d9ee1c5673cc302e45..9eade2339a36e5cba7ab2586cbc76fbc1dfe5955 100644 --- a/src/test/java/org/olat/group/test/BusinessGroupServiceTest.java +++ b/src/test/java/org/olat/group/test/BusinessGroupServiceTest.java @@ -47,7 +47,6 @@ import org.olat.core.id.Roles; import org.olat.core.id.User; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; -import org.olat.core.util.Encoder; import org.olat.core.util.mail.MailPackage; import org.olat.group.BusinessGroup; import org.olat.group.BusinessGroupService; @@ -169,8 +168,8 @@ public class BusinessGroupServiceTest extends OlatTestCase { bgWithWaitingList.setMaxParticipants(new Integer(2)); // Identities String suffix = UUID.randomUUID().toString(); - User UserWg1 = userManager.createAndPersistUser("FirstName_" + suffix, "LastName_" + suffix, suffix + "_junittest@olat.unizh.ch"); - wg1 = securityManager.createAndPersistIdentity(suffix, UserWg1, BaseSecurityModule.getDefaultAuthProviderIdentifier(), suffix, Encoder.encrypt("wg1")); + User userWg1 = userManager.createAndPersistUser("FirstName_" + suffix, "LastName_" + suffix, suffix + "_junittest@olat.unizh.ch"); + wg1 = securityManager.createAndPersistIdentity(suffix, userWg1, BaseSecurityModule.getDefaultAuthProviderIdentifier(), suffix, "wg1"); dbInstance.commitAndCloseSession(); diff --git a/src/test/java/org/olat/ldap/LDAPLoginTest.java b/src/test/java/org/olat/ldap/LDAPLoginTest.java index 1dcdb3a2a443902cae623767e8ed05cff6af08ae..d17c341b195fe1d1382ba562a35d2ceffaf392e8 100644 --- a/src/test/java/org/olat/ldap/LDAPLoginTest.java +++ b/src/test/java/org/olat/ldap/LDAPLoginTest.java @@ -169,7 +169,7 @@ public class LDAPLoginTest extends OlatTestCase { try { //create user but with different attributes - must fail since user already exists User user = UserManager.getInstance().createUser("klaus", "Meier", "klaus@meier.ch"); - Identity identity = securityManager.createAndPersistIdentityAndUser("kmeier", user, "LDAP", "kmeier", null); + Identity identity = securityManager.createAndPersistIdentityAndUser("kmeier", user, "LDAP", "kmeier"); SecurityGroup secGroup = securityManager.findSecurityGroupByName(LDAPConstants.SECURITY_GROUP_LDAP); securityManager.addIdentityToSecurityGroup(identity, secGroup); @@ -188,7 +188,7 @@ public class LDAPLoginTest extends OlatTestCase { } else { //create user but with different attributes - must fail since user already exists User user = UserManager.getInstance().createUser("klaus", "Meier", "klaus@meier.ch"); - Identity identity = securityManager.createAndPersistIdentityAndUser("kmeier", user, "LDAP", "kmeier", null); + Identity identity = securityManager.createAndPersistIdentityAndUser("kmeier", user, "LDAP", "kmeier"); SecurityGroup secGroup = securityManager.findSecurityGroupByName(LDAPConstants.SECURITY_GROUP_LDAP); securityManager.addIdentityToSecurityGroup(identity, secGroup); // simulate closed session (user adding from startup job) @@ -250,14 +250,14 @@ public class LDAPLoginTest extends OlatTestCase { //create some users in LDAPSecurityGroup User user = UserManager.getInstance().createUser("grollia", "wa", "gorrila@olat.org"); - Identity identity = securityManager.createAndPersistIdentityAndUser("gorilla", user, "LDAP", "gorrila", null); + Identity identity = securityManager.createAndPersistIdentityAndUser("gorilla", user, "LDAP", "gorrila"); SecurityGroup secGroup1 = securityManager.findSecurityGroupByName(LDAPConstants.SECURITY_GROUP_LDAP); securityManager.addIdentityToSecurityGroup(identity, secGroup1); user = UserManager.getInstance().createUser("wer", "immer", "immer@olat.org"); - identity = securityManager.createAndPersistIdentityAndUser("der", user, "LDAP", "der", null); + identity = securityManager.createAndPersistIdentityAndUser("der", user, "LDAP", "der"); securityManager.addIdentityToSecurityGroup(identity, secGroup1); user = UserManager.getInstance().createUser("die", "da", "chaspi@olat.org"); - identity = securityManager.createAndPersistIdentityAndUser("das", user, "LDAP", "das", null); + identity = securityManager.createAndPersistIdentityAndUser("das", user, "LDAP", "das"); securityManager.addIdentityToSecurityGroup(identity, secGroup1); // simulate closed session @@ -330,11 +330,11 @@ public class LDAPLoginTest extends OlatTestCase { //create Users in LDAP Group only existing in OLAT User user1 = UserManager.getInstance().createUser("hansi", "hürlima", "hansi@hansli.com"); - Identity identity1 = securityManager.createAndPersistIdentityAndUser("hansi", user1, "LDAP", "hansi", null); + Identity identity1 = securityManager.createAndPersistIdentityAndUser("hansi", user1, "LDAP", "hansi"); SecurityGroup secGroup1 = securityManager.findSecurityGroupByName(LDAPConstants.SECURITY_GROUP_LDAP); securityManager.addIdentityToSecurityGroup(identity1, secGroup1); user1 = UserManager.getInstance().createUser("chaspi", "meier", "chaspi@hansli.com"); - identity1 = securityManager.createAndPersistIdentityAndUser("chaspi", user1, "LDAP", "chaspi", null); + identity1 = securityManager.createAndPersistIdentityAndUser("chaspi", user1, "LDAP", "chaspi"); securityManager.addIdentityToSecurityGroup(identity1, secGroup1); //create User to Delete List diff --git a/src/test/java/org/olat/restapi/UserAuthenticationMgmtTest.java b/src/test/java/org/olat/restapi/UserAuthenticationMgmtTest.java index 3cb8b5759bb7cb27c3912b8c3c01ef974b2b905a..f204bb3a33685240bb07680b15a6511b6193af67 100644 --- a/src/test/java/org/olat/restapi/UserAuthenticationMgmtTest.java +++ b/src/test/java/org/olat/restapi/UserAuthenticationMgmtTest.java @@ -55,6 +55,7 @@ import org.olat.basesecurity.BaseSecurity; import org.olat.basesecurity.BaseSecurityManager; import org.olat.core.commons.persistence.DBFactory; import org.olat.core.id.Identity; +import org.olat.core.util.Encoder; import org.olat.restapi.support.vo.AuthenticationVO; import org.olat.test.OlatJerseyTestCase; @@ -155,7 +156,7 @@ public class UserAuthenticationMgmtTest extends OlatJerseyTestCase { //create an authentication token BaseSecurity baseSecurity = BaseSecurityManager.getInstance(); Identity adminIdent = baseSecurity.findIdentityByName("administrator"); - Authentication authentication = baseSecurity.createAndPersistAuthentication(adminIdent, "REST-A-2", "administrator", "credentials"); + Authentication authentication = baseSecurity.createAndPersistAuthentication(adminIdent, "REST-A-2", "administrator", "credentials", Encoder.Algorithm.sha512); assertTrue(authentication != null && authentication.getKey() != null && authentication.getKey().longValue() > 0); DBFactory.getInstance().intermediateCommit(); diff --git a/src/test/java/org/olat/test/AllTestsJunit4.java b/src/test/java/org/olat/test/AllTestsJunit4.java index 56e54c5b1b34d8f19b8d91516c8a747825796e9e..0163194b60c8f52b642c7f25c885bdeb324fa76d 100644 --- a/src/test/java/org/olat/test/AllTestsJunit4.java +++ b/src/test/java/org/olat/test/AllTestsJunit4.java @@ -60,6 +60,7 @@ import org.junit.runners.Suite; org.olat.core.util.coordinate.LockEntryTest.class, org.olat.core.util.StringHelperTest.class, org.olat.core.util.FormatterTest.class, + org.olat.core.util.EncoderTest.class, org.olat.core.util.mail.manager.MailManagerTest.class, org.olat.core.id.context.BusinessControlFactoryTest.class, org.olat.core.id.context.HistoryManagerTest.class, @@ -95,6 +96,7 @@ import org.junit.runners.Suite; org.olat.basesecurity.BaseSecurityTest.class,//ok org.olat.basesecurity.BaseSecurityManagerTest.class,//ok org.olat.user.UserManagerTest.class,//ok + org.olat.user.UserNameAndPasswordSyntaxCheckerWithRegexpTest.class,//ok org.olat.repository.RepositoryManagerTest.class,//ok org.olat.repository.RepositoryManagerConcurrentTest.class,//ok org.olat.repository.RepositoryManagerQueryTest.class,//ok diff --git a/src/test/java/org/olat/test/JunitTestHelper.java b/src/test/java/org/olat/test/JunitTestHelper.java index f3776c42c1c9eee0f5d8503f2dfa704299e8377b..b3ede57d305a089d8c498d985c21bd3d8573a35a 100644 --- a/src/test/java/org/olat/test/JunitTestHelper.java +++ b/src/test/java/org/olat/test/JunitTestHelper.java @@ -42,7 +42,6 @@ import org.olat.core.id.OLATResourceable; import org.olat.core.id.Roles; import org.olat.core.id.User; import org.olat.core.util.CodeHelper; -import org.olat.core.util.Encoder; import org.olat.core.util.resource.OresHelper; import org.olat.course.CourseFactory; import org.olat.course.DeployableCourseExport; @@ -107,8 +106,7 @@ public class JunitTestHelper { SecurityGroup group = securityManager.findSecurityGroupByName(Constants.GROUP_OLATUSERS); if (group == null) group = securityManager.createAndPersistNamedSecurityGroup(Constants.GROUP_OLATUSERS); User user = UserManager.getInstance().createUser("first" + login, "last" + login, login + "@" + maildomain); - identity = securityManager.createAndPersistIdentityAndUser(login, user, BaseSecurityModule.getDefaultAuthProviderIdentifier(), login, - Encoder.encrypt(PWD)); + identity = securityManager.createAndPersistIdentityAndUser(login, user, BaseSecurityModule.getDefaultAuthProviderIdentifier(), login, PWD); securityManager.addIdentityToSecurityGroup(identity, group); return identity; } @@ -125,8 +123,7 @@ public class JunitTestHelper { SecurityGroup group = securityManager.findSecurityGroupByName(Constants.GROUP_AUTHORS); if (group == null) group = securityManager.createAndPersistNamedSecurityGroup(Constants.GROUP_AUTHORS); User user = UserManager.getInstance().createUser("first" + login, "last" + login, login + "@" + maildomain); - identity = securityManager.createAndPersistIdentityAndUser(login, user, BaseSecurityModule.getDefaultAuthProviderIdentifier(), login, - Encoder.encrypt(PWD)); + identity = securityManager.createAndPersistIdentityAndUser(login, user, BaseSecurityModule.getDefaultAuthProviderIdentifier(), login, PWD); securityManager.addIdentityToSecurityGroup(identity, group); return identity; } @@ -143,8 +140,7 @@ public class JunitTestHelper { SecurityGroup group = securityManager.findSecurityGroupByName(Constants.GROUP_ADMIN); if (group == null) group = securityManager.createAndPersistNamedSecurityGroup(Constants.GROUP_ADMIN); User user = UserManager.getInstance().createUser("first" + login, "last" + login, login + "@" + maildomain); - identity = securityManager.createAndPersistIdentityAndUser(login, user, BaseSecurityModule.getDefaultAuthProviderIdentifier(), login, - Encoder.encrypt(PWD)); + identity = securityManager.createAndPersistIdentityAndUser(login, user, BaseSecurityModule.getDefaultAuthProviderIdentifier(), login, PWD); securityManager.addIdentityToSecurityGroup(identity, group); return identity; } diff --git a/src/test/java/org/olat/test/Selenium2TestsJunit4.java b/src/test/java/org/olat/test/Selenium2TestsJunit4.java deleted file mode 100644 index 232f4a89706a921b42efcfbf05bbfe35a54aa587..0000000000000000000000000000000000000000 --- a/src/test/java/org/olat/test/Selenium2TestsJunit4.java +++ /dev/null @@ -1,49 +0,0 @@ -/** - * <a href="http://www.openolat.org"> - * OpenOLAT - Online Learning and Training</a><br> - * <p> - * Licensed under the Apache License, Version 2.0 (the "License"); <br> - * you may not use this file except in compliance with the License.<br> - * You may obtain a copy of the License at the - * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> - * <p> - * Unless required by applicable law or agreed to in writing,<br> - * software distributed under the License is distributed on an "AS IS" BASIS, <br> - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> - * See the License for the specific language governing permissions and <br> - * limitations under the License. - * <p> - * Initial code contributed and copyrighted by<br> - * frentix GmbH, http://www.frentix.com - * <p> - */ -package org.olat.test; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -/** - * Description:<br/> - * May be deprecated, see pom.xml surefire configuration. - * - * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com - * @author jkraehemann, joel.kraehemann@frentix.com, frentix.com - */ -@RunWith(Suite.class) -@Suite.SuiteClasses({ - org.olat.login.FunctionalLoginTest.class, - org.olat.login.FunctionalResumeTest.class, - org.olat.portal.FunctionalSettingsTest.class, - org.olat.portfolio.FunctionalArtefactTest.class, - org.olat.course.FunctionalBackTest.class, - org.olat.course.FunctionalCourseTest.class, - org.olat.course.nodes.cp.FunctionalCPTest.class, - org.olat.course.nodes.feed.FunctionalBlogTest.class, - org.olat.course.nodes.feed.FunctionalPodcastTest.class, - org.olat.course.nodes.iq.FunctionalIQTestTest.class, - org.olat.course.nodes.portfolio.FunctionalPortfolioTest.class, - org.olat.course.nodes.wiki.FunctionalWikiTest.class -}) -public class Selenium2TestsJunit4 { - // -} \ No newline at end of file diff --git a/src/test/java/org/olat/user/UserManagerTest.java b/src/test/java/org/olat/user/UserManagerTest.java index 185861eebee55a4e43576be86198ca76dd5cf859..70a828e06e315027528ebb918b46705c0a38f0a2 100644 --- a/src/test/java/org/olat/user/UserManagerTest.java +++ b/src/test/java/org/olat/user/UserManagerTest.java @@ -31,7 +31,6 @@ import org.olat.basesecurity.BaseSecurityModule; import org.olat.core.commons.persistence.DB; import org.olat.core.id.Identity; import org.olat.core.id.User; -import org.olat.core.util.Encoder; import org.olat.test.OlatTestCase; import org.springframework.beans.factory.annotation.Autowired; @@ -57,7 +56,7 @@ public class UserManagerTest extends OlatTestCase { String name = "createid-" + UUID.randomUUID().toString(); String email = name + "@frentix.com"; User user = userManager.createUser("first" + name, "last" + name, email); - Identity identity = securityManager.createAndPersistIdentityAndUser(name, user, BaseSecurityModule.getDefaultAuthProviderIdentifier(), name, Encoder.encrypt("secret")); + Identity identity = securityManager.createAndPersistIdentityAndUser(name, user, BaseSecurityModule.getDefaultAuthProviderIdentifier(), name, "secret"); dbInstance.commitAndCloseSession(); //get empty (must survive) diff --git a/src/test/java/org/olat/user/UserNameAndPasswordSyntaxCheckerWithRegexpTest.java b/src/test/java/org/olat/user/UserNameAndPasswordSyntaxCheckerWithRegexpTest.java new file mode 100644 index 0000000000000000000000000000000000000000..2962496f32d04741715d641e4c1db29c4e4f8388 --- /dev/null +++ b/src/test/java/org/olat/user/UserNameAndPasswordSyntaxCheckerWithRegexpTest.java @@ -0,0 +1,45 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.user; + +import junit.framework.Assert; + +import org.junit.Test; + +/** + * + * Initial date: 23.08.2013<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class UserNameAndPasswordSyntaxCheckerWithRegexpTest { + + @Test + public void testCustom() { + //Min. 7 characters, one uppercase, one lowercase, one number + UserNameAndPasswordSyntaxCheckerWithRegexp checker = new UserNameAndPasswordSyntaxCheckerWithRegexp(); + checker.setPasswordRegExp("(?=^.{7,}$)((?=.*\\d)|(?=.*\\W+))(?![.\\n])(?=.*[A-Z])(?=.*[a-z]).*$"); + + Assert.assertTrue(checker.syntaxCheckOlatPassword("Kanu#01")); + Assert.assertTrue(checker.syntaxCheckOlatPassword("Kanuunc1")); + Assert.assertFalse(checker.syntaxCheckOlatPassword("Kanu#1"));//less than 7 characters + Assert.assertFalse(checker.syntaxCheckOlatPassword("Kanuunch"));//no number + } +}