001/*
002 * (C) Copyright 2015 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *  Vladimir Pasquier <vpasquier@nuxeo.com>
018 */
019package org.nuxeo.shibboleth.invitation;
020
021import java.io.Serializable;
022import java.util.HashMap;
023import java.util.Map;
024
025import javax.ws.rs.FormParam;
026import javax.ws.rs.GET;
027import javax.ws.rs.POST;
028import javax.ws.rs.Path;
029import javax.ws.rs.PathParam;
030import javax.ws.rs.Produces;
031
032import org.apache.commons.logging.Log;
033import org.apache.commons.logging.LogFactory;
034import org.nuxeo.ecm.platform.web.common.vh.VirtualHostHelper;
035import org.nuxeo.ecm.user.invite.AlreadyProcessedRegistrationException;
036import org.nuxeo.ecm.user.invite.DefaultInvitationUserFactory;
037import org.nuxeo.ecm.user.invite.UserInvitationService;
038import org.nuxeo.ecm.user.invite.UserRegistrationException;
039import org.nuxeo.ecm.user.registration.UserRegistrationService;
040import org.nuxeo.ecm.webengine.forms.FormData;
041import org.nuxeo.ecm.webengine.model.Template;
042import org.nuxeo.ecm.webengine.model.WebObject;
043import org.nuxeo.ecm.webengine.model.impl.ModuleRoot;
044import org.nuxeo.runtime.api.Framework;
045
046@Path("/shibboInvite")
047@WebObject(type = "shibboInvite")
048@Produces("text/html;charset=UTF-8")
049public class ShibboInviteObject extends ModuleRoot {
050    private static final Log log = LogFactory.getLog(ShibboInviteObject.class);
051
052    @POST
053    @Path("validate")
054    public Object validateTrialForm(@FormParam("isShibbo") boolean isShibbo) {
055        UserInvitationService usr = fetchService();
056
057        FormData formData = getContext().getForm();
058        String requestId = formData.getString("RequestId");
059        String password = formData.getString("Password");
060        String passwordConfirmation = formData.getString("PasswordConfirmation");
061
062        // Check if the requestId is an existing one
063        try {
064            usr.checkRequestId(requestId);
065        } catch (AlreadyProcessedRegistrationException ape) {
066            return getView("ValidationErrorTemplate").arg("exceptionMsg",
067                    ctx.getMessage("label.error.requestAlreadyProcessed"));
068        } catch (UserRegistrationException ue) {
069            return getView("ValidationErrorTemplate").arg("exceptionMsg",
070                    ctx.getMessage("label.error.requestNotExisting", requestId));
071        }
072
073        if (!isShibbo) {
074            // Check if both entered passwords are correct
075            if (password == null || "".equals(password.trim())) {
076                return redisplayFormWithErrorMessage("EnterPassword",
077                        ctx.getMessage("label.registerForm.validation.password"), formData);
078
079            }
080            if (passwordConfirmation == null || "".equals(passwordConfirmation.trim()) && !isShibbo) {
081                return redisplayFormWithErrorMessage("EnterPassword",
082                        ctx.getMessage("label.registerForm.validation.passwordconfirmation"), formData);
083            }
084            password = password.trim();
085            passwordConfirmation = passwordConfirmation.trim();
086            if (!password.equals(passwordConfirmation) && !isShibbo) {
087                return redisplayFormWithErrorMessage("EnterPassword",
088                        ctx.getMessage("label.registerForm.validation.passwordvalidation"), formData);
089            }
090        }
091        Map<String, Serializable> registrationData;
092        try {
093            Map<String, Serializable> additionalInfo = buildAdditionalInfos();
094            // Add the entered password to the document model
095            additionalInfo.put(DefaultInvitationUserFactory.PASSWORD_KEY, password);
096            // Validate the creation of the user
097            registrationData = usr.validateRegistration(requestId, additionalInfo);
098        } catch (AlreadyProcessedRegistrationException ape) {
099            log.info("Try to validate an already processed registration");
100            return getView("ValidationErrorTemplate").arg("exceptionMsg",
101                    ctx.getMessage("label.error.requestAlreadyProcessed"));
102        } catch (UserRegistrationException ue) {
103            log.warn("Unable to validate registration request", ue);
104            return getView("ValidationErrorTemplate").arg("exceptionMsg",
105                    ctx.getMessage("label.errror.requestNotAccepted"));
106        }
107        // User redirected to the logout page after validating the password
108        String webappName = VirtualHostHelper.getWebAppName(getContext().getRequest());
109        String redirectUrl = "/" + webappName + "/";
110        if (!isShibbo) {
111            redirectUrl += "logout";
112        }
113        return getView("UserCreated").arg("redirectUrl", redirectUrl)
114                                     .arg("data", registrationData)
115                                     .arg("isShibbo", isShibbo);
116    }
117
118    protected UserInvitationService fetchService() {
119        return Framework.getService(UserRegistrationService.class);
120    }
121
122    @GET
123    @Path("enterpassword/{configurationName}/{requestId}")
124    public Object validatePasswordForm(@PathParam("requestId") String requestId,
125            @PathParam("configurationName") String configurationName) {
126
127        UserInvitationService usr = fetchService();
128        try {
129            usr.checkRequestId(requestId);
130        } catch (AlreadyProcessedRegistrationException ape) {
131            return getView("ValidationErrorTemplate").arg("exceptionMsg",
132                    ctx.getMessage("label.error.requestAlreadyProcessed"));
133        } catch (UserRegistrationException ue) {
134            return getView("ValidationErrorTemplate").arg("exceptionMsg",
135                    ctx.getMessage("label.error.requestNotExisting", requestId));
136        }
137
138        Map<String, String> data = new HashMap<String, String>();
139        data.put("RequestId", requestId);
140        data.put("ConfigurationName", configurationName);
141        String webappName = VirtualHostHelper.getWebAppName(getContext().getRequest());
142        String validationRelUrl = usr.getConfiguration(configurationName).getValidationRelUrl();
143        String valUrl = "/" + webappName + "/" + validationRelUrl;
144        data.put("ValidationUrl", valUrl);
145        return getView("EnterPassword").arg("data", data);
146    }
147
148    protected Map<String, Serializable> buildAdditionalInfos() {
149        return new HashMap<>();
150    }
151
152    protected Template redisplayFormWithMessage(String messageType, String formName, String message, FormData data) {
153        Map<String, String> savedData = new HashMap<String, String>();
154        for (String key : data.getKeys()) {
155            savedData.put(key, data.getString(key));
156        }
157        return getView(formName).arg("data", savedData).arg(messageType, message);
158    }
159
160    protected Template redisplayFormWithInfoMessage(String formName, String message, FormData data) {
161        return redisplayFormWithMessage("info", formName, message, data);
162    }
163
164    protected Template redisplayFormWithErrorMessage(String formName, String message, FormData data) {
165        return redisplayFormWithMessage("err", formName, message, data);
166    }
167
168}