blob: db95a6b1aadaf0b1664cfc6a3a197bfeff0ca3fd [file] [log] [blame]
/**
*
* Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation
*/
package org.eclipse.osbp.authentication.ui.login;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.security.Key;
import java.text.MessageFormat;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.List;
import java.util.Locale;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.crypto.spec.SecretKeySpec;
import javax.inject.Inject;
import org.apache.commons.lang.SerializationUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.mail.Email;
import org.apache.shiro.codec.Hex;
import org.apache.shiro.crypto.AesCipherService;
import org.apache.shiro.crypto.CryptoException;
import org.apache.shiro.crypto.PaddingScheme;
import org.apache.shiro.util.ByteSource;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.core.services.events.IEventBroker;
import org.eclipse.equinox.app.IApplicationContext;
import org.eclipse.osbp.authentication.account.dtos.UserAccountDto;
import org.eclipse.osbp.authentication.ui.login.BrowserCookie.Callback;
import org.eclipse.osbp.dsl.dto.lib.impl.DtoServiceAccess;
import org.eclipse.osbp.preferences.ProductConfiguration;
import org.eclipse.osbp.runtime.common.filter.IDTOServiceWithMutablePersistence;
import org.eclipse.osbp.ui.api.metadata.IDSLMetadataService;
import org.eclipse.osbp.ui.api.themes.EnumCssClass;
import org.eclipse.osbp.ui.api.user.IUser;
import org.eclipse.osbp.ui.initialization.IInitializationNotification;
import org.eclipse.osbp.user.User;
import org.eclipse.osbp.vaaclipse.addons.app.VaadinE4Application;
import org.eclipse.osbp.vaaclipse.publicapi.authentication.AuthenticationConstants;
import org.eclipse.osbp.vaaclipse.publicapi.resources.BundleResource;
import org.osgi.framework.Bundle;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.Version;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.vaadin.event.Action;
import com.vaadin.event.Action.Handler;
import com.vaadin.event.ShortcutAction;
import com.vaadin.server.Page;
import com.vaadin.shared.ui.label.ContentMode;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.CheckBox;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Image;
import com.vaadin.ui.Label;
import com.vaadin.ui.NativeButton;
import com.vaadin.ui.Notification;
import com.vaadin.ui.Notification.Type;
import com.vaadin.ui.Panel;
import com.vaadin.ui.PasswordField;
import com.vaadin.ui.ProgressBar;
import com.vaadin.ui.TextField;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;
/* to be called as login procedure this class must be registered in the product's plugin.xml as extension
* like this:
* <property
name="applicationAuthenticationProvider"
value="bundleclass://org.eclipse.osbp.utils.ui/org.eclipse.osbp.utils.vaaclipse.AuthenticationProvider">
</property>
*/
/* the remember me function stores a cookie named NAME_COOKIE with 40 days validity.
* the contents username and password is crypted using aes encryption.
* the key for encryption is a static with a one time randomized static key
* the key inside this cookie is encrypted using aes with a one time randomized static key
*/
@SuppressWarnings("serial")
public class AuthenticationProvider implements Callback, Handler {
@Inject
private IEventBroker eventBroker;
@Inject
private IEclipseContext context;
@Inject
private IDSLMetadataService dslMetadataService;
private IPostAuthentication postAuthentication;
/** The Constant LOGGER. */
private static final Logger LOGGER = LoggerFactory.getLogger(AuthenticationProvider.class);
private AesCipherService cipher;
// this cookie remembers the user credentials
private static final String NAME_COOKIE = "osbp_rememberme"; //$NON-NLS-1$
// this cookie remembers the cipher key
private static final String KEY_COOKIE = "osbp_basic"; //$NON-NLS-1$
// the key to cipher the key
private static final byte[] CIPHER_KEY = Hex.decode("CA69A6B7B1C453A1885DFA8EA5743121");
private static final int KEY_SIZE = 128;
private Locale locale;
private boolean keyWasFound = false;
private Key key;
private int failedLoginCnt = 0;
private Label title;
private TextField userField;
private PasswordField passwordField;
private Button login;
private CheckBox remembermeField;
private Button forgotpasswordField;
private Button register;
private Image lockedImage;
private Image unlockedImage;
private Label copyrightField;
private Label versionField;
private String cookieValue;
private ProgressBar progressValue;
private VerticalLayout imageArea;
// Have the unmodified Enter key cause an event
Action do_login = new ShortcutAction("Default key", ShortcutAction.KeyCode.ENTER, null);
// Have the C key modified with Alt cause an event
Action action_cancel = new ShortcutAction("Alt+C", ShortcutAction.KeyCode.C, new int[] { ShortcutAction.ModifierKey.ALT });
public AuthenticationProvider() {
InitializationListener.addAuthenticationProvider(this);
}
@PreDestroy
public void preDestroy() {
InitializationListener.removeAuthenticationProvider(this);
}
public void setDSLMetadataService(IDSLMetadataService dslMetadataService) {
this.dslMetadataService = dslMetadataService;
}
public IPostAuthentication getPostAuthentication() {
return postAuthentication;
}
public void setPostAuthentication(IPostAuthentication postAuthentication) {
this.postAuthentication = postAuthentication;
}
@SuppressWarnings("restriction")
@PostConstruct
public void init(VerticalLayout parent) {
LOGGER.debug("AuthenticationProvider init");
if (InitializationListener.getUserAccessService() == null) {
LOGGER.error("userAccessService not available");
return;
}
cipher = new AesCipherService();
locale = UI.getCurrent().getLocale();
cipher.setKeySize(KEY_SIZE);
/* Application name, version and vendor*/
IApplicationContext appcontext = VaadinE4Application.getInstance().getAppContext();
Bundle bundle = appcontext.getBrandingBundle();
Version brandingVersion = bundle.getVersion();
String version = brandingVersion != null ? brandingVersion.toString() : "0";
String brandingName = appcontext.getBrandingName();
String appName = brandingName != null ? brandingName : "App";
Dictionary<String, String> headers = bundle.getHeaders();
String brandingVendor = headers.get("Bundle-Vendor");
String vendor = brandingVendor != null ? brandingVendor : "Loetz GmbH&Co.KG Heidelberg Germany";
/* --------------------------- */
// set polling is necessary due to possible progress bars
UI.getCurrent().setPollInterval(1000);
Panel loginPanel = new Panel();
loginPanel.setWidth("430px");
loginPanel.setId("loginPanelArea");
loginPanel.addStyleName("loginPanelArea os-login");
parent.addComponent(loginPanel);
parent.setComponentAlignment(loginPanel, Alignment.TOP_CENTER);
parent.setPrimaryStyleName("osbp");
loginPanel.setDescription(dslMetadataService.translate(locale.toLanguageTag(), "login_caption_tip"));
VerticalLayout loginForm = new VerticalLayout();
loginForm.setSizeFull();
loginForm.setMargin(true);
loginForm.setId("osbpLoginForm");
loginForm.addStyleName("osbpLoginForm");
loginPanel.setContent(loginForm);
VerticalLayout fullArea = new VerticalLayout();
fullArea.setSizeFull();
fullArea.setId("loginFullArea");
fullArea.addStyleName("loginFullArea");
HorizontalLayout titleArea = new HorizontalLayout();
titleArea.setSizeFull();
titleArea.setId("loginTitelArea");
titleArea.addStyleName("loginTitleArea");
fullArea.addComponent(titleArea);
fullArea.setComponentAlignment(titleArea, Alignment.TOP_CENTER);
title = new Label( appName + "<br>" + dslMetadataService.translate(locale.toLanguageTag(), "login_caption") );
title.setContentMode(ContentMode.HTML);
title.addStyleName(EnumCssClass.VIEW_HEADER_H2.toString());
titleArea.addComponent(title);
loginForm.addComponent(fullArea);
HorizontalLayout userArea = new HorizontalLayout();
userArea.setId("loginUserArea");
userArea.addStyleName("loginUserArea");
userArea.setSizeFull();
userArea.setMargin(true);
fullArea.addComponent(userArea);
VerticalLayout textArea = new VerticalLayout();
textArea.setSizeFull();
userArea.addComponent(textArea);
userArea.setExpandRatio(textArea, 0.85f);
userArea.setId("loginTextArea");
userArea.addStyleName("loginTextArea");
imageArea = new VerticalLayout();
imageArea.setSizeFull();
imageArea.setMargin(true);
userArea.addComponent(imageArea);
userArea.setExpandRatio(imageArea, 0.15f);
VerticalLayout buttonArea = new VerticalLayout();
buttonArea.setId("loginButtonArea");
buttonArea.addStyleName("loginButtonArea");
buttonArea.setSizeFull();
buttonArea.setMargin(true);
fullArea.addComponent(buttonArea);
HorizontalLayout loginArea = new HorizontalLayout();
loginArea.setId("loginLoginArea");
loginArea.addStyleName("loginLoginArea");
loginArea.setSizeFull();
buttonArea.addComponent(loginArea);
HorizontalLayout registerArea = new HorizontalLayout();
registerArea.setId("loginRegisterArea");
registerArea.addStyleName("loginRegisterArea");
registerArea.setSizeFull();
buttonArea.addComponent(registerArea);
VerticalLayout copyrightArea = new VerticalLayout();
copyrightArea.setId("loginCopyrightArea");
copyrightArea.addStyleName("loginCopyrightArea");
copyrightArea.setSizeFull();
loginForm.addComponent(copyrightArea);
if(context != null) {
lockedImage = new Image(null, BundleResource.valueOf("platform:/plugin/"
+ FrameworkUtil.getBundle(AuthenticationProvider.class).getSymbolicName() + "/assets/locked.png"));
unlockedImage = new Image(null, BundleResource.valueOf("platform:/plugin/"
+ FrameworkUtil.getBundle(AuthenticationProvider.class).getSymbolicName() + "/assets/unlocked.png"));
imageArea.addComponent(lockedImage);
imageArea.setComponentAlignment(lockedImage, Alignment.MIDDLE_CENTER);
}
userField = new TextField();
userField.setSizeFull();
textArea.addComponent(userField);
userField.setInputPrompt(dslMetadataService.translate(locale.toLanguageTag(), "username"));
userField.setDescription(dslMetadataService.translate(locale.toLanguageTag(), "username_tip"));
passwordField = new PasswordField();
passwordField.setSizeFull();
textArea.addComponent(passwordField);
passwordField.setInputPrompt(dslMetadataService.translate(locale.toLanguageTag(), "password"));
passwordField.setDescription(dslMetadataService.translate(locale.toLanguageTag(), "password_tip"));
progressValue = new ProgressBar();
progressValue.setSizeFull();
progressValue.addStyleName("initialization-progress");
progressValue.setVisible(false);
textArea.addComponent(progressValue);
if (!ProductConfiguration.hasNoRememberMe()) {
remembermeField = new CheckBox();
remembermeField.setSizeFull();
loginArea.addComponent(remembermeField);
remembermeField.setCaption(dslMetadataService.translate(locale.toLanguageTag(), "remember_me"));
remembermeField.setDescription(dslMetadataService.translate(locale.toLanguageTag(), "remember_me_tip"));
}
login = new Button();
login.setSizeFull();
loginArea.addComponent(login);
login.setCaption(dslMetadataService.translate(locale.toLanguageTag(), "sign_in"));
login.setDescription(dslMetadataService.translate(locale.toLanguageTag(), "sign_in_tip"));
login.addClickListener(new ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
doLogin();
}
});
if(context != null) {
forgotpasswordField = new NativeButton();
forgotpasswordField.setSizeFull();
registerArea.addComponent(forgotpasswordField);
forgotpasswordField.setCaption(dslMetadataService.translate(locale.toLanguageTag(), "forgot_password"));
forgotpasswordField.setDescription(dslMetadataService.translate(locale.toLanguageTag(), "forgot_password_tip"));
forgotpasswordField.addClickListener(new ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
doResetPassword();
}
});
register = new Button();
register.setSizeFull();
registerArea.addComponent(register);
register.setCaption(dslMetadataService.translate(locale.toLanguageTag(), "register_new_user"));
register.setDescription(dslMetadataService.translate(locale.toLanguageTag(), "register_new_user_tip"));
register.addClickListener(new ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
doRegister();
}
});
}
copyrightField = new Label();
copyrightField.setSizeFull();
copyrightArea.addComponent(copyrightField);
copyrightArea.setComponentAlignment(copyrightField, Alignment.MIDDLE_CENTER);
String actualYear = String.valueOf(LocalDate.now().getYear());
String cprText = dslMetadataService.translate(locale.toLanguageTag(), "copyright") + actualYear + " " + vendor;
String trdmText = dslMetadataService.translate(locale.toLanguageTag(), "trademark");
copyrightField.setValue(cprText + "<br>" + trdmText);
copyrightField.setContentMode(ContentMode.HTML);
versionField = new Label();
versionField.setSizeFull();
versionField.addStyleName("loginVersionField");
copyrightArea.addComponent(versionField);
copyrightArea.setComponentAlignment(copyrightField, Alignment.MIDDLE_CENTER);
versionField.setValue(dslMetadataService.translate(locale.toLanguageTag(), "version") + ": "+ version);
// Set this object as the action handler
loginPanel.addActionHandler(this);
LOGGER.debug("AuthenticationProvider layouted");
// eventually encrypt uncrypted passwords
checkCookie();
InitializationListener.addAuthenticationProvider(this);
}
private void checkCookie() {
// examine the cookies
keyWasFound = false;
// keyWasFound will be set by callback function onValueDetected
// when the key cookie was found - onValueDetected starts a new
// detectCookie for the remember-me function
cookieValue = null;
// detectCookie will set this value for a hashCode check
if (!ProductConfiguration.hasNoRememberMe()) {
BrowserCookie.detectCookieValue(KEY_COOKIE, this);
}
LOGGER.debug("AuthenticationProvider cookie detecting finished");
}
private void sendResetPasswordEmail(UserAccountDto user, String resetPassword) {
Email email = AuthenticationUiUtil.getEmail();
String emailSubject = dslMetadataService.translate(locale.toLanguageTag(), "email_password_reset_subject");
if ( "email_password_reset_subject".equals(emailSubject) ){
emailSubject = "Your new password";
}
String charset=Charset.defaultCharset().name();
email.setCharset(charset);
email.setSubject(emailSubject);
try {
email.setFrom(ProductConfiguration.getAdminEmail(), ProductConfiguration.getAdminEmailUsername() );
String emailBody = dslMetadataService.translate(locale.toLanguageTag(), "email_password_reset_body");
if ( "email_password_reset_body".equals(emailBody) ){
emailBody="Please find your new password here.\nYou have to change it with your next login!\n\nYour new password is: {0}.";
}
String fmt=MessageFormat.format(emailBody,resetPassword).replace("\\n", "\n");
email.setMsg(fmt);
email.addTo(user.getEmail());
email.send();
} catch (Exception e) {
LOGGER.error("EmailException: " + e.getLocalizedMessage());
LOGGER.error("failed to send password {} to user {} to address {}", resetPassword, user.getUserName(), user.getEmail() );
}
}
/**
* Retrieve actions for a specific component. This method will be called for
* each object that has a handler; in this example just for login panel. The
* returned action list might as well be static list.
*/
@Override
public Action[] getActions(Object target, Object sender) {
return new Action[] { do_login };
}
/**
* Handle actions received from keyboard. This simply directs the actions to
* the same listener methods that are called with ButtonClick events.
*/
@Override
public void handleAction(Action action, Object sender, Object target) {
if (action == do_login) {
doLogin();
}
}
public void doLogin() {
checkCookie();
InitializationListener.getUserAccessService().logout();
login.focus();
String username = userField.getValue();
String password = passwordField.getValue();
if (username.trim().isEmpty())
username = null;
if (check(username, password, ProductConfiguration.hasNoRememberMe() ? false : remembermeField.getValue())) {
if (!checkPasswordReset(username)) {
if(context != null) {
imageArea.removeComponent(lockedImage);
imageArea.addComponent(unlockedImage);
}
User user = new User(username);
if(context != null) {
if (context.get(IUser.class) == null) {
context.set(IUser.class, user);
context.set("user", user);
}
if(eventBroker != null) {
eventBroker.post(AuthenticationConstants.Events.Authentication.name, user);
}
}
if(postAuthentication != null) {
postAuthentication.execute(user);
}
}
}
}
private boolean check(String username, String password, Boolean rememberMe) {
boolean cookieValid = false;
if (cookieValue != null) {
if (!InitializationListener.getUserAccessService().isCookieValid(username, cookieValue)) {
// fraud detected - lock user account
LOGGER.debug("cookie fraud detection - account is locked");
InitializationListener.getUserAccessService().lockAccount(username, true);
}
cookieValid = true;
}
if (!tryToAuthenticate(AuthenticationUiUtil.PORTAL_ID, username, password)) {
if (InitializationListener.getUserAccessService().isAccountLocked(username)) {
// wait exponentially along failed logins up to a maximum of
// 18,2 hours to prevent "Rapid-Fire Login Attempts"
// http://stackoverflow.com/questions/549/the-definitive-guide-to-form-based-website-authentication
Double sleep=(1000.0 * Math.max(5,Math.pow(2, Math.min(failedLoginCnt++, 16))-1));
int sleepSeconds=sleep.intValue()/1000;
Notification notification = new Notification(dslMetadataService.translate(locale.toLanguageTag(), "lockedmessage"), Type.ERROR_MESSAGE);
notification.setDelayMsec(sleep.intValue());
LOGGER.info("Login '{}' is locked for {} seconds now ... pls. wait", username, ((Integer)sleepSeconds).toString() ); //NOSONAR
notification.show(Page.getCurrent());
} else if (InitializationListener.getUserAccessService().isAccountNotRegistered(username)) {
Notification.show(dslMetadataService.translate(locale.toLanguageTag(), "not_registered_message"), Type.ERROR_MESSAGE);
} else if (!InitializationListener.getUserAccessService().isAccountEnabled(username)) {
Notification.show(dslMetadataService.translate(locale.toLanguageTag(), "disabledmessage"), Type.ERROR_MESSAGE);
} else {
Double sleep=(1000.0 * Math.max(5,Math.pow(2, Math.min(failedLoginCnt++, 16))-1));
int sleepSeconds=sleep.intValue()/1000;
Notification notification = new Notification(dslMetadataService.translate(locale.toLanguageTag(), "failedmessage"), Type.ERROR_MESSAGE);
notification.setDelayMsec(sleep.intValue());
LOGGER.info("Login '{}' is delayed for {} seconds now ... pls. wait", username, ((Integer)sleepSeconds).toString() ); //NOSONAR
notification.show(Page.getCurrent());
failedLoginCnt++;
}
return false;
}
failedLoginCnt=0;
if (!cookieValid) {
// if login is valid and remember_me is active, store a cookie
if (rememberMe) {
// create a new cipher key if not already found
if (!keyWasFound) {
key = cipher.generateNewKey(KEY_SIZE);
byte[] keyValue = SerializationUtils.serialize(key);
ByteSource encryptedData = null;
try {
cipher.setPaddingScheme(PaddingScheme.PKCS5);
encryptedData = cipher.encrypt(pkcs5Bytes(keyValue), generateKey().getEncoded());
BrowserCookie.setCookie(KEY_COOKIE, Hex.encodeToString(encryptedData.getBytes()), 40 * 24L * 3600L, "/");
keyWasFound = true;
} catch (Exception e) {
Throwable cause = e.getCause();
String msg = e.getLocalizedMessage();
if (cause != null) {
msg += "->" + cause.getLocalizedMessage();
}
LOGGER.error(msg);
}
}
List<String> loginCredentials = new ArrayList<>();
loginCredentials.add(username);
loginCredentials.add(password);
loginCredentials.add(rememberMe.toString());
String loginData = encryptData(loginCredentials);
if (loginData != null) {
// cookie stays valid up to 40 days
BrowserCookie.setCookie(NAME_COOKIE, loginData, 40 * 24L * 3600L, "/");
InitializationListener.getUserAccessService().setCookieHash(username, loginData);
LOGGER.debug("cookie set for remember me");
}
} else {
// destroy cookie
BrowserCookie.setCookie(NAME_COOKIE, "", 0L, "/");
InitializationListener.getUserAccessService().setCookieHash(username, null);
LOGGER.debug("cookie destroyed for remember me");
}
}
return true;
}
private String encryptData(List<String> loginCredentials) {
cipher.setPaddingScheme(PaddingScheme.PKCS5);
String data = String.join(",", loginCredentials);
ByteSource encryptedData = null;
try {
encryptedData = cipher.encrypt(pkcs5Bytes(data), key.getEncoded());
} catch (CryptoException | UnsupportedEncodingException e) {
Throwable cause = e.getCause();
String msg = e.getLocalizedMessage();
if (cause != null) {
msg += "->" + cause.getLocalizedMessage();
}
LOGGER.error(msg);
return null;
}
return encryptedData.toHex();
}
private List<String> decryptData(String loginData) {
cipher.setPaddingScheme(PaddingScheme.PKCS5);
List<String> credentials = new ArrayList<>();
ByteSource decryptedData = null;
if (loginData != null) {
try {
decryptedData = cipher.decrypt(Hex.decode(loginData), key.getEncoded());
} catch (CryptoException e) {
Throwable cause = e.getCause();
String msg = e.getLocalizedMessage();
if (cause != null) {
msg += "->" + cause.getLocalizedMessage();
}
LOGGER.error(msg);
return credentials;
}
String decryptedString = new String(decryptedData.getBytes());
String[] data = decryptedString.split(",");
for (String d : data) {
credentials.add(d.trim());
}
}
return credentials;
}
// this callback is called by javascript on detection of the desired cookie
@Override
public void onValueDetected(String cookieName, String value) {
if (cookieName != null && value != null) {
LOGGER.debug("cookie " + cookieName + " was found");
if (KEY_COOKIE.equals(cookieName)) {
try {
// deserialize the decoded hex encoded string
cipher.setPaddingScheme(PaddingScheme.PKCS5);
key = (Key) SerializationUtils.deserialize(cipher.decrypt(Hex.decode(value), generateKey().getEncoded()).getBytes());
keyWasFound = true;
BrowserCookie.detectCookieValue(NAME_COOKIE, this);
} catch (Exception e) {
Throwable cause = e.getCause();
String msg = e.getLocalizedMessage();
if (cause != null) {
msg += "->" + cause.getLocalizedMessage();
}
LOGGER.error(msg);
}
} else if (NAME_COOKIE.equals(cookieName)) {
// store for a later cookie validation
cookieValue = value;
List<String> loginCredentials = decryptData(value);
if (loginCredentials.size() == 3) {
UI.getCurrent().getSession().lock();
userField.setValue(loginCredentials.get(0));
passwordField.setValue(loginCredentials.get(1));
remembermeField.setValue(true);
UI.getCurrent().getSession().unlock();
LOGGER.debug("cookie decoded");
if (ProductConfiguration.hasAutoLogin()) {
login.click();
}
} else {
LOGGER.debug("cookie for remember me has invalid item count");
}
}
} else {
LOGGER.debug("no more valid cookies found");
}
}
/*
* helper function for the PKCS5 algorithm to create a correct padding
* pattern to 16 byte boundaries
*
* the space is filled with the hexadecimal value of the number of padded
* characters
*
* as shiro creates bytecode encoding UTF-8 by default, we must use the same
* for padding characters and the returning byte array
*/
private byte[] pkcs5Bytes(String data) throws UnsupportedEncodingException {
return pkcs5Bytes(data.getBytes("UTF-8"));
}
private byte[] pkcs5Bytes(byte[] data) throws UnsupportedEncodingException {
byte diff = (byte) (16 - data.length % 16);
byte[] result = new byte[data.length + diff];
for (int i = 0; i < data.length + diff; i++) {
if (i < data.length)
result[i] = data[i];
else
result[i] = diff;
}
return result;
}
private static Key generateKey() throws Exception {
Key key = new SecretKeySpec(CIPHER_KEY, "AES");
return key;
}
/**
* Try to authenticate with the credentials given!<br>
* {@link #setAuthenticated(boolean)} will explicit be called!
*
* @param portalId
* @param userName
* @param password
* @return true if the user was authenticated successful
*/
boolean tryToAuthenticate(String portalId, String userName, String password) {
boolean authenticated = InitializationListener.getUserAccessService().isAuthenticated();
if (!authenticated) {
try {
authenticated = InitializationListener.getUserAccessService().authenticate(portalId, userName, password);
} catch (Exception e) {
LOGGER.error(e.getLocalizedMessage());
}
}
return authenticated;
}
public void notifyInitializationStep(IInitializationNotification notification) {
notifiyInitializationStep(notification, true);
}
public void notifyInitializationDone(IInitializationNotification notification) {
notifiyInitializationStep(notification, false);
}
private void notifiyInitializationStep(IInitializationNotification notification, boolean blockUi) {
if (progressValue != null) {
progressValue.setValue((float) notification.getRecommendedProgressValue());
progressValue.setCaption(notification.getRecommendedProgressTitle(true));
progressValue.setVisible(blockUi);
}
enableLoginUI(!blockUi);
}
public void enableLoginUI(boolean reEnableLoginUi) {
if (userField != null) {
userField.setEnabled(reEnableLoginUi);
passwordField.setEnabled(reEnableLoginUi);
login.setEnabled(reEnableLoginUi);
remembermeField.setEnabled(reEnableLoginUi);
if(context != null) {
register.setEnabled(reEnableLoginUi);
}
}
}
public void doRegister() {
register.focus();
String username = userField.getValue();
if (username.trim().isEmpty()) {
Notification.show(dslMetadataService.translate(locale.toLanguageTag(), "register_username_is_empty_message"));
userField.focus();
} else if (InitializationListener.getUserAccessService().checkNotLoggedInUsernameExists(username)) {
Notification.show(dslMetadataService.translate(locale.toLanguageTag(), "register_username_already_exists"));
} else { // Do a registration only if the user doesn´t already exist.
User user = new User(username);
if (context.get(User.class) == null) {
context.set(User.class, user);
context.set("user", user);
}
RegistrationDialog registerDialog = new RegistrationDialog();
Window registerWindow = registerDialog.init(eventBroker, dslMetadataService, user);
UI.getCurrent().addWindow(registerWindow);
}
}
public void doResetPassword() {
forgotpasswordField.focus();
String username = userField.getValue();
if (username.trim().isEmpty()) {
username = null;
}
if (InitializationListener.getUserAccessService().checkNotLoggedInUsernameExists(username)) {
UserAccountDto user = (UserAccountDto) InitializationListener.getUserAccessService().findUserAccount(username);
String resetPassword = RandomStringUtils.randomAlphanumeric(8);
@SuppressWarnings("restriction")
IDTOServiceWithMutablePersistence<UserAccountDto> service = (IDTOServiceWithMutablePersistence<UserAccountDto>) DtoServiceAccess
.getService(UserAccountDto.class);
String encryptedPassword = InitializationListener.getUserAccessService().encryptPassword(resetPassword);
user.setPassword(encryptedPassword);
user.setPasswordReset(true);
user.setLocked(false);
user.setFailedAttempt(0);
user.setEnabled(true);
service.update(user);
Notification.show(dslMetadataService.translate(locale.toLanguageTag(), "password_reset_success_message"));
sendResetPasswordEmail(user, resetPassword);
}
}
public boolean checkPasswordReset(String username) {
// Do a registration only if the user doesn´t already exist.
if(eventBroker != null) {
UserAccountDto userAccount = (UserAccountDto) InitializationListener.getUserAccessService().findUserAccount(username);
if (userAccount != null && userAccount.getPasswordReset()) {
NewPasswordDialog newPasswordDialog = new NewPasswordDialog();
Window registerWindow = newPasswordDialog.init(eventBroker, dslMetadataService, userAccount);
UI.getCurrent().addWindow(registerWindow);
return true;
}
}
return false;
}
}