Loading gms-client/gms-client-lib/src/main/java/it/inaf/ia2/gms/client/GmsClient.java +6 −0 Original line number Diff line number Diff line package it.inaf.ia2.gms.client; import it.inaf.ia2.gms.client.call.AddInvitedRegistrationCall; import it.inaf.ia2.gms.client.call.HttpClientWrapper; import it.inaf.ia2.gms.client.call.AddMemberCall; import it.inaf.ia2.gms.client.call.AddPermissionCall; Loading @@ -13,6 +14,7 @@ import it.inaf.ia2.gms.client.call.RemovePermissionCall; import it.inaf.ia2.gms.client.model.Permission; import it.inaf.ia2.gms.client.model.UserPermission; import java.util.List; import java.util.Map; public class GmsClient { Loading Loading @@ -71,4 +73,8 @@ public class GmsClient { public List<UserPermission> getUserPermissions(String userId) { return new GetUserPermissionsCall(httpClientWrapper).getUserPermissions(userId); } public void addInvitedRegistration(String token, String email, Map<String, Permission> groupsPermissions) { new AddInvitedRegistrationCall(httpClientWrapper).addInvitedRegistration(token, email, groupsPermissions); } } gms-client/gms-client-lib/src/main/java/it/inaf/ia2/gms/client/call/AddInvitedRegistrationCall.java 0 → 100644 +56 −0 Original line number Diff line number Diff line package it.inaf.ia2.gms.client.call; import it.inaf.ia2.gms.client.model.Permission; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Base64; import java.util.Map; import java.util.stream.Collectors; public class AddInvitedRegistrationCall extends BaseGmsCall { public AddInvitedRegistrationCall(HttpClientWrapper clientWrapper) { super(clientWrapper); } public void addInvitedRegistration(String token, String email, Map<String, Permission> groupsPermissions) { String tokenHash = getTokenHash(token); String endpoint = "invited-registration"; String bodyParams = "token_hash=" + tokenHash + "&email=" + email + "&groups=" + String.join("\n", groupsPermissions.entrySet() .stream().map(e -> e.getKey() + " " + e.getValue()) .collect(Collectors.toList())); HttpRequest groupsRequest = newHttpRequest(endpoint) .header("Accept", "text/plain") .header("Content-Type", "application/x-www-form-urlencoded") .POST(HttpRequest.BodyPublishers.ofString(bodyParams)) .build(); getClient().sendAsync(groupsRequest, HttpResponse.BodyHandlers.ofInputStream()) .thenApply(response -> { if (response.statusCode() == 201) { return true; } logServerErrorInputStream(groupsRequest, response); throw new IllegalStateException("Unable to create invited registration"); }).join(); } private String getTokenHash(String token) { try { MessageDigest digest = MessageDigest.getInstance("SHA-256"); byte[] hash = digest.digest(token.getBytes(StandardCharsets.UTF_8)); return Base64.getEncoder().encodeToString(hash); } catch (NoSuchAlgorithmException ex) { throw new RuntimeException(ex); } } } gms/src/main/java/it/inaf/ia2/gms/authn/SecurityConfig.java +1 −1 Original line number Diff line number Diff line Loading @@ -64,7 +64,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { */ @Override public void configure(WebSecurity web) throws Exception { web.ignoring().antMatchers("/ws/basic/**", "/ws/jwt/**", "/error", "/logout"); web.ignoring().antMatchers("/ws/jwt/**", "/error", "/logout", "/invited-registration"); } /** Loading gms/src/main/java/it/inaf/ia2/gms/controller/HomePageController.java +17 −1 Original line number Diff line number Diff line package it.inaf.ia2.gms.controller; import it.inaf.ia2.gms.authn.SessionData; import it.inaf.ia2.gms.manager.InvitedRegistrationManager; import it.inaf.ia2.gms.model.request.GroupsRequest; import it.inaf.ia2.gms.model.response.GroupsTabResponse; import it.inaf.ia2.gms.model.response.HomePageResponse; import it.inaf.ia2.gms.persistence.model.InvitedRegistration; import java.io.IOException; import java.util.Optional; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import javax.validation.Valid; Loading @@ -25,6 +30,9 @@ public class HomePageController { @Autowired private GroupsTabResponseBuilder groupsTabResponseBuilder; @Autowired private InvitedRegistrationManager invitedRegistrationManager; @ResponseBody @GetMapping(value = "/home", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) public ResponseEntity<HomePageResponse> getMainPage(@Valid GroupsRequest request) { Loading @@ -42,7 +50,15 @@ public class HomePageController { } @GetMapping(value = "/", produces = MediaType.TEXT_HTML_VALUE) public String index() { public String index(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Optional<InvitedRegistration> optReg = invitedRegistrationManager.completeInvitedRegistrationIfNecessary(); if (optReg.isPresent()) { request.setAttribute("invited-registration", optReg.get()); return "/registration-completed"; //request.getRequestDispatcher("/registration-completed").forward(request, response); } return "index.html"; } Loading gms/src/main/java/it/inaf/ia2/gms/controller/InvitedRegistrationController.java 0 → 100644 +74 −0 Original line number Diff line number Diff line package it.inaf.ia2.gms.controller; import it.inaf.ia2.gms.manager.InvitedRegistrationManager; import it.inaf.ia2.gms.persistence.model.InvitedRegistration; import it.inaf.ia2.gms.service.GroupNameService; import java.io.IOException; import java.io.InputStream; import java.util.Scanner; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; @Controller public class InvitedRegistrationController { @Autowired private InvitedRegistrationManager invitedRegistrationManager; @Autowired private GroupNameService groupNameService; @GetMapping(value = "/invited-registration", produces = MediaType.TEXT_HTML_VALUE) public void index(@RequestParam("token") String token, HttpServletRequest request, HttpServletResponse response) throws IOException { InvitedRegistration invitedRegistration = invitedRegistrationManager.getInvitedRegistrationFromToken(token); String html = getFileContent("invited-registration.html") .replace("#EMAIL#", invitedRegistration.getEmail()) .replace("#GROUPS#", getGroupsList(invitedRegistration)) .replace("#HOME#", request.getContextPath()); response.getOutputStream().print(html); } @GetMapping(value = "/registration-completed", produces = MediaType.TEXT_HTML_VALUE) public void completed(HttpServletRequest request, HttpServletResponse response) throws IOException { response.setContentType("text/html;charset=UTF-8"); InvitedRegistration invitedRegistration = (InvitedRegistration) request.getAttribute("invited-registration"); if (invitedRegistration == null) { // redirect to home String baseUrl = ServletUriComponentsBuilder.fromCurrentContextPath().build().toUriString(); response.sendRedirect(baseUrl); } else { String html = getFileContent("registration-completed.html") .replace("#GROUPS#", getGroupsList(invitedRegistration)) .replace("#HOME#", request.getContextPath()); response.getOutputStream().print(html); } } private String getFileContent(String templateFileName) throws IOException { try (InputStream in = InvitedRegistrationController.class.getClassLoader().getResourceAsStream("templates/" + templateFileName)) { Scanner s = new Scanner(in).useDelimiter("\\A"); return s.hasNext() ? s.next() : ""; } } private String getGroupsList(InvitedRegistration invitedRegistration) { String groups = "<ul>"; for (String groupName : groupNameService.getGroupsNamesFromIdentifiers( invitedRegistration.getGroupsPermissions().keySet())) { groups += "<li>" + groupName + "</li>"; } groups += "</ul>"; return groups; } } Loading
gms-client/gms-client-lib/src/main/java/it/inaf/ia2/gms/client/GmsClient.java +6 −0 Original line number Diff line number Diff line package it.inaf.ia2.gms.client; import it.inaf.ia2.gms.client.call.AddInvitedRegistrationCall; import it.inaf.ia2.gms.client.call.HttpClientWrapper; import it.inaf.ia2.gms.client.call.AddMemberCall; import it.inaf.ia2.gms.client.call.AddPermissionCall; Loading @@ -13,6 +14,7 @@ import it.inaf.ia2.gms.client.call.RemovePermissionCall; import it.inaf.ia2.gms.client.model.Permission; import it.inaf.ia2.gms.client.model.UserPermission; import java.util.List; import java.util.Map; public class GmsClient { Loading Loading @@ -71,4 +73,8 @@ public class GmsClient { public List<UserPermission> getUserPermissions(String userId) { return new GetUserPermissionsCall(httpClientWrapper).getUserPermissions(userId); } public void addInvitedRegistration(String token, String email, Map<String, Permission> groupsPermissions) { new AddInvitedRegistrationCall(httpClientWrapper).addInvitedRegistration(token, email, groupsPermissions); } }
gms-client/gms-client-lib/src/main/java/it/inaf/ia2/gms/client/call/AddInvitedRegistrationCall.java 0 → 100644 +56 −0 Original line number Diff line number Diff line package it.inaf.ia2.gms.client.call; import it.inaf.ia2.gms.client.model.Permission; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Base64; import java.util.Map; import java.util.stream.Collectors; public class AddInvitedRegistrationCall extends BaseGmsCall { public AddInvitedRegistrationCall(HttpClientWrapper clientWrapper) { super(clientWrapper); } public void addInvitedRegistration(String token, String email, Map<String, Permission> groupsPermissions) { String tokenHash = getTokenHash(token); String endpoint = "invited-registration"; String bodyParams = "token_hash=" + tokenHash + "&email=" + email + "&groups=" + String.join("\n", groupsPermissions.entrySet() .stream().map(e -> e.getKey() + " " + e.getValue()) .collect(Collectors.toList())); HttpRequest groupsRequest = newHttpRequest(endpoint) .header("Accept", "text/plain") .header("Content-Type", "application/x-www-form-urlencoded") .POST(HttpRequest.BodyPublishers.ofString(bodyParams)) .build(); getClient().sendAsync(groupsRequest, HttpResponse.BodyHandlers.ofInputStream()) .thenApply(response -> { if (response.statusCode() == 201) { return true; } logServerErrorInputStream(groupsRequest, response); throw new IllegalStateException("Unable to create invited registration"); }).join(); } private String getTokenHash(String token) { try { MessageDigest digest = MessageDigest.getInstance("SHA-256"); byte[] hash = digest.digest(token.getBytes(StandardCharsets.UTF_8)); return Base64.getEncoder().encodeToString(hash); } catch (NoSuchAlgorithmException ex) { throw new RuntimeException(ex); } } }
gms/src/main/java/it/inaf/ia2/gms/authn/SecurityConfig.java +1 −1 Original line number Diff line number Diff line Loading @@ -64,7 +64,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { */ @Override public void configure(WebSecurity web) throws Exception { web.ignoring().antMatchers("/ws/basic/**", "/ws/jwt/**", "/error", "/logout"); web.ignoring().antMatchers("/ws/jwt/**", "/error", "/logout", "/invited-registration"); } /** Loading
gms/src/main/java/it/inaf/ia2/gms/controller/HomePageController.java +17 −1 Original line number Diff line number Diff line package it.inaf.ia2.gms.controller; import it.inaf.ia2.gms.authn.SessionData; import it.inaf.ia2.gms.manager.InvitedRegistrationManager; import it.inaf.ia2.gms.model.request.GroupsRequest; import it.inaf.ia2.gms.model.response.GroupsTabResponse; import it.inaf.ia2.gms.model.response.HomePageResponse; import it.inaf.ia2.gms.persistence.model.InvitedRegistration; import java.io.IOException; import java.util.Optional; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import javax.validation.Valid; Loading @@ -25,6 +30,9 @@ public class HomePageController { @Autowired private GroupsTabResponseBuilder groupsTabResponseBuilder; @Autowired private InvitedRegistrationManager invitedRegistrationManager; @ResponseBody @GetMapping(value = "/home", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) public ResponseEntity<HomePageResponse> getMainPage(@Valid GroupsRequest request) { Loading @@ -42,7 +50,15 @@ public class HomePageController { } @GetMapping(value = "/", produces = MediaType.TEXT_HTML_VALUE) public String index() { public String index(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Optional<InvitedRegistration> optReg = invitedRegistrationManager.completeInvitedRegistrationIfNecessary(); if (optReg.isPresent()) { request.setAttribute("invited-registration", optReg.get()); return "/registration-completed"; //request.getRequestDispatcher("/registration-completed").forward(request, response); } return "index.html"; } Loading
gms/src/main/java/it/inaf/ia2/gms/controller/InvitedRegistrationController.java 0 → 100644 +74 −0 Original line number Diff line number Diff line package it.inaf.ia2.gms.controller; import it.inaf.ia2.gms.manager.InvitedRegistrationManager; import it.inaf.ia2.gms.persistence.model.InvitedRegistration; import it.inaf.ia2.gms.service.GroupNameService; import java.io.IOException; import java.io.InputStream; import java.util.Scanner; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; @Controller public class InvitedRegistrationController { @Autowired private InvitedRegistrationManager invitedRegistrationManager; @Autowired private GroupNameService groupNameService; @GetMapping(value = "/invited-registration", produces = MediaType.TEXT_HTML_VALUE) public void index(@RequestParam("token") String token, HttpServletRequest request, HttpServletResponse response) throws IOException { InvitedRegistration invitedRegistration = invitedRegistrationManager.getInvitedRegistrationFromToken(token); String html = getFileContent("invited-registration.html") .replace("#EMAIL#", invitedRegistration.getEmail()) .replace("#GROUPS#", getGroupsList(invitedRegistration)) .replace("#HOME#", request.getContextPath()); response.getOutputStream().print(html); } @GetMapping(value = "/registration-completed", produces = MediaType.TEXT_HTML_VALUE) public void completed(HttpServletRequest request, HttpServletResponse response) throws IOException { response.setContentType("text/html;charset=UTF-8"); InvitedRegistration invitedRegistration = (InvitedRegistration) request.getAttribute("invited-registration"); if (invitedRegistration == null) { // redirect to home String baseUrl = ServletUriComponentsBuilder.fromCurrentContextPath().build().toUriString(); response.sendRedirect(baseUrl); } else { String html = getFileContent("registration-completed.html") .replace("#GROUPS#", getGroupsList(invitedRegistration)) .replace("#HOME#", request.getContextPath()); response.getOutputStream().print(html); } } private String getFileContent(String templateFileName) throws IOException { try (InputStream in = InvitedRegistrationController.class.getClassLoader().getResourceAsStream("templates/" + templateFileName)) { Scanner s = new Scanner(in).useDelimiter("\\A"); return s.hasNext() ? s.next() : ""; } } private String getGroupsList(InvitedRegistration invitedRegistration) { String groups = "<ul>"; for (String groupName : groupNameService.getGroupsNamesFromIdentifiers( invitedRegistration.getGroupsPermissions().keySet())) { groups += "<li>" + groupName + "</li>"; } groups += "</ul>"; return groups; } }