diff --git a/content-resources/src/main/resources/flyway/oskari/V2_13_0__add_created_field_to_user_table.sql b/content-resources/src/main/resources/flyway/oskari/V2_13_0__add_created_field_to_user_table.sql new file mode 100644 index 0000000000..1c978efbb0 --- /dev/null +++ b/content-resources/src/main/resources/flyway/oskari/V2_13_0__add_created_field_to_user_table.sql @@ -0,0 +1,2 @@ +ALTER TABLE oskari_users ADD COLUMN created TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(); +ALTER TABLE oskari_users ADD COLUMN last_login TIMESTAMP WITH TIME ZONE DEFAULT null; \ No newline at end of file diff --git a/service-base/src/main/java/fi/nls/oskari/domain/User.java b/service-base/src/main/java/fi/nls/oskari/domain/User.java index d47b7d155b..b59bea275c 100755 --- a/service-base/src/main/java/fi/nls/oskari/domain/User.java +++ b/service-base/src/main/java/fi/nls/oskari/domain/User.java @@ -8,6 +8,7 @@ import org.json.JSONObject; import java.io.Serializable; +import java.time.OffsetDateTime; import java.util.Arrays; import java.util.LinkedHashSet; import java.util.List; @@ -27,6 +28,8 @@ public class User implements Serializable { private static final String KEY_USERID = "userID"; private final static String KEY_ROLES = "roles"; private final static String KEY_ADMIN = "admin"; + private final static String KEY_CREATED = "created"; + private final static String KEY_LAST_LOGIN = "lastLogin"; private long id = -1; private String lastname = ""; @@ -34,6 +37,8 @@ public class User implements Serializable { private String screenname = ""; private String email = ""; private JSONObject attributes = new JSONObject(); + private OffsetDateTime created; + private OffsetDateTime lastLogin; private String uuid = ""; private Set roles = new LinkedHashSet<>(); @@ -210,6 +215,22 @@ public String getFirstname() { return firstname; } + public OffsetDateTime getCreated() { + return created; + } + + public void setCreated(OffsetDateTime created) { + this.created = created; + } + + public OffsetDateTime getLastLogin() { + return lastLogin; + } + + public void setLastLogin(OffsetDateTime lastLogin) { + this.lastLogin = lastLogin; + } + public JSONObject toJSON() { try { JSONObject userData = new JSONObject(); @@ -219,6 +240,8 @@ public JSONObject toJSON() { userData.put(KEY_NICKNAME, getScreenname()); userData.put(KEY_USERUUID, getUuid()); userData.put(KEY_USERID, getId()); + userData.put(KEY_CREATED, getCreated()); + userData.put(KEY_LAST_LOGIN, getLastLogin()); if (isAdmin()){ userData.put(KEY_ADMIN, true); } diff --git a/service-users/src/main/java/fi/nls/oskari/user/DatabaseUserService.java b/service-users/src/main/java/fi/nls/oskari/user/DatabaseUserService.java index 08f67bc863..1bcbf2a842 100755 --- a/service-users/src/main/java/fi/nls/oskari/user/DatabaseUserService.java +++ b/service-users/src/main/java/fi/nls/oskari/user/DatabaseUserService.java @@ -11,7 +11,14 @@ import org.apache.commons.codec.digest.DigestUtils; import org.springframework.security.crypto.bcrypt.BCrypt; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + public class DatabaseUserService extends UserService { diff --git a/service-users/src/main/java/fi/nls/oskari/user/UsersMapper.java b/service-users/src/main/java/fi/nls/oskari/user/UsersMapper.java index 628e7ce038..d14659f7a5 100644 --- a/service-users/src/main/java/fi/nls/oskari/user/UsersMapper.java +++ b/service-users/src/main/java/fi/nls/oskari/user/UsersMapper.java @@ -13,22 +13,24 @@ public interface UsersMapper { @Result(property="email", column="email"), @Result(property="uuid", column="uuid"), @Result(property="screenname", column="user_name"), - @Result(property="attributes", column="attributes") + @Result(property="attributes", column="attributes"), + @Result(property="created", column="created"), + @Result(property="lastLogin", column="last_login") }) - @Select("SELECT id, first_name, last_name, user_name, email, uuid, attributes" + + @Select("SELECT id, first_name, last_name, user_name, email, uuid, attributes, created, last_login" + " FROM oskari_users" + " ORDER BY user_name") List findAll(); @ResultMap("UsersResult") - @Select("SELECT id, first_name, last_name, user_name, email, uuid, attributes" + + @Select("SELECT id, first_name, last_name, user_name, email, uuid, attributes, created, last_login" + " FROM oskari_users" + " ORDER BY user_name" + " LIMIT #{limit} OFFSET #{offset}") List findAllPaginated(@Param("limit") int limit, @Param("offset") int offset); @ResultMap("UsersResult") - @Select("SELECT id, first_name, last_name, user_name, email, uuid, attributes" + + @Select("SELECT id, first_name, last_name, user_name, email, uuid, attributes, created, last_login" + " FROM oskari_users" + " WHERE " + " user_name ilike '%' || #{query} || '%'" + @@ -74,12 +76,13 @@ public interface UsersMapper { " last_name = #{lastname}, " + " user_name = #{screenname}, " + " email = #{email}, " + - " attributes = #{attributes} " + + " attributes = #{attributes}, " + + " last_login = #{lastLogin} " + " WHERE id = #{id}") void updateUser(User user); @ResultMap("UsersResult") - @Select("SELECT id, first_name, last_name, user_name, email, uuid, attributes" + + @Select("SELECT id, first_name, last_name, user_name, email, uuid, attributes, created, last_login" + " FROM oskari_users" + " WHERE id = #{id}") User find(long id); @@ -95,7 +98,7 @@ public interface UsersMapper { String getPassword(final String username); @ResultMap("UsersResult") - @Select("SELECT id, first_name, last_name, user_name, email, uuid, attributes" + + @Select("SELECT id, first_name, last_name, user_name, email, uuid, attributes, created, last_login" + " FROM oskari_users" + " WHERE user_name = #{username}") User findByUserName(String username); diff --git a/servlet-map/src/main/java/fi/nls/oskari/spring/security/OskariUserHelper.java b/servlet-map/src/main/java/fi/nls/oskari/spring/security/OskariUserHelper.java index 1155ad21e4..84d2b068d4 100755 --- a/servlet-map/src/main/java/fi/nls/oskari/spring/security/OskariUserHelper.java +++ b/servlet-map/src/main/java/fi/nls/oskari/spring/security/OskariUserHelper.java @@ -6,6 +6,7 @@ import fi.nls.oskari.log.LogFactory; import fi.nls.oskari.log.Logger; import fi.nls.oskari.service.UserService; +import fi.nls.oskari.user.MybatisUserService; import org.oskari.log.AuditLog; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; @@ -15,6 +16,7 @@ import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; +import java.time.OffsetDateTime; import java.util.ArrayList; import java.util.List; import java.util.Set; @@ -25,6 +27,7 @@ public class OskariUserHelper { private static Logger log = LogFactory.getLogger(OskariUserHelper.class); + private MybatisUserService userService = new MybatisUserService(); /** * Common code done for SAML and DB authentication on successful login @@ -77,6 +80,11 @@ private void setupSession(final HttpServletRequest httpRequest, final String use AuditLog.user(ActionParameters.getClientIp(httpRequest), loadedUser) .withMsg("Login") .updated(AuditLog.ResourceType.USER); + + // update last login + User userToUpdate = UserService.getInstance().getUser(username); + userToUpdate.setLastLogin(OffsetDateTime.now()); + userService.updateUser(userToUpdate); } else { log.error("Login user check failed! Got user from principal, but can't find it in Oskari db:", username);