Skip to content

Commit 279c46f

Browse files
committed
Get connections
Signed-off-by: Etienne Homer <[email protected]>
1 parent 8696a80 commit 279c46f

File tree

8 files changed

+112
-14
lines changed

8 files changed

+112
-14
lines changed

src/main/java/org/gridsuite/useradmin/server/UserAdminController.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import io.swagger.v3.oas.annotations.responses.ApiResponse;
1111
import io.swagger.v3.oas.annotations.responses.ApiResponses;
1212
import io.swagger.v3.oas.annotations.tags.Tag;
13+
import org.gridsuite.useradmin.server.repository.ConnectionEntity;
1314
import org.gridsuite.useradmin.server.repository.UserInfosEntity;
1415
import org.gridsuite.useradmin.server.service.UserAdminService;
1516
import org.springframework.http.MediaType;
@@ -65,4 +66,10 @@ public ResponseEntity<Void> userExists(@PathVariable("sub") String sub) {
6566
return service.subExists(sub) ? ResponseEntity.ok().build() : ResponseEntity.noContent().build();
6667
}
6768

69+
@GetMapping(value = "/connections")
70+
@Operation(summary = "get the connections")
71+
@ApiResponse(responseCode = "200", description = "The connections list")
72+
public ResponseEntity<List<ConnectionEntity>> getConnections(@RequestHeader("userId") String userId) {
73+
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(service.getConnections(userId));
74+
}
6875
}

src/main/java/org/gridsuite/useradmin/server/repository/ConnectionEntity.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
import javax.persistence.*;
1515
import java.time.LocalDateTime;
16+
import java.util.UUID;
1617

1718
/**
1819
* @author Etienne Homer <etienne.homer at rte-france.com>
@@ -26,6 +27,9 @@
2627
public class ConnectionEntity {
2728

2829
@Id
30+
@Column(name = "id")
31+
private UUID id;
32+
2933
@Column(name = "sub", nullable = false)
3034
private String sub;
3135

@@ -37,4 +41,8 @@ public class ConnectionEntity {
3741

3842
@Column(name = "connectionAccepted", nullable = false)
3943
private Boolean connectionAccepted;
44+
45+
public ConnectionEntity(String sub, LocalDateTime firstConnexionDate, LocalDateTime lastConnexionDate, Boolean connectionAccepted) {
46+
this(UUID.randomUUID(), sub, firstConnexionDate, lastConnexionDate, connectionAccepted);
47+
}
4048
}

src/main/java/org/gridsuite/useradmin/server/repository/ConnectionRepository.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@
99
import org.springframework.data.jpa.repository.JpaRepository;
1010
import org.springframework.stereotype.Repository;
1111

12+
import java.util.List;
1213
import java.util.UUID;
1314

1415
/**
1516
* @author Etienne Homer <etienne.homer at rte-france.com>
1617
*/
1718
@Repository
1819
public interface ConnectionRepository extends JpaRepository<ConnectionEntity, UUID> {
19-
ConnectionEntity findBySub(String sub);
20+
List<ConnectionEntity> findBySub(String sub);
2021
}

src/main/java/org/gridsuite/useradmin/server/service/UserAdminService.java

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,11 @@
1919
import org.springframework.stereotype.Service;
2020

2121
import java.time.LocalDateTime;
22-
import java.util.List;
23-
import java.util.Objects;
24-
import java.util.UUID;
22+
import java.util.*;
23+
import java.util.concurrent.ConcurrentHashMap;
24+
import java.util.function.Function;
25+
import java.util.function.Predicate;
26+
import java.util.stream.Collectors;
2527

2628
import static org.gridsuite.useradmin.server.UserAdminException.Type.FORBIDDEN;
2729

@@ -50,6 +52,27 @@ public List<UserInfosEntity> getUsers(String userId) {
5052
return userAdminRepository.findAll();
5153
}
5254

55+
public List<ConnectionEntity> getConnections(String userId) {
56+
if (!isAdmin(userId)) {
57+
throw new UserAdminException(FORBIDDEN);
58+
}
59+
return removeDuplicates(connectionRepository.findAll());
60+
}
61+
62+
public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
63+
Set<Object> seen = ConcurrentHashMap.newKeySet();
64+
return t -> seen.add(keyExtractor.apply(t));
65+
}
66+
67+
68+
private List<ConnectionEntity> removeDuplicates(List<ConnectionEntity> connections) {
69+
List<ConnectionEntity> connectionsWithoutDuplicates = connections.stream().filter(distinctByKey(ConnectionEntity::getSub)).collect(Collectors.toList());
70+
connectionsWithoutDuplicates.stream().forEach(c -> c.setLastConnexionDate(connectionRepository.findBySub(c.getSub()).stream().max(Comparator.comparing(ConnectionEntity::getLastConnexionDate)).get().getLastConnexionDate()));
71+
connectionRepository.deleteAll();
72+
connectionRepository.saveAll(connectionsWithoutDuplicates);
73+
return connectionsWithoutDuplicates;
74+
}
75+
5376
public void createUser(String sub, String userId) {
5477
if (!isAdmin(userId)) {
5578
throw new UserAdminException(FORBIDDEN);
@@ -72,7 +95,7 @@ public boolean subExists(String sub) {
7295
}
7396

7497
public void recordConnectionAttempt(String sub, Boolean isAllowed) {
75-
ConnectionEntity connectionEntity = connectionRepository.findBySub(sub);
98+
ConnectionEntity connectionEntity = connectionRepository.findBySub(sub).stream().max(Comparator.comparing(ConnectionEntity::getLastConnexionDate)).orElse(null);
7699
if (connectionEntity == null) {
77100
connectionEntity = new ConnectionEntity(sub, LocalDateTime.now(), LocalDateTime.now(), isAllowed);
78101
try {

src/main/resources/config/application.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@ dbName: useradmin
66

77
useradmin:
88
admins:
9-
# - admin1
9+
- etiennehomer
1010
# - admin2

src/main/resources/db/changelog/changesets/changelog_2022-09-28T09:54:20Z.xml renamed to src/main/resources/db/changelog/changesets/changelog_2022-09-29T15:14:17Z.xml

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
22
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:pro="http://www.liquibase.org/xml/ns/pro" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/pro http://www.liquibase.org/xml/ns/pro/liquibase-pro-4.1.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
3-
<changeSet author="homereti (generated)" id="1664358870409-1">
3+
<changeSet author="homereti (generated)" id="1664464467053-1">
44
<createTable tableName="connection">
5-
<column name="sub" type="VARCHAR(255)">
5+
<column name="id" type="UUID">
66
<constraints nullable="false" primaryKey="true" primaryKeyName="connectionPK"/>
77
</column>
88
<column name="connection_accepted" type="BOOLEAN">
@@ -14,6 +14,14 @@
1414
<column name="last_connexion_date" type="TIMESTAMP">
1515
<constraints nullable="false"/>
1616
</column>
17+
<column name="sub" type="VARCHAR(255)">
18+
<constraints nullable="false"/>
19+
</column>
1720
</createTable>
1821
</changeSet>
22+
<changeSet author="homereti (generated)" id="1664464467053-2">
23+
<createIndex indexName="connection_sub_index" tableName="connection">
24+
<column name="sub"/>
25+
</createIndex>
26+
</changeSet>
1927
</databaseChangeLog>

src/main/resources/db/changelog/db.changelog-master.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@ databaseChangeLog:
55
relativeToChangelogFile: true
66

77
- include:
8-
file: changesets/changelog_2022-09-28T09:54:20Z.xml
8+
file: changesets/changelog_2022-09-29T15:14:17Z.xml
99
relativeToChangelogFile: true

src/test/java/org/gridsuite/useradmin/server/UserAdminTest.java

Lines changed: 56 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import com.fasterxml.jackson.core.type.TypeReference;
1010
import com.fasterxml.jackson.databind.ObjectMapper;
11+
import org.gridsuite.useradmin.server.repository.ConnectionEntity;
1112
import org.gridsuite.useradmin.server.repository.ConnectionRepository;
1213
import org.gridsuite.useradmin.server.repository.UserAdminRepository;
1314
import org.gridsuite.useradmin.server.repository.UserInfosEntity;
@@ -63,6 +64,8 @@ public void setup() {
6364
}
6465

6566
private static final String USER_SUB = "user1";
67+
68+
private static final String USER_SUB2 = "user2";
6669
private static final String ADMIN_USER = "admin1";
6770

6871
private static final String NOT_ADMIN = "notAdmin";
@@ -107,16 +110,16 @@ public void testUserAdmin() throws Exception {
107110
.andExpect(status().isNoContent())
108111
.andReturn();
109112
assertEquals(2, connectionRepository.findAll().size());
110-
assertTrue(connectionRepository.findBySub(USER_SUB).getConnectionAccepted());
111-
assertFalse(connectionRepository.findBySub("UNKNOWN").getConnectionAccepted());
112-
LocalDateTime firstConnectionDate = connectionRepository.findBySub(USER_SUB).getFirstConnexionDate();
113+
assertTrue(connectionRepository.findBySub(USER_SUB).get(0).getConnectionAccepted());
114+
assertFalse(connectionRepository.findBySub("UNKNOWN").get(0).getConnectionAccepted());
115+
LocalDateTime firstConnectionDate = connectionRepository.findBySub(USER_SUB).get(0).getFirstConnexionDate();
113116
//firstConnectionDate and lastConnectionDate are equals cause this is the first connection for this user
114-
assertTrue(firstConnectionDate.toEpochSecond(ZoneOffset.UTC) < connectionRepository.findBySub(USER_SUB).getLastConnexionDate().toEpochSecond(ZoneOffset.UTC) + 2);
117+
assertTrue(firstConnectionDate.toEpochSecond(ZoneOffset.UTC) < connectionRepository.findBySub(USER_SUB).get(0).getLastConnexionDate().toEpochSecond(ZoneOffset.UTC) + 2);
115118

116119
mockMvc.perform(head("/" + UserAdminApi.API_VERSION + "/users/{sub}", USER_SUB))
117120
.andExpect(status().isOk())
118121
.andReturn();
119-
assertEquals(firstConnectionDate, connectionRepository.findBySub(USER_SUB).getFirstConnexionDate());
122+
assertEquals(firstConnectionDate, connectionRepository.findBySub(USER_SUB).get(0).getFirstConnexionDate());
120123

121124
mockMvc.perform(delete("/" + UserAdminApi.API_VERSION + "/users/{id}", userId)
122125
.header("userId", ADMIN_USER)
@@ -152,4 +155,52 @@ public void testUserAdmin() throws Exception {
152155
.andExpect(status().isForbidden())
153156
.andReturn();
154157
}
158+
159+
@Test
160+
public void testGetConnections() throws Exception {
161+
mockMvc.perform(post("/" + UserAdminApi.API_VERSION + "/users/{sub}", USER_SUB)
162+
.header("userId", ADMIN_USER)
163+
)
164+
.andExpect(status().isOk())
165+
.andReturn();
166+
167+
mockMvc.perform(post("/" + UserAdminApi.API_VERSION + "/users/{sub}", USER_SUB2)
168+
.header("userId", ADMIN_USER)
169+
)
170+
.andExpect(status().isOk())
171+
.andReturn();
172+
173+
List<UserInfosEntity> userEntities = userEntities = objectMapper.readValue(
174+
mockMvc.perform(get("/" + UserAdminApi.API_VERSION + "/users")
175+
.header("userId", ADMIN_USER)
176+
.contentType(APPLICATION_JSON))
177+
.andExpect(status().isOk())
178+
.andReturn().getResponse().getContentAsString(),
179+
new TypeReference<>() {
180+
});
181+
182+
assertEquals(2, userEntities.size());
183+
184+
UUID userId = userEntities.get(0).getId();
185+
186+
mockMvc.perform(head("/" + UserAdminApi.API_VERSION + "/users/{sub}", USER_SUB))
187+
.andExpect(status().isOk())
188+
.andReturn();
189+
190+
mockMvc.perform(head("/" + UserAdminApi.API_VERSION + "/users/{sub}", USER_SUB2))
191+
.andExpect(status().isOk())
192+
.andReturn();
193+
194+
List<ConnectionEntity> connectionEntities = objectMapper.readValue(
195+
mockMvc.perform(get("/" + UserAdminApi.API_VERSION + "/connections")
196+
.header("userId", ADMIN_USER)
197+
.contentType(APPLICATION_JSON))
198+
.andExpect(status().isOk())
199+
.andReturn().getResponse().getContentAsString(),
200+
new TypeReference<>() {
201+
});
202+
203+
assertEquals(2, connectionEntities.size());
204+
205+
}
155206
}

0 commit comments

Comments
 (0)