From 8c8112e95f1e4ad27b9cd75de63603002beba4e7 Mon Sep 17 00:00:00 2001
From: srosse <none@none>
Date: Fri, 18 Mar 2016 09:05:21 +0100
Subject: [PATCH] OO-1941: update the last login field of identity with a
 dedicated hibernate mapping

---
 .../delete/service/UserDeletionManager.java   |  11 +-
 .../admin/user/imp/TransientIdentity.java     |   5 -
 .../olat/admin/user/imp/UpdateIdentity.java   |   5 -
 .../org/olat/basesecurity/BaseSecurity.java   |   2 +-
 .../basesecurity/BaseSecurityManager.java     |  11 +-
 .../olat/basesecurity/IdentityImpl.hbm.xml    |   2 +-
 .../org/olat/basesecurity/IdentityImpl.java   |   9 +-
 .../model/IdentityLastLoginImpl.java          |  92 ++++++++++
 src/main/java/org/olat/core/id/Identity.java  |   7 +-
 .../olat/core/util/mail/ui/EMailIdentity.java |   4 -
 .../course/run/preview/PreviewIdentity.java   |   5 -
 src/main/resources/META-INF/persistence.xml   |   1 +
 .../basesecurity/SecurityManagerTest.java     | 160 +++++++-----------
 13 files changed, 174 insertions(+), 140 deletions(-)
 create mode 100644 src/main/java/org/olat/basesecurity/model/IdentityLastLoginImpl.java

diff --git a/src/main/java/org/olat/admin/user/delete/service/UserDeletionManager.java b/src/main/java/org/olat/admin/user/delete/service/UserDeletionManager.java
index 61b72cada58..d1a814ae278 100644
--- a/src/main/java/org/olat/admin/user/delete/service/UserDeletionManager.java
+++ b/src/main/java/org/olat/admin/user/delete/service/UserDeletionManager.java
@@ -381,15 +381,14 @@ public class UserDeletionManager extends BasicManager {
 	 * Re-activate an identity, lastLogin = now, reset deleteemaildate = null.
 	 * @param identity
 	 */
-	public Identity setIdentityAsActiv(final Identity anIdentity) {
-		final Identity reloadedIdentity = securityManager.setIdentityLastLogin(anIdentity);
-
-		LifeCycleManager lifeCycleManagerForIdenitiy = LifeCycleManager.createInstanceFor(reloadedIdentity);
+	public Identity setIdentityAsActiv(final Identity identity) {
+		securityManager.setIdentityLastLogin(identity);
+		LifeCycleManager lifeCycleManagerForIdenitiy = LifeCycleManager.createInstanceFor(identity);
 		if (lifeCycleManagerForIdenitiy.hasLifeCycleEntry(SEND_DELETE_EMAIL_ACTION)) {
-			logAudit("User-Deletion: Remove from delete-list identity=" + reloadedIdentity);
+			logAudit("User-Deletion: Remove from delete-list identity=" + identity);
 			lifeCycleManagerForIdenitiy.deleteTimestampFor(SEND_DELETE_EMAIL_ACTION);
 		}
-		return reloadedIdentity;
+		return identity;
 	}
 
 	/**
diff --git a/src/main/java/org/olat/admin/user/imp/TransientIdentity.java b/src/main/java/org/olat/admin/user/imp/TransientIdentity.java
index f359b30bd7c..d7d087973e1 100644
--- a/src/main/java/org/olat/admin/user/imp/TransientIdentity.java
+++ b/src/main/java/org/olat/admin/user/imp/TransientIdentity.java
@@ -96,11 +96,6 @@ public class TransientIdentity implements Identity, User {
 		return null;
 	}
 
-	@Override
-	public void setLastLogin(Date loginDate) {
-		//
-	}
-
 	@Override
 	public Integer getStatus() {
 		return null;
diff --git a/src/main/java/org/olat/admin/user/imp/UpdateIdentity.java b/src/main/java/org/olat/admin/user/imp/UpdateIdentity.java
index 37984c96d4f..0477fc61dc4 100644
--- a/src/main/java/org/olat/admin/user/imp/UpdateIdentity.java
+++ b/src/main/java/org/olat/admin/user/imp/UpdateIdentity.java
@@ -117,11 +117,6 @@ public class UpdateIdentity implements Identity {
 		return identity.getLastLogin();
 	}
 
-	@Override
-	public void setLastLogin(Date loginDate) {
-		//
-	}
-
 	@Override
 	public Integer getStatus() {
 		return identity.getStatus();
diff --git a/src/main/java/org/olat/basesecurity/BaseSecurity.java b/src/main/java/org/olat/basesecurity/BaseSecurity.java
index 0df0e788d26..eedbc943f82 100644
--- a/src/main/java/org/olat/basesecurity/BaseSecurity.java
+++ b/src/main/java/org/olat/basesecurity/BaseSecurity.java
@@ -613,7 +613,7 @@ public interface BaseSecurity {
 	 * @param identity
 	 * @return
 	 */
-	public Identity setIdentityLastLogin(Identity identity);
+	public void setIdentityLastLogin(IdentityRef identity);
 	
 	/**
 	 * Set the identity name. 
diff --git a/src/main/java/org/olat/basesecurity/BaseSecurityManager.java b/src/main/java/org/olat/basesecurity/BaseSecurityManager.java
index 6c63c94fb4c..aa88909c3b8 100644
--- a/src/main/java/org/olat/basesecurity/BaseSecurityManager.java
+++ b/src/main/java/org/olat/basesecurity/BaseSecurityManager.java
@@ -1908,12 +1908,13 @@ public class BaseSecurityManager implements BaseSecurity {
 	}
 	
 	@Override
-	public Identity setIdentityLastLogin(Identity identity) {
-		Identity reloadedIdentity = loadForUpdate(identity); 
-		reloadedIdentity.setLastLogin(new Date());
-		reloadedIdentity = dbInstance.getCurrentEntityManager().merge(reloadedIdentity);
+	public void setIdentityLastLogin(IdentityRef identity) {
+		dbInstance.getCurrentEntityManager()
+				.createNamedQuery("updateIdentityLastLogin")
+				.setParameter("identityKey", identity.getKey())
+				.setParameter("now", new Date())
+				.executeUpdate();
 		dbInstance.commit();
-		return reloadedIdentity;
 	}
 	
 	@Override
diff --git a/src/main/java/org/olat/basesecurity/IdentityImpl.hbm.xml b/src/main/java/org/olat/basesecurity/IdentityImpl.hbm.xml
index 91b997fc5d6..88411df64ea 100644
--- a/src/main/java/org/olat/basesecurity/IdentityImpl.hbm.xml
+++ b/src/main/java/org/olat/basesecurity/IdentityImpl.hbm.xml
@@ -10,7 +10,7 @@
     
     <version name="version" access="field" column="version" type="int"/>
 	<property  name="creationDate" column="creationdate" type="timestamp" />
- 	<property  name="lastLogin" column="lastlogin" type="timestamp" />
+ 	<property  name="lastLogin" column="lastlogin" update="false" type="timestamp" />
  	<property  name="externalId" column="external_id" type="string" />
  	
     <property name="name" type="string">
diff --git a/src/main/java/org/olat/basesecurity/IdentityImpl.java b/src/main/java/org/olat/basesecurity/IdentityImpl.java
index 4abbad5c195..1fac668be0f 100644
--- a/src/main/java/org/olat/basesecurity/IdentityImpl.java
+++ b/src/main/java/org/olat/basesecurity/IdentityImpl.java
@@ -117,22 +117,24 @@ public class IdentityImpl extends PersistentObject implements Identity, Identity
 	 * 
 	 * @param user The user to set
 	 */
+	@SuppressWarnings("unused")
 	private void setUser(User user) {
 		this.user = user;
 	}
 
 	/**
-	 * Set new last login value
+	 * for hibernate only.
 	 * 
 	 * @param newLastLogin  The new last login date
 	 */
-	public void setLastLogin(Date newLastLogin) {
+	private void setLastLogin(Date newLastLogin) {
 		this.lastLogin = newLastLogin;
 	}
 
 	/**
 	 * @see java.lang.Object#toString()
 	 */
+	@Override
 	public String toString() {
 		return "Identity[name=" + name + "], " + super.toString();
 	}
@@ -156,6 +158,7 @@ public class IdentityImpl extends PersistentObject implements Identity, Identity
 	 * Compares the usernames.
 	 * @see java.lang.Object#equals(java.lang.Object)
 	 */
+	@Override
 	public boolean equals(Object obj) {
 		if(this == obj)
 			return true;
@@ -166,11 +169,11 @@ public class IdentityImpl extends PersistentObject implements Identity, Identity
 		return this.getName().equals(identity.getName());
 	}
 
+	@Override
 	public int hashCode() {
 		int hash = 7;
 		hash = 31 * hash;
 		hash = 31 * hash + (null == this.getName() ? 0 : this.getName().hashCode());
 		return hash;
 	}
-
 }
\ No newline at end of file
diff --git a/src/main/java/org/olat/basesecurity/model/IdentityLastLoginImpl.java b/src/main/java/org/olat/basesecurity/model/IdentityLastLoginImpl.java
new file mode 100644
index 00000000000..efb9062d7d9
--- /dev/null
+++ b/src/main/java/org/olat/basesecurity/model/IdentityLastLoginImpl.java
@@ -0,0 +1,92 @@
+/**
+ * <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.basesecurity.model;
+
+import java.util.Date;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
+import javax.persistence.Table;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+
+import org.olat.basesecurity.IdentityRef;
+import org.olat.core.id.Persistable;
+
+/**
+ * 
+ * Initial date: 18.03.2016<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+@Entity(name="bidentitylastlogin")
+@Table(name="o_bs_identity")
+@NamedQueries({
+	@NamedQuery(name="updateIdentityLastLogin", query="update bidentitylastlogin set lastLogin=:now where key=:identityKey")
+})
+public class IdentityLastLoginImpl implements Persistable, IdentityRef {
+
+	private static final long serialVersionUID = 2090002193918262648L;
+
+	@Id
+	@GeneratedValue(strategy = GenerationType.IDENTITY)
+	@Column(name="id", nullable=false, unique=true, insertable=true, updatable=false)
+	private Long key;
+
+	@Temporal(TemporalType.TIMESTAMP)
+	@Column(name="lastlogin", nullable=false, insertable=true, updatable=true)
+	private Date lastLogin;
+	
+	public IdentityLastLoginImpl() {
+		//
+	}
+
+	@Override
+	public Long getKey() {
+		return key;
+	}
+
+	@Override
+	public int hashCode() {
+		return key == null ? 3975 : key.hashCode();
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if(this == obj) {
+			return true;
+		}
+		if(obj instanceof IdentityLastLoginImpl) {
+			IdentityLastLoginImpl id = (IdentityLastLoginImpl)obj;
+			return key != null && key.equals(id.key);
+		}
+		return false;
+	}
+
+	@Override
+	public boolean equalsByPersistableKey(Persistable persistable) {
+		return equals(persistable);
+	}
+}
diff --git a/src/main/java/org/olat/core/id/Identity.java b/src/main/java/org/olat/core/id/Identity.java
index 16bdc2245f3..575628dfea5 100644
--- a/src/main/java/org/olat/core/id/Identity.java
+++ b/src/main/java/org/olat/core/id/Identity.java
@@ -71,12 +71,7 @@ public interface Identity extends CreateInfo, IdentityRef, Persistable {
 	 * @return Last date when the user logged in.
 	 */
 	public Date getLastLogin();
-	
-	/**
-	 * Set a new last login date for the user. 
-	 * @param loginDate  New last-login date.
-	 */
-	public void setLastLogin(Date loginDate);
+
 
 	/**
 	 * @return Current identity status 
diff --git a/src/main/java/org/olat/core/util/mail/ui/EMailIdentity.java b/src/main/java/org/olat/core/util/mail/ui/EMailIdentity.java
index c7c8ba4a802..51f6ee5095e 100644
--- a/src/main/java/org/olat/core/util/mail/ui/EMailIdentity.java
+++ b/src/main/java/org/olat/core/util/mail/ui/EMailIdentity.java
@@ -79,10 +79,6 @@ public class EMailIdentity implements Identity {
 		return null;
 	}
 
-	@Override
-	public void setLastLogin(Date loginDate) {/**/
-	}
-
 	@Override
 	public Integer getStatus() {
 		return null;
diff --git a/src/main/java/org/olat/course/run/preview/PreviewIdentity.java b/src/main/java/org/olat/course/run/preview/PreviewIdentity.java
index c0254efa1d8..3eb46dcfbee 100644
--- a/src/main/java/org/olat/course/run/preview/PreviewIdentity.java
+++ b/src/main/java/org/olat/course/run/preview/PreviewIdentity.java
@@ -141,11 +141,6 @@ public final class PreviewIdentity implements Identity, User {
 		return new Date();
 	}
 
-	@Override
-	public void setLastLogin(Date loginDate) {
-		//
-	}
-
 	@Override
 	public Integer getStatus() {
 		return Identity.STATUS_ACTIV;
diff --git a/src/main/resources/META-INF/persistence.xml b/src/main/resources/META-INF/persistence.xml
index 25fb8845171..f10858f35a7 100644
--- a/src/main/resources/META-INF/persistence.xml
+++ b/src/main/resources/META-INF/persistence.xml
@@ -79,6 +79,7 @@
 		<class>org.olat.basesecurity.model.GrantImpl</class>
 		<class>org.olat.basesecurity.model.GroupMembershipImpl</class>
 		<class>org.olat.basesecurity.model.UserProperty</class>
+		<class>org.olat.basesecurity.model.IdentityLastLoginImpl</class>
 		<class>org.olat.core.dispatcher.mapper.model.PersistedMapper</class>
 		<class>org.olat.commons.calendar.model.ImportedCalendar</class>
 		<class>org.olat.commons.calendar.model.ImportedToCalendar</class>
diff --git a/src/test/java/org/olat/basesecurity/SecurityManagerTest.java b/src/test/java/org/olat/basesecurity/SecurityManagerTest.java
index e73fcd94063..5d38316c829 100644
--- a/src/test/java/org/olat/basesecurity/SecurityManagerTest.java
+++ b/src/test/java/org/olat/basesecurity/SecurityManagerTest.java
@@ -26,8 +26,6 @@
 
 package org.olat.basesecurity;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
 import java.util.Calendar;
@@ -36,11 +34,10 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import org.junit.Assert;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.olat.core.commons.persistence.DB;
-import org.olat.core.commons.persistence.DBFactory;
 import org.olat.core.id.Identity;
 import org.olat.core.id.UserConstants;
 import org.olat.core.util.Encoder;
@@ -48,6 +45,7 @@ import org.olat.test.JunitTestHelper;
 import org.olat.test.OlatTestCase;
 import org.springframework.beans.factory.annotation.Autowired;
 
+
 /**
  * SecurityTestSuite is a container of all Tests in this package.
  * 
@@ -55,11 +53,19 @@ import org.springframework.beans.factory.annotation.Autowired;
  */
 public class SecurityManagerTest extends OlatTestCase {
 
-	private Identity s1,s2,s3,testAdmin;
+	private Identity s1, s2;
 	private static String testLogin = "test-login";
 	
 	@Autowired
-	private BaseSecurity securityManager;
+	private DB dbInstance;
+	@Autowired
+	private BaseSecurityManager securityManager;
+	
+	@Before
+	public void setup() throws Exception {
+		s1 = JunitTestHelper.createAndPersistIdentityAsUser(testLogin);
+		s2 = JunitTestHelper.createAndPersistIdentityAsUser("coop");
+	}
 
 	// Already tested in BusinessGroupTest :
 	//  - getGroupsWithPermissionOnOlatResourceable
@@ -71,14 +77,14 @@ public class SecurityManagerTest extends OlatTestCase {
 	public void testGetIdentitiesByPowerSearch() {
 		// test using visibility search
 		List<Identity> userList = securityManager.getVisibleIdentitiesByPowerSearch(testLogin, null, true, null, null, null, null, null);
-		assertEquals(1,userList.size());
+		Assert.assertEquals(1,userList.size());
 		Identity identity = userList.get(0);
-		assertEquals(testLogin,identity.getName());
+		Assert.assertEquals(testLogin,identity.getName());
 		// test using powser search
 		userList = securityManager.getIdentitiesByPowerSearch(testLogin, null, true, null, null, null, null, null, null, null, null);
-		assertEquals(1,userList.size());
+		Assert.assertEquals(1,userList.size());
 		identity = userList.get(0);
-		assertEquals(testLogin,identity.getName());
+		Assert.assertEquals(testLogin,identity.getName());
 	}
 	
 	@Test
@@ -88,14 +94,14 @@ public class SecurityManagerTest extends OlatTestCase {
 		userProperties.put(UserConstants.LASTNAME, "last"+ testLogin);
 		// test using visibility search
 		List<Identity> userList = securityManager.getVisibleIdentitiesByPowerSearch(testLogin, userProperties, true, null, null, null, null, null);
-		assertEquals(1,userList.size());
+		Assert.assertEquals(1,userList.size());
 		Identity identity = userList.get(0);
-		assertEquals("first" + testLogin,identity.getUser().getProperty(UserConstants.FIRSTNAME, null));
+		Assert.assertEquals("first" + testLogin,identity.getUser().getProperty(UserConstants.FIRSTNAME, null));
 		// test using powser search
 		userList = securityManager.getIdentitiesByPowerSearch(testLogin, userProperties, true, null, null, null, null, null, null, null, null);
-		assertEquals(1,userList.size());
+		Assert.assertEquals(1,userList.size());
 		identity = userList.get(0);
-		assertEquals("first" + testLogin,identity.getUser().getProperty(UserConstants.FIRSTNAME, null));
+		Assert.assertEquals("first" + testLogin,identity.getUser().getProperty(UserConstants.FIRSTNAME, null));
 	}
 
 	@Test
@@ -106,10 +112,10 @@ public class SecurityManagerTest extends OlatTestCase {
 		userProperties.put(UserConstants.LASTNAME, s2.getUser().getProperty(UserConstants.LASTNAME, null));
 		// with AND search (conjunction) no identity is found
 		List<Identity> userList = securityManager.getIdentitiesByPowerSearch(null, userProperties, true, null, null, null, null, null, null, null, null);
-		assertEquals(0, userList.size());
+		Assert.assertEquals(0, userList.size());
 		// with OR search both identities are found
 		userList = securityManager.getIdentitiesByPowerSearch(null, userProperties, false, null, null, null, null, null, null, null, null);
-		assertEquals(2, userList.size());
+		Assert.assertEquals(2, userList.size());
 
 		// 2) two fields wheras only one matches to one single user
 		userProperties = new HashMap<String, String>();
@@ -117,30 +123,29 @@ public class SecurityManagerTest extends OlatTestCase {
 		userProperties.put(UserConstants.LASTNAME, "some nonexisting value");
 		// with AND search (conjunction) no identity is found
 		userList = securityManager.getIdentitiesByPowerSearch(null, userProperties, true, null, null, null, null, null, null, null, null);
-		assertEquals(0, userList.size());
+		Assert.assertEquals(0, userList.size());
 		// with OR search first identity ist found
 		userList = securityManager.getIdentitiesByPowerSearch(null, userProperties, false, null, null, null, null, null, null, null, null);
-		assertEquals(1, userList.size());
+		Assert.assertEquals(1, userList.size());
 	}
-
 	
 	@Test
 	public void testGetIdentitiesByPowerSearchWithAuthProviders() {
 		// 1) only auth providers and login
-	  String[] authProviders = {BaseSecurityModule.getDefaultAuthProviderIdentifier()};
+		String[] authProviders = {BaseSecurityModule.getDefaultAuthProviderIdentifier()};
 		for (int i = 0; i < authProviders.length; i++) {
-			assertTrue("Provider name.length must be <= 8", authProviders[i].length() <= 8);
+			Assert.assertTrue("Provider name.length must be <= 8", authProviders[i].length() <= 8);
 		}
-	  List<Identity> userList = securityManager.getVisibleIdentitiesByPowerSearch(testLogin, null, true, null, null, authProviders, null, null);
-		assertEquals(1,userList.size());
+		List<Identity> userList = securityManager.getVisibleIdentitiesByPowerSearch(testLogin, null, true, null, null, authProviders, null, null);
+		Assert.assertEquals(1,userList.size());
 		Identity identity =  userList.get(0);
-		assertEquals(testLogin,identity.getName());
-	  String[] nonAuthProviders = {"NonAuth"};
+		Assert.assertEquals(testLogin,identity.getName());
+		String[] nonAuthProviders = {"NonAuth"};
 		for (int i = 0; i < nonAuthProviders.length; i++) {
 			assertTrue("Provider name.length must be <= 8", nonAuthProviders[i].length() <= 8);
 		}
-	  userList = securityManager.getVisibleIdentitiesByPowerSearch(testLogin, null, true, null, null, nonAuthProviders, null, null);
-		assertEquals(0,userList.size());
+		userList = securityManager.getVisibleIdentitiesByPowerSearch(testLogin, null, true, null, null, nonAuthProviders, null, null);
+	  	Assert.assertEquals(0,userList.size());
 		
 		// 2) two fields wheras only one matches to one single user
 		Map<String, String> userProperties = new HashMap<String, String>();
@@ -148,120 +153,77 @@ public class SecurityManagerTest extends OlatTestCase {
 		userProperties.put(UserConstants.LASTNAME, "some nonexisting value");
 		// with AND search (conjunction) no identity is found
 		userList = securityManager.getIdentitiesByPowerSearch(null, userProperties, true, null, null, authProviders, null, null, null, null, null);
-		assertEquals(0, userList.size());
+		Assert.assertEquals(0, userList.size());
 		// with OR search first identity ist found
 		userList = securityManager.getIdentitiesByPowerSearch(null, userProperties, false, null, null, authProviders, null, null, null, null, null);
-		assertEquals(1, userList.size());
+		Assert.assertEquals(1, userList.size());
 
 		// 3) two fields wheras only one matches to one single user
 		securityManager.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);
+			Assert.assertTrue("Provider name.length must be <= 8", myProviders[i].length() <= 8);
 		}
 		userProperties = new HashMap<String, String>();
 		userProperties.put(UserConstants.FIRSTNAME, s1.getUser().getProperty(UserConstants.FIRSTNAME, null));
 		userProperties.put(UserConstants.LASTNAME, "some nonexisting value");
 		// with AND search (conjunction) no identity is found
 		userList = securityManager.getIdentitiesByPowerSearch(null, userProperties, true, null, null, myProviders, null, null, null, null, null);
-		assertEquals(0, userList.size());
+		Assert.assertEquals(0, userList.size());
 		// with OR search identity is found via auth provider and via first name
 		userList = securityManager.getIdentitiesByPowerSearch(null, userProperties, false, null, null, myProviders, null, null, null, null, null);
-		assertEquals(1, userList.size());
+		Assert.assertEquals(1, userList.size());
 	}
 	
 	@Test
 	public void testRemoveIdentityFromSecurityGroup() {
 		SecurityGroup olatUsersGroup = securityManager.findSecurityGroupByName(Constants.GROUP_OLATUSERS);
-		assertTrue(securityManager.isIdentityInSecurityGroup(s1, olatUsersGroup));
+		Assert.assertTrue(securityManager.isIdentityInSecurityGroup(s1, olatUsersGroup));
 		securityManager.removeIdentityFromSecurityGroup(s1, olatUsersGroup);
-		assertFalse(securityManager.isIdentityInSecurityGroup(s1, olatUsersGroup));
+		Assert.assertFalse(securityManager.isIdentityInSecurityGroup(s1, olatUsersGroup));
 		securityManager.addIdentityToSecurityGroup(s1, olatUsersGroup);
-		assertTrue(securityManager.isIdentityInSecurityGroup(s1, olatUsersGroup));
+		Assert.assertTrue(securityManager.isIdentityInSecurityGroup(s1, olatUsersGroup));
 	}
 	
 	@Test
 	public void testGetIdentitiesAndDateOfSecurityGroup() {
 		SecurityGroup olatUsersGroup = securityManager.findSecurityGroupByName(Constants.GROUP_OLATUSERS);
 		List<Object[]> identities = securityManager.getIdentitiesAndDateOfSecurityGroup(olatUsersGroup);// not sortedByAddDate
-		assertTrue("Found no users", identities.size() > 0);
+		Assert.assertTrue("Found no users", identities.size() > 0);
 		Object[] firstIdentity = identities.get(0);
-		assertTrue("Wrong type, Identity[0] must be an Identity", firstIdentity[0] instanceof Identity);
-		assertTrue("Wrong type, Identity[1] must be a Date", firstIdentity[1] instanceof Date);
+		Assert.assertTrue("Wrong type, Identity[0] must be an Identity", firstIdentity[0] instanceof Identity);
+		Assert.assertTrue("Wrong type, Identity[1] must be a Date", firstIdentity[1] instanceof Date);
 	}
 	
 	@Test
 	public void testGetAuthentications() {
 		List<Authentication> authentications = securityManager.getAuthentications(s1);
 		Authentication authentication = authentications.get(0);
-		assertEquals(testLogin,authentication.getAuthusername());
+		Assert.assertEquals(testLogin,authentication.getAuthusername());
 	}
 
-	@Test public void testFindAuthenticationByAuthusername() {
+	@Test
+	public void testFindAuthenticationByAuthusername() {
 		Authentication authentication = securityManager.findAuthenticationByAuthusername(testLogin, BaseSecurityModule.getDefaultAuthProviderIdentifier());
-		assertEquals(testLogin,authentication.getAuthusername());
+		Assert.assertEquals(testLogin,authentication.getAuthusername());
 	}
 
-	@Test @Ignore
-	public void testCountUniqueUserLoginsSince(){
-
-   	// Set lastLogin for 4 test users to now
-		DB db = DBFactory.getInstance();
-		Date now = new Date();
-		s1.setLastLogin(now);
-		db.updateObject(s1);
-		s2.setLastLogin(now);
-		db.updateObject(s2);
-		s3.setLastLogin(now);
-		db.updateObject(s3);
-		testAdmin.setLastLogin(now);
-		db.updateObject(testAdmin);
-		db.closeSession();
+	@Test
+	public void testUpdateLatLogin() {
+		securityManager.setIdentityLastLogin(s1);
+		dbInstance.commitAndCloseSession();
 
-		Calendar c1 = Calendar.getInstance();
-		c1.add(Calendar.DAY_OF_YEAR, -100);// -100
-		assertTrue("Found no user-logins", securityManager.countUniqueUserLoginsSince(c1.getTime()) >= 4); 
-		Long initialUserLogins = securityManager.countUniqueUserLoginsSince(c1.getTime());
-		
-		// Set lastLogin for the 4 test-users
-		c1 = Calendar.getInstance();
-		c1.add(Calendar.DAY_OF_YEAR, -100);
-		s1.setLastLogin(c1.getTime());
-		c1 = Calendar.getInstance();
-		c1.add(Calendar.DAY_OF_YEAR, -15); 
-		s2.setLastLogin(c1.getTime());
-		s3.setLastLogin(c1.getTime());
-		testAdmin.setLastLogin(c1.getTime());
-	
-		// Set lastLogin for 4 test users
-		db.updateObject(s1);
-		db.updateObject(s2);
-		db.updateObject(s3);
-		db.updateObject(testAdmin);
-		db.closeSession();
-		
-		Calendar c2 = Calendar.getInstance();		
-		c2.add(Calendar.DAY_OF_YEAR, -2); 
-		assertEquals(initialUserLogins - 4, securityManager.countUniqueUserLoginsSince(c2.getTime()).intValue() );
-		c2 = Calendar.getInstance();
-		c2.add(Calendar.DAY_OF_YEAR, - 14); 
-		assertEquals(initialUserLogins - 4, securityManager.countUniqueUserLoginsSince(c2.getTime()).intValue());
-		c2 = Calendar.getInstance();
-		c2.add(Calendar.DAY_OF_YEAR, - 16); 
-		assertEquals(initialUserLogins - 1, securityManager.countUniqueUserLoginsSince(c2.getTime()).intValue());
-		c2 = Calendar.getInstance();
-		c2.add(Calendar.DAY_OF_YEAR, - 99); 
-		assertEquals(initialUserLogins - 1, securityManager.countUniqueUserLoginsSince(c2.getTime()).intValue());
-		c2 = Calendar.getInstance();
-		c2.add(Calendar.DAY_OF_YEAR, - 101); 
-		assertEquals(initialUserLogins, securityManager.countUniqueUserLoginsSince(c2.getTime()));
+		s1 = securityManager.loadIdentityByKey(s1.getKey());
+		Date lastLogin = s1.getLastLogin();
+		Assert.assertNotNull(lastLogin);
 	}
 
-	@Before
-	public void setup() throws Exception {
-		s1 = JunitTestHelper.createAndPersistIdentityAsUser(testLogin);
-		s2 = JunitTestHelper.createAndPersistIdentityAsUser("coop");
-		s3 = JunitTestHelper.createAndPersistIdentityAsAuthor("diesbach");
-		testAdmin = JunitTestHelper.createAndPersistIdentityAsAdmin("testAdmin");
+	@Test
+	public void testCountUniqueUserLoginsSince() {
+		Calendar cal = Calendar.getInstance();
+		cal.add(Calendar.DAY_OF_YEAR, -100);
+		Long initialUserLogins = securityManager.countUniqueUserLoginsSince(cal.getTime());
+		Assert.assertNotNull(initialUserLogins);
+		Assert.assertTrue(initialUserLogins.longValue() >= 0);
 	}
 }
\ No newline at end of file
-- 
GitLab