/*! * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * Copyright (c) 2002-2013 Pentaho Corporation.. All rights reserved. */ package org.pentaho.pms.ui.security; import java.util.ArrayList; import java.util.List; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.ShellAdapter; import org.eclipse.swt.events.ShellEvent; import org.eclipse.swt.layout.FormAttachment; import org.eclipse.swt.layout.FormData; import org.eclipse.swt.layout.FormLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Dialog; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeItem; import org.pentaho.di.ui.core.PropsUI; import org.pentaho.di.ui.core.gui.WindowProperty; import org.pentaho.di.ui.core.widget.TreeMemory; import org.pentaho.di.ui.trans.step.BaseStepDialog; import org.pentaho.pms.messages.Messages; import org.pentaho.pms.schema.security.SecurityACL; import org.pentaho.pms.schema.security.SecurityOwner; import org.pentaho.pms.schema.security.SecurityReference; import org.pentaho.pms.ui.util.Const; import org.pentaho.pms.ui.util.GUIResource; public class SelectSecurityOwnerRightsDialog extends Dialog { private static final String STRING_SECURITY_TREE = "SecurityTree"; //$NON-NLS-1$ private Button wOK, wCancel; private Listener lsOK, lsCancel; private Shell shell; private SecurityReference securityReference; private Text wFilter; private int rights; private int ownerType; private String ownerName; private boolean ok; private Tree wTree; private boolean firstRefresh; private SecurityOwner owner; public SelectSecurityOwnerRightsDialog(Shell shell, SecurityReference securityReference, SecurityOwner owner, int rights) { super(shell, SWT.NONE); this.securityReference = securityReference; this.owner = owner; this.rights = rights; ok=false; firstRefresh=true; } public boolean open() { PropsUI props = PropsUI.getInstance(); Shell parent = getParent(); Display display = parent.getDisplay(); shell = new Shell(parent, SWT.DIALOG_TRIM | SWT.RESIZE); shell.setBackground(GUIResource.getInstance().getColorBackground()); FormLayout formLayout = new FormLayout (); formLayout.marginWidth = Const.FORM_MARGIN; formLayout.marginHeight = Const.FORM_MARGIN; shell.setLayout(formLayout); shell.setText(Messages.getString("SelectSecurityOwnerRightsDialog.USER_SELECT_OWNER_RIGHTS")); //$NON-NLS-1$ int middle = props.getMiddlePct(); int margin = Const.MARGIN; // Some buttons at the bottom to create a baseline // wOK=new Button(shell, SWT.PUSH); wOK.setText(Messages.getString("General.USER_OK")); //$NON-NLS-1$ wCancel=new Button(shell, SWT.PUSH); wCancel.setText(Messages.getString("General.USER_CANCEL")); //$NON-NLS-1$ BaseStepDialog.positionBottomButtons(shell, new Button[] { wOK, wCancel }, margin, null); // From step line Label wlFilter = new Label(shell, SWT.LEFT); wlFilter.setText(Messages.getString("SelectSecurityOwnerRightsDialog.USER_FILTER")); //$NON-NLS-1$ props.setLook(wlFilter); FormData fdlFilter = new FormData(); fdlFilter.left = new FormAttachment(0, 0); fdlFilter.top = new FormAttachment(0, margin); wlFilter.setLayoutData(fdlFilter); wFilter = new Text(shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER); props.setLook(wFilter); wFilter.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { refreshTree(); } } ); FormData fdFilter = new FormData(); fdFilter.left = new FormAttachment(wlFilter, 2*margin); fdFilter.top = new FormAttachment(0, margin); fdFilter.right= new FormAttachment(100, 0); wFilter.setLayoutData(fdFilter); if (owner!=null) { wFilter.setEnabled(false); } wTree = new Tree(shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER); props.setLook(wTree); FormData fdTree = new FormData(); fdTree.left = new FormAttachment(0, 0); fdTree.top = new FormAttachment(wFilter, margin); fdTree.right = new FormAttachment(middle, 0); fdTree.bottom = new FormAttachment(wOK, -margin); wTree.setLayoutData(fdTree); TreeMemory.addTreeListener(wTree, STRING_SECURITY_TREE); if (owner!=null) { // wTree.setEnabled(false); } Control lastControl = wFilter; final List<Button> checkBoxes = new ArrayList<Button>(); final List<Integer> masks = new ArrayList<Integer>(); for (int i=0;i<securityReference.getAcls().size();i++) { final SecurityACL acl = securityReference.getAcls().get(i); final Button checkBox = new Button(shell, SWT.CHECK); checkBox.setText(acl.getName()); props.setLook(checkBox); FormData fdCheckBox = new FormData(); fdCheckBox.left = new FormAttachment(middle, margin); fdCheckBox.right = new FormAttachment(100, 0); fdCheckBox.top = new FormAttachment(lastControl, margin); checkBox.setLayoutData(fdCheckBox); checkBoxes.add(checkBox); masks.add(new Integer(acl.getMask())); checkBox.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { // The rights: int mask = securityReference.findAcl((((Button)e.widget).getText())).getMask(); rights &= (0xFFFF-mask); // clear the mask if (checkBox.getSelection()) { rights |= mask; // set the mask // Optionally set other the appropriate checkboxes too... for (int ix=0;ix<checkBoxes.size();ix++) { Button b = checkBoxes.get(ix); int checkMask = securityReference.findAcl(b.getText()).getMask(); if ( (mask & checkMask)==checkMask && checkMask!=0) { b.setSelection(checkBox.getSelection()); } } } } } ); if ((rights & acl.getMask())==acl.getMask() && acl.getMask()>0) { checkBox.setSelection(true); } if (acl.getMask()==0) { if (rights==0) { checkBox.setSelection(true); } checkBox.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { for (int ix=0;ix<checkBoxes.size();ix++) { Button b = checkBoxes.get(ix); b.setSelection(false); } checkBox.setSelection(true); rights=0; } } ); } else { checkBox.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { for (int ix=0;ix<checkBoxes.size();ix++) { Button b = checkBoxes.get(ix); int mask = masks.get(ix).intValue(); if (mask==0) b.setSelection(rights==0); } } } ); } lastControl = checkBox; } // Add the "All" button too final Button checkBox = new Button(shell, SWT.PUSH); checkBox.setText(Messages.getString("SelectSecurityOwnerRightsDialog.USER_CHECK_ALL")); //$NON-NLS-1$ props.setLook(checkBox); FormData fdCheckBox = new FormData(); fdCheckBox.left = new FormAttachment(middle, margin); fdCheckBox.top = new FormAttachment(lastControl, margin); checkBox.setLayoutData(fdCheckBox); checkBox.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent arg0) { rights=0; for (int i=0;i<checkBoxes.size();i++) { Button b = checkBoxes.get(i); int mask = masks.get(i).intValue(); b.setSelection(mask!=0); rights|=mask; } } } ); // Add listeners lsCancel = new Listener() { public void handleEvent(Event e) { cancel(); } }; lsOK = new Listener() { public void handleEvent(Event e) { ok(); } }; wOK.addListener (SWT.Selection, lsOK ); wCancel.addListener(SWT.Selection, lsCancel ); // Detect [X] or ALT-F4 or something that kills this window... shell.addShellListener( new ShellAdapter() { public void shellClosed(ShellEvent e) { cancel(); } } ); getData(); WindowProperty winprop = props.getScreen(shell.getText()); if (winprop!=null) winprop.setShell(shell); else shell.pack(); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } return ok; } private boolean filterMatches(String string, String filter) { if (Const.isEmpty(filter)) return true; // no filter set String upperString = string.toUpperCase(); String upperFilter = filter.toUpperCase(); return upperString.indexOf(upperFilter)>=0; } private void refreshTree() { TreeItem[] selection = null; wTree.removeAll(); TreeItem tiUsers = new TreeItem(wTree, SWT.NONE); tiUsers.setText(SecurityOwner.STRING_USER_DESC); if (firstRefresh) { TreeMemory.getInstance().storeExpanded(STRING_SECURITY_TREE, tiUsers, true); } String filter = wFilter.getText(); for (int i=0;i<securityReference.getUsers().size();i++) { String user = securityReference.getUsers().get(i); if (filterMatches(user, filter)) { TreeItem tiUser = new TreeItem(tiUsers, SWT.NONE); tiUser.setText(user); tiUser.setForeground(GUIResource.getInstance().getColorBlue()); if (owner!=null && owner.getOwnerType()==SecurityOwner.OWNER_TYPE_USER && owner.getOwnerName().equals(user)) { selection = new TreeItem[] { tiUser }; } } } TreeItem tiRoles = new TreeItem(wTree, SWT.NONE); tiRoles.setText(SecurityOwner.STRING_ROLE_DESC); if (firstRefresh) { TreeMemory.getInstance().storeExpanded(STRING_SECURITY_TREE, tiRoles, true); } for (int i=0;i<securityReference.getRoles().size();i++) { String role = securityReference.getRoles().get(i); if (filterMatches(role, filter)) { TreeItem tiRole = new TreeItem(tiRoles, SWT.NONE); tiRole.setText(role); tiRole.setForeground(GUIResource.getInstance().getColorBlue()); if (owner!=null && owner.getOwnerType()==SecurityOwner.OWNER_TYPE_ROLE && owner.getOwnerName().equals(role)) { selection = new TreeItem[] { tiRole }; } } } firstRefresh=false; TreeMemory.setExpandedFromMemory(wTree, STRING_SECURITY_TREE); if (selection!=null) { wTree.setSelection(selection); wTree.showSelection(); } } public void dispose() { PropsUI.getInstance().setScreen(new WindowProperty(shell)); shell.dispose(); } /** * Copy information from the meta-data relationshipMeta to the dialog fields. */ public void getData() { refreshTree(); } private void cancel() { ok=false; dispose(); } private void ok() { if (wTree.getSelectionCount()==1) { String[] path = Const.getTreeStrings(wTree.getSelection()[0]); if (path.length==2) { ownerType = SecurityOwner.getOwnerType(path[0]); ownerName = path[1]; ok=true; dispose(); } } } public int getRights() { return rights; } public String getOwnerName() { return ownerName; } public int getOwnerType() { return ownerType; } }