From 545ecd97c4b4e7fa56090c7a29f1a287f9f84d81 Mon Sep 17 00:00:00 2001 From: Philip Dengler Date: Thu, 4 Jun 2020 07:20:58 +0200 Subject: [PATCH 1/5] last login time column added --- .../src/components/views/settings/userlist/UserDataTable.js | 1 + 1 file changed, 1 insertion(+) diff --git a/components/inspectit-ocelot-configurationserver-ui/src/components/views/settings/userlist/UserDataTable.js b/components/inspectit-ocelot-configurationserver-ui/src/components/views/settings/userlist/UserDataTable.js index 12b994bb90..99a1fb5c7f 100644 --- a/components/inspectit-ocelot-configurationserver-ui/src/components/views/settings/userlist/UserDataTable.js +++ b/components/inspectit-ocelot-configurationserver-ui/src/components/views/settings/userlist/UserDataTable.js @@ -30,6 +30,7 @@ class UserDataTable extends React.Component { + } /> Date: Thu, 4 Jun 2020 07:46:02 +0200 Subject: [PATCH 2/5] last login time added --- .../ocelot/rest/users/AccountController.java | 12 ++++++++++-- .../main/java/rocks/inspectit/ocelot/user/User.java | 3 +++ .../db/migration/V1.1__database__lastLoginAdded.sql | 2 ++ 3 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 components/inspectit-ocelot-configurationserver/src/main/resources/db/migration/V1.1__database__lastLoginAdded.sql diff --git a/components/inspectit-ocelot-configurationserver/src/main/java/rocks/inspectit/ocelot/rest/users/AccountController.java b/components/inspectit-ocelot-configurationserver/src/main/java/rocks/inspectit/ocelot/rest/users/AccountController.java index ca9f9db167..1ae98c0e6a 100644 --- a/components/inspectit-ocelot-configurationserver/src/main/java/rocks/inspectit/ocelot/rest/users/AccountController.java +++ b/components/inspectit-ocelot-configurationserver/src/main/java/rocks/inspectit/ocelot/rest/users/AccountController.java @@ -27,6 +27,10 @@ import rocks.inspectit.ocelot.user.UserPermissions; import rocks.inspectit.ocelot.user.UserService; +import java.sql.Timestamp; +import java.text.Format; +import java.text.SimpleDateFormat; +import java.util.Date; import java.util.Set; import java.util.stream.Collectors; @@ -58,8 +62,12 @@ public class AccountController extends AbstractBaseController { @ApiResponse(code = 200, message = "The access token", examples = @Example(value = @ExampleProperty(value = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsImV4cCI6MTU2MTYyODE1NH0.KelDW1OXg9xlMjSiblwZqui7sya4Crq833b-98p8UZ4", mediaType = "text/plain"))) @GetMapping("account/token") - public String acuireNewAccessToken(Authentication user) { - return tokenManager.createToken(user.getName()); + public String acuireNewAccessToken(Authentication auth) { + String timeStamp = new SimpleDateFormat("dd/MM/yyyy HH:mm").format(new Date()); + User user = userService.getUserByName(auth.getName()).get(); + user.setLastLoginTime(timeStamp); + userService.addOrUpdateUser(user); + return tokenManager.createToken(auth.getName()); } @ApiOperation(value = "Change Password", notes = "Changes the password of the logged in user." + diff --git a/components/inspectit-ocelot-configurationserver/src/main/java/rocks/inspectit/ocelot/user/User.java b/components/inspectit-ocelot-configurationserver/src/main/java/rocks/inspectit/ocelot/user/User.java index 3e20bd98a0..761b76147c 100644 --- a/components/inspectit-ocelot-configurationserver/src/main/java/rocks/inspectit/ocelot/user/User.java +++ b/components/inspectit-ocelot-configurationserver/src/main/java/rocks/inspectit/ocelot/user/User.java @@ -56,6 +56,9 @@ public class User implements Auditable { @Column(nullable = false) private boolean isLdapUser; + @Column + private String lastLoginTime; + @Override @JsonIgnore public AuditDetail getAuditDetail() { diff --git a/components/inspectit-ocelot-configurationserver/src/main/resources/db/migration/V1.1__database__lastLoginAdded.sql b/components/inspectit-ocelot-configurationserver/src/main/resources/db/migration/V1.1__database__lastLoginAdded.sql new file mode 100644 index 0000000000..579a7193d8 --- /dev/null +++ b/components/inspectit-ocelot-configurationserver/src/main/resources/db/migration/V1.1__database__lastLoginAdded.sql @@ -0,0 +1,2 @@ +ALTER TABLE user +ADD last_login_time varchar(30); \ No newline at end of file From 03b2595be4c45ba1bacdeccc3a676519591bc35e Mon Sep 17 00:00:00 2001 From: Philip Date: Wed, 10 Jun 2020 10:37:55 +0200 Subject: [PATCH 3/5] review backend --- .../ocelot/rest/users/AccountController.java | 15 ++++++--------- .../java/rocks/inspectit/ocelot/user/User.java | 5 ++++- .../migration/V1.1__database__lastLoginAdded.sql | 2 -- .../db/migration/V2__database__lastLoginAdded.sql | 2 ++ 4 files changed, 12 insertions(+), 12 deletions(-) delete mode 100644 components/inspectit-ocelot-configurationserver/src/main/resources/db/migration/V1.1__database__lastLoginAdded.sql create mode 100644 components/inspectit-ocelot-configurationserver/src/main/resources/db/migration/V2__database__lastLoginAdded.sql diff --git a/components/inspectit-ocelot-configurationserver/src/main/java/rocks/inspectit/ocelot/rest/users/AccountController.java b/components/inspectit-ocelot-configurationserver/src/main/java/rocks/inspectit/ocelot/rest/users/AccountController.java index 1ae98c0e6a..19671cda6c 100644 --- a/components/inspectit-ocelot-configurationserver/src/main/java/rocks/inspectit/ocelot/rest/users/AccountController.java +++ b/components/inspectit-ocelot-configurationserver/src/main/java/rocks/inspectit/ocelot/rest/users/AccountController.java @@ -26,11 +26,6 @@ import rocks.inspectit.ocelot.user.User; import rocks.inspectit.ocelot.user.UserPermissions; import rocks.inspectit.ocelot.user.UserService; - -import java.sql.Timestamp; -import java.text.Format; -import java.text.SimpleDateFormat; -import java.util.Date; import java.util.Set; import java.util.stream.Collectors; @@ -63,10 +58,12 @@ public class AccountController extends AbstractBaseController { @Example(value = @ExampleProperty(value = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsImV4cCI6MTU2MTYyODE1NH0.KelDW1OXg9xlMjSiblwZqui7sya4Crq833b-98p8UZ4", mediaType = "text/plain"))) @GetMapping("account/token") public String acuireNewAccessToken(Authentication auth) { - String timeStamp = new SimpleDateFormat("dd/MM/yyyy HH:mm").format(new Date()); - User user = userService.getUserByName(auth.getName()).get(); - user.setLastLoginTime(timeStamp); - userService.addOrUpdateUser(user); + long timeStamp = System.currentTimeMillis(); + if(userService.getUserByName(auth.getName()).isPresent()){ + User user = userService.getUserByName(auth.getName()).get(); + user.setLastLoginTime(timeStamp); + userService.addOrUpdateUser(user); + } return tokenManager.createToken(auth.getName()); } diff --git a/components/inspectit-ocelot-configurationserver/src/main/java/rocks/inspectit/ocelot/user/User.java b/components/inspectit-ocelot-configurationserver/src/main/java/rocks/inspectit/ocelot/user/User.java index 761b76147c..e063ff0fe6 100644 --- a/components/inspectit-ocelot-configurationserver/src/main/java/rocks/inspectit/ocelot/user/User.java +++ b/components/inspectit-ocelot-configurationserver/src/main/java/rocks/inspectit/ocelot/user/User.java @@ -56,8 +56,11 @@ public class User implements Auditable { @Column(nullable = false) private boolean isLdapUser; + /** + * Indicates the time when the user last logged in. + */ @Column - private String lastLoginTime; + private long lastLoginTime; @Override @JsonIgnore diff --git a/components/inspectit-ocelot-configurationserver/src/main/resources/db/migration/V1.1__database__lastLoginAdded.sql b/components/inspectit-ocelot-configurationserver/src/main/resources/db/migration/V1.1__database__lastLoginAdded.sql deleted file mode 100644 index 579a7193d8..0000000000 --- a/components/inspectit-ocelot-configurationserver/src/main/resources/db/migration/V1.1__database__lastLoginAdded.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE user -ADD last_login_time varchar(30); \ No newline at end of file diff --git a/components/inspectit-ocelot-configurationserver/src/main/resources/db/migration/V2__database__lastLoginAdded.sql b/components/inspectit-ocelot-configurationserver/src/main/resources/db/migration/V2__database__lastLoginAdded.sql new file mode 100644 index 0000000000..acef19a8fb --- /dev/null +++ b/components/inspectit-ocelot-configurationserver/src/main/resources/db/migration/V2__database__lastLoginAdded.sql @@ -0,0 +1,2 @@ +ALTER TABLE user +ADD last_login_time BIGINT; \ No newline at end of file From f66b0c785152ff1fea449213434f1c39900ec8d0 Mon Sep 17 00:00:00 2001 From: Philip Dengler Date: Wed, 10 Jun 2020 11:46:00 +0200 Subject: [PATCH 4/5] review frontend --- .../views/settings/userlist/UserDataTable.js | 37 ++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/components/inspectit-ocelot-configurationserver-ui/src/components/views/settings/userlist/UserDataTable.js b/components/inspectit-ocelot-configurationserver-ui/src/components/views/settings/userlist/UserDataTable.js index 99a1fb5c7f..b96be627be 100644 --- a/components/inspectit-ocelot-configurationserver-ui/src/components/views/settings/userlist/UserDataTable.js +++ b/components/inspectit-ocelot-configurationserver-ui/src/components/views/settings/userlist/UserDataTable.js @@ -22,8 +22,43 @@ class UserDataTable extends React.Component { this.setState({ userToDelete: null }); }; + addZero(x, n) { + while (x.toString().length < n) { + x = '0' + x; + } + return x; + } + + buildTimeStamp(users) { + for (let i = 0; i < users.length; i++) { + try { + const time = users[i].lastLoginTime; + const d = new Date(time); + const timeStamp = + this.addZero(d.getDate(), 2) + + '/' + + this.addZero(d.getMonth() + 1, 2) + + '/' + + d.getFullYear() + + ' ' + + this.addZero(d.getHours(), 2) + + ':' + + this.addZero(d.getMinutes(), 2) + + ':' + + this.addZero(d.getSeconds(), 2); + users[i].lastLoginTime = timeStamp; + } catch (e) { + continue; + } + } + return users; + } + render() { - const { users, filterValue, maxHeight } = this.props; + const { filterValue, maxHeight } = this.props; + let { users } = this.props; + + users = this.buildTimeStamp(users); return (
From c51586a9193193b9a12045e5c197ee32acf13996 Mon Sep 17 00:00:00 2001 From: Marius Oehler Date: Mon, 15 Jun 2020 15:55:24 +0200 Subject: [PATCH 5/5] Small refactoring of accountcontroller and userdatatable --- .../views/settings/userlist/UserDataTable.js | 44 +++---------------- .../ocelot/rest/users/AccountController.java | 13 +++--- ...dded.sql => V2__added_user_login_time.sql} | 0 .../rest/users/AccountControllerIntTest.java | 31 +++++++++++++ 4 files changed, 46 insertions(+), 42 deletions(-) rename components/inspectit-ocelot-configurationserver/src/main/resources/db/migration/{V2__database__lastLoginAdded.sql => V2__added_user_login_time.sql} (100%) diff --git a/components/inspectit-ocelot-configurationserver-ui/src/components/views/settings/userlist/UserDataTable.js b/components/inspectit-ocelot-configurationserver-ui/src/components/views/settings/userlist/UserDataTable.js index b96be627be..6635557b35 100644 --- a/components/inspectit-ocelot-configurationserver-ui/src/components/views/settings/userlist/UserDataTable.js +++ b/components/inspectit-ocelot-configurationserver-ui/src/components/views/settings/userlist/UserDataTable.js @@ -6,6 +6,7 @@ import { Column } from 'primereact/column'; import { Button } from 'primereact/button'; import { settingsActions } from '../../../../redux/ducks/settings'; import DeleteDialog from '../dialogs/DeleteDialog'; +import dateformat from 'dateformat'; /** * Fetches and lists all users. @@ -22,50 +23,19 @@ class UserDataTable extends React.Component { this.setState({ userToDelete: null }); }; - addZero(x, n) { - while (x.toString().length < n) { - x = '0' + x; - } - return x; - } - - buildTimeStamp(users) { - for (let i = 0; i < users.length; i++) { - try { - const time = users[i].lastLoginTime; - const d = new Date(time); - const timeStamp = - this.addZero(d.getDate(), 2) + - '/' + - this.addZero(d.getMonth() + 1, 2) + - '/' + - d.getFullYear() + - ' ' + - this.addZero(d.getHours(), 2) + - ':' + - this.addZero(d.getMinutes(), 2) + - ':' + - this.addZero(d.getSeconds(), 2); - users[i].lastLoginTime = timeStamp; - } catch (e) { - continue; - } - } - return users; - } - render() { - const { filterValue, maxHeight } = this.props; - let { users } = this.props; - - users = this.buildTimeStamp(users); + const { users, filterValue, maxHeight } = this.props; return (
- + (user.lastLoginTime === 0 ? '-' : dateformat(user.lastLoginTime, 'yyyy-mm-dd HH:MM:ss'))} + /> } /> userOptional = userService.getUserByName(auth.getName()); + + if (userOptional.isPresent()) { + User user = userOptional.get(); + user.setLastLoginTime(System.currentTimeMillis()); userService.addOrUpdateUser(user); } return tokenManager.createToken(auth.getName()); diff --git a/components/inspectit-ocelot-configurationserver/src/main/resources/db/migration/V2__database__lastLoginAdded.sql b/components/inspectit-ocelot-configurationserver/src/main/resources/db/migration/V2__added_user_login_time.sql similarity index 100% rename from components/inspectit-ocelot-configurationserver/src/main/resources/db/migration/V2__database__lastLoginAdded.sql rename to components/inspectit-ocelot-configurationserver/src/main/resources/db/migration/V2__added_user_login_time.sql diff --git a/components/inspectit-ocelot-configurationserver/src/test/java/rocks/inspectit/ocelot/rest/users/AccountControllerIntTest.java b/components/inspectit-ocelot-configurationserver/src/test/java/rocks/inspectit/ocelot/rest/users/AccountControllerIntTest.java index 8bfeaabaef..7e2749837f 100644 --- a/components/inspectit-ocelot-configurationserver/src/test/java/rocks/inspectit/ocelot/rest/users/AccountControllerIntTest.java +++ b/components/inspectit-ocelot-configurationserver/src/test/java/rocks/inspectit/ocelot/rest/users/AccountControllerIntTest.java @@ -119,4 +119,35 @@ void testAdminPermissions() { .build()); } } + + @Nested + class AcquireNewAccessToken { + + @Test + void acquireToken() { + long now = System.currentTimeMillis(); + + userService.addOrUpdateUser(User.builder() + .username("John") + .password("doe") + .build()); + + long loginTimeBefore = userService + .getUserByName("John").get() + .getLastLoginTime(); + assertThat(loginTimeBefore).isZero(); + + ResponseEntity result = rest + .withBasicAuth("John", "doe") + .getForEntity("/api/v1/account/token", String.class); + + assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); + + long loginTimeAfter = userService + .getUserByName("John").get() + .getLastLoginTime(); + assertThat(loginTimeAfter).isGreaterThanOrEqualTo(now); + } + + } }