/*! * Copyright 2010 - 2015 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.ui.repository.pur.repositoryexplorer.controller; import java.util.ArrayList; import java.util.Collections; import java.util.EnumSet; import java.util.List; import org.pentaho.di.core.exception.KettleException; import org.pentaho.di.i18n.BaseMessages; import org.pentaho.di.repository.Repository; import org.pentaho.di.ui.repository.pur.repositoryexplorer.IAclObject; import org.pentaho.di.ui.repository.pur.repositoryexplorer.ILockObject; import org.pentaho.di.ui.repository.pur.repositoryexplorer.IUIEEUser; import org.pentaho.di.ui.repository.pur.repositoryexplorer.model.UIRepositoryObjectAcl; import org.pentaho.di.ui.repository.repositoryexplorer.AccessDeniedException; import org.pentaho.di.ui.repository.repositoryexplorer.ContextChangeVetoer; import org.pentaho.di.ui.repository.repositoryexplorer.ControllerInitializationException; import org.pentaho.di.ui.repository.repositoryexplorer.IUISupportController; import org.pentaho.di.ui.repository.repositoryexplorer.controllers.IBrowseController; import org.pentaho.di.ui.repository.repositoryexplorer.model.UIRepositoryContent; import org.pentaho.di.ui.repository.repositoryexplorer.model.UIRepositoryDirectory; import org.pentaho.di.ui.repository.repositoryexplorer.model.UIRepositoryObject; import org.pentaho.platform.api.repository2.unified.RepositoryFilePermission; import org.pentaho.ui.xul.binding.Binding; import org.pentaho.ui.xul.binding.BindingConvertor; import org.pentaho.ui.xul.components.XulCheckbox; import org.pentaho.ui.xul.components.XulLabel; import org.pentaho.ui.xul.containers.XulDeck; /** * * This is the XulEventHandler for the browse panel of the repository explorer. It sets up the bindings for browse * functionality. * */ public class PermissionsController extends AbstractPermissionsController implements ContextChangeVetoer, IUISupportController, java.io.Serializable { private static final long serialVersionUID = -6151060931568671109L; /* EESOURCE: UPDATE SERIALVERUID */ private static final Class<?> PKG = IUIEEUser.class; private static final int NO_ACL = 0; private static final int ACL = 1; private XulDeck aclDeck; private XulCheckbox inheritParentPermissionCheckbox; private XulLabel fileFolderLabel; List<UIRepositoryObject> repoObject = new ArrayList<UIRepositoryObject>(); private IBrowseController browseController; public PermissionsController() { } public List<UIRepositoryObject> getSelectedObjects() { return repoObject; } public void init( Repository rep ) throws ControllerInitializationException { try { super.init( rep ); browseController = (IBrowseController) this.getXulDomContainer().getEventHandler( "browseController" ); browseController.addContextChangeVetoer( this ); createBindings(); } catch ( Exception e ) { throw new ControllerInitializationException( e ); } } protected void createBindings() { super.createBindings(); fileFolderLabel = (XulLabel) document.getElementById( "file-folder-name" );//$NON-NLS-1$ aclDeck = (XulDeck) document.getElementById( "acl-deck" );//$NON-NLS-1$ inheritParentPermissionCheckbox = (XulCheckbox) document.getElementById( "inherit-from-parent-permission-checkbox" );//$NON-NLS-1$ bf.setBindingType( Binding.Type.ONE_WAY ); BindingConvertor<List<UIRepositoryObject>, List<UIRepositoryObjectAcl>> securityBindingConverter = new BindingConvertor<List<UIRepositoryObject>, List<UIRepositoryObjectAcl>>() { @Override public List<UIRepositoryObjectAcl> sourceToTarget( List<UIRepositoryObject> ro ) { if ( ro == null ) { return null; } if ( ro.size() <= 0 ) { return null; } setSelectedRepositoryObject( ro ); if ( !hasManageAclAccess() ) { // disable everything applyAclButton.setDisabled( true ); addAclButton.setDisabled( true ); removeAclButton.setDisabled( true ); inheritParentPermissionCheckbox.setDisabled( true ); manageAclCheckbox.setDisabled( true ); deleteCheckbox.setDisabled( true ); writeCheckbox.setDisabled( true ); readCheckbox.setDisabled( true ); viewAclsModel.setHasManageAclAccess( false ); } else { applyAclButton.setDisabled( false ); inheritParentPermissionCheckbox.setDisabled( false ); viewAclsModel.setHasManageAclAccess( true ); } viewAclsModel.setRemoveEnabled( false ); List<UIRepositoryObjectAcl> selectedAclList = Collections.emptyList(); // we've moved to a new file/folder; need to clear out what the model thinks is selected viewAclsModel.setSelectedAclList( selectedAclList ); permissionsCheckboxHandler.updateCheckboxes( EnumSet.noneOf( RepositoryFilePermission.class ) ); UIRepositoryObject repoObject = ro.get( 0 ); try { if ( repoObject instanceof IAclObject ) { ( (IAclObject) repoObject ).getAcls( viewAclsModel ); } else { throw new IllegalStateException( BaseMessages.getString( PKG, "PermissionsController.NoAclSupport" ) ); //$NON-NLS-1$ } fileFolderLabel .setValue( BaseMessages.getString( PKG, "AclTab.UserRolePermission", repoObject.getName() ) ); //$NON-NLS-1$ bf.setBindingType( Binding.Type.ONE_WAY ); bf.createBinding( viewAclsModel, "acls", userRoleList, "elements" ); //$NON-NLS-1$ //$NON-NLS-2$ updateInheritFromParentPermission(); } catch ( AccessDeniedException ade ) { if ( mainController == null || !mainController.handleLostRepository( ade ) ) { messageBox.setTitle( BaseMessages.getString( PKG, "Dialog.Error" ) );//$NON-NLS-1$ messageBox.setAcceptLabel( BaseMessages.getString( PKG, "Dialog.Ok" ) );//$NON-NLS-1$ messageBox.setMessage( BaseMessages.getString( PKG, "PermissionsController.UnableToGetAcls", repoObject.getName(), ade.getLocalizedMessage() ) );//$NON-NLS-1$ messageBox.open(); } } catch ( Exception e ) { if ( mainController == null || !mainController.handleLostRepository( e ) ) { messageBox.setTitle( BaseMessages.getString( PKG, "Dialog.Error" ) );//$NON-NLS-1$ messageBox.setAcceptLabel( BaseMessages.getString( PKG, "Dialog.Ok" ) );//$NON-NLS-1$ messageBox.setMessage( BaseMessages.getString( PKG, "PermissionsController.UnableToGetAcls", repoObject.getName(), e.getLocalizedMessage() ) ); //$NON-NLS-1$ messageBox.open(); } } aclDeck.setSelectedIndex( ACL ); return viewAclsModel.getAcls(); } @Override public List<UIRepositoryObject> targetToSource( List<UIRepositoryObjectAcl> elements ) { return null; } }; // Binding between the selected repository objects and the user role list for acls securityBinding = bf.createBinding( browseController, "repositoryObjects", userRoleList, "elements", securityBindingConverter );//$NON-NLS-1$ //$NON-NLS-2$ securityBinding = bf.createBinding( browseController, "repositoryDirectories", userRoleList, "elements", securityBindingConverter );//$NON-NLS-1$ //$NON-NLS-2$ bf.setBindingType( Binding.Type.BI_DIRECTIONAL ); // Binding Add Remove button to the inherit check box. If the checkbox is checked that disable add remove bf.createBinding( viewAclsModel, "entriesInheriting", inheritParentPermissionCheckbox, "checked" ); //$NON-NLS-1$ //$NON-NLS-2$ // Setting the default Deck to show no permission aclDeck.setSelectedIndex( NO_ACL ); try { if ( securityBinding != null ) { securityBinding.fireSourceChanged(); } } catch ( Exception e ) { if ( mainController == null || !mainController.handleLostRepository( e ) ) { // convert to runtime exception so it bubbles up through the UI throw new RuntimeException( e ); } } } public void setSelectedRepositoryObject( List<UIRepositoryObject> roList ) { if ( roList != null ) { repoObject.clear(); repoObject.addAll( roList ); } } public String getName() { return "permissionsController";//$NON-NLS-1$ } /** * apply method is called when the user clicks the apply button on the UI */ public void apply() { List<UIRepositoryObject> roList = getSelectedObjects(); /* * if (roList != null && roList.size() == 1 && (roList.get(0) instanceof UIRepositoryDirectory)) { * applyAclConfirmationDialog.show(); } else { */ applyOnObjectOnly( roList, false ); /* } */ } /** * applyOnObjectOnly is called to save acl for a file object only * * @param roList * @param hideDialog */ private void applyOnObjectOnly( List<UIRepositoryObject> roList, boolean hideDialog ) { try { if ( roList.get( 0 ) instanceof UIRepositoryDirectory ) { UIRepositoryDirectory rd = (UIRepositoryDirectory) roList.get( 0 ); if ( rd instanceof IAclObject ) { ( (IAclObject) rd ).setAcls( viewAclsModel ); } else { throw new IllegalStateException( BaseMessages.getString( PKG, "PermissionsController.NoAclSupport" ) ); //$NON-NLS-1$ } } else { UIRepositoryContent rc = (UIRepositoryContent) roList.get( 0 ); if ( rc instanceof ILockObject && ( (ILockObject) rc ).isLocked() ) { messageBox.setTitle( BaseMessages.getString( PKG, "Dialog.Error" ) );//$NON-NLS-1$ messageBox.setAcceptLabel( BaseMessages.getString( PKG, "Dialog.Ok" ) );//$NON-NLS-1$ messageBox.setMessage( BaseMessages.getString( PKG, "PermissionsController.LockedObjectWarning" ) ); //$NON-NLS-1$ messageBox.open(); viewAclsModel.setModelDirty( false ); return; } else if ( rc instanceof IAclObject ) { ( (IAclObject) rc ).setAcls( viewAclsModel ); } else { throw new IllegalStateException( BaseMessages.getString( PKG, "PermissionsController.NoAclSupport" ) ); //$NON-NLS-1$ } } /* * if (hideDialog) { applyAclConfirmationDialog.hide(); } */ viewAclsModel.setModelDirty( false ); messageBox.setTitle( BaseMessages.getString( PKG, "Dialog.Success" ) ); //$NON-NLS-1$ messageBox.setAcceptLabel( BaseMessages.getString( PKG, "Dialog.Ok" ) ); //$NON-NLS-1$ messageBox.setMessage( BaseMessages.getString( PKG, "PermissionsController.PermissionAppliedSuccessfully" ) ); //$NON-NLS-1$ messageBox.open(); } catch ( AccessDeniedException ade ) { /* * if (hideDialog) { applyAclConfirmationDialog.hide(); } */ if ( mainController == null || !mainController.handleLostRepository( ade ) ) { messageBox.setTitle( BaseMessages.getString( PKG, "Dialog.Error" ) ); //$NON-NLS-1$ messageBox.setAcceptLabel( BaseMessages.getString( PKG, "Dialog.Ok" ) ); //$NON-NLS-1$ messageBox.setMessage( ade.getLocalizedMessage() ); messageBox.open(); } } catch ( KettleException kex ) { if ( mainController == null || !mainController.handleLostRepository( kex ) ) { messageBox.setTitle( BaseMessages.getString( PKG, "Dialog.Error" ) ); //$NON-NLS-1$ messageBox.setAcceptLabel( BaseMessages.getString( PKG, "Dialog.Ok" ) ); //$NON-NLS-1$ messageBox.setMessage( kex.getLocalizedMessage() ); messageBox.open(); } } } /* * TODO Once we have the functionality to apply permission recursively to the folder and its children we need to * uncomment the section below * * public void setApplyOnly() { applyOnlyRadioButton.setSelected(true); applyRecursiveRadioButton.setSelected(false); * } * * public void setApplyRecursive() { applyOnlyRadioButton.setSelected(false); * applyRecursiveRadioButton.setSelected(true); } */ /** * applyAcl is called to save the acls back to the repository * * @throws Exception */ public void applyAcl() throws Exception { /* * TODO Once we have the functionality to apply permission recursively to the folder and its children we need to * uncomment the section below * * // We will call the the server apply method that only applies this acls changes on the current object /*if * (applyOnlyRadioButton.isSelected()) { */ List<UIRepositoryObject> roList = getSelectedObjects(); applyOnObjectOnly( roList, true ); /* * } else { // TODO We will call the the server apply method that applies this acls changes on the current object * and its children applyAclConfirmationDialog.hide(); messageBox.setTitle(BaseMessages.getString(PKG, * "Dialog.Error")); //$NON-NLS-1$ messageBox.setAcceptLabel(BaseMessages.getString(PKG, "Dialog.Ok")); * //$NON-NLS-1$ messageBox.setMessage(BaseMessages.getString(PKG, * "PermissionsController.Error.FunctionalityNotSupported")); //$NON-NLS-1$ messageBox.open(); } */ } /* * public void closeApplyAclConfirmationDialog() { applyAclConfirmationDialog.hide(); } */ /* * If the user check or unchecks the inherit from parent checkbox, this method is called. */ public void updateInheritFromParentPermission() throws AccessDeniedException { viewAclsModel.setEntriesInheriting( inheritParentPermissionCheckbox.isChecked() ); if ( inheritParentPermissionCheckbox.isChecked() ) { addAclButton.setDisabled( true ); UIRepositoryObject ro = repoObject.get( 0 ); if ( ro instanceof IAclObject ) { // force inherit to true to get effective ACLs before apply... ( (IAclObject) ro ).clearAcl(); ( (IAclObject) ro ).getAcls( viewAclsModel, true ); } permissionsCheckboxHandler.updateCheckboxes( EnumSet.noneOf( RepositoryFilePermission.class ) ); } else { addAclButton.setDisabled( !hasManageAclAccess() ); permissionsCheckboxHandler.processCheckboxes(); } } @Override protected void updateCheckboxes( UIRepositoryObjectAcl acl ) { permissionsCheckboxHandler.updateCheckboxes( !inheritParentPermissionCheckbox.isChecked() && hasManageAclAccess(), acl.getPermissionSet() ); } }