/* * Copyright 2011-2012 Amazon Technologies, Inc. * * 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://aws.amazon.com/apache2.0 * * This file 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 com.amazonaws.eclipse.explorer.s3.acls; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.TableEditor; import org.eclipse.swt.events.FocusEvent; import org.eclipse.swt.events.FocusListener; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableItem; import org.eclipse.swt.widgets.Text; import com.amazonaws.eclipse.core.AwsToolkitCore; import com.amazonaws.services.s3.model.AccessControlList; import com.amazonaws.services.s3.model.CanonicalGrantee; import com.amazonaws.services.s3.model.EmailAddressGrantee; import com.amazonaws.services.s3.model.Grant; import com.amazonaws.services.s3.model.Grantee; import com.amazonaws.services.s3.model.GroupGrantee; import com.amazonaws.services.s3.model.Owner; import com.amazonaws.services.s3.model.Permission; /** * Abstract base class providing the framework for object and bucket ACL editing UIs. */ public abstract class EditPermissionsDialog extends Dialog { private Table table; private AccessControlList acl; protected EditPermissionsDialog() { super(Display.getDefault().getActiveShell()); setShellStyle(SWT.DIALOG_TRIM | SWT.RESIZE | SWT.MAX | SWT.APPLICATION_MODAL); } /** * Returns the title to set for the dialog shell. * * @return the title to set for the dialog shell. */ protected abstract String getShellTitle(); /** * Returns a list of PermissionOption objects that describe which S3 * Permissions are applicable for the specific UI provided by a subclass. * * @return a list of PermissionOption objects that describe which S3 * Permissions are applicable for the specific UI provided by a * subclass. */ protected abstract List<PermissionOption> getPermissionOptions(); /** * Returns the S3 ACL to use when initializing the dialog's UI. * * @return the S3 ACL to use when initializing the dialog's UI. */ protected abstract AccessControlList getAcl(); @Override public void create() { super.create(); getShell().setText(getShellTitle()); } @Override protected Control createDialogArea(final Composite parent) { parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); final Composite composite = new Composite(parent, SWT.BORDER); composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); composite.setLayout(new GridLayout()); createPermissionsTable(composite); Composite buttonComposite = new Composite(composite, SWT.NONE); GridLayout buttonCompositeLayout = new GridLayout(2, true); buttonCompositeLayout.horizontalSpacing = 0; buttonCompositeLayout.marginLeft = 0; buttonCompositeLayout.marginWidth = 0; buttonCompositeLayout.marginHeight = 0; buttonComposite.setLayout(buttonCompositeLayout); buttonComposite.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false)); Button addButton = new Button(buttonComposite, SWT.PUSH); GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, false); addButton.setLayoutData(gridData); addButton.setText("Add Grant"); addButton.setImage(AwsToolkitCore.getDefault().getImageRegistry().get(AwsToolkitCore.IMAGE_ADD)); addButton.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { createTableItem(true); } public void widgetDefaultSelected(SelectionEvent e) { widgetSelected(e); } }); Button removeButton = new Button(buttonComposite, SWT.PUSH); removeButton.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); removeButton.setText("Remove Grants"); removeButton.setImage(AwsToolkitCore.getDefault().getImageRegistry().get(AwsToolkitCore.IMAGE_REMOVE)); removeButton.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { List<Integer> selectionIndices = new ArrayList<Integer>(); for (int selectionIndex : table.getSelectionIndices()) { // Skip the first two rows with group permissions if (selectionIndex < 2) continue; selectionIndices.add(selectionIndex); TableItem item = table.getItem(selectionIndex); TableItemData data = (TableItemData)item.getData(); for (Button button : data.checkboxes) button.dispose(); if (data.granteeTextbox != null) data.granteeTextbox.dispose(); } int[] indiciesToRemove = new int[selectionIndices.size()]; for (int i = 0; i < selectionIndices.size(); i++) { indiciesToRemove[i] = selectionIndices.get(i); } table.remove(indiciesToRemove); } public void widgetDefaultSelected(SelectionEvent e) { widgetSelected(e); } }); displayPermissions(); return composite; } public AccessControlList getAccessControlList() { return acl; } @Override public boolean close() { acl = new AccessControlList(); acl.setOwner((Owner)table.getData("owner")); Set<Grant> grants = acl.getGrants(); for (TableItem item : table.getItems()) { TableItemData data = (TableItemData)item.getData(); Grantee grantee = data.grantee; for (Button checkbox : data.checkboxes) { if (checkbox.getSelection()) { Permission permission = (Permission)checkbox.getData(); grants.add(new Grant(grantee, permission)); } } } /* * TODO: We might want to run the S3 setAcl call here in case it * fails with some correctable error, like a non-unique email * address grantee, uknown id, etc. */ return super.close(); } private void createPermissionsTable(Composite composite) { table = new Table(composite, SWT.BORDER | SWT.MULTI); table.setLinesVisible(true); table.setHeaderVisible(true); GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true); layoutData.minimumHeight = 125; table.setLayoutData(layoutData); TableColumn granteeColumn = new TableColumn(table, SWT.NONE); granteeColumn.setWidth(250); granteeColumn.setText("Grantee"); for (PermissionOption permissionOption : getPermissionOptions()) { TableColumn readDataPermissionColumn = new TableColumn(table, SWT.CENTER); readDataPermissionColumn.setWidth(75); readDataPermissionColumn.setText(permissionOption.header); } table.addListener(SWT.MeasureItem, new Listener() { private Point preferredSize; public void handleEvent(Event event) { if (preferredSize == null) { Text text = new Text(table, SWT.BORDER); preferredSize = text.computeSize(SWT.DEFAULT, SWT.DEFAULT); text.dispose(); } event.height = preferredSize.y; } }); table.layout(); } static class PermissionOption { Permission permission; String header; PermissionOption(Permission permission, String header) { this.permission = permission; this.header = header; } } private TableItem createTableItem(boolean withTextEditor) { final TableItem item = new TableItem(table, SWT.NONE); final TableItemData data = new TableItemData(); item.setData(data); if (withTextEditor) { TableEditor editor = new TableEditor(table); final Text granteeText = new Text(table, SWT.BORDER); data.granteeTextbox = granteeText; granteeText.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { String grantee = granteeText.getText(); if (grantee.contains("@")) { data.grantee = new EmailAddressGrantee(grantee); } else { data.grantee = new CanonicalGrantee(grantee); } } }); granteeText.addFocusListener(new FocusListener() { public void focusLost(FocusEvent e) {} public void focusGained(FocusEvent e) { table.setSelection(item); } }); granteeText.setFocus(); editor.grabHorizontal = true; editor.setEditor(granteeText, item, 0); } int column = 1; for (PermissionOption permissionOption : getPermissionOptions()) { TableEditor editor = new TableEditor(table); final Button checkbox = new Button(table, SWT.CHECK); checkbox.setData(permissionOption.permission); Point checkboxSize = checkbox.computeSize(SWT.DEFAULT, table.getItemHeight()); editor.minimumWidth = checkboxSize.x; editor.minimumHeight = checkboxSize.y; editor.setEditor(checkbox, item, column++); data.checkboxes.add(checkbox); } return item; } private void displayPermissions() { AccessControlList startingAcl = getAcl(); table.clearAll(); table.setData("owner", startingAcl.getOwner()); Map<Grantee, Set<Permission>> permissionsByGrantee = new TreeMap<Grantee, Set<Permission>>(new GranteeComparator()); permissionsByGrantee.put(GroupGrantee.AllUsers, new HashSet<Permission>()); permissionsByGrantee.put(GroupGrantee.AuthenticatedUsers, new HashSet<Permission>()); for (Grant grant : startingAcl.getGrants()) { if (permissionsByGrantee.get(grant.getGrantee()) == null) { permissionsByGrantee.put(grant.getGrantee(), new HashSet<Permission>()); } Set<Permission> permissions = permissionsByGrantee.get(grant.getGrantee()); permissions.add(grant.getPermission()); } for (Grantee grantee : permissionsByGrantee.keySet()) { Set<Permission> permissions = permissionsByGrantee.get(grantee); TableItem item = createTableItem(false); TableItemData data = (TableItemData)item.getData(); data.grantee = grantee; item.setText(new String[] {getGranteeDisplayName(grantee), "", ""}); if (permissions.contains(Permission.FullControl)) { for (Button checkbox : data.checkboxes) { checkbox.setSelection(true); } } for (Button checkbox : data.checkboxes) { Permission permission = (Permission)checkbox.getData(); if (permissions.contains(permission)) { checkbox.setSelection(true); } } } } private String getGranteeDisplayName(Grantee grantee) { if (grantee instanceof CanonicalGrantee) { CanonicalGrantee canonicalGrantee = (CanonicalGrantee)grantee; if (canonicalGrantee.getDisplayName() != null) { return canonicalGrantee.getDisplayName(); } } if (grantee instanceof GroupGrantee) { switch ((GroupGrantee)grantee) { case AllUsers: return "All Users"; case AuthenticatedUsers: return "Authenticated Users"; case LogDelivery: return "Log Delivery"; } } return grantee.getIdentifier(); } static class TableItemData { Grantee grantee; List<Button> checkboxes = new ArrayList<Button>(); Text granteeTextbox; } }