| /** |
| * |
| * 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 v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation |
| */ |
| package org.eclipse.osbp.authentication.providerimpl; |
| |
| import java.util.Collection; |
| |
| import org.apache.shiro.authc.credential.DefaultPasswordService; |
| import org.apache.shiro.authc.credential.PasswordService; |
| import org.eclipse.osbp.authentication.account.dtos.UserAccountDto; |
| import org.eclipse.osbp.dsl.dto.lib.impl.DtoServiceAccess; |
| import org.eclipse.osbp.dsl.dto.lib.services.IDTOServiceWithMutablePersistence; |
| import org.eclipse.osbp.dsl.dto.lib.services.Query; |
| import org.eclipse.osbp.dsl.dto.lib.services.filters.LCompare; |
| import org.eclipse.osbp.persistence.IPersistenceService; |
| import org.eclipse.osbp.ui.api.useraccess.IUserAccessService; |
| import org.osgi.framework.InvalidSyntaxException; |
| import org.osgi.service.component.ComponentContext; |
| import org.osgi.service.component.annotations.Component; |
| import org.osgi.service.component.annotations.Reference; |
| import org.osgi.service.component.annotations.ReferenceCardinality; |
| import org.osgi.service.component.annotations.ReferencePolicy; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| /** |
| * The Class UserProtocol controls login attempts of users, if successful or |
| * not. User accounts will be locked on too many unsuccessful login attempts. |
| * The maximum tries is configured in the preferences. |
| */ |
| @Component(service = {}, immediate = true) |
| public class UserProtocol { |
| |
| /** The dto user account dto service. */ |
| private static IDTOServiceWithMutablePersistence<UserAccountDto> dtoUserAccountDtoService = null; |
| |
| /** The find by user name. */ |
| private static boolean findByUserName = true; // false means find by email |
| |
| /** The Constant LOGGER. */ |
| private static final Logger LOGGER = LoggerFactory.getLogger(UserProtocol.class); |
| |
| /** The persistence service. */ |
| private IPersistenceService persistenceService; |
| |
| /** The persistence id. */ |
| private static String persistenceId = "authentication"; |
| |
| /** The password service. */ |
| private static PasswordService passwordService = null; |
| |
| // |
| // OSGI Infrastructure |
| // |
| |
| /** |
| * Called by OSGi-DS to activate the service. |
| * |
| * @param context |
| * the context |
| * @throws Exception |
| * the exception |
| */ |
| protected void activate(ComponentContext context) { |
| LOGGER.debug("UserProtocol activated"); |
| } |
| |
| /** |
| * Internal activate. |
| * |
| * @throws InvalidSyntaxException |
| * the invalid syntax exception |
| */ |
| @SuppressWarnings("restriction") |
| protected static void internalActivate() { |
| if (UserProtocol.dtoUserAccountDtoService == null) { |
| UserProtocol.dtoUserAccountDtoService = (IDTOServiceWithMutablePersistence<UserAccountDto>) DtoServiceAccess |
| .getService(UserAccountDto.class); |
| } |
| // for password encryption |
| if (UserProtocol.passwordService == null) { |
| UserProtocol.passwordService = new DefaultPasswordService(); |
| } |
| } |
| |
| /** |
| * Called by OSGi-DS to deactivate the service. |
| * |
| * @param context |
| * the context |
| */ |
| protected void deactivate(ComponentContext context) { |
| // NOP |
| } |
| |
| /** |
| * Gets the dto user account dto service. |
| * |
| * @return the dto user account dto service |
| */ |
| public static IDTOServiceWithMutablePersistence<UserAccountDto> getDtoUserAccountDtoService() { |
| UserProtocol.internalActivate(); |
| return UserProtocol.dtoUserAccountDtoService; |
| } |
| |
| /** |
| * Gets the password service. |
| * |
| * @return the password service |
| */ |
| public static PasswordService getPasswordService() { |
| return UserProtocol.passwordService; |
| } |
| |
| /** |
| * Find user account. |
| * |
| * @param username |
| * the username |
| * @return the user account dto |
| */ |
| // TODO (JCD): New method that ONLY finds a user. That´s all! |
| public UserAccountDto findUserAccount(String username) { |
| Collection<UserAccountDto> users = null; |
| try { |
| // try to find by username |
| users = getDtoUserAccountDtoService().find(new Query(new LCompare.Equal("userName", username))); |
| } catch (Exception e) { |
| LOGGER.error("Exception while trying to find user", e); |
| } |
| if (users != null) { |
| if (users.size() > 1) { |
| LOGGER.error("user account is not unique - first match taken"); |
| } else if (users.isEmpty()) { |
| LOGGER.debug("user account not found"); |
| return null; |
| } |
| return users.iterator().next(); |
| } |
| return null; |
| } |
| |
| /** |
| * Find user account. |
| * |
| * @param username |
| * the username |
| * @return the user account dto |
| */ |
| // TODO (JCD): I changed this method into OLD due to the not knowing heed of |
| // a method that finds a user by email using the introduced username and |
| // that creates a new user if it doesn´t exist and that all in a |
| // find.Method. Very strange!!!! |
| public UserAccountDto findUserAccount_OLD(String username) { |
| Collection<UserAccountDto> users = null; |
| try { |
| if (isFindByUserName()) { |
| // try to find by username first |
| users = getDtoUserAccountDtoService().find(new Query(new LCompare.Equal("userName", username))); |
| } else { |
| // try to find by email |
| users = getDtoUserAccountDtoService().find(new Query(new LCompare.Equal("email", username))); |
| } |
| } catch (Exception e) { |
| LOGGER.error("Exception while trying to find user", e); |
| } |
| if (users != null) { |
| if (users.size() > 1) { |
| LOGGER.error("user account is not unique - first match taken"); |
| } else if (users.isEmpty()) { |
| LOGGER.debug("user account not found -create one"); |
| UserAccountDto userAccount = new UserAccountDto(); |
| userAccount.setEnabled(true); |
| if (isFindByUserName()) { |
| userAccount.setUserName(username); |
| } else { |
| userAccount.setEmail(username); |
| } |
| getDtoUserAccountDtoService().update(userAccount); |
| return userAccount; |
| } |
| return users.iterator().next(); |
| } |
| return null; |
| } |
| |
| /** |
| * Update user account. |
| * |
| * @param user |
| * the user |
| */ |
| public void updateUserAccount(UserAccountDto user) { |
| getDtoUserAccountDtoService().update(user); |
| } |
| |
| /** |
| * Delete user account. |
| * |
| * @param user |
| * the user |
| */ |
| public void deleteUserAccount(UserAccountDto user) { |
| getDtoUserAccountDtoService().delete(user); |
| } |
| |
| /** |
| * Track successful login attempt. |
| * |
| * @param username |
| * the username |
| */ |
| public void trackSuccessfulLoginAttempt(String username) { |
| UserAccountDto user = this.findUserAccount(username); |
| if (user != null) { |
| int cnt = user.getSuccessfulAttempt(); |
| cnt++; |
| user.setSuccessfulAttempt(cnt); |
| user.setFailedAttempt(0); |
| updateUserAccount(user); |
| } |
| } |
| |
| /** |
| * Track failed login attempt. |
| * |
| * @param username |
| * the username |
| * @return the int |
| */ |
| public int trackFailedLoginAttempt(String username) { |
| if (IUserAccessService.ADMINISTRATOR.equals(username)) { |
| return 0; |
| } |
| UserAccountDto user = findUserAccount(username); |
| if (user != null) { |
| int cnt = user.getFailedAttempt(); |
| cnt++; |
| user.setFailedAttempt(cnt); |
| updateUserAccount(user); |
| return cnt; |
| } |
| return 0; |
| } |
| |
| /** |
| * Checks if is account locked. |
| * |
| * @param username |
| * the username |
| * @return true, if is account locked |
| */ |
| public boolean isAccountLocked(String username) { |
| if (IUserAccessService.ADMINISTRATOR.equals(username)) { |
| return false; |
| } |
| UserAccountDto user = findUserAccount(username); |
| if (user != null) { |
| return user.getLocked(); |
| } |
| return false; |
| } |
| |
| /** |
| * Checks if the account is still not registered. |
| * |
| * @param username |
| * the username |
| * @return true, if the account is still not registered |
| */ |
| public boolean isAccountNotRegistered(String username) { |
| if (IUserAccessService.ADMINISTRATOR.equals(username)) { |
| return false; |
| } |
| UserAccountDto user = findUserAccount(username); |
| if (user != null) { |
| return user.getNotRegistered(); |
| } |
| return false; |
| } |
| |
| /** |
| * Checks if is account enabled. |
| * |
| * @param username |
| * the username |
| * @return true, if is account enabled |
| */ |
| public boolean isAccountEnabled(String username) { |
| if (IUserAccessService.ADMINISTRATOR.equals(username)) { |
| return true; |
| } |
| UserAccountDto user = findUserAccount(username); |
| if (user != null) { |
| return user.getEnabled(); |
| } |
| return false; |
| } |
| |
| /** |
| * Lock account. |
| * |
| * @param username |
| * the username |
| * @param locked |
| * the locked |
| */ |
| public void lockAccount(String username, boolean locked) { |
| UserAccountDto user = findUserAccount(username); |
| if (user != null) { |
| user.setLocked(locked); |
| updateUserAccount(user); |
| } |
| } |
| |
| /** |
| * Enable account. |
| * |
| * @param username |
| * the username |
| * @param enabled |
| * the enabled |
| */ |
| public void enableAccount(String username, boolean enabled) { |
| UserAccountDto user = findUserAccount(username); |
| if (user != null) { |
| user.setEnabled(enabled); |
| updateUserAccount(user); |
| } |
| } |
| |
| /** |
| * Sets the cookie hash. |
| * |
| * @param username |
| * the username |
| * @param cookie |
| * the cookie |
| */ |
| public void setCookieHash(String username, String cookie) { |
| UserAccountDto user = findUserAccount(username); |
| if (user != null) { |
| user.setCookieHashCode(hashCodeForCookie(cookie)); |
| updateUserAccount(user); |
| } |
| } |
| |
| /** |
| * Hash code for cookie. |
| * |
| * @param cookie |
| * the cookie |
| * @return the int |
| */ |
| private int hashCodeForCookie(String cookie) { |
| return cookie == null ? 0 : cookie.hashCode(); |
| } |
| |
| /** |
| * Checks if is cookie valid. |
| * |
| * @param username |
| * the username |
| * @param cookie |
| * the cookie |
| * @return true, if is cookie valid |
| */ |
| public boolean isCookieValid(String username, String cookie) { |
| UserAccountDto user = findUserAccount(username); |
| if (user != null) { |
| if (Integer.compareUnsigned(user.getCookieHashCode(), hashCodeForCookie(cookie)) == 0) { |
| LOGGER.debug("cookie is valid"); |
| return true; |
| } else { |
| LOGGER.debug("fraud detected as an invalid cookie was presented. expected:" + user.getCookieHashCode() + " found:" |
| + cookie.hashCode()); |
| return false; |
| } |
| } else { |
| LOGGER.error("user '{}' could not be found", username); |
| return true; |
| } |
| } |
| |
| /** |
| * Checks if is find by user name. |
| * |
| * @return true, if is find by user name |
| */ |
| public boolean isFindByUserName() { |
| return findByUserName; |
| } |
| |
| /** |
| * Gets the persistence service. |
| * |
| * @return the persistence service |
| */ |
| public IPersistenceService getPersistenceService() { |
| return persistenceService; |
| } |
| |
| /** |
| * Gets the persistence id. |
| * |
| * @return the persistence id |
| */ |
| public static String getPersistenceId() { |
| return persistenceId; |
| } |
| |
| /** |
| * Encrypt password. |
| * |
| * @param decryptedPassword |
| * the decrypted password |
| * @return the string |
| */ |
| public String encryptPassword(String decryptedPassword) { |
| return UserProtocol.passwordService.encryptPassword(decryptedPassword); |
| } |
| |
| /** |
| * Encrypt passwords. |
| */ |
| public void encryptPasswords() { |
| Query query = new Query(new LCompare.Equal("enabled", 0)); |
| int size = getDtoUserAccountDtoService().size(query); |
| Collection<UserAccountDto> users = getDtoUserAccountDtoService().getByIndex(0, size, query); |
| for (UserAccountDto user : users) { |
| user.setPassword(encryptPassword(user.getPassword())); |
| user.setEnabled(true); |
| getDtoUserAccountDtoService().update(user); |
| } |
| } |
| |
| /** |
| * Bind persistence service. |
| * |
| * @param persistenceService |
| * the persistence service |
| */ |
| @Reference(cardinality = ReferenceCardinality.MANDATORY, policy = ReferencePolicy.STATIC) |
| public synchronized void bindPersistenceService(final IPersistenceService persistenceService) { |
| this.persistenceService = persistenceService; |
| this.persistenceService.registerPersistenceUnit(persistenceId, getClass()); |
| internalActivate(); |
| LOGGER.debug("UserProtocolPersistenceService bound"); |
| } |
| |
| /** |
| * Unbind persistence service. |
| * |
| * @param persistenceService |
| * the persistence service |
| */ |
| public synchronized void unbindPersistenceService(final IPersistenceService persistenceService) { // NOSONAR |
| this.persistenceService = null; |
| LOGGER.debug("UserProtocolPersistenceService unbound"); |
| } |
| } |