From 6914a0851c86d3ca7944ff04b4207827aab9aa8b Mon Sep 17 00:00:00 2001 From: chasegawa Date: Tue, 23 May 2023 13:32:38 -0700 Subject: [PATCH] SHIBUI-2568 Adding tracking of logins for use in telemetry reporting --- .../ui/security/controller/UsersController.java | 7 +++++++ .../repository/UserLoginRecordRepository.java | 6 ++++++ .../admin/ui/security/service/UserService.java | 7 +++++++ .../ui/security/service/UserServiceTests.groovy | 13 +++++++++++++ 4 files changed, 33 insertions(+) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/controller/UsersController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/controller/UsersController.java index a2faab3d0..f20ce7889 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/controller/UsersController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/controller/UsersController.java @@ -90,6 +90,13 @@ public User getCurrentUser(Principal principal) { return userService.getCurrentUser(); } + @PreAuthorize("hasRole('ADMIN')") + @Transactional(readOnly = true) + @GetMapping("/loginCount") + public int getDailyLoginCount() { + return userService.getDailyLoginCount(); + } + @PreAuthorize("hasRole('ADMIN')") @Transactional(readOnly = true) @GetMapping("/{username}") diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/repository/UserLoginRecordRepository.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/repository/UserLoginRecordRepository.java index b5819bcd5..22a97fabb 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/repository/UserLoginRecordRepository.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/repository/UserLoginRecordRepository.java @@ -2,9 +2,15 @@ import edu.internet2.tier.shibboleth.admin.ui.security.model.UserLoginRecord; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import java.util.Date; import java.util.Optional; public interface UserLoginRecordRepository extends JpaRepository { Optional findByUsernameAndLogin(String username, String formattedDate); + + @Query(value = "SELECT count(*) FROM UserLoginRecord ulr WHERE ulr.loginDate >= :sinceDate") + int countLoginsSince(@Param("sinceDate") Date sinceDate); } \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/service/UserService.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/service/UserService.java index 82429ab26..e2a45b12f 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/service/UserService.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/service/UserService.java @@ -17,6 +17,7 @@ import edu.internet2.tier.shibboleth.admin.ui.security.repository.UserRepository; import lombok.NoArgsConstructor; import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.time.DateUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; @@ -24,6 +25,7 @@ import org.springframework.transaction.annotation.Transactional; import java.text.SimpleDateFormat; +import java.time.LocalDate; import java.util.ArrayList; import java.util.Date; import java.util.HashSet; @@ -261,4 +263,9 @@ public void updateLoginRecord(String username) { userLoginRecordRepository.saveAndFlush(ulr); } } + + public int getDailyLoginCount() { + Date since = DateUtils.addDays(new Date(), -1); + return userLoginRecordRepository.countLoginsSince(since); + } } \ No newline at end of file diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/security/service/UserServiceTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/security/service/UserServiceTests.groovy index df99bf0b3..5b7b9feb0 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/security/service/UserServiceTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/security/service/UserServiceTests.groovy @@ -6,6 +6,7 @@ import edu.internet2.tier.shibboleth.admin.ui.security.model.Ownership import edu.internet2.tier.shibboleth.admin.ui.security.model.Role import edu.internet2.tier.shibboleth.admin.ui.security.model.User import edu.internet2.tier.shibboleth.admin.ui.security.model.UserLoginRecord +import org.apache.commons.lang.time.DateUtils import java.text.SimpleDateFormat @@ -193,6 +194,7 @@ class UserServiceTests extends AbstractBaseDataJpaTest { then: userLoginRecordRepository.findByUsernameAndLogin("username", formattedDate).isPresent() userLoginRecordRepository.count() == 1 + userService.getDailyLoginCount() == 1 when: userService.updateLoginRecord("username2") @@ -200,5 +202,16 @@ class UserServiceTests extends AbstractBaseDataJpaTest { then: userLoginRecordRepository.findByUsernameAndLogin("username2", formattedDate).isPresent() userLoginRecordRepository.count() == 2 + userService.getDailyLoginCount() == 2 + + when: 'older logins in db, should be same counts' + Date older = DateUtils.addDays(new Date(), -3) + String formattedDate2 = DATE_FORMAT.format(older) + UserLoginRecord ulr2 = new UserLoginRecord("username", older, formattedDate2) + userLoginRecordRepository.save(ulr2) + + then: + userLoginRecordRepository.count() == 3 + userService.getDailyLoginCount() == 2 } } \ No newline at end of file