/*! * Copyright 2010 - 2017 Pentaho Corporation. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.pentaho.di.repository.pur; import com.sun.jersey.api.client.Client; import com.sun.jersey.api.client.WebResource; import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter; import org.apache.commons.logging.Log; import org.json.JSONException; import org.json.JSONObject; import org.pentaho.di.core.exception.KettleException; import org.pentaho.di.i18n.BaseMessages; import org.pentaho.di.repository.IUser; import org.pentaho.di.repository.pur.model.IEEUser; import org.pentaho.di.repository.pur.model.IRole; import org.pentaho.di.ui.repository.pur.services.IRoleSupportSecurityManager; import org.pentaho.platform.api.engine.security.userroledao.UserRoleInfo; import org.pentaho.platform.security.userrole.ws.IUserRoleListWebService; import org.pentaho.platform.security.userroledao.ws.IUserRoleWebService; import org.pentaho.platform.security.userroledao.ws.ProxyPentahoRole; import org.pentaho.platform.security.userroledao.ws.ProxyPentahoUser; import org.pentaho.platform.security.userroledao.ws.UserRoleException; import org.pentaho.platform.security.userroledao.ws.UserRoleSecurityInfo; import javax.ws.rs.core.MediaType; import java.util.ArrayList; import java.util.List; public class UserRoleDelegate implements java.io.Serializable { private static final long serialVersionUID = 1295309456550391059L; /* EESOURCE: UPDATE SERIALVERUID */ private UserRoleListChangeListenerCollection userRoleListChangeListeners; private final Log logger; IUserRoleWebService userRoleWebService; IUserRoleListWebService userDetailsRoleListWebService; IRoleSupportSecurityManager rsm; UserRoleLookupCache lookupCache; UserRoleSecurityInfo userRoleSecurityInfo; UserRoleInfo userRoleInfo; boolean hasNecessaryPermissions = false; boolean managed = true; public UserRoleDelegate( IRoleSupportSecurityManager rsm, PurRepositoryMeta repositoryMeta, IUser userInfo, Log logger, ServiceManager serviceManager ) { this.logger = logger; String login = userInfo.getLogin(); String password = userInfo.getPassword(); try { this.userDetailsRoleListWebService = serviceManager.createService( login, password, IUserRoleListWebService.class ); this.userRoleWebService = serviceManager.createService( login, password, IUserRoleWebService.class ); this.rsm = rsm; initManaged( repositoryMeta, userInfo ); updateUserRoleInfo(); } catch ( Exception e ) { this.logger.error( BaseMessages.getString( UserRoleDelegate.class, "UserRoleDelegate.ERROR_0001_UNABLE_TO_INITIALIZE_USER_ROLE_WEBSVC" ), e ); //$NON-NLS-1$ } } // package-local constructor for testing purposes UserRoleDelegate( Log logger, IUserRoleListWebService userDetailsRoleListWebService, IUserRoleWebService userRoleWebService ) { this.logger = logger; this.userDetailsRoleListWebService = userDetailsRoleListWebService; this.userRoleWebService = userRoleWebService; } private void initManaged( PurRepositoryMeta repositoryMeta, IUser userInfo ) throws JSONException { String baseUrl = repositoryMeta.getRepositoryLocation().getUrl(); String webService = baseUrl + ( baseUrl.endsWith( "/" ) ? "" : "/" ) + "api/system/authentication-provider"; HTTPBasicAuthFilter authFilter = new HTTPBasicAuthFilter( userInfo.getLogin(), userInfo.getPassword() ); Client client = new Client(); client.addFilter( authFilter ); WebResource resource = client.resource( webService ); String response = resource.accept( MediaType.APPLICATION_JSON_TYPE ).get( String.class ); String provider = new JSONObject( response ).getString( "authenticationType" ); managed = "jackrabbit".equals( provider ); } public void updateUserRoleInfo() throws UserRoleException { if ( isManaged() ) { userRoleSecurityInfo = userRoleWebService.getUserRoleSecurityInfo(); lookupCache = new UserRoleLookupCache( userRoleSecurityInfo, rsm ); hasNecessaryPermissions = true; } else { userRoleInfo = userDetailsRoleListWebService.getUserRoleInfo(); hasNecessaryPermissions = false; } } public boolean isManaged() { return managed; } private void ensureHasPermissions() throws KettleException { if ( !hasNecessaryPermissions ) { throw new KettleException( BaseMessages.getString( UserRoleDelegate.class, "UserRoleDelegate.ERROR_0014_INSUFFICIENT_PRIVILEGES" ) ); //$NON-NLS-1$ } } public void createUser( IUser newUser ) throws KettleException { ensureHasPermissions(); ProxyPentahoUser user = UserRoleHelper.convertToPentahoProxyUser( newUser ); try { ProxyPentahoUser[] existingUsers = userRoleWebService.getUsers(); if ( existsAmong( existingUsers, user ) ) { throw userExistsException(); } } catch ( UserRoleException e ) { throw cannotCreateUserException( newUser, e ); } try { userRoleWebService.createUser( user ); if ( newUser instanceof IEEUser ) { userRoleWebService .setRoles( user, UserRoleHelper.convertToPentahoProxyRoles( ( (IEEUser) newUser ).getRoles() ) ); } lookupCache.insertUserToLookupSet( newUser ); fireUserRoleListChange(); } catch ( Exception e ) { // it is the only way to determine AlreadyExistsException if ( e.getCause().toString().contains( "org.pentaho.platform.api.engine.security.userroledao.AlreadyExistsException" ) ) { throw userExistsException(); } throw cannotCreateUserException( newUser, e ); } } private boolean existsAmong( ProxyPentahoUser[] existing, ProxyPentahoUser user ) { if ( existing != null ) { String name = user.getName(); for ( ProxyPentahoUser pentahoUser : existing ) { if ( name.equals( pentahoUser.getName() ) ) { return true; } } } return false; } private KettleException userExistsException() { return new KettleException( BaseMessages.getString( UserRoleDelegate.class, "UserRoleDelegate.ERROR_0015_USER_NAME_ALREADY_EXISTS" ) ); } private KettleException cannotCreateUserException( IUser user, Exception e ) { return new KettleException( BaseMessages.getString( UserRoleDelegate.class, "UserRoleDelegate.ERROR_0002_UNABLE_TO_CREATE_USER", user.getName() ), e ); } public void deleteUsers( List<IUser> users ) throws KettleException { ensureHasPermissions(); try { userRoleWebService.deleteUsers( UserRoleHelper.convertToPentahoProxyUsers( users ) ); lookupCache.removeUsersFromLookupSet( users ); fireUserRoleListChange(); } catch ( Exception e ) { throw new KettleException( BaseMessages.getString( UserRoleDelegate.class, "UserRoleDelegate.ERROR_0003_UNABLE_TO_DELETE_USERS", e.getLocalizedMessage() ), e ); //$NON-NLS-1$ } } public void deleteUser( String name ) throws KettleException { ensureHasPermissions(); try { ProxyPentahoUser user = userRoleWebService.getUser( name ); if ( user != null ) { ProxyPentahoUser[] users = new ProxyPentahoUser[1]; users[0] = user; userRoleWebService.deleteUsers( users ); fireUserRoleListChange(); } else { throw new KettleException( BaseMessages.getString( UserRoleDelegate.class, "UserRoleDelegate.ERROR_0004_UNABLE_TO_DELETE_USER", name ) ); //$NON-NLS-1$ } } catch ( Exception e ) { throw new KettleException( BaseMessages.getString( UserRoleDelegate.class, "UserRoleDelegate.ERROR_0004_UNABLE_TO_DELETE_USER", name ), e ); //$NON-NLS-1$ } } public void setUsers( List<IUser> users ) throws KettleException { // TODO Figure out what to do here } public IUser getUser( String name, String password ) throws KettleException { ensureHasPermissions(); IUser userInfo = null; try { ProxyPentahoUser user = userRoleWebService.getUser( name ); if ( user != null && user.getName().equals( name ) && user.getPassword().equals( password ) ) { userInfo = UserRoleHelper.convertToUserInfo( user, userRoleWebService.getRolesForUser( user ), rsm ); } } catch ( Exception e ) { throw new KettleException( BaseMessages.getString( UserRoleDelegate.class, "UserRoleDelegate.ERROR_0005_UNABLE_TO_GET_USER", name ), e ); //$NON-NLS-1$ } return userInfo; } public IUser getUser( String name ) throws KettleException { ensureHasPermissions(); IUser userInfo = null; try { ProxyPentahoUser user = userRoleWebService.getUser( name ); if ( user != null && user.getName().equals( name ) ) { userInfo = UserRoleHelper.convertToUserInfo( user, userRoleWebService.getRolesForUser( user ), rsm ); } } catch ( Exception e ) { throw new KettleException( BaseMessages.getString( UserRoleDelegate.class, "UserRoleDelegate.ERROR_0005_UNABLE_TO_GET_USER", name ), e ); //$NON-NLS-1$ } return userInfo; } public List<IUser> getUsers() throws KettleException { try { if ( hasNecessaryPermissions ) { return UserRoleHelper.convertFromProxyPentahoUsers( userRoleSecurityInfo, rsm ); } else { return UserRoleHelper.convertFromNonPentahoUsers( userRoleInfo, rsm ); } } catch ( Exception e ) { throw new KettleException( BaseMessages.getString( UserRoleDelegate.class, "UserRoleDelegate.ERROR_0006_UNABLE_TO_GET_USERS" ), e ); //$NON-NLS-1$ } } public void updateUser( IUser user ) throws KettleException { ensureHasPermissions(); try { ProxyPentahoUser proxyUser = UserRoleHelper.convertToPentahoProxyUser( user ); userRoleWebService.updateUser( proxyUser ); if ( user instanceof IEEUser ) { userRoleWebService.setRoles( proxyUser, UserRoleHelper.convertToPentahoProxyRoles( ( (IEEUser) user ) .getRoles() ) ); } lookupCache.updateUserInLookupSet( user ); fireUserRoleListChange(); } catch ( Exception e ) { throw new KettleException( BaseMessages.getString( UserRoleDelegate.class, "UserRoleDelegate.ERROR_0007_UNABLE_TO_UPDATE_USER", user.getLogin() ), e ); //$NON-NLS-1$ } } public void createRole( IRole newRole ) throws KettleException { ensureHasPermissions(); ProxyPentahoRole role = UserRoleHelper.convertToPentahoProxyRole( newRole ); try { ProxyPentahoRole[] existingRoles = userRoleWebService.getRoles(); if ( existsAmong( existingRoles, role ) ) { throw roleExistsException(); } } catch ( UserRoleException e ) { throw cannotCreateRoleException( newRole, e ); } try { userRoleWebService.createRole( role ); userRoleWebService.setUsers( role, UserRoleHelper.convertToPentahoProxyUsers( newRole.getUsers() ) ); lookupCache.insertRoleToLookupSet( newRole ); fireUserRoleListChange(); } catch ( UserRoleException e ) { throw cannotCreateRoleException( newRole, e ); } catch ( Exception e ) { // it is the only way to determine AlreadyExistsException if ( e.getCause().toString().contains( "org.pentaho.platform.api.engine.security.userroledao.AlreadyExistsException" ) ) { throw roleExistsException(); } } } private boolean existsAmong( ProxyPentahoRole[] existing, ProxyPentahoRole role ) { if ( existing != null ) { String name = role.getName(); for ( ProxyPentahoRole pentahoRole : existing ) { if ( name.equalsIgnoreCase( pentahoRole.getName() ) ) { return true; } } } return false; } private KettleException roleExistsException() { return new KettleException( BaseMessages.getString( UserRoleDelegate.class, "UserRoleDelegate.ERROR_0016_ROLE_NAME_ALREADY_EXISTS" ) ); } private KettleException cannotCreateRoleException( IRole role, Exception e ) { return new KettleException( BaseMessages.getString( UserRoleDelegate.class, "UserRoleDelegate.ERROR_0008_UNABLE_TO_CREATE_ROLE", role.getName() ), e ); } public void deleteRoles( List<IRole> roles ) throws KettleException { ensureHasPermissions(); try { userRoleWebService.deleteRoles( UserRoleHelper.convertToPentahoProxyRoles( roles ) ); lookupCache.removeRolesFromLookupSet( roles ); fireUserRoleListChange(); } catch ( Exception e ) { throw new KettleException( BaseMessages.getString( UserRoleDelegate.class, "UserRoleDelegate.ERROR_0009_UNABLE_TO_DELETE_ROLES" ), e ); //$NON-NLS-1$ } } public IRole getRole( String name ) throws KettleException { ensureHasPermissions(); try { return UserRoleHelper.convertFromProxyPentahoRole( userRoleWebService, UserRoleHelper.getProxyPentahoRole( userRoleWebService, name ), lookupCache, rsm ); } catch ( Exception e ) { throw new KettleException( BaseMessages.getString( UserRoleDelegate.class, "UserRoleDelegate.ERROR_0010_UNABLE_TO_GET_ROLE", name ), e ); //$NON-NLS-1$ } } public List<IRole> getRoles() throws KettleException { try { if ( hasNecessaryPermissions ) { return UserRoleHelper.convertToListFromProxyPentahoRoles( userRoleSecurityInfo, rsm ); } else { return UserRoleHelper.convertToListFromNonPentahoRoles( userRoleInfo, rsm ); } } catch ( Exception e ) { throw new KettleException( BaseMessages.getString( UserRoleDelegate.class, "UserRoleDelegate.ERROR_0011_UNABLE_TO_GET_ROLES" ), e ); //$NON-NLS-1$ } } public List<IRole> getDefaultRoles() throws KettleException { ensureHasPermissions(); try { return UserRoleHelper.convertToListFromProxyPentahoDefaultRoles( userRoleSecurityInfo, rsm ); } catch ( Exception e ) { throw new KettleException( BaseMessages.getString( UserRoleDelegate.class, "UserRoleDelegate.ERROR_0011_UNABLE_TO_GET_ROLES" ), e ); //$NON-NLS-1$ } } public void updateRole( IRole role ) throws KettleException { ensureHasPermissions(); try { List<String> users = new ArrayList<String>(); for ( IUser user : role.getUsers() ) { users.add( user.getLogin() ); } userRoleWebService.updateRole( role.getName(), role.getDescription(), users ); lookupCache.updateRoleInLookupSet( role ); fireUserRoleListChange(); } catch ( Exception e ) { throw new KettleException( BaseMessages.getString( UserRoleDelegate.class, "UserRoleDelegate.ERROR_0012_UNABLE_TO_UPDATE_ROLE", role.getName() ), e ); //$NON-NLS-1$ } } public void deleteRole( String name ) throws KettleException { ensureHasPermissions(); try { ProxyPentahoRole roleToDelete = UserRoleHelper.getProxyPentahoRole( userRoleWebService, name ); if ( roleToDelete != null ) { ProxyPentahoRole[] roleArray = new ProxyPentahoRole[1]; roleArray[0] = roleToDelete; userRoleWebService.deleteRoles( roleArray ); fireUserRoleListChange(); } else { throw new KettleException( BaseMessages.getString( UserRoleDelegate.class, "UserRoleDelegate.ERROR_0013_UNABLE_TO_DELETE_ROLE", name ) ); //$NON-NLS-1$ } } catch ( Exception e ) { throw new KettleException( BaseMessages.getString( UserRoleDelegate.class, "UserRoleDelegate.ERROR_0013_UNABLE_TO_DELETE_ROLE", name ), e ); //$NON-NLS-1$ } } public void setRoles( List<IRole> roles ) throws KettleException { // TODO Figure out what to do here } public void addUserRoleListChangeListener( IUserRoleListChangeListener listener ) { if ( userRoleListChangeListeners == null ) { userRoleListChangeListeners = new UserRoleListChangeListenerCollection(); } userRoleListChangeListeners.add( listener ); } public void removeUserRoleListChangeListener( IUserRoleListChangeListener listener ) { if ( userRoleListChangeListeners != null ) { userRoleListChangeListeners.remove( listener ); } } /** * Fire all current {@link IUserRoleListChangeListener}. */ void fireUserRoleListChange() { if ( userRoleListChangeListeners != null ) { userRoleListChangeListeners.fireOnChange(); } } }