NIHVIVO-2819 Store the time of last login as part of the UserAccount. Display it on the List page.
This commit is contained in:
parent
c5c4ecd394
commit
0fdf28d3f5
14 changed files with 87 additions and 8 deletions
|
@ -54,6 +54,7 @@ public class UserAccount {
|
||||||
private boolean passwordChangeRequired = false;
|
private boolean passwordChangeRequired = false;
|
||||||
|
|
||||||
private int loginCount = 0; // Never negative.
|
private int loginCount = 0; // Never negative.
|
||||||
|
private long lastLoginTime = 0L; // Never negative.
|
||||||
private Status status = Status.INACTIVE; // Might be null.
|
private Status status = Status.INACTIVE; // Might be null.
|
||||||
private String externalAuthId = ""; // Never null.
|
private String externalAuthId = ""; // Never null.
|
||||||
|
|
||||||
|
@ -143,6 +144,14 @@ public class UserAccount {
|
||||||
this.loginCount = Math.max(0, loginCount);
|
this.loginCount = Math.max(0, loginCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long getLastLoginTime() {
|
||||||
|
return lastLoginTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastLoginTime(long lastLoginTime) {
|
||||||
|
this.lastLoginTime = Math.max(0, lastLoginTime);
|
||||||
|
}
|
||||||
|
|
||||||
public Status getStatus() {
|
public Status getStatus() {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,8 @@ public class UserAccountsOrdering {
|
||||||
|
|
||||||
public enum Field {
|
public enum Field {
|
||||||
EMAIL("email"), FIRST_NAME("firstName"), LAST_NAME("lastName"), STATUS(
|
EMAIL("email"), FIRST_NAME("firstName"), LAST_NAME("lastName"), STATUS(
|
||||||
"status"), ROLE("ps"), LOGIN_COUNT("count");
|
"status"), ROLE("ps"), LOGIN_COUNT("count"), LAST_LOGIN_TIME(
|
||||||
|
"lastLogin");
|
||||||
|
|
||||||
public static Field DEFAULT_FIELD = EMAIL;
|
public static Field DEFAULT_FIELD = EMAIL;
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,8 @@ public class UserAccountsSelector {
|
||||||
+ "PREFIX fn: <http://www.w3.org/2005/xpath-functions#> \n"
|
+ "PREFIX fn: <http://www.w3.org/2005/xpath-functions#> \n"
|
||||||
+ "PREFIX auth: <http://vitro.mannlib.cornell.edu/ns/vitro/authorization#> \n";
|
+ "PREFIX auth: <http://vitro.mannlib.cornell.edu/ns/vitro/authorization#> \n";
|
||||||
|
|
||||||
private static final String ALL_VARIABLES = "?uri ?email ?firstName ?lastName ?pwd ?expire ?count ?status ?isRoot";
|
private static final String ALL_VARIABLES = "?uri ?email ?firstName "
|
||||||
|
+ "?lastName ?pwd ?expire ?count ?lastLogin ?status ?isRoot";
|
||||||
|
|
||||||
private static final String COUNT_VARIABLE = "?uri";
|
private static final String COUNT_VARIABLE = "?uri";
|
||||||
|
|
||||||
|
@ -169,6 +170,7 @@ public class UserAccountsSelector {
|
||||||
+ " OPTIONAL { ?uri auth:md5password ?pwd } \n"
|
+ " OPTIONAL { ?uri auth:md5password ?pwd } \n"
|
||||||
+ " OPTIONAL { ?uri auth:passwordChangeExpires ?expire } \n"
|
+ " OPTIONAL { ?uri auth:passwordChangeExpires ?expire } \n"
|
||||||
+ " OPTIONAL { ?uri auth:loginCount ?count } \n"
|
+ " OPTIONAL { ?uri auth:loginCount ?count } \n"
|
||||||
|
+ " OPTIONAL { ?uri auth:lastLoginTime ?lastLogin } \n"
|
||||||
+ " OPTIONAL { ?uri auth:status ?status } \n"
|
+ " OPTIONAL { ?uri auth:status ?status } \n"
|
||||||
+ " OPTIONAL { ?uri ?isRoot auth:RootUserAccount }";
|
+ " OPTIONAL { ?uri ?isRoot auth:RootUserAccount }";
|
||||||
}
|
}
|
||||||
|
@ -326,6 +328,7 @@ public class UserAccountsSelector {
|
||||||
user.setMd5Password(ifLiteralPresent(solution, "pwd", ""));
|
user.setMd5Password(ifLiteralPresent(solution, "pwd", ""));
|
||||||
user.setPasswordLinkExpires(ifLongPresent(solution, "expire", 0L));
|
user.setPasswordLinkExpires(ifLongPresent(solution, "expire", 0L));
|
||||||
user.setLoginCount(ifIntPresent(solution, "count", 0));
|
user.setLoginCount(ifIntPresent(solution, "count", 0));
|
||||||
|
user.setLastLoginTime(ifLongPresent(solution, "lastLogin", 0));
|
||||||
user.setStatus(parseStatus(solution, "status", null));
|
user.setStatus(parseStatus(solution, "status", null));
|
||||||
user.setRootUser(solution.contains("isRoot"));
|
user.setRootUser(solution.contains("isRoot"));
|
||||||
return user;
|
return user;
|
||||||
|
|
|
@ -141,6 +141,7 @@ public class UserAccountsAddPage extends UserAccountsPage {
|
||||||
u.setPasswordChangeRequired(false);
|
u.setPasswordChangeRequired(false);
|
||||||
u.setPasswordLinkExpires(0);
|
u.setPasswordLinkExpires(0);
|
||||||
u.setLoginCount(0);
|
u.setLoginCount(0);
|
||||||
|
u.setLastLoginTime(0L);
|
||||||
u.setStatus(Status.INACTIVE);
|
u.setStatus(Status.INACTIVE);
|
||||||
u.setPermissionSetUris(Collections.singleton(selectedRoleUri));
|
u.setPermissionSetUris(Collections.singleton(selectedRoleUri));
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ import static edu.cornell.mannlib.vitro.webapp.controller.accounts.UserAccountsS
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -34,9 +35,6 @@ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.Tem
|
||||||
/**
|
/**
|
||||||
* Handle the List page.
|
* Handle the List page.
|
||||||
*
|
*
|
||||||
* TODO: agree with Manolo how to do the column heads as links that change the
|
|
||||||
* sort order
|
|
||||||
*
|
|
||||||
* TODO: auto-complete
|
* TODO: auto-complete
|
||||||
*/
|
*/
|
||||||
public class UserAccountsListPage extends UserAccountsPage {
|
public class UserAccountsListPage extends UserAccountsPage {
|
||||||
|
@ -242,6 +240,15 @@ public class UserAccountsListPage extends UserAccountsPage {
|
||||||
return account.getLoginCount();
|
return account.getLoginCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Date getLastLoginTime() {
|
||||||
|
long time = account.getLastLoginTime();
|
||||||
|
if (time > 0L) {
|
||||||
|
return new Date(time);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public String getStatus() {
|
public String getStatus() {
|
||||||
Status status = account.getStatus();
|
Status status = account.getStatus();
|
||||||
if (status == null) {
|
if (status == null) {
|
||||||
|
@ -299,7 +306,7 @@ public class UserAccountsListPage extends UserAccountsPage {
|
||||||
HttpSession session = req.getSession();
|
HttpSession session = req.getSession();
|
||||||
Object o = session.getAttribute(ATTRIBUTE);
|
Object o = session.getAttribute(ATTRIBUTE);
|
||||||
session.removeAttribute(ATTRIBUTE);
|
session.removeAttribute(ATTRIBUTE);
|
||||||
|
|
||||||
if (o instanceof Message) {
|
if (o instanceof Message) {
|
||||||
((Message) o).applyToBodyMap(body);
|
((Message) o).applyToBodyMap(body);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
package edu.cornell.mannlib.vitro.webapp.controller.authenticate;
|
package edu.cornell.mannlib.vitro.webapp.controller.authenticate;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
@ -137,6 +138,7 @@ public class BasicAuthenticator extends Authenticator {
|
||||||
*/
|
*/
|
||||||
private void recordLoginOnUserRecord(UserAccount userAccount) {
|
private void recordLoginOnUserRecord(UserAccount userAccount) {
|
||||||
userAccount.setLoginCount(userAccount.getLoginCount() + 1);
|
userAccount.setLoginCount(userAccount.getLoginCount() + 1);
|
||||||
|
userAccount.setLastLoginTime(new Date().getTime());
|
||||||
getUserAccountsDao().updateUserAccount(userAccount);
|
getUserAccountsDao().updateUserAccount(userAccount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -157,6 +157,7 @@ public class VitroVocabulary {
|
||||||
public static final String USERACCOUNT_MD5_PASSWORD = VITRO_AUTH + "md5password";
|
public static final String USERACCOUNT_MD5_PASSWORD = VITRO_AUTH + "md5password";
|
||||||
public static final String USERACCOUNT_OLD_PASSWORD = VITRO_AUTH + "oldpassword";
|
public static final String USERACCOUNT_OLD_PASSWORD = VITRO_AUTH + "oldpassword";
|
||||||
public static final String USERACCOUNT_LOGIN_COUNT = VITRO_AUTH + "loginCount";
|
public static final String USERACCOUNT_LOGIN_COUNT = VITRO_AUTH + "loginCount";
|
||||||
|
public static final String USERACCOUNT_LAST_LOGIN_TIME = VITRO_AUTH + "lastLoginTime";
|
||||||
public static final String USERACCOUNT_STATUS = VITRO_AUTH + "status";
|
public static final String USERACCOUNT_STATUS = VITRO_AUTH + "status";
|
||||||
public static final String USERACCOUNT_PASSWORD_LINK_EXPIRES = VITRO_AUTH + "passwordLinkExpires";
|
public static final String USERACCOUNT_PASSWORD_LINK_EXPIRES = VITRO_AUTH + "passwordLinkExpires";
|
||||||
public static final String USERACCOUNT_PASSWORD_CHANGE_REQUIRED = VITRO_AUTH + "passwordChangeRequired";
|
public static final String USERACCOUNT_PASSWORD_CHANGE_REQUIRED = VITRO_AUTH + "passwordChangeRequired";
|
||||||
|
|
|
@ -127,6 +127,7 @@ public class JenaBaseDaoCon {
|
||||||
protected DatatypeProperty USERACCOUNT_MD5_PASSWORD = _constModel.createDatatypeProperty(VitroVocabulary.USERACCOUNT_MD5_PASSWORD);
|
protected DatatypeProperty USERACCOUNT_MD5_PASSWORD = _constModel.createDatatypeProperty(VitroVocabulary.USERACCOUNT_MD5_PASSWORD);
|
||||||
protected DatatypeProperty USERACCOUNT_OLD_PASSWORD = _constModel.createDatatypeProperty(VitroVocabulary.USERACCOUNT_OLD_PASSWORD);
|
protected DatatypeProperty USERACCOUNT_OLD_PASSWORD = _constModel.createDatatypeProperty(VitroVocabulary.USERACCOUNT_OLD_PASSWORD);
|
||||||
protected DatatypeProperty USERACCOUNT_LOGIN_COUNT = _constModel.createDatatypeProperty(VitroVocabulary.USERACCOUNT_LOGIN_COUNT);
|
protected DatatypeProperty USERACCOUNT_LOGIN_COUNT = _constModel.createDatatypeProperty(VitroVocabulary.USERACCOUNT_LOGIN_COUNT);
|
||||||
|
protected DatatypeProperty USERACCOUNT_LAST_LOGIN_TIME = _constModel.createDatatypeProperty(VitroVocabulary.USERACCOUNT_LAST_LOGIN_TIME);
|
||||||
protected DatatypeProperty USERACCOUNT_STATUS = _constModel.createDatatypeProperty(VitroVocabulary.USERACCOUNT_STATUS);
|
protected DatatypeProperty USERACCOUNT_STATUS = _constModel.createDatatypeProperty(VitroVocabulary.USERACCOUNT_STATUS);
|
||||||
protected DatatypeProperty USERACCOUNT_PASSWORD_LINK_EXPIRES = _constModel.createDatatypeProperty(VitroVocabulary.USERACCOUNT_PASSWORD_LINK_EXPIRES);
|
protected DatatypeProperty USERACCOUNT_PASSWORD_LINK_EXPIRES = _constModel.createDatatypeProperty(VitroVocabulary.USERACCOUNT_PASSWORD_LINK_EXPIRES);
|
||||||
protected DatatypeProperty USERACCOUNT_PASSWORD_CHANGE_REQUIRED = _constModel.createDatatypeProperty(VitroVocabulary.USERACCOUNT_PASSWORD_CHANGE_REQUIRED);
|
protected DatatypeProperty USERACCOUNT_PASSWORD_CHANGE_REQUIRED = _constModel.createDatatypeProperty(VitroVocabulary.USERACCOUNT_PASSWORD_CHANGE_REQUIRED);
|
||||||
|
|
|
@ -98,6 +98,7 @@ public class UserAccountsDaoJena extends JenaBaseDao implements UserAccountsDao
|
||||||
u.setPasswordChangeRequired(getPropertyBooleanValue(r,
|
u.setPasswordChangeRequired(getPropertyBooleanValue(r,
|
||||||
USERACCOUNT_PASSWORD_CHANGE_REQUIRED));
|
USERACCOUNT_PASSWORD_CHANGE_REQUIRED));
|
||||||
u.setLoginCount(getPropertyIntValue(r, USERACCOUNT_LOGIN_COUNT));
|
u.setLoginCount(getPropertyIntValue(r, USERACCOUNT_LOGIN_COUNT));
|
||||||
|
u.setLastLoginTime(getPropertyLongValue(r, USERACCOUNT_LAST_LOGIN_TIME));
|
||||||
u.setStatusFromString(getPropertyStringValue(r, USERACCOUNT_STATUS));
|
u.setStatusFromString(getPropertyStringValue(r, USERACCOUNT_STATUS));
|
||||||
u.setExternalAuthId(getPropertyStringValue(r,
|
u.setExternalAuthId(getPropertyStringValue(r,
|
||||||
USERACCOUNT_EXTERNAL_AUTH_ID));
|
USERACCOUNT_EXTERNAL_AUTH_ID));
|
||||||
|
@ -190,6 +191,8 @@ public class UserAccountsDaoJena extends JenaBaseDao implements UserAccountsDao
|
||||||
userAccount.isPasswordChangeRequired(), model);
|
userAccount.isPasswordChangeRequired(), model);
|
||||||
addPropertyIntValue(res, USERACCOUNT_LOGIN_COUNT,
|
addPropertyIntValue(res, USERACCOUNT_LOGIN_COUNT,
|
||||||
userAccount.getLoginCount(), model);
|
userAccount.getLoginCount(), model);
|
||||||
|
addPropertyLongValue(res, USERACCOUNT_LAST_LOGIN_TIME,
|
||||||
|
userAccount.getLastLoginTime(), model);
|
||||||
if (userAccount.getStatus() != null) {
|
if (userAccount.getStatus() != null) {
|
||||||
addPropertyStringValue(res, USERACCOUNT_STATUS, userAccount
|
addPropertyStringValue(res, USERACCOUNT_STATUS, userAccount
|
||||||
.getStatus().toString(), model);
|
.getStatus().toString(), model);
|
||||||
|
@ -247,6 +250,8 @@ public class UserAccountsDaoJena extends JenaBaseDao implements UserAccountsDao
|
||||||
userAccount.isPasswordChangeRequired(), model, true);
|
userAccount.isPasswordChangeRequired(), model, true);
|
||||||
updatePropertyIntValue(res, USERACCOUNT_LOGIN_COUNT,
|
updatePropertyIntValue(res, USERACCOUNT_LOGIN_COUNT,
|
||||||
userAccount.getLoginCount(), model);
|
userAccount.getLoginCount(), model);
|
||||||
|
updatePropertyLongValue(res, USERACCOUNT_LAST_LOGIN_TIME,
|
||||||
|
userAccount.getLastLoginTime(), model);
|
||||||
if (userAccount.getStatus() == null) {
|
if (userAccount.getStatus() == null) {
|
||||||
updatePropertyStringValue(res, USERACCOUNT_STATUS, null, model);
|
updatePropertyStringValue(res, USERACCOUNT_STATUS, null, model);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -84,6 +84,7 @@ public class UserAccountsSelectorTest extends AbstractTestClass {
|
||||||
assertEquals("password", "garbage", acct.getMd5Password());
|
assertEquals("password", "garbage", acct.getMd5Password());
|
||||||
assertEquals("expires", 1100234965897L, acct.getPasswordLinkExpires());
|
assertEquals("expires", 1100234965897L, acct.getPasswordLinkExpires());
|
||||||
assertEquals("loginCount", 50, acct.getLoginCount());
|
assertEquals("loginCount", 50, acct.getLoginCount());
|
||||||
|
assertEquals("lastLogin", 1020304050607080L, acct.getLastLoginTime());
|
||||||
assertEquals("status", UserAccount.Status.ACTIVE, acct.getStatus());
|
assertEquals("status", UserAccount.Status.ACTIVE, acct.getStatus());
|
||||||
assertEqualSets(
|
assertEqualSets(
|
||||||
"permissions",
|
"permissions",
|
||||||
|
@ -107,6 +108,7 @@ public class UserAccountsSelectorTest extends AbstractTestClass {
|
||||||
assertEquals("password", "garbage", acct.getMd5Password());
|
assertEquals("password", "garbage", acct.getMd5Password());
|
||||||
assertEquals("expires", 0L, acct.getPasswordLinkExpires());
|
assertEquals("expires", 0L, acct.getPasswordLinkExpires());
|
||||||
assertEquals("loginCount", 7, acct.getLoginCount());
|
assertEquals("loginCount", 7, acct.getLoginCount());
|
||||||
|
assertEquals("lastLogin", 1122334455667788L, acct.getLastLoginTime());
|
||||||
assertEquals("status", UserAccount.Status.ACTIVE, acct.getStatus());
|
assertEquals("status", UserAccount.Status.ACTIVE, acct.getStatus());
|
||||||
assertEqualSets("permissions", Collections.<String> emptySet(),
|
assertEqualSets("permissions", Collections.<String> emptySet(),
|
||||||
acct.getPermissionSetUris());
|
acct.getPermissionSetUris());
|
||||||
|
@ -237,6 +239,23 @@ public class UserAccountsSelectorTest extends AbstractTestClass {
|
||||||
assertSelectedUris(10, "user10", "user04", "user08");
|
assertSelectedUris(10, "user10", "user04", "user08");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void sortByLastLoginTimeAscending() {
|
||||||
|
UserAccountsOrdering orderBy = new UserAccountsOrdering(
|
||||||
|
Field.LAST_LOGIN_TIME, Direction.ASCENDING);
|
||||||
|
selectOnCriteria(3, 1, orderBy, "", "");
|
||||||
|
// user06 has no login count: reads as 0.
|
||||||
|
assertSelectedUris(10, "user07", "user03", "user06");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void sortByLastLoginTimeDescending() {
|
||||||
|
UserAccountsOrdering orderBy = new UserAccountsOrdering(
|
||||||
|
Field.LAST_LOGIN_TIME, Direction.DESCENDING);
|
||||||
|
selectOnCriteria(3, 1, orderBy, "", "");
|
||||||
|
assertSelectedUris(10, "user08", "user10", "user09");
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
// filtering tests
|
// filtering tests
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
|
@ -23,6 +23,7 @@ mydomain:user01
|
||||||
auth:md5password "garbage" ;
|
auth:md5password "garbage" ;
|
||||||
auth:passwordChangeExpires 0 ;
|
auth:passwordChangeExpires 0 ;
|
||||||
auth:loginCount 5 ;
|
auth:loginCount 5 ;
|
||||||
|
auth:lastLoginTime 100 ;
|
||||||
auth:status "ACTIVE" ;
|
auth:status "ACTIVE" ;
|
||||||
auth:hasPermissionSet mydomain:role1 ;
|
auth:hasPermissionSet mydomain:role1 ;
|
||||||
.
|
.
|
||||||
|
@ -35,6 +36,7 @@ mydomain:user02
|
||||||
auth:md5password "garbage" ;
|
auth:md5password "garbage" ;
|
||||||
auth:passwordChangeExpires 0 ;
|
auth:passwordChangeExpires 0 ;
|
||||||
auth:loginCount 5 ;
|
auth:loginCount 5 ;
|
||||||
|
auth:lastLoginTime 100 ;
|
||||||
auth:status "INACTIVE" ;
|
auth:status "INACTIVE" ;
|
||||||
auth:hasPermissionSet mydomain:role1 ;
|
auth:hasPermissionSet mydomain:role1 ;
|
||||||
.
|
.
|
||||||
|
@ -47,6 +49,7 @@ mydomain:user03
|
||||||
auth:md5password "garbage" ;
|
auth:md5password "garbage" ;
|
||||||
auth:passwordChangeExpires 0 ;
|
auth:passwordChangeExpires 0 ;
|
||||||
auth:loginCount 0 ;
|
auth:loginCount 0 ;
|
||||||
|
auth:lastLoginTime 1 ;
|
||||||
auth:status "INACTIVE" ;
|
auth:status "INACTIVE" ;
|
||||||
auth:hasPermissionSet mydomain:role1 ;
|
auth:hasPermissionSet mydomain:role1 ;
|
||||||
auth:hasPermissionSet mydomain:role2 ;
|
auth:hasPermissionSet mydomain:role2 ;
|
||||||
|
@ -60,6 +63,7 @@ mydomain:user04
|
||||||
# auth:md5password NONE ;
|
# auth:md5password NONE ;
|
||||||
auth:passwordChangeExpires 0 ;
|
auth:passwordChangeExpires 0 ;
|
||||||
auth:loginCount 9 ;
|
auth:loginCount 9 ;
|
||||||
|
auth:lastLoginTime 3 ;
|
||||||
auth:status "ACTIVE" ;
|
auth:status "ACTIVE" ;
|
||||||
.
|
.
|
||||||
|
|
||||||
|
@ -71,6 +75,7 @@ mydomain:user05
|
||||||
auth:md5password "garbage" ;
|
auth:md5password "garbage" ;
|
||||||
# auth:passwordChangeExpires NONE ;
|
# auth:passwordChangeExpires NONE ;
|
||||||
auth:loginCount 2 ;
|
auth:loginCount 2 ;
|
||||||
|
auth:lastLoginTime 100 ;
|
||||||
auth:status "ACTIVE" ;
|
auth:status "ACTIVE" ;
|
||||||
auth:hasPermissionSet mydomain:role1 ;
|
auth:hasPermissionSet mydomain:role1 ;
|
||||||
.
|
.
|
||||||
|
@ -83,6 +88,7 @@ mydomain:user06
|
||||||
auth:md5password "garbage" ;
|
auth:md5password "garbage" ;
|
||||||
auth:passwordChangeExpires 0 ;
|
auth:passwordChangeExpires 0 ;
|
||||||
# auth:loginCount NONE ;
|
# auth:loginCount NONE ;
|
||||||
|
auth:lastLoginTime 2 ;
|
||||||
auth:status "INACTIVE" ;
|
auth:status "INACTIVE" ;
|
||||||
auth:hasPermissionSet mydomain:role1 ;
|
auth:hasPermissionSet mydomain:role1 ;
|
||||||
.
|
.
|
||||||
|
@ -95,6 +101,7 @@ mydomain:user07
|
||||||
auth:md5password "garbage" ;
|
auth:md5password "garbage" ;
|
||||||
auth:passwordChangeExpires 0 ;
|
auth:passwordChangeExpires 0 ;
|
||||||
auth:loginCount 1 ;
|
auth:loginCount 1 ;
|
||||||
|
# auth:lastLoginTime NONE ;
|
||||||
# auth:status NONE ;
|
# auth:status NONE ;
|
||||||
auth:hasPermissionSet mydomain:role2 ;
|
auth:hasPermissionSet mydomain:role2 ;
|
||||||
.
|
.
|
||||||
|
@ -108,6 +115,7 @@ mydomain:user08
|
||||||
auth:md5password "garbage" ;
|
auth:md5password "garbage" ;
|
||||||
auth:passwordChangeExpires 0 ;
|
auth:passwordChangeExpires 0 ;
|
||||||
auth:loginCount 7 ;
|
auth:loginCount 7 ;
|
||||||
|
auth:lastLoginTime 1122334455667788 ;
|
||||||
auth:status "ACTIVE" ;
|
auth:status "ACTIVE" ;
|
||||||
.
|
.
|
||||||
|
|
||||||
|
@ -119,6 +127,7 @@ mydomain:user09
|
||||||
auth:md5password "garbage" ;
|
auth:md5password "garbage" ;
|
||||||
auth:passwordChangeExpires 0 ;
|
auth:passwordChangeExpires 0 ;
|
||||||
auth:loginCount 3 ;
|
auth:loginCount 3 ;
|
||||||
|
auth:lastLoginTime 1000000000000000 ;
|
||||||
auth:status "ACTIVE" ;
|
auth:status "ACTIVE" ;
|
||||||
auth:hasPermissionSet mydomain:role1 ;
|
auth:hasPermissionSet mydomain:role1 ;
|
||||||
.
|
.
|
||||||
|
@ -129,8 +138,9 @@ mydomain:user10
|
||||||
auth:firstName "Bob" ;
|
auth:firstName "Bob" ;
|
||||||
auth:lastName "Caruso" ;
|
auth:lastName "Caruso" ;
|
||||||
auth:md5password "garbage" ;
|
auth:md5password "garbage" ;
|
||||||
auth:passwordChangeExpires "1100234965897" ;
|
auth:passwordChangeExpires 1100234965897 ;
|
||||||
auth:loginCount 50 ;
|
auth:loginCount 50 ;
|
||||||
|
auth:lastLoginTime 1020304050607080 ;
|
||||||
auth:status "ACTIVE" ;
|
auth:status "ACTIVE" ;
|
||||||
auth:hasPermissionSet mydomain:role2 ;
|
auth:hasPermissionSet mydomain:role2 ;
|
||||||
.
|
.
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.dao.jena;
|
package edu.cornell.mannlib.vitro.webapp.dao.jena;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.Assert.assertNull;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
|
@ -86,6 +85,7 @@ public class UserAccountsDaoJenaTest extends AbstractTestClass {
|
||||||
assertEquals("linkExpires", 0L, u.getPasswordLinkExpires());
|
assertEquals("linkExpires", 0L, u.getPasswordLinkExpires());
|
||||||
assertEquals("changeRequired", false, u.isPasswordChangeRequired());
|
assertEquals("changeRequired", false, u.isPasswordChangeRequired());
|
||||||
assertEquals("loginCount", 5, u.getLoginCount());
|
assertEquals("loginCount", 5, u.getLoginCount());
|
||||||
|
assertEquals("loginTime", 12345678L, u.getLastLoginTime());
|
||||||
assertEquals("status", Status.ACTIVE, u.getStatus());
|
assertEquals("status", Status.ACTIVE, u.getStatus());
|
||||||
assertEquals("externalAuthId", "user1", u.getExternalAuthId());
|
assertEquals("externalAuthId", "user1", u.getExternalAuthId());
|
||||||
assertEquals("permissionSetUris", Collections.singleton(URI_ROLE1),
|
assertEquals("permissionSetUris", Collections.singleton(URI_ROLE1),
|
||||||
|
@ -141,6 +141,7 @@ public class UserAccountsDaoJenaTest extends AbstractTestClass {
|
||||||
in.setPasswordLinkExpires(999966663333L);
|
in.setPasswordLinkExpires(999966663333L);
|
||||||
in.setPasswordChangeRequired(true);
|
in.setPasswordChangeRequired(true);
|
||||||
in.setLoginCount(42);
|
in.setLoginCount(42);
|
||||||
|
in.setLastLoginTime(8877665544332211L);
|
||||||
in.setStatus(Status.INACTIVE);
|
in.setStatus(Status.INACTIVE);
|
||||||
in.setExternalAuthId("newUser");
|
in.setExternalAuthId("newUser");
|
||||||
in.setPermissionSetUris(buildSet(URI_ROLE1, URI_ROLE2));
|
in.setPermissionSetUris(buildSet(URI_ROLE1, URI_ROLE2));
|
||||||
|
@ -157,6 +158,7 @@ public class UserAccountsDaoJenaTest extends AbstractTestClass {
|
||||||
assertEquals("linkExpires", 999966663333L, u.getPasswordLinkExpires());
|
assertEquals("linkExpires", 999966663333L, u.getPasswordLinkExpires());
|
||||||
assertEquals("changeRequired", true, u.isPasswordChangeRequired());
|
assertEquals("changeRequired", true, u.isPasswordChangeRequired());
|
||||||
assertEquals("loginCount", 42, u.getLoginCount());
|
assertEquals("loginCount", 42, u.getLoginCount());
|
||||||
|
assertEquals("lastLoginTime", 8877665544332211L, u.getLastLoginTime());
|
||||||
assertEquals("status", Status.INACTIVE, u.getStatus());
|
assertEquals("status", Status.INACTIVE, u.getStatus());
|
||||||
assertEquals("externalAuthId", "newUser", u.getExternalAuthId());
|
assertEquals("externalAuthId", "newUser", u.getExternalAuthId());
|
||||||
assertEquals("permissionSetUris", buildSet(URI_ROLE1, URI_ROLE2),
|
assertEquals("permissionSetUris", buildSet(URI_ROLE1, URI_ROLE2),
|
||||||
|
@ -188,6 +190,7 @@ public class UserAccountsDaoJenaTest extends AbstractTestClass {
|
||||||
up.setPasswordLinkExpires(1L);
|
up.setPasswordLinkExpires(1L);
|
||||||
up.setPasswordChangeRequired(false);
|
up.setPasswordChangeRequired(false);
|
||||||
up.setLoginCount(43);
|
up.setLoginCount(43);
|
||||||
|
up.setLastLoginTime(1020304050607080L);
|
||||||
up.setStatus(Status.ACTIVE);
|
up.setStatus(Status.ACTIVE);
|
||||||
up.setExternalAuthId("updatedUser1");
|
up.setExternalAuthId("updatedUser1");
|
||||||
up.setPermissionSetUris(buildSet(URI_ROLE1, URI_ROLE3));
|
up.setPermissionSetUris(buildSet(URI_ROLE1, URI_ROLE3));
|
||||||
|
@ -204,6 +207,7 @@ public class UserAccountsDaoJenaTest extends AbstractTestClass {
|
||||||
assertEquals("changeExpires", 1L, u.getPasswordLinkExpires());
|
assertEquals("changeExpires", 1L, u.getPasswordLinkExpires());
|
||||||
assertEquals("changeRequired", false, u.isPasswordChangeRequired());
|
assertEquals("changeRequired", false, u.isPasswordChangeRequired());
|
||||||
assertEquals("loginCount", 43, u.getLoginCount());
|
assertEquals("loginCount", 43, u.getLoginCount());
|
||||||
|
assertEquals("lastLoginTime", 1020304050607080L, u.getLastLoginTime());
|
||||||
assertEquals("status", Status.ACTIVE, u.getStatus());
|
assertEquals("status", Status.ACTIVE, u.getStatus());
|
||||||
assertEquals("externalAuthId", "updatedUser1", u.getExternalAuthId());
|
assertEquals("externalAuthId", "updatedUser1", u.getExternalAuthId());
|
||||||
assertEquals("permissionSetUris", buildSet(URI_ROLE1, URI_ROLE3),
|
assertEquals("permissionSetUris", buildSet(URI_ROLE1, URI_ROLE3),
|
||||||
|
|
|
@ -16,6 +16,7 @@ mydomain:user01
|
||||||
auth:md5password "garbage" ;
|
auth:md5password "garbage" ;
|
||||||
auth:passwordChangeExpires 0 ;
|
auth:passwordChangeExpires 0 ;
|
||||||
auth:loginCount 5 ;
|
auth:loginCount 5 ;
|
||||||
|
auth:lastLoginTime 12345678 ;
|
||||||
auth:status "ACTIVE" ;
|
auth:status "ACTIVE" ;
|
||||||
auth:externalAuthId "user1";
|
auth:externalAuthId "user1";
|
||||||
auth:hasPermissionSet mydomain:role1 ;
|
auth:hasPermissionSet mydomain:role1 ;
|
||||||
|
|
|
@ -122,6 +122,14 @@
|
||||||
<a class="sort-desc" href="?accountsPerPage=${accountsPerPage}&orderField=count&orderDirection=DESC" title="descending order"></a>
|
<a class="sort-desc" href="?accountsPerPage=${accountsPerPage}&orderField=count&orderDirection=DESC" title="descending order"></a>
|
||||||
</nav>
|
</nav>
|
||||||
</th>
|
</th>
|
||||||
|
|
||||||
|
<th scope="col">
|
||||||
|
Last Login Time
|
||||||
|
<nav class="account-alpha-browse">
|
||||||
|
<a class="sort-asc" href="?accountsPerPage=${accountsPerPage}&orderField=lastLogin&orderDirection=ASC" title="ascending order"></a>
|
||||||
|
<a class="sort-desc" href="?accountsPerPage=${accountsPerPage}&orderField=lastLogin&orderDirection=DESC" title="descending order"></a>
|
||||||
|
</nav>
|
||||||
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
|
@ -144,6 +152,13 @@
|
||||||
</#list>
|
</#list>
|
||||||
</td>
|
</td>
|
||||||
<td>${account.loginCount}</td>
|
<td>${account.loginCount}</td>
|
||||||
|
<td>
|
||||||
|
<#if account.lastLoginTime??>
|
||||||
|
${account.lastLoginTime?datetime?string.full}
|
||||||
|
<#else>
|
||||||
|
|
||||||
|
</#if>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</#list>
|
</#list>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue