001/*
002 * This library is part of OpenCms -
003 * the Open Source Content Management System
004 *
005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * For further information about Alkacon Software, please see the
018 * company website: http://www.alkacon.com
019 *
020 * For further information about OpenCms, please see the
021 * project website: http://www.opencms.org
022 *
023 * You should have received a copy of the GNU Lesser General Public
024 * License along with this library; if not, write to the Free Software
025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
026 */
027
028package org.opencms.ui.login;
029
030import org.opencms.db.CmsLoginMessage;
031import org.opencms.i18n.CmsMessages;
032import org.opencms.main.OpenCms;
033import org.opencms.security.CmsOrganizationalUnit;
034import org.opencms.ui.CmsVaadinUtils;
035import org.opencms.ui.Messages;
036import org.opencms.ui.components.CmsFakeWindow;
037import org.opencms.ui.components.OpenCmsTheme;
038
039import java.util.List;
040import java.util.Locale;
041import java.util.Map;
042
043import com.google.common.collect.Maps;
044import com.vaadin.annotations.DesignRoot;
045import com.vaadin.event.ShortcutAction.KeyCode;
046import com.vaadin.server.FontAwesome;
047import com.vaadin.ui.Button;
048import com.vaadin.ui.Button.ClickEvent;
049import com.vaadin.ui.Button.ClickListener;
050import com.vaadin.ui.themes.ValoTheme;
051import com.vaadin.v7.shared.ui.label.ContentMode;
052import com.vaadin.v7.ui.Label;
053import com.vaadin.v7.ui.OptionGroup;
054import com.vaadin.v7.ui.TextField;
055import com.vaadin.v7.ui.VerticalLayout;
056
057/**
058 * Login form.<p>
059 */
060@DesignRoot
061public class CmsLoginForm extends VerticalLayout {
062
063    /** The private PC type constant. */
064    public static final String PC_TYPE_PRIVATE = "private";
065
066    /** The public PC type constant. */
067    public static final String PC_TYPE_PUBLIC = "public";
068
069    /** Version id. */
070    private static final long serialVersionUID = 1L;
071
072    /** The login controller. */
073    protected CmsLoginController m_controller;
074
075    /** The label showing the copyright information. */
076    private Label m_copyright;
077
078    /** The error label. */
079    private Label m_error;
080
081    /** Button for opening the "forgot password" dialog. */
082    private Button m_forgotPasswordButton;
083
084    /**Fake window. */
085    private CmsFakeWindow m_fakeWindow;
086
087    /** Label showing an optional configurable message.*/
088    private Label m_additionalMessage;
089
090    /** Login button. */
091    private Button m_loginButton;
092
093    /** Button to show / hide advanced options. */
094    private Button m_optionsButton;
095
096    /** Boolean which indicated whether the advanced options are currently visible. */
097    private boolean m_optionsVisible;
098
099    /** Widget for OU selection. */
100    private CmsLoginOuSelector m_ouSelect;
101
102    /** Widget for entering the password. */
103    private CmsLoginPasswordField m_passwordField;
104
105    /** The password visibility toggle. */
106    private Button m_showPasswordButton;
107
108    /** The security field, which allows the user to choose between a private or public PC. */
109    private OptionGroup m_securityField;
110
111    /** Widget for entering the user name.  */
112    private TextField m_userField;
113
114    private boolean m_multipleOus;
115
116    /**
117     * Creates a new instance.<p>
118     *
119     * @param controller the login controller
120     * @param locale the locale to use
121     */
122    public CmsLoginForm(CmsLoginController controller, Locale locale) {
123
124        m_controller = controller;
125        final CmsMessages messages = OpenCms.getWorkplaceManager().getMessages(locale);
126        Map<String, String> macros = Maps.newHashMap();
127        macros.put("showSecure", "" + controller.isShowSecure());
128        String pctype = controller.getPcType();
129        CmsVaadinUtils.readAndLocalizeDesign(this, messages, macros);
130        m_securityField.addItem(PC_TYPE_PUBLIC);
131        m_securityField.addItem(PC_TYPE_PRIVATE);
132        m_securityField.setValue(pctype);
133        m_copyright.setContentMode(ContentMode.HTML);
134        m_copyright.setValue(CmsLoginHelper.getCopyrightHtml(locale));
135        CmsLoginMessage beforeLoginMessage = OpenCms.getLoginManager().getBeforeLoginMessage();
136        if ((beforeLoginMessage != null) && beforeLoginMessage.isEnabled()) {
137            m_additionalMessage.setVisible(true);
138            m_additionalMessage.setContentMode(ContentMode.HTML);
139            m_additionalMessage.setValue(beforeLoginMessage.getMessage());
140        }
141        m_securityField.setItemCaption(
142            PC_TYPE_PRIVATE,
143            messages.key(org.opencms.workplace.Messages.GUI_LOGIN_PCTYPE_PRIVATE_0));
144        m_securityField.setItemCaption(
145            PC_TYPE_PUBLIC,
146            messages.key(org.opencms.workplace.Messages.GUI_LOGIN_PCTYPE_PUBLIC_0));
147        setWidth("600px");
148        m_loginButton.setClickShortcut(KeyCode.ENTER);
149        m_loginButton.addClickListener(new ClickListener() {
150
151            private static final long serialVersionUID = 1L;
152
153            public void buttonClick(ClickEvent event) {
154
155                m_controller.onClickLogin();
156            }
157        });
158        addAttachListener(new AttachListener() {
159
160            private static final long serialVersionUID = 1L;
161
162            @SuppressWarnings("synthetic-access")
163            public void attach(AttachEvent event) {
164
165                m_userField.focus();
166            }
167        });
168
169        ClickListener forgotPasswordListener = new ClickListener() {
170
171            private static final long serialVersionUID = 1L;
172
173            public void buttonClick(ClickEvent event) {
174
175                m_controller.onClickForgotPassword();
176            }
177        };
178
179        m_forgotPasswordButton.addClickListener(forgotPasswordListener);
180
181        m_optionsButton.addClickListener(
182
183            new ClickListener() {
184
185                private static final long serialVersionUID = 1L;
186
187                public void buttonClick(ClickEvent event) {
188
189                    toggleOptionsVisible();
190                }
191
192            });
193        m_error.setContentMode(ContentMode.HTML);
194        m_showPasswordButton.addStyleName("o-login-show-password");
195        m_showPasswordButton.addStyleName(ValoTheme.BUTTON_BORDERLESS);
196        m_showPasswordButton.addStyleName(OpenCmsTheme.BUTTON_UNPADDED);
197        m_showPasswordButton.setIcon(FontAwesome.EYE_SLASH);
198        m_showPasswordButton.addClickListener(evt -> togglePasswordVisible());
199
200    }
201
202    /**
203     * Hides the error message.
204     */
205    public void clearError() {
206
207        m_error.setVisible(false);
208    }
209
210    /**
211     * Gets the OU.<p>
212     *
213     * @return the OU
214     */
215    public String getOrgUnit() {
216
217        return m_ouSelect.getValue();
218    }
219
220    /**
221     * Gets the password.<p>
222     *
223     * @return the password
224     */
225    public String getPassword() {
226
227        return m_passwordField.getValue();
228    }
229
230    /**
231     * Gets the PC type.<p>
232     *
233     * @return the PC type
234     */
235    public String getPcType() {
236
237        return "" + m_securityField.getValue();
238    }
239
240    /**
241     * Gets the user.<p>
242     *
243     * @return the user
244     */
245    public String getUser() {
246
247        return m_userField.getValue();
248    }
249
250    /**
251     * Resets the password field.<p>
252     */
253    public void resetPassword() {
254
255        m_passwordField.clear();
256
257    }
258
259    /**
260     * Selects a specific org unit.<p>
261     *
262     * @param preselectedOu the OU to select
263     */
264    public void selectOrgUnit(String preselectedOu) {
265
266        if (preselectedOu == null) {
267            if (OpenCms.getLoginManager().isOrgUnitRequired()) {
268                preselectedOu = CmsLoginOuSelector.OU_NONE;
269            } else {
270                preselectedOu = "/";
271            }
272        }
273        m_ouSelect.setValue(preselectedOu);
274
275    }
276
277    /**
278     * Sets visibility of 'advanced' options.<p>
279     *
280     * @param optionsVisible true if the options should be shown, false if not
281     */
282    public void setOptionsVisible(boolean optionsVisible) {
283
284        m_optionsVisible = optionsVisible;
285
286        boolean ousVisible = optionsVisible && !m_ouSelect.isAlwaysHidden();
287        m_ouSelect.setVisible(ousVisible);
288        m_forgotPasswordButton.setVisible(optionsVisible);
289        String optionsMessage = CmsVaadinUtils.getMessageText(
290            optionsVisible ? Messages.GUI_LOGIN_OPTIONS_HIDE_0 : Messages.GUI_LOGIN_OPTIONS_SHOW_0);
291        m_optionsButton.setCaption(optionsMessage);
292    }
293
294    /**
295     * Sets the org units available for selection.<p>
296     *
297     * @param ous the ous
298     */
299    public void setSelectableOrgUnits(List<CmsOrganizationalUnit> ous) {
300
301        boolean addEmptySelection = OpenCms.getLoginManager().isOrgUnitRequired() && (ous.size() > 1);
302        m_ouSelect.initOrgUnits(ous, addEmptySelection);
303        boolean optionsVisible = addEmptySelection && (ous.size() > 1);
304        setOptionsVisible(optionsVisible);
305    }
306
307    /**
308     * Toggles visibility of 'advanced' options.<p>
309     */
310    public void toggleOptionsVisible() {
311
312        setOptionsVisible(!m_optionsVisible);
313    }
314
315    /**
316     * Toggles the password visibility (also changes icon for the password visibility toggle button).
317     */
318    protected void togglePasswordVisible() {
319
320        boolean visible = !m_passwordField.isPasswordVisible();
321        m_showPasswordButton.setIcon(visible ? FontAwesome.EYE : FontAwesome.EYE_SLASH);
322        m_passwordField.setPasswordVisible(visible);
323
324    }
325
326    /**
327     * Displays the given login error.<p>
328     *
329     * @param messageHTML the error message
330     */
331    void displayError(String messageHTML) {
332
333        // m_fakeWindow.addStyleName("waggler");
334        m_error.setValue(messageHTML);
335        m_error.setVisible(true);
336        CmsVaadinUtils.waggleMeOnce(m_fakeWindow);
337        //
338        //Add JavaScript code, which adds the wiggle class and removes it after a short time.
339        //        JavaScript.getCurrent().execute(
340        //            "wiggleElement=document.querySelectorAll(\".waggler\")[0];\n"
341        //                + "wiggleElement.className=wiggleElement.className + \" waggle\";\n"
342        //                + "setTimeout(function () {\n"
343        //                + "element=document.querySelectorAll(\".waggle\")[0];\n"
344        //                + "element.className=element.className.replace(/\\bwaggle\\b/g, \"\");"
345        //                + "    }, 1500);");
346    }
347
348}