diff --git a/apps/dnet-orgs-database-application/src/main/java/eu/dnetlib/organizations/WebSecurityConfig.java b/apps/dnet-orgs-database-application/src/main/java/eu/dnetlib/organizations/WebSecurityConfig.java index 212bf5fe..52c2ed9f 100644 --- a/apps/dnet-orgs-database-application/src/main/java/eu/dnetlib/organizations/WebSecurityConfig.java +++ b/apps/dnet-orgs-database-application/src/main/java/eu/dnetlib/organizations/WebSecurityConfig.java @@ -28,15 +28,15 @@ import org.springframework.security.web.access.AccessDeniedHandler; import eu.dnetlib.organizations.controller.UserInfo; import eu.dnetlib.organizations.controller.UserRole; import eu.dnetlib.organizations.model.User; -import eu.dnetlib.organizations.repository.UserRepository; import eu.dnetlib.organizations.utils.AuthenticationUtils; +import eu.dnetlib.organizations.utils.DatabaseUtils; @Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired - private UserRepository userRepository; + private DatabaseUtils databaseUtils; @Autowired private ClientRegistrationRepository clientRegistrationRepository; @@ -114,7 +114,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { return (userRequest) -> { final OidcUser oidcUser = delegate.loadUser(userRequest); - final String role = "ROLE_" + OPENORGS_ROLE_PREFIX + userRepository.findById(oidcUser.getEmail()) + final String role = "ROLE_" + OPENORGS_ROLE_PREFIX + databaseUtils.findUser(oidcUser.getEmail()) .map(User::getRole) .filter(StringUtils::isNotBlank) .orElse(UserRole.NOT_AUTHORIZED.toString()); diff --git a/apps/dnet-orgs-database-application/src/main/java/eu/dnetlib/organizations/model/view/UserView.java b/apps/dnet-orgs-database-application/src/main/java/eu/dnetlib/organizations/model/view/UserView.java index 573f5a79..e09b4da8 100644 --- a/apps/dnet-orgs-database-application/src/main/java/eu/dnetlib/organizations/model/view/UserView.java +++ b/apps/dnet-orgs-database-application/src/main/java/eu/dnetlib/organizations/model/view/UserView.java @@ -1,6 +1,7 @@ package eu.dnetlib.organizations.model.view; import java.io.Serializable; +import java.time.OffsetDateTime; import javax.persistence.Column; import javax.persistence.Entity; @@ -16,7 +17,7 @@ import com.vladmihalcea.hibernate.type.array.StringArrayType; @Entity @Table(name = "users_view") @TypeDefs({ - @TypeDef(name = "string-array", typeClass = StringArrayType.class) + @TypeDef(name = "string-array", typeClass = StringArrayType.class) }) public class UserView implements Serializable { @@ -35,6 +36,12 @@ public class UserView implements Serializable { @Column(name = "role") private String role; + @Column(name = "first_access") + private OffsetDateTime firstAccess; + + @Column(name = "last_access") + private OffsetDateTime lastAccess; + @Type(type = "string-array") @Column(name = "countries", columnDefinition = "text[]") private String[] countries; @@ -70,4 +77,20 @@ public class UserView implements Serializable { public void setCountries(final String[] countries) { this.countries = countries; } + + public OffsetDateTime getFirstAccess() { + return firstAccess; + } + + public void setFirstAccess(final OffsetDateTime firstAccess) { + this.firstAccess = firstAccess; + } + + public OffsetDateTime getLastAccess() { + return lastAccess; + } + + public void setLastAccess(final OffsetDateTime lastAccess) { + this.lastAccess = lastAccess; + } } diff --git a/apps/dnet-orgs-database-application/src/main/java/eu/dnetlib/organizations/repository/UserRepository.java b/apps/dnet-orgs-database-application/src/main/java/eu/dnetlib/organizations/repository/UserRepository.java index 0fb1188f..0d2da87e 100644 --- a/apps/dnet-orgs-database-application/src/main/java/eu/dnetlib/organizations/repository/UserRepository.java +++ b/apps/dnet-orgs-database-application/src/main/java/eu/dnetlib/organizations/repository/UserRepository.java @@ -1,9 +1,17 @@ package eu.dnetlib.organizations.repository; +import java.time.OffsetDateTime; + import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; import eu.dnetlib.organizations.model.User; public interface UserRepository extends JpaRepository { + @Modifying + @Query("update User set last_access = ?2 where email = ?1") + void updateLastAccess(final String email, OffsetDateTime now); + } diff --git a/apps/dnet-orgs-database-application/src/main/java/eu/dnetlib/organizations/utils/DatabaseUtils.java b/apps/dnet-orgs-database-application/src/main/java/eu/dnetlib/organizations/utils/DatabaseUtils.java index 65771b50..652b087b 100644 --- a/apps/dnet-orgs-database-application/src/main/java/eu/dnetlib/organizations/utils/DatabaseUtils.java +++ b/apps/dnet-orgs-database-application/src/main/java/eu/dnetlib/organizations/utils/DatabaseUtils.java @@ -401,6 +401,15 @@ public class DatabaseUtils { } } + @Transactional + public Optional findUser(final String email) { + final Optional user = userRepository.findById(email); + if (user.isPresent()) { + userRepository.updateLastAccess(email, OffsetDateTime.now()); + } + return user; + } + private String findFirstString(final List views, final Function mapper) { return views.stream().map(mapper).filter(StringUtils::isNotBlank).findFirst().orElse(null); } diff --git a/apps/dnet-orgs-database-application/src/main/resources/sql/schema.sql b/apps/dnet-orgs-database-application/src/main/resources/sql/schema.sql index cc5e6a97..2828a769 100644 --- a/apps/dnet-orgs-database-application/src/main/resources/sql/schema.sql +++ b/apps/dnet-orgs-database-application/src/main/resources/sql/schema.sql @@ -310,9 +310,11 @@ CREATE TABLE user_roles(role text PRIMARY KEY); INSERT INTO user_roles VALUES ('ADMIN'), ('NATIONAL_ADMIN'), ('USER'), ('PENDING'), ('NOT_AUTHORIZED'); CREATE TABLE users ( - email text PRIMARY KEY, - valid boolean DEFAULT true, - role text NOT NULL default 'USER' REFERENCES user_roles(role) + email text PRIMARY KEY, + valid boolean DEFAULT true, + role text NOT NULL default 'USER' REFERENCES user_roles(role), + first_access timestamp with time zone DEFAULT now(), + last_access timestamp with time zone DEFAULT now() ); CREATE TABLE user_countries ( @@ -507,11 +509,13 @@ CREATE VIEW users_view AS SELECT u.email, u.valid, u.role, + u.first_access, + u.last_access, array_remove(array_agg(uc.country), NULL) AS countries FROM users u LEFT OUTER JOIN user_countries uc ON (u.email = uc.email) -GROUP BY u.email, u.valid, u.role +GROUP BY u.email, u.valid, u.role, u.first_access, u.last_access ORDER BY u.email; CREATE VIEW suggestions_info_by_country_view AS SELECT c.val AS country, diff --git a/apps/dnet-orgs-database-application/src/main/resources/static/resources/html/pages/admin/users.html b/apps/dnet-orgs-database-application/src/main/resources/static/resources/html/pages/admin/users.html index 4a82ea01..cc21d3d3 100644 --- a/apps/dnet-orgs-database-application/src/main/resources/static/resources/html/pages/admin/users.html +++ b/apps/dnet-orgs-database-application/src/main/resources/static/resources/html/pages/admin/users.html @@ -2,23 +2,24 @@
-
+
- + - + + - + - +
UserUser Enabled Super Admin National AdminCountriesFirst/Last accessCountries
{{u.email}}{{u.email}} not configured @@ -30,7 +31,11 @@ + + {{u.firstAccess | date}}
+ {{u.lastAccess | date}} +
no countries