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 + "/logout";
110        if (isShibbo) {
111            return getView("UserCreated").arg("data", registrationData)
112                                         .arg("redirectUrl", "/nuxeo/site/shibboleth?requestedUrl=")
113                                         .arg("isShibbo", isShibbo);
114        }
115        return getView("UserCreated").arg("redirectUrl", redirectUrl)
116                                     .arg("data", registrationData)
117                                     .arg("isShibbo", isShibbo);
118    }
119
120    protected UserInvitationService fetchService() {
121        return Framework.getLocalService(UserRegistrationService.class);
122    }
123
124    @GET
125    @Path("enterpassword/{configurationName}/{requestId}")
126    public Object validatePasswordForm(@PathParam("requestId") String requestId,
127            @PathParam("configurationName") String configurationName) {
128
129        UserInvitationService usr = fetchService();
130        try {
131            usr.checkRequestId(requestId);
132        } catch (AlreadyProcessedRegistrationException ape) {
133            return getView("ValidationErrorTemplate").arg("exceptionMsg",
134                    ctx.getMessage("label.error.requestAlreadyProcessed"));
135        } catch (UserRegistrationException ue) {
136            return getView("ValidationErrorTemplate").arg("exceptionMsg",
137                    ctx.getMessage("label.error.requestNotExisting", requestId));
138        }
139
140        Map<String, String> data = new HashMap<String, String>();
141        data.put("RequestId", requestId);
142        data.put("ConfigurationName", configurationName);
143        String webappName = VirtualHostHelper.getWebAppName(getContext().getRequest());
144        String validationRelUrl = usr.getConfiguration(configurationName).getValidationRelUrl();
145        String valUrl = "/" + webappName + "/" + validationRelUrl;
146        data.put("ValidationUrl", valUrl);
147        return getView("EnterPassword").arg("data", data);
148    }
149
150    protected Map<String, Serializable> buildAdditionalInfos() {
151        return new HashMap<>();
152    }
153
154    protected Template redisplayFormWithMessage(String messageType, String formName, String message, FormData data) {
155        Map<String, String> savedData = new HashMap<String, String>();
156        for (String key : data.getKeys()) {
157            savedData.put(key, data.getString(key));
158        }
159        return getView(formName).arg("data", savedData).arg(messageType, message);
160    }
161
162    protected Template redisplayFormWithInfoMessage(String formName, String message, FormData data) {
163        return redisplayFormWithMessage("info", formName, message, data);
164    }
165
166    protected Template redisplayFormWithErrorMessage(String formName, String message, FormData data) {
167        return redisplayFormWithMessage("err", formName, message, data);
168    }
169
170}