blob: 853f11902d682a697f22a338b23a345c94be2c58 [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 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.shiro.extensions;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.inject.Inject;
import org.apache.shiro.authc.AccountException;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.PasswordMatcher;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.subject.PrincipalCollection;
import org.eclipse.osbp.authentication.account.dtos.UserAccountDto;
import org.eclipse.osbp.authentication.providerimpl.AuthenticationInformation;
import org.eclipse.osbp.authentication.providerimpl.AuthorizationInformation;
import org.eclipse.osbp.authentication.providerimpl.UserProtocol;
import org.eclipse.osbp.authentication.shiro.extensionsimpl.UserAccessAuthorizationRealm;
import org.eclipse.osbp.jpa.services.Query;
import org.eclipse.osbp.jpa.services.filters.LCompare;
import org.eclipse.osbp.preferences.ProductConfiguration;
import org.eclipse.osbp.ui.api.useraccess.AbstractPosition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The Class DTORealm.
*/
public class DTORealm extends UserAccessAuthorizationRealm {
/** The Constant LOGGER. */
private static final Logger LOGGER = LoggerFactory.getLogger("realm");
/** The dto token. */
private IPortalAuthenticationToken dtoToken = null;
/**
* Instantiates a new DTO realm.
*
* @throws Exception the exception
*/
public DTORealm() throws Exception {
setName(ProductConfiguration.SHIRO_DTO_REALM); // This name must match the name in the User class's getPrincipals() method
// we use shiro's 500.000 iterations salted password
setCredentialsMatcher(new PasswordMatcher());
setAuthorizationCachingEnabled(true);
if (!org.eclipse.osbp.preferences.ProductConfigurationPrefs.SHIRO_DTO_REALM_CLASS.equals(getClass().getCanonicalName())) {
throw new IllegalArgumentException("configuration key in preferences has to be modified");
}
}
/* (non-Javadoc)
* @see org.eclipse.osbp.authentication.shiro.extensionsimpl.UserAccessAuthorizationRealm#doGetAuthorizationInfo(org.apache.shiro.subject.PrincipalCollection)
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(final PrincipalCollection principals) {
//null usernames are invalid
if (principals == null) {
throw new AuthorizationException("PrincipalCollection method argument cannot be null.");
}
final String username = (String) getAvailablePrincipal(principals);
UserAccountDto account = findUserAccount(username);
if (account == null) {
return null;
}
// the positions are linked by the username
AbstractPosition position = findPositionForUser(account.getUserName());
if(position == null) {
return null;
}
return new AuthorizationInformation(
getPortalId(),
principals,
position,
findPermissionsForUser(username));
}
/* (non-Javadoc)
* @see org.eclipse.osbp.authentication.shiro.extensionsimpl.UserAccessAuthorizationRealm#doGetAuthenticationInfo(org.apache.shiro.authc.AuthenticationToken)
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(final AuthenticationToken token) throws AuthenticationException {
dtoToken = (IPortalAuthenticationToken)token;
if (!(token instanceof UsernamePasswordToken)) {
throw new IllegalStateException("Token has to be instance of UsernamePasswordToken class");
}
final UsernamePasswordToken userPassToken = (UsernamePasswordToken) token;
if (userPassToken.getUsername() == null) {
throw new AccountException("Null usernames are not allowed by this realm.");
}
UserAccountDto account = findUserAccount(userPassToken.getUsername());
if (account == null)
throw new UnknownAccountException();
final AuthenticationInformation authenticationInfo = new AuthenticationInformation(account.getUserName(), account.getPassword(), ProductConfiguration.SHIRO_DTO_REALM, account.getEnabled(), account.getLocked());
if ( authenticationInfo.isLocked() ) {
LOGGER.debug("Account {} is locked.", token);
throw new LockedAccountException();
}
if ( ! authenticationInfo.isEnabled() ) {
LOGGER.debug("Account {} is disabled.", token);
throw new DisabledAccountException();
}
dtoToken.setAuthenticatedByRealm(this);
return authenticationInfo;
}
/* (non-Javadoc)
* @see org.apache.shiro.realm.AuthenticatingRealm#setCredentialsMatcher(org.apache.shiro.authc.credential.CredentialsMatcher)
*/
@Override
@Inject
public void setCredentialsMatcher(final CredentialsMatcher credentialsMatcher) {
super.setCredentialsMatcher(credentialsMatcher);
}
/* (non-Javadoc)
* @see org.apache.shiro.realm.AuthenticatingRealm#supports(org.apache.shiro.authc.AuthenticationToken)
*/
@Override
public boolean supports(AuthenticationToken token) {
return token != null && token instanceof IPortalAuthenticationToken &&
getPortalId().equals(((IPortalAuthenticationToken)token).getPortalId());
}
/* (non-Javadoc)
* @see org.eclipse.osbp.authentication.shiro.extensionsimpl.UserAccessAuthorizationRealm#getAllUsers()
*/
@Override
public Set<String> getAllUsers() {
Set<String> retcode = new HashSet<>();
Query query = new Query();
dtoToken.getUserProtocol();
int size = UserProtocol.getDtoUserAccountDtoService().size(query);
dtoToken.getUserProtocol();
Collection<UserAccountDto> users = UserProtocol.getDtoUserAccountDtoService().getByIndex(0, size, query);
for(UserAccountDto user:users) {
if (user.getUserName() != null) {
retcode.add(user.getUserName());
}
}
return retcode;
}
/* (non-Javadoc)
* @see org.eclipse.osbp.authentication.shiro.extensionsimpl.UserAccessAuthorizationRealm#getAllUsersPositions()
*/
@Override
public Map<String,String> getAllUsersPositions() {
Map<String,String> retcode = new HashMap<>();
Query query = new Query();
dtoToken.getUserProtocol();
int size = UserProtocol.getDtoUserAccountDtoService().size(query);
dtoToken.getUserProtocol();
Collection<UserAccountDto> users = UserProtocol.getDtoUserAccountDtoService().getByIndex(0, size, query);
for(UserAccountDto user:users) {
if (user.getUserName() != null) {
retcode.put(user.getUserName(), user.getPosition());
}
}
return retcode;
}
/* (non-Javadoc)
* @see org.eclipse.osbp.authentication.shiro.extensions.IUserAccess#getAllEmails()
*/
@Override
public Set<String> getAllEmails() {
Set<String> retcode = new HashSet<>();
Query query = new Query();
dtoToken.getUserProtocol();
int size = UserProtocol.getDtoUserAccountDtoService().size(query);
dtoToken.getUserProtocol();
Collection<UserAccountDto> users = UserProtocol.getDtoUserAccountDtoService().getByIndex(0, size, query);
for(UserAccountDto user:users) {
if (user.getEmail() != null) {
retcode.add(user.getEmail());
}
}
return retcode;
}
/* (non-Javadoc)
* @see org.eclipse.osbp.authentication.shiro.extensionsimpl.UserAccessAuthorizationRealm#findUserAccount(java.lang.String)
*/
@Override
public UserAccountDto findUserAccount(String username) {
Collection<UserAccountDto> users = null; // NOSONAR
if (ProductConfiguration.getIdentifyByUsername()) {
dtoToken.getUserProtocol();
// try to find by username first
users = UserProtocol.getDtoUserAccountDtoService().find(new Query(new LCompare.Equal("userName", username))); // NOSONAR
}
else {
dtoToken.getUserProtocol();
// try to find by email
users = UserProtocol.getDtoUserAccountDtoService().find(new Query(new LCompare.Equal("email", username)));
}
if (users == null || users.isEmpty() ) {
LOGGER.debug("user account not found");
return null;
}
else if (users.size() > 1) {
LOGGER.error("user account is not unique '{}'- first match taken", username);
}
return users.iterator().next();
}
/* (non-Javadoc)
* @see org.eclipse.osbp.authentication.shiro.extensionsimpl.UserAccessAuthorizationRealm#findUsersForPosition(java.lang.String)
*/
@Override
public Set<String> findUsersForPosition(String orgNode) {
Set<String> retcode = new HashSet<>();
dtoToken.getUserProtocol();
Collection<UserAccountDto> users = UserProtocol.getDtoUserAccountDtoService().find(new Query());
for(UserAccountDto user:users) {
if(orgNode.equals(user.getPosition())) {
retcode.add(user.getUserName());
}
}
return retcode;
}
}