/** * ============================================================================= * * ORCID (R) Open Source * http://orcid.org * * Copyright (c) 2012-2014 ORCID, Inc. * Licensed under an MIT-Style License (MIT) * http://orcid.org/open-source-license * * This copyright and license information (including a link to the full license) * shall be included in its entirety in all copies or substantial portion of * the software. * * ============================================================================= */ package org.orcid.frontend.web.controllers; import java.util.ArrayList; import java.util.HashMap; import java.util.Locale; import java.util.Map; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang.StringUtils; import org.orcid.jaxb.model.message.CreationMethod; import org.orcid.pojo.ajaxForm.OauthRegistrationForm; import org.orcid.pojo.ajaxForm.PojoUtil; import org.orcid.pojo.ajaxForm.RequestInfoForm; import org.orcid.pojo.ajaxForm.Text; import org.orcid.utils.OrcidRequestUtil; import org.orcid.utils.OrcidStringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.core.Authentication; import org.springframework.security.oauth2.common.exceptions.RedirectMismatchException; import org.springframework.security.web.savedrequest.HttpSessionRequestCache; import org.springframework.security.web.savedrequest.SavedRequest; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.support.SimpleSessionStatus; import org.springframework.web.servlet.support.RequestContextUtils; import org.springframework.web.servlet.view.RedirectView; @Controller("oauthRegisterController") public class OauthRegistrationController extends OauthControllerBase { private static final Logger LOGGER = LoggerFactory.getLogger(OauthRegistrationController.class); @Resource private RegistrationController registrationController; public RegistrationController getRegistrationController() { return registrationController; } public void setRegistrationController(RegistrationController registrationController) { this.registrationController = registrationController; } @RequestMapping(value = "/oauth/custom/register/empty.json", method = RequestMethod.GET) public @ResponseBody OauthRegistrationForm getRegister(HttpServletRequest request, HttpServletResponse response) { // Remove the session hash if needed if (request.getSession().getAttribute(RegistrationController.GRECAPTCHA_SESSION_ATTRIBUTE_NAME) != null) { request.getSession().removeAttribute(RegistrationController.GRECAPTCHA_SESSION_ATTRIBUTE_NAME); } OauthRegistrationForm empty = new OauthRegistrationForm(registrationController.getRegister(request, response)); // Creation type in oauth will always be member referred empty.setCreationType(Text.valueOf(CreationMethod.MEMBER_REFERRED.value())); Text emptyText = Text.valueOf(StringUtils.EMPTY); empty.setPassword(emptyText); return empty; } @RequestMapping(value = "/oauth/custom/register.json", method = RequestMethod.POST) public @ResponseBody OauthRegistrationForm checkRegisterForm(HttpServletRequest request, HttpServletResponse response, @RequestBody OauthRegistrationForm form) { form.setErrors(new ArrayList<String>()); RequestInfoForm requestInfoForm = (RequestInfoForm) request.getSession().getAttribute(REQUEST_INFO_FORM); if (form.getApproved()) { registrationController.validateRegistrationFields(request, form); registrationController.validateGrcaptcha(request, form); } else { SavedRequest savedRequest = new HttpSessionRequestCache().getRequest(request, response); String stateParam = null; if (savedRequest != null && savedRequest.getParameterMap() != null && savedRequest.getParameterValues("state") != null) { if (savedRequest.getParameterValues("state").length > 0) stateParam = savedRequest.getParameterValues("state")[0]; } form.setRedirectUrl(buildDenyRedirectUri(requestInfoForm.getRedirectUrl(), stateParam)); } return form; } @RequestMapping(value = "/oauth/custom/registerConfirm.json", method = RequestMethod.POST) public @ResponseBody RequestInfoForm registerAndAuthorize(HttpServletRequest request, HttpServletResponse response, @RequestBody OauthRegistrationForm form) { RequestInfoForm requestInfoForm = (RequestInfoForm) request.getSession().getAttribute(REQUEST_INFO_FORM); if (form.getApproved()) { boolean usedCaptcha = false; // If recatcha wasn't loaded do nothing. This is for countries that // block google. if (form.getGrecaptchaWidgetId().getValue() != null) { // If the captcha verified key is not in the session, redirect // to the login page if (request.getSession().getAttribute(RegistrationController.GRECAPTCHA_SESSION_ATTRIBUTE_NAME) == null || PojoUtil.isEmpty(form.getGrecaptcha()) || !form.getGrecaptcha().getValue().equals( request.getSession().getAttribute(RegistrationController.GRECAPTCHA_SESSION_ATTRIBUTE_NAME))) { String redirectUri = this.getBaseUri() + REDIRECT_URI_ERROR; // Set the client id redirectUri = redirectUri.replace("{0}", requestInfoForm.getClientId()); // Set the response type if needed if (!PojoUtil.isEmpty(requestInfoForm.getResponseType())) redirectUri += "&response_type=" + requestInfoForm.getResponseType(); // Set the redirect uri if (!PojoUtil.isEmpty(requestInfoForm.getRedirectUrl())) redirectUri += "&redirect_uri=" + requestInfoForm.getRedirectUrl(); // remove email access scope if present but not granted if (requestInfoForm.containsEmailReadPrivateScope() && !form.isEmailAccessAllowed()) { requestInfoForm.removeEmailReadPrivateScope(); } // Set the scope param if (!PojoUtil.isEmpty(requestInfoForm.getScopesAsString())) redirectUri += "&scope=" + requestInfoForm.getScopesAsString(); // Copy the state param if present if (!PojoUtil.isEmpty(requestInfoForm.getStateParam())) redirectUri += "&state=" + requestInfoForm.getStateParam(); requestInfoForm.setRedirectUrl(redirectUri); SavedRequest savedRequest = new HttpSessionRequestCache().getRequest(request, response); if (savedRequest != null) LOGGER.info("OauthConfirmAccessController original request: " + savedRequest.getRedirectUrl()); LOGGER.info("OauthConfirmAccessController form.getRedirectUri being sent to client browser: " + requestInfoForm.getRedirectUrl()); return requestInfoForm; } usedCaptcha = true; } // Remove the session hash if needed if (request.getSession().getAttribute(RegistrationController.GRECAPTCHA_SESSION_ATTRIBUTE_NAME) != null) { request.getSession().removeAttribute(RegistrationController.GRECAPTCHA_SESSION_ATTRIBUTE_NAME); } //Strip any html code from names before validating them if(!PojoUtil.isEmpty(form.getFamilyNames())){ form.getFamilyNames().setValue(OrcidStringUtils.stripHtml(form.getFamilyNames().getValue())); } if(!PojoUtil.isEmpty(form.getGivenNames())) { form.getGivenNames().setValue(OrcidStringUtils.stripHtml(form.getGivenNames().getValue())); } // Check there are no errors registrationController.validateRegistrationFields(request, form); if (form.getErrors().isEmpty()) { // Register user try { // Locale Locale locale = RequestContextUtils.getLocale(request); // Ip String ip = OrcidRequestUtil.getIpAddress(request); registrationController.createMinimalRegistration(request, form, usedCaptcha, locale, ip); } catch(Exception e) { requestInfoForm.getErrors().add(getMessage("register.error.generalError")); return requestInfoForm; } // Authenticate user String email = form.getEmail().getValue(); String password = form.getPassword().getValue(); Authentication auth = authenticateUser(request, email, password); // Create authorization params SimpleSessionStatus status = new SimpleSessionStatus(); Map<String, Object> model = new HashMap<String, Object>(); Map<String, String> params = new HashMap<String, String>(); Map<String, String> approvalParams = new HashMap<String, String>(); fillOauthParams(requestInfoForm, params, approvalParams, form.getPersistentTokenEnabled(), form.isEmailAccessAllowed()); // Authorize try { authorizationEndpoint.authorize(model, params, status, auth); } catch (RedirectMismatchException rUriError) { String redirectUri = this.getBaseUri() + REDIRECT_URI_ERROR; // Set the client id redirectUri = redirectUri.replace("{0}", requestInfoForm.getClientId()); // Set the response type if needed if (!PojoUtil.isEmpty(requestInfoForm.getResponseType())) redirectUri += "&response_type=" + requestInfoForm.getResponseType(); // Set the redirect uri if (!PojoUtil.isEmpty(requestInfoForm.getRedirectUrl())) redirectUri += "&redirect_uri=" + requestInfoForm.getRedirectUrl(); // Set the scope param if (!PojoUtil.isEmpty(requestInfoForm.getScopesAsString())) redirectUri += "&scope=" + requestInfoForm.getScopesAsString(); // Copy the state param if present if (!PojoUtil.isEmpty(requestInfoForm.getStateParam())) redirectUri += "&state=" + requestInfoForm.getStateParam(); requestInfoForm.setRedirectUrl(redirectUri); LOGGER.info("OauthRegisterController being sent to client browser: " + requestInfoForm.getRedirectUrl()); return requestInfoForm; } // Approve RedirectView view = (RedirectView) authorizationEndpoint.approveOrDeny(approvalParams, model, status, auth); requestInfoForm.setRedirectUrl(view.getUrl()); } } else { requestInfoForm.setRedirectUrl(buildDenyRedirectUri(requestInfoForm.getRedirectUrl(), requestInfoForm.getStateParam())); } if(new HttpSessionRequestCache().getRequest(request, response) != null) new HttpSessionRequestCache().removeRequest(request, response); LOGGER.info("OauthConfirmAccessController form.getRedirectUri being sent to client browser: " + requestInfoForm.getRedirectUrl()); return requestInfoForm; } }