Skip to content

Commit

Permalink
Test and documentation for mobile API endpoint verification code #587
Browse files Browse the repository at this point in the history
  • Loading branch information
oharsta committed Jan 22, 2025
1 parent 557e5c6 commit 9f15747
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 23 deletions.
22 changes: 15 additions & 7 deletions myconext-server/src/main/java/myconext/api/UserController.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import jakarta.validation.Valid;
import lombok.Getter;
import lombok.SneakyThrows;
import myconext.cron.DisposableEmailProviders;
import myconext.exceptions.*;
Expand Down Expand Up @@ -72,9 +73,11 @@ public class UserController implements UserAuthentication {

private static final Log LOG = LogFactory.getLog(UserController.class);

@Getter
private final UserRepository userRepository;
private final AuthenticationRequestRepository authenticationRequestRepository;
private final MailBox mailBox;
@Getter
private final Manage manage;
private final OpenIDConnect openIDConnect;
private final String magicLinkUrl;
Expand Down Expand Up @@ -980,6 +983,13 @@ public ResponseEntity<StatusResponse> deleteUser(Authentication authentication,
return doLogout(request);
}

@Operation(summary = "Create verification control code password link",
description = """
Create a verification control code which users can use to prove their identity at the Service Desk. The
code is also send by email to the user. The required field are firstName, lastName and dayOfBirth.
There are no input validations, if the user's dayOfBirth can not be parsed, then this is solved in
the approval proces in the Serivce Desk
""")
@PostMapping("sp/control-code")
public ResponseEntity<ControlCode> createUserControlCode(Authentication authentication,
@RequestBody ControlCode controlCode) {
Expand All @@ -1006,6 +1016,11 @@ public ResponseEntity<ControlCode> createUserControlCode(Authentication authenti
return ResponseEntity.ok(controlCode);
}


@Operation(summary = "Delete existing verification control code",
description = """
Delete an existing verification control code for a user
""")
@DeleteMapping("sp/control-code")
public ResponseEntity<UserResponse> deleteUserControlCode(Authentication authentication) {
User user = userFromAuthentication(authentication);
Expand Down Expand Up @@ -1077,11 +1092,4 @@ private ResponseEntity return404() {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(Collections.singletonMap("status", HttpStatus.NOT_FOUND.value()));
}

public Manage getManage() {
return manage;
}

public UserRepository getUserRepository() {
return userRepository;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -333,11 +333,16 @@ protected Response magicResponse(MagicLinkResponse magicLinkResponse) {
return response;
}


protected String samlResponse(MagicLinkResponse magicLinkResponse) throws IOException {
Response response = magicResponse(magicLinkResponse);

return samlAuthnResponse(response, Optional.empty());
}

protected void clearExternalAccounts(String email) {
User user = userRepository.findOneUserByEmail(email);
user.getLinkedAccounts().clear();
user.getExternalLinkedAccounts().clear();
userRepository.save(user);

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1451,12 +1451,4 @@ private String hash() {
return Base64.getUrlEncoder().withoutPadding().encodeToString(bytes);
}

private void clearExternalAccounts(String email) {
User user = userRepository.findOneUserByEmail(email);
user.getLinkedAccounts().clear();
user.getExternalLinkedAccounts().clear();
userRepository.save(user);

}

}
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
package myconext.api;

import com.github.tomakehurst.wiremock.junit.WireMockRule;
import io.restassured.common.mapper.TypeRef;
import io.restassured.http.ContentType;
import lombok.SneakyThrows;
import myconext.AbstractIntegrationTest;
import myconext.model.CreateAccount;
import myconext.model.IdentityProvider;
import myconext.model.UpdateUserNameRequest;
import myconext.model.User;
import myconext.model.*;
import org.junit.ClassRule;
import org.junit.Test;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;

import java.io.IOException;
import java.util.Map;

import static io.restassured.RestAssured.given;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.*;
import static org.junit.Assert.assertNull;

public class UserMobileControllerTest extends AbstractIntegrationTest {

Expand Down Expand Up @@ -139,4 +140,36 @@ public void createEduIDInApp() {
.statusCode(302)
.header("Location", "http://localhost:3000/client/mobile/created?new=true");
}

@SneakyThrows
@Test
public void createUserControlCodeMobileApi() {
clearExternalAccounts("[email protected]");
ControlCode controlCode = new ControlCode("Lee", "Harpers", "01 Mar 1977");
ControlCode responseControlCode = given()
.accept(ContentType.JSON)
.contentType(ContentType.JSON)
.auth().oauth2(opaqueAccessToken(true, "eduid.nl/mobile"))
.body(controlCode)
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.when()
.post("/mobile/api/sp/control-code")
.as(ControlCode.class);
assertEquals(5, responseControlCode.getCode().length());
User user = userRepository.findOneUserByEmail("[email protected]");
assertEquals(user.getControlCode().getCode(), responseControlCode.getCode());

Map<String, Object> userResponse = given()
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.auth().oauth2(opaqueAccessToken(true, "eduid.nl/mobile"))
.when()
.delete("/mobile/api/sp/control-code")
.as(new TypeRef<>() {
});
assertFalse(userResponse.containsKey("controlCode"));

User userFromDB = userRepository.findOneUserByEmail("[email protected]");
assertNull(userFromDB.getControlCode());
}

}

0 comments on commit 9f15747

Please sign in to comment.