001/*
002 * (C) Copyright 2006-2013 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 *     Nuxeo - initial API and implementation
018 */
019
020package org.nuxeo.ecm.platform.ui.web.auth;
021
022import java.util.Collections;
023import java.util.List;
024import java.util.stream.Collectors;
025
026import javax.servlet.http.HttpServletRequest;
027
028import org.apache.commons.lang.StringUtils;
029import org.apache.commons.logging.Log;
030import org.apache.commons.logging.LogFactory;
031import org.nuxeo.ecm.core.api.DocumentLocation;
032import org.nuxeo.ecm.core.api.IdRef;
033import org.nuxeo.ecm.core.api.NuxeoException;
034import org.nuxeo.ecm.core.api.PathRef;
035import org.nuxeo.ecm.platform.ui.web.auth.service.LoginProviderLinkComputer;
036import org.nuxeo.ecm.platform.ui.web.auth.service.LoginScreenConfig;
037import org.nuxeo.ecm.platform.ui.web.auth.service.LoginStartupPage;
038import org.nuxeo.ecm.platform.ui.web.auth.service.PluggableAuthenticationService;
039import org.nuxeo.ecm.platform.url.api.DocumentView;
040import org.nuxeo.ecm.platform.url.api.DocumentViewCodecManager;
041import org.nuxeo.ecm.platform.web.common.vh.VirtualHostHelper;
042import org.nuxeo.runtime.api.Framework;
043
044/**
045 * Simple helper class for easy access form the login.jsp page
046 *
047 * @author <a href="mailto:tdelprat@nuxeo.com">Tiry</a>
048 * @since 5.7
049 */
050public class LoginScreenHelper {
051
052    protected static final Log log = LogFactory.getLog(LoginScreenHelper.class);
053
054    public static final String NUXEO_PROTOCOL = "nuxeo://";
055
056    /**
057     * @since 8.4
058     */
059    public static final String DEFAULT_STARTUP_PAGE_PATH = "home.html";
060
061    public static LoginScreenConfig getConfig() {
062        PluggableAuthenticationService authService = (PluggableAuthenticationService) Framework.getRuntime()
063                                                                                               .getComponent(
064                                                                                                       PluggableAuthenticationService.NAME);
065        if (authService != null) {
066            return authService.getLoginScreenConfig();
067        }
068        return null;
069    }
070
071    public static void registerLoginProvider(String name, String iconUrl, String link, String label, String description,
072            LoginProviderLinkComputer computer) {
073
074        LoginScreenConfig config = getConfig();
075        if (config != null) {
076            config.registerLoginProvider(name, iconUrl, link, label, description, computer);
077        } else {
078            throw new NuxeoException("There is no available LoginScreen config");
079        }
080    }
081
082    public static String getValueWithDefault(String value, String defaultValue) {
083        if (value == null || value.isEmpty()) {
084            return defaultValue;
085        }
086        return value;
087    }
088
089    /**
090     * Returns the startup page URL according to the path returned by {@link #getStartupPagePath()}.
091     *
092     * @since 8.4
093     */
094    public static String getStartupPageURL(HttpServletRequest request) {
095        return VirtualHostHelper.getBaseURL(request) + getStartupPagePath();
096    }
097
098    /**
099     * Returns the path of the startup page depending on the {@link LoginScreenConfig}/{@link LoginStartupPage}
100     * contributions to the {@code loginScreen} extension point.
101     *
102     * @since 8.4
103     */
104    public static String getStartupPagePath() {
105        LoginScreenConfig config = getConfig();
106        if (config == null) {
107            log.debug("No <loginScreenConfig> contribution found, startup page path = " + DEFAULT_STARTUP_PAGE_PATH);
108            return DEFAULT_STARTUP_PAGE_PATH;
109        }
110        LoginStartupPage defaultStartupPage = getDefaultStartupPage(config);
111        log.debug("Default <startupPage> contribution: " + defaultStartupPage);
112        // No <startupPage> contributions, return home.html
113        if (defaultStartupPage == null) {
114            log.debug("No <startupPage> contribution found, startup page path = " + DEFAULT_STARTUP_PAGE_PATH);
115            return DEFAULT_STARTUP_PAGE_PATH;
116        }
117        // Return the path of the <startupPage> contribution with the highest priority
118        String startupPagePath = defaultStartupPage.getPath();
119        if (startupPagePath.startsWith("/")) {
120            startupPagePath = startupPagePath.substring(1);
121        }
122        log.debug("Startup page path = " + startupPagePath);
123        return startupPagePath;
124    }
125
126    /**
127     * Returns the paths of the startup pages coming from the {@link LoginScreenConfig}/{@link LoginStartupPage}
128     * contributions to the {@code loginScreen} extension point.
129     *
130     * @since 8.10
131     */
132    public static List<String> getStartupPagePaths() {
133        LoginScreenConfig config = getConfig();
134        if (config == null) {
135            return Collections.emptyList();
136        }
137        return config.getStartupPages()
138                     .values()
139                     .stream()
140                     .sorted((p1, p2) -> p2.compareTo(p1))
141                     .map(startupPage -> startupPage.getPath())
142                     .collect(Collectors.toList());
143    }
144
145    /**
146     * Returns the {@link LoginStartupPage} contribution with the highest priority or {@code null} if none is
147     * contributed.
148     *
149     * @since 8.4
150     */
151    protected static LoginStartupPage getDefaultStartupPage(LoginScreenConfig config) {
152        if (config.getStartupPages().isEmpty()) {
153            return null;
154        }
155        return Collections.max(config.getStartupPages().values());
156    }
157
158    /**
159     * Returns a full URL that can be handled by the mobile applications.
160     *
161     * @since 8.10
162     */
163    public static String getURLForMobileApplication(HttpServletRequest request) {
164        String baseURL = VirtualHostHelper.getBaseURL(request);
165        String requestedUrl = request.getParameter("requestedUrl");
166        return getURLForMobileApplication(baseURL, requestedUrl);
167    }
168
169    /**
170     * Returns a full URL that can be handled by the mobile applications.
171     *
172     * @since 8.10
173     */
174    public static String getURLForMobileApplication(String baseURL, String requestedURL) {
175        if (!baseURL.endsWith("/")) {
176            baseURL += "/";
177        }
178
179        String url = String.format("%s%s", NUXEO_PROTOCOL, baseURL.replaceAll("://", "/"));
180        if (StringUtils.isBlank(requestedURL)) {
181            return url;
182        }
183
184        DocumentViewCodecManager documentViewCodecManager = Framework.getService(DocumentViewCodecManager.class);
185        DocumentView docView = documentViewCodecManager.getDocumentViewFromUrl(requestedURL, false, null);
186        if (docView != null && docView.getDocumentLocation() != null) {
187            DocumentLocation docLoc = docView.getDocumentLocation();
188            String serverName = docLoc.getServerName();
189            if (serverName == null) {
190                return url;
191            }
192
193            url += serverName;
194            IdRef idRef = docLoc.getIdRef();
195            PathRef pathRef = docLoc.getPathRef();
196            if (idRef != null) {
197                url += "/id/" + idRef;
198            } else if (pathRef != null) {
199                url += "/path" + pathRef;
200            }
201        }
202
203        return url;
204    }
205
206}