From 686cfb51d6d9535fc6078d5b6bafbdbfb6d9872b Mon Sep 17 00:00:00 2001 From: Andrew Rowley Date: Thu, 16 Jan 2025 16:53:33 +0000 Subject: [PATCH 1/7] Remove unused state --- .../manchester/spinnaker/alloc/allocator/AllocatorFailTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/SpiNNaker-allocserv/src/test/java/uk/ac/manchester/spinnaker/alloc/allocator/AllocatorFailTest.java b/SpiNNaker-allocserv/src/test/java/uk/ac/manchester/spinnaker/alloc/allocator/AllocatorFailTest.java index e1952d5296..de93c5e8e5 100644 --- a/SpiNNaker-allocserv/src/test/java/uk/ac/manchester/spinnaker/alloc/allocator/AllocatorFailTest.java +++ b/SpiNNaker-allocserv/src/test/java/uk/ac/manchester/spinnaker/alloc/allocator/AllocatorFailTest.java @@ -19,7 +19,6 @@ import static org.junit.jupiter.api.Assumptions.assumeTrue; import static uk.ac.manchester.spinnaker.alloc.model.JobState.READY; import static uk.ac.manchester.spinnaker.alloc.model.JobState.QUEUED; -import static uk.ac.manchester.spinnaker.alloc.model.JobState.DESTROYED; import java.io.IOException; import java.util.List; From 79efcb38773edafea469888e8c6a5213fc970202 Mon Sep 17 00:00:00 2001 From: Andrew Rowley Date: Thu, 16 Jan 2025 18:24:08 +0000 Subject: [PATCH 2/7] Surely updating a user should describe user? --- .../uk/ac/manchester/spinnaker/alloc/admin/AdminImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SpiNNaker-allocserv/src/main/java/uk/ac/manchester/spinnaker/alloc/admin/AdminImpl.java b/SpiNNaker-allocserv/src/main/java/uk/ac/manchester/spinnaker/alloc/admin/AdminImpl.java index 4bdc60c89c..da02acc516 100644 --- a/SpiNNaker-allocserv/src/main/java/uk/ac/manchester/spinnaker/alloc/admin/AdminImpl.java +++ b/SpiNNaker-allocserv/src/main/java/uk/ac/manchester/spinnaker/alloc/admin/AdminImpl.java @@ -210,10 +210,10 @@ public UserRecord updateUser(int id, UserRecord providedUser, UriInfo ui, log.warn("CALLED updateUser({})", providedUser.getUserName()); var adminUser = security.getUserPrincipal().getName(); providedUser.setUserId(null); - var ub = ui.getBaseUriBuilder().path(DESCRIBE_GROUP); + var ub = ui.getBaseUriBuilder().path(DESCRIBE_USER); return userManager .updateUser(id, providedUser, adminUser, - m -> ub.build(m.getGroupId())) + m -> ub.build(m.getUserId())) .orElseThrow(AdminImpl::noUser).sanitise(); } From 554f81e3a9f6288f4c5b6192e7981e805008fb7e Mon Sep 17 00:00:00 2001 From: Andrew Rowley Date: Thu, 16 Jan 2025 19:10:59 +0000 Subject: [PATCH 3/7] Try without ignore here? --- .../java/uk/ac/manchester/spinnaker/alloc/model/UserRecord.java | 1 - 1 file changed, 1 deletion(-) diff --git a/SpiNNaker-allocserv/src/main/java/uk/ac/manchester/spinnaker/alloc/model/UserRecord.java b/SpiNNaker-allocserv/src/main/java/uk/ac/manchester/spinnaker/alloc/model/UserRecord.java index 59021a72bd..ca5d04ea41 100644 --- a/SpiNNaker-allocserv/src/main/java/uk/ac/manchester/spinnaker/alloc/model/UserRecord.java +++ b/SpiNNaker-allocserv/src/main/java/uk/ac/manchester/spinnaker/alloc/model/UserRecord.java @@ -288,7 +288,6 @@ public void setOpenIdSubject(String subject) { } /** @return Whether this is an internal user. */ - @JsonIgnore public boolean isInternal() { return isInternal; } From 8773f05bb88c262e6038d25e1d4922ffbd5a0ec8 Mon Sep 17 00:00:00 2001 From: Andrew Rowley Date: Fri, 24 Jan 2025 16:27:44 +0000 Subject: [PATCH 4/7] Add some more tests --- SpiNNaker-allocserv/pom.xml | 10 ++ .../alloc/admin/AdminControllerImpl.java | 17 ++- .../spinnaker/alloc/TestSupport.java | 2 +- .../alloc/admin/AdminControllerTest.java | 143 ++++++++++++++++++ .../alloc/admin/UserControlTest.java | 123 +++++++++++++++ 5 files changed, 291 insertions(+), 4 deletions(-) create mode 100644 SpiNNaker-allocserv/src/test/java/uk/ac/manchester/spinnaker/alloc/admin/AdminControllerTest.java create mode 100644 SpiNNaker-allocserv/src/test/java/uk/ac/manchester/spinnaker/alloc/admin/UserControlTest.java diff --git a/SpiNNaker-allocserv/pom.xml b/SpiNNaker-allocserv/pom.xml index 54948e3548..dee7c91b23 100644 --- a/SpiNNaker-allocserv/pom.xml +++ b/SpiNNaker-allocserv/pom.xml @@ -335,6 +335,11 @@ limitations under the License. spring-boot-test test + + org.springframework.boot + spring-boot-test-autoconfigure + test + uk.ac.manchester.spinnaker SpiNNaker-comms @@ -365,6 +370,11 @@ limitations under the License. org.springframework.security spring-security-core + + org.springframework.security + spring-security-test + test + org.springframework.boot spring-boot-starter-security diff --git a/SpiNNaker-allocserv/src/main/java/uk/ac/manchester/spinnaker/alloc/admin/AdminControllerImpl.java b/SpiNNaker-allocserv/src/main/java/uk/ac/manchester/spinnaker/alloc/admin/AdminControllerImpl.java index 01b0c7cd0f..1eef57fb72 100644 --- a/SpiNNaker-allocserv/src/main/java/uk/ac/manchester/spinnaker/alloc/admin/AdminControllerImpl.java +++ b/SpiNNaker-allocserv/src/main/java/uk/ac/manchester/spinnaker/alloc/admin/AdminControllerImpl.java @@ -86,7 +86,9 @@ import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.stream.Collectors; +import javax.servlet.http.HttpServletRequest; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Response.Status; @@ -292,13 +294,22 @@ private ModelAndView errors(DataAccessException exception) { } @ExceptionHandler(BindException.class) - ModelAndView validationError(BindException result) { + ModelAndView validationError(BindException result, HttpServletRequest req) { + log.debug("Binding problem on request {}", req.getRequestURI()); + if (req.getMethod() == "POST") { + try { + log.debug("Body: {}", req.getReader().lines().collect( + Collectors.joining())); + } catch (IOException e) { + log.debug("Failed to read request body", e); + } + } if (result.hasGlobalErrors()) { // I don't believe this is really reachable code - log.debug("binding problem", result); + log.debug("global binding problem", result); return errors(errorMessage(result.getGlobalError())); } else if (result.hasFieldErrors()) { - log.debug("binding problem", result); + log.debug("field binding problem", result); return errors(errorMessage(result.getFieldError())); } else { // This should definitely be unreachable diff --git a/SpiNNaker-allocserv/src/test/java/uk/ac/manchester/spinnaker/alloc/TestSupport.java b/SpiNNaker-allocserv/src/test/java/uk/ac/manchester/spinnaker/alloc/TestSupport.java index 990d21c345..f5d45292dc 100644 --- a/SpiNNaker-allocserv/src/test/java/uk/ac/manchester/spinnaker/alloc/TestSupport.java +++ b/SpiNNaker-allocserv/src/test/java/uk/ac/manchester/spinnaker/alloc/TestSupport.java @@ -178,7 +178,7 @@ private static void makeMachine(Connection c, int width, int height, } } - private static void makeUser(Connection c) { + protected static void makeUser(Connection c) { try (var u = c.update(INSERT_USER)) { u.call(USER, USER_NAME, BASIC, true); } diff --git a/SpiNNaker-allocserv/src/test/java/uk/ac/manchester/spinnaker/alloc/admin/AdminControllerTest.java b/SpiNNaker-allocserv/src/test/java/uk/ac/manchester/spinnaker/alloc/admin/AdminControllerTest.java new file mode 100644 index 0000000000..be3e2f470e --- /dev/null +++ b/SpiNNaker-allocserv/src/test/java/uk/ac/manchester/spinnaker/alloc/admin/AdminControllerTest.java @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2025 The University of Manchester + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package uk.ac.manchester.spinnaker.alloc.admin; + +import static uk.ac.manchester.spinnaker.alloc.admin.AdminController.BASE_PATH; +import static uk.ac.manchester.spinnaker.alloc.admin.AdminController.CREATE_USER_PATH; +import static uk.ac.manchester.spinnaker.alloc.admin.AdminController.USERS_PATH; +import static org.junit.Assert.assertTrue; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrlPattern; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.forwardedUrl; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; + +import java.util.Base64; + +import javax.ws.rs.core.MediaType; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit.jupiter.web.SpringJUnitWebConfig; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; + +import uk.ac.manchester.spinnaker.alloc.TestSupport; +import uk.ac.manchester.spinnaker.alloc.model.UserRecord; +import uk.ac.manchester.spinnaker.alloc.security.TrustLevel; + +@AutoConfigureMockMvc +@SpringBootTest +@SpringJUnitWebConfig(TestSupport.Config.class) +@ActiveProfiles("unittest") +public class AdminControllerTest extends TestSupport { + + @Autowired + private MockMvc mvc; + + @Autowired + private UserControl userControl; + + @Test + public void testCreateUser() throws Exception { + doTransactionalTest(() -> { + // Create an admin + UserRecord admin = new UserRecord(); + admin.setUserName("admin"); + admin.setEnabled(true); + admin.setHasPassword(true); + admin.setTrustLevel(TrustLevel.ADMIN); + admin.setPassword("admin"); + + var adminRecord = userControl.createUser(admin); + assertTrue(adminRecord.isPresent()); + + String userPass = Base64.getEncoder().encodeToString( + "admin:admin".getBytes()); + try { + var result = mvc.perform( + MockMvcRequestBuilders + .post(BASE_PATH + CREATE_USER_PATH) + .with(csrf()) + .header("Authorization", "Basic " + userPass) + .param("internal", "true") + .param("userName", "test") + .param("trustLevel", "USER") + .param("password", "test") + .param("enabled", "true") + .param("hasPassword", "true") + .accept(MediaType.APPLICATION_JSON)); + result.andExpect( + redirectedUrlPattern(BASE_PATH + USERS_PATH + "/*")); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + } + + @Test + public void updateUserPassword() throws Exception { + doTransactionalTest(() -> { + // Create an admin + UserRecord admin = new UserRecord(); + admin.setUserName("admin"); + admin.setEnabled(true); + admin.setHasPassword(true); + admin.setTrustLevel(TrustLevel.ADMIN); + admin.setPassword("admin"); + + var adminRecord = userControl.createUser(admin); + assertTrue(adminRecord.isPresent()); + + String userPass = Base64.getEncoder().encodeToString( + "admin:admin".getBytes()); + + // Create a user + UserRecord test = new UserRecord(); + test.setUserName("test"); + test.setEnabled(true); + test.setHasPassword(true); + test.setTrustLevel(TrustLevel.USER); + test.setPassword("test"); + + var testRecord = userControl.createUser(test); + assertTrue(testRecord.isPresent()); + UserRecord testUser = testRecord.get(); + + try { + var result = mvc.perform( + MockMvcRequestBuilders + .post(BASE_PATH + USERS_PATH + "/" + testUser.getUserId()) + .with(csrf()) + .header("Authorization", "Basic " + userPass) + .param("internal", "true") + .param("userName", "test") + .param("trustLevel", "USER") + .param("password", "testchange") + .accept(MediaType.APPLICATION_JSON)); + + // Note: not sure how to get this dynamically! + result.andExpect( + forwardedUrl("/WEB-INF/views/admin/userdetails.jsp")); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + } + + +} diff --git a/SpiNNaker-allocserv/src/test/java/uk/ac/manchester/spinnaker/alloc/admin/UserControlTest.java b/SpiNNaker-allocserv/src/test/java/uk/ac/manchester/spinnaker/alloc/admin/UserControlTest.java new file mode 100644 index 0000000000..7332447a7a --- /dev/null +++ b/SpiNNaker-allocserv/src/test/java/uk/ac/manchester/spinnaker/alloc/admin/UserControlTest.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2025 The University of Manchester + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package uk.ac.manchester.spinnaker.alloc.admin; + +import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assumptions.assumeTrue; + +import java.io.IOException; +import java.net.URI; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit.jupiter.web.SpringJUnitWebConfig; + +import uk.ac.manchester.spinnaker.alloc.TestSupport; +import uk.ac.manchester.spinnaker.alloc.model.UserRecord; +import uk.ac.manchester.spinnaker.alloc.security.TrustLevel; + +@SpringBootTest +@SpringJUnitWebConfig(TestSupport.Config.class) +@ActiveProfiles("unittest") +public class UserControlTest extends TestSupport { + + @Autowired + private UserControl userControl; + + @BeforeEach + void checkSetup() throws IOException { + assumeTrue(db != null, "spring-configured DB engine absent"); + killDB(); + } + + @Test + public void testCreateUser() { + doTransactionalTest(() -> { + UserRecord user = new UserRecord(); + user.setUserName("test"); + user.setEnabled(true); + user.setHasPassword(true); + user.setTrustLevel(TrustLevel.USER); + user.setPassword("test"); + + var userRecord = userControl.createUser(user); + assertTrue(userRecord.isPresent()); + + // The response is just a user sketch... + var realUserRecord = userRecord.get(); + assertTrue(realUserRecord.getUserId() != null); + assertEquals(user.getUserName(), realUserRecord.getUserName()); + assertEquals(null, realUserRecord.getOpenIdSubject()); + }); + } + + @Test + public void testGetUserRecord() { + doTransactionalTest(() -> { + makeUser(conn); + var record = userControl.getUser(USER, + (mr) -> {return URI.create("");}); + assertTrue(record.isPresent()); + var user = record.get(); + assertEquals(USER, user.getUserId()); + assertEquals(USER_NAME, user.getUserName()); + }); + } + + @Test + public void testUpdateUser() { + + // Create a user + UserRecord user = new UserRecord(); + user.setUserName("test"); + user.setEnabled(true); + user.setHasPassword(true); + user.setTrustLevel(TrustLevel.USER); + user.setPassword("test"); + + var userRecord = userControl.createUser(user); + assertTrue(userRecord.isPresent()); + var id = userRecord.get().getUserId(); + + // Create an admin + UserRecord admin = new UserRecord(); + admin.setUserName("admin"); + admin.setEnabled(true); + admin.setHasPassword(true); + admin.setTrustLevel(TrustLevel.ADMIN); + admin.setPassword("admin"); + + var adminRecord = userControl.createUser(admin); + assertTrue(adminRecord.isPresent()); + + // Update the user password + var retrievedUser = userControl.getUser( + userRecord.get().getUserName(), (mr) -> { + return URI.create(""); + }).get(); + retrievedUser.sanitise(); + retrievedUser.setPassword("newpassword"); + retrievedUser.setUserId(null); + var result = userControl.updateUser(id, retrievedUser, + admin.getUserName(), (mr) -> {return URI.create("");}); + assertTrue(result.isPresent()); + } + +} From 7a6fdf9fad6b628005e8f5037f976cba2ed780f9 Mon Sep 17 00:00:00 2001 From: Andrew Rowley Date: Fri, 24 Jan 2025 16:28:44 +0000 Subject: [PATCH 5/7] Fix #1156 by including the internal in the form --- .../src/main/webapp/WEB-INF/views/admin/userdetails.jsp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/SpiNNaker-allocserv/src/main/webapp/WEB-INF/views/admin/userdetails.jsp b/SpiNNaker-allocserv/src/main/webapp/WEB-INF/views/admin/userdetails.jsp index 264663bfc0..865d385108 100644 --- a/SpiNNaker-allocserv/src/main/webapp/WEB-INF/views/admin/userdetails.jsp +++ b/SpiNNaker-allocserv/src/main/webapp/WEB-INF/views/admin/userdetails.jsp @@ -10,7 +10,7 @@ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - https://www.apache.org/licenses/LICENSE-2.0 + https://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -34,6 +34,7 @@ limitations under the License. + User Name: From 51c80daca652494d2f0f65f4b1256cd7205362bf Mon Sep 17 00:00:00 2001 From: Andrew Rowley Date: Mon, 27 Jan 2025 14:11:56 +0000 Subject: [PATCH 6/7] Make sure that the user returned has more details --- .../alloc/admin/AdminControllerImpl.java | 2 +- .../spinnaker/alloc/admin/AdminImpl.java | 5 +-- .../spinnaker/alloc/admin/UserControl.java | 33 ++++++++----------- .../alloc/admin/AdminControllerTest.java | 11 +++++-- .../alloc/admin/UserControlTest.java | 10 +++--- 5 files changed, 30 insertions(+), 31 deletions(-) diff --git a/SpiNNaker-allocserv/src/main/java/uk/ac/manchester/spinnaker/alloc/admin/AdminControllerImpl.java b/SpiNNaker-allocserv/src/main/java/uk/ac/manchester/spinnaker/alloc/admin/AdminControllerImpl.java index 1eef57fb72..b09e35a4c0 100644 --- a/SpiNNaker-allocserv/src/main/java/uk/ac/manchester/spinnaker/alloc/admin/AdminControllerImpl.java +++ b/SpiNNaker-allocserv/src/main/java/uk/ac/manchester/spinnaker/alloc/admin/AdminControllerImpl.java @@ -427,7 +427,7 @@ public ModelAndView getUserCreationForm(ModelMap ignored) { public ModelAndView createUser(UserRecord user, ModelMap model, RedirectAttributes attrs) { user.initCreationDefaults(); - var realUser = userManager.createUser(user) + var realUser = userManager.createUser(user, this::showGroupInfoUrl) .orElseThrow(() -> new AdminException( "user creation failed (duplicate username?)")); int id = realUser.getUserId(); diff --git a/SpiNNaker-allocserv/src/main/java/uk/ac/manchester/spinnaker/alloc/admin/AdminImpl.java b/SpiNNaker-allocserv/src/main/java/uk/ac/manchester/spinnaker/alloc/admin/AdminImpl.java index da02acc516..cb263d8353 100644 --- a/SpiNNaker-allocserv/src/main/java/uk/ac/manchester/spinnaker/alloc/admin/AdminImpl.java +++ b/SpiNNaker-allocserv/src/main/java/uk/ac/manchester/spinnaker/alloc/admin/AdminImpl.java @@ -186,11 +186,12 @@ public Map listUsers(UriInfo ui) { @Override public Response createUser(UserRecord providedUser, UriInfo ui) { log.warn("CALLED createUser({})", providedUser.getUserName()); + var ub = ui.getBaseUriBuilder().path(DESCRIBE_USER); providedUser.initCreationDefaults(); - var realUser = userManager.createUser(providedUser) + var realUser = userManager.createUser(providedUser, + m -> ub.build(m.getUserId())) .orElseThrow(() -> new RequestFailedException(NOT_MODIFIED, "user already exists")); - var ub = ui.getBaseUriBuilder().path(DESCRIBE_USER); int id = realUser.getUserId(); return created(ub.build(id)).type(APPLICATION_JSON) .entity(realUser.sanitise()).build(); diff --git a/SpiNNaker-allocserv/src/main/java/uk/ac/manchester/spinnaker/alloc/admin/UserControl.java b/SpiNNaker-allocserv/src/main/java/uk/ac/manchester/spinnaker/alloc/admin/UserControl.java index 45a494886b..4714e45e30 100644 --- a/SpiNNaker-allocserv/src/main/java/uk/ac/manchester/spinnaker/alloc/admin/UserControl.java +++ b/SpiNNaker-allocserv/src/main/java/uk/ac/manchester/spinnaker/alloc/admin/UserControl.java @@ -108,18 +108,6 @@ public void close() { super.close(); } - /** - * Get a user. - * - * @param id - * User ID - * @return Database row, if user exists. - * @see SQLQueries#GET_USER_DETAILS - */ - Optional getUser(int id) { - return getUserDetails.call1(UserControl::sketchUser, id); - } - Function populateMemberships(Function urlGen) { if (isNull(urlGen)) { @@ -368,20 +356,25 @@ private static UserRecord sketchUser(Row row) { * @return A description of the created user, or {@link Optional#empty()} if * the user exists already. */ - public Optional createUser(UserRecord user) { + public Optional createUser(UserRecord user, + Function urlGen) { // This is a slow operation; don't hold a database transaction var encPass = passServices.encodePassword(user.getPassword()); try (var sql = new CreateSQL()) { - return sql.transaction(() -> createUser(user, encPass, sql)); + return sql.transaction( + () -> createUser(user, encPass, urlGen, sql)); } } private Optional createUser(UserRecord user, String encPass, - CreateSQL sql) { - return sql - .createUser(user.getUserName(), encPass, user.getTrustLevel(), - !user.getEnabled(), user.getOpenIdSubject()) - .flatMap(sql::getUser); + Function urlGen, CreateSQL sql) { + var result = sql.createUser(user.getUserName(), encPass, + user.getTrustLevel(), !user.getEnabled(), + user.getOpenIdSubject()); + if (result.isEmpty()) { + return Optional.empty(); + } + return getUser(result.get(), urlGen); } /** @@ -517,7 +510,7 @@ private Optional updateUser(int id, UserRecord user, } } - return sql.getUser(id).map(sql.populateMemberships(urlGen)); + return getUser(id, urlGen); } /** diff --git a/SpiNNaker-allocserv/src/test/java/uk/ac/manchester/spinnaker/alloc/admin/AdminControllerTest.java b/SpiNNaker-allocserv/src/test/java/uk/ac/manchester/spinnaker/alloc/admin/AdminControllerTest.java index be3e2f470e..09f565c781 100644 --- a/SpiNNaker-allocserv/src/test/java/uk/ac/manchester/spinnaker/alloc/admin/AdminControllerTest.java +++ b/SpiNNaker-allocserv/src/test/java/uk/ac/manchester/spinnaker/alloc/admin/AdminControllerTest.java @@ -23,6 +23,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.forwardedUrl; import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; +import java.net.URI; import java.util.Base64; import javax.ws.rs.core.MediaType; @@ -63,7 +64,8 @@ public void testCreateUser() throws Exception { admin.setTrustLevel(TrustLevel.ADMIN); admin.setPassword("admin"); - var adminRecord = userControl.createUser(admin); + var adminRecord = userControl.createUser(admin, + m -> URI.create("")); assertTrue(adminRecord.isPresent()); String userPass = Base64.getEncoder().encodeToString( @@ -100,8 +102,10 @@ public void updateUserPassword() throws Exception { admin.setTrustLevel(TrustLevel.ADMIN); admin.setPassword("admin"); - var adminRecord = userControl.createUser(admin); + var adminRecord = userControl.createUser(admin, + m -> URI.create("")); assertTrue(adminRecord.isPresent()); + log.info("Admin created: {}", adminRecord.get()); String userPass = Base64.getEncoder().encodeToString( "admin:admin".getBytes()); @@ -114,7 +118,8 @@ public void updateUserPassword() throws Exception { test.setTrustLevel(TrustLevel.USER); test.setPassword("test"); - var testRecord = userControl.createUser(test); + var testRecord = userControl.createUser(test, + m -> URI.create("")); assertTrue(testRecord.isPresent()); UserRecord testUser = testRecord.get(); diff --git a/SpiNNaker-allocserv/src/test/java/uk/ac/manchester/spinnaker/alloc/admin/UserControlTest.java b/SpiNNaker-allocserv/src/test/java/uk/ac/manchester/spinnaker/alloc/admin/UserControlTest.java index 7332447a7a..2ea73eee02 100644 --- a/SpiNNaker-allocserv/src/test/java/uk/ac/manchester/spinnaker/alloc/admin/UserControlTest.java +++ b/SpiNNaker-allocserv/src/test/java/uk/ac/manchester/spinnaker/alloc/admin/UserControlTest.java @@ -57,7 +57,8 @@ public void testCreateUser() { user.setTrustLevel(TrustLevel.USER); user.setPassword("test"); - var userRecord = userControl.createUser(user); + var userRecord = userControl.createUser(user, + m -> URI.create("")); assertTrue(userRecord.isPresent()); // The response is just a user sketch... @@ -72,8 +73,7 @@ public void testCreateUser() { public void testGetUserRecord() { doTransactionalTest(() -> { makeUser(conn); - var record = userControl.getUser(USER, - (mr) -> {return URI.create("");}); + var record = userControl.getUser(USER, m -> URI.create("")); assertTrue(record.isPresent()); var user = record.get(); assertEquals(USER, user.getUserId()); @@ -92,7 +92,7 @@ public void testUpdateUser() { user.setTrustLevel(TrustLevel.USER); user.setPassword("test"); - var userRecord = userControl.createUser(user); + var userRecord = userControl.createUser(user, m-> URI.create("")); assertTrue(userRecord.isPresent()); var id = userRecord.get().getUserId(); @@ -104,7 +104,7 @@ public void testUpdateUser() { admin.setTrustLevel(TrustLevel.ADMIN); admin.setPassword("admin"); - var adminRecord = userControl.createUser(admin); + var adminRecord = userControl.createUser(admin, m -> URI.create("")); assertTrue(adminRecord.isPresent()); // Update the user password From 5d206abab84fc5e13bf01c29b8ce7918458f0ee8 Mon Sep 17 00:00:00 2001 From: Andrew Rowley Date: Mon, 27 Jan 2025 14:21:59 +0000 Subject: [PATCH 7/7] Add doc for new parameter --- .../uk/ac/manchester/spinnaker/alloc/admin/UserControl.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/SpiNNaker-allocserv/src/main/java/uk/ac/manchester/spinnaker/alloc/admin/UserControl.java b/SpiNNaker-allocserv/src/main/java/uk/ac/manchester/spinnaker/alloc/admin/UserControl.java index 4714e45e30..fc99900645 100644 --- a/SpiNNaker-allocserv/src/main/java/uk/ac/manchester/spinnaker/alloc/admin/UserControl.java +++ b/SpiNNaker-allocserv/src/main/java/uk/ac/manchester/spinnaker/alloc/admin/UserControl.java @@ -353,6 +353,9 @@ private static UserRecord sketchUser(Row row) { * * @param user * The description of the user to create. + * @param urlGen + * How to construct the URL for a group membership in the + * response. If {@code null}, the memberships will be omitted. * @return A description of the created user, or {@link Optional#empty()} if * the user exists already. */