/*****************************************************************************
* Copyright (c) 2008 g-Eclipse Consortium
* 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
*
* Initial development of the original code was made for the
* g-Eclipse project founded by European Union
* project number: FP6-IST-034327 http://www.geclipse.eu/
*
* Contributors:
* Ariel Garcia - initial API and implementation
*****************************************************************************/
package eu.geclipse.ui.dialogs;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.resource.ImageDescriptor;
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.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import eu.geclipse.core.accesscontrol.ActorType;
import eu.geclipse.core.accesscontrol.IACLActor;
import eu.geclipse.core.accesscontrol.IACLCapability;
import eu.geclipse.core.accesscontrol.IACLEntry;
import eu.geclipse.core.accesscontrol.IACLPolicy;
import eu.geclipse.ui.internal.Activator;
import eu.geclipse.ui.widgets.StoredCombo;
/**
* Dialog for editing single ACL entries {@link IACLEntry}.
*
* @author agarcia
*/
public class AccessControlRuleDialog extends Dialog {
/** If <code>true</code> the "OK" button will be relabeled "Save" */
boolean withSaveButton;
/* Dialog widgets */
Combo actorTypeCombo;
private Group entryGroup;
private Combo policyCombo;
private Combo capCombo;
private CertificateComposite actorDNCertComposite;
private CertificateComposite actorCACertComposite;
private FieldComposite groupNameComposite;
private FieldComposite userNameComposite;
private FieldComposite userEmailComposite;
private SAMLComposite samlComposite;
/** The ACL entry to edit */
private IACLEntry entry;
/** The old value of actor type, for updating the dialog correctly */
private ActorType type;
/**
* The constructor.
*
* @param entry the {@link IACLEntry} to edit.
* @param withSaveButton display a "Save" button instead of the "OK" one.
* To be used in the case single ACL entries must be saved separately.
* @param parentShell the parent shell.
*/
protected AccessControlRuleDialog( final IACLEntry entry,
final boolean withSaveButton,
final Shell parentShell )
{
super( parentShell );
setShellStyle( SWT.CLOSE | SWT.TITLE | SWT.BORDER | SWT.APPLICATION_MODAL
| SWT.RESIZE | SWT.MIN | SWT.MAX );
this.withSaveButton = withSaveButton;
this.entry = entry;
this.type = this.entry.getActor().getActorType();
}
/*
* (non-Javadoc)
* @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
*/
@Override
public Control createDialogArea( final Composite parent ) {
GridData gData;
Composite mainComp = new Composite( parent, SWT.NONE );
mainComp.setLayout( new GridLayout( 1, false ) );
gData = new GridData( SWT.FILL, SWT.FILL, true, true );
gData.grabExcessHorizontalSpace = true;
gData.grabExcessVerticalSpace = true;
mainComp.setLayoutData( gData );
this.entryGroup = new Group( mainComp, SWT.NONE );
this.entryGroup.setLayout( new GridLayout( 2, false ) );
this.entryGroup.setText( Messages.getString("AccessControlRuleDialog.group_title") ); //$NON-NLS-1$
gData = new GridData( SWT.FILL, SWT.FILL, true, true );
gData.heightHint = 260;
gData.widthHint = 500;
this.entryGroup.setLayoutData( gData );
createDialogWidgets( this.entryGroup );
// Fill in the policy data
List< String > policyNames = new ArrayList< String >( 5 );
IACLPolicy[] policies = this.entry.getSupportedPolicies();
for ( IACLPolicy policy : policies ) {
String name = policy.toString();
policyNames.add( name != null ? name : "" ); //$NON-NLS-1$
}
this.policyCombo.setItems( policyNames.toArray( new String[ policyNames.size() ] ) );
IACLPolicy policy = this.entry.getPolicy();
if ( policy != null ) {
this.policyCombo.select( this.policyCombo.indexOf( policy.toString() ) );
}
// Fill in the capability data
List< String > capNames = new ArrayList< String >( 5 );
IACLCapability[] capabilities = this.entry.getSupportedCapabilities();
for ( IACLCapability capability : capabilities ) {
String name = capability.getName();
capNames.add( name != null ? name : "" ); //$NON-NLS-1$
}
this.capCombo.setItems( capNames.toArray( new String[ capNames.size() ] ) );
IACLCapability capability = this.entry.getCapability();
if ( capability != null ) {
this.capCombo.select( this.capCombo.indexOf( capability.getName() ) );
}
// Fill in the actor type data
List< String > aTypeNames = new ArrayList< String >( 5 );
IACLActor actor = this.entry.getActor();
assert actor != null
: "Null actor in ACL entry: implementation BUG."; //$NON-NLS-1$
ActorType[] aTypes = actor.getSupportedTypes();
for ( ActorType aType : aTypes ) {
String name = aType.getName();
aTypeNames.add( name != null ? name : "" ); //$NON-NLS-1$
}
this.actorTypeCombo.setItems( aTypeNames.toArray( new String[ aTypeNames.size() ] ) );
ActorType aType = actor.getActorType();
int index = this.actorTypeCombo.indexOf( aType.getName() );
this.actorTypeCombo.select( index );
updateDialogContents( aType );
return mainComp;
}
/*
* (non-Javadoc)
* @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
*/
@Override
protected void configureShell( final Shell shell ) {
super.configureShell( shell );
shell.setText( Messages.getString("AccessControlRuleDialog.dialog_title") ); //$NON-NLS-1$
}
/**
* Create the dialog buttons. We override the superclass' method to be able
* to modify the OK button label if each entry has to be saved individually.
*/
@Override
protected void createButtonsForButtonBar( final Composite parent ) {
// We change just the label of the OK button
String buttonText = null;
if ( this.withSaveButton ) {
buttonText = Messages.getString("AccessControlRuleDialog.save_button_text"); //$NON-NLS-1$
} else {
buttonText = IDialogConstants.OK_LABEL;
}
// TODO reenable when write support is available
Button button;
button = createButton( parent, IDialogConstants.OK_ID,
buttonText, true );
button.setEnabled( false );
createButton( parent, IDialogConstants.CANCEL_ID,
IDialogConstants.CANCEL_LABEL, false );
}
/**
* Helper method to create all the dialog widgets.
*/
private void createDialogWidgets( final Composite group ) {
GridData gData;
// The policy widgets
Label policyLabel = new Label( group, SWT.LEAD );
gData = new GridData( SWT.LEAD, SWT.CENTER, false, false );
policyLabel.setLayoutData( gData );
policyLabel.setText( Messages.getString("AccessControlRuleDialog.policy_label") ); //$NON-NLS-1$
this.policyCombo = new Combo( group, SWT.READ_ONLY | SWT.DROP_DOWN | SWT.LEAD );
gData = new GridData( SWT.FILL, SWT.CENTER, true, false );
this.policyCombo.setLayoutData( gData );
// The capability widgets
Label capLabel = new Label( group, SWT.LEAD );
gData = new GridData( SWT.LEAD, SWT.CENTER, false, false );
capLabel.setLayoutData( gData );
capLabel.setText( Messages.getString("AccessControlRuleDialog.capability_label") ); //$NON-NLS-1$
this.capCombo = new Combo( group, SWT.READ_ONLY | SWT.DROP_DOWN | SWT.LEAD );
gData = new GridData( SWT.FILL, SWT.CENTER, true, false );
this.capCombo.setLayoutData( gData );
// The actor type widgets
Label actorTypeLabel = new Label( group, SWT.LEAD );
gData = new GridData( SWT.LEAD, SWT.CENTER, false, false );
actorTypeLabel.setLayoutData( gData );
actorTypeLabel.setText( Messages.getString("AccessControlRuleDialog.actor_type_label") ); //$NON-NLS-1$
this.actorTypeCombo = new Combo( group, SWT.READ_ONLY | SWT.DROP_DOWN | SWT.LEAD );
gData = new GridData( SWT.FILL, SWT.CENTER, true, false );
this.actorTypeCombo.setLayoutData( gData );
this.actorTypeCombo.addModifyListener( new ModifyListener() {
public void modifyText( final ModifyEvent e ) {
ActorType aType = getSelectedActorType(
AccessControlRuleDialog.this.actorTypeCombo.getText() );
updateDialogContents( aType );
}
} );
// The actor DN composite
this.actorDNCertComposite
= new CertificateComposite( this.entryGroup,
Messages.getString("AccessControlRuleDialog.actor_DN_label") ); //$NON-NLS-1$
gData = new GridData( SWT.FILL, SWT.CENTER, true, false );
gData.horizontalSpan = 2;
this.actorDNCertComposite.setLayoutData( gData );
setVisibility( this.actorDNCertComposite, false );
// The actor CA composite
this.actorCACertComposite
= new CertificateComposite( this.entryGroup,
Messages.getString("AccessControlRuleDialog.signing_CA_label") ); //$NON-NLS-1$
gData = new GridData( SWT.FILL, SWT.CENTER, true, false );
gData.horizontalSpan = 2;
this.actorCACertComposite.setLayoutData( gData );
setVisibility( this.actorCACertComposite, false );
// The group composite
this.groupNameComposite
= new FieldComposite( this.entryGroup,
Messages.getString("AccessControlRuleDialog.group_name_label") ); //$NON-NLS-1$
gData = new GridData( SWT.FILL, SWT.CENTER, true, false );
gData.horizontalSpan = 2;
this.groupNameComposite.setLayoutData( gData );
setVisibility( this.groupNameComposite, false );
// The user composite
this.userNameComposite
= new FieldComposite( this.entryGroup,
Messages.getString("AccessControlRuleDialog.user_name_label") ); //$NON-NLS-1$
gData = new GridData( SWT.FILL, SWT.CENTER, true, false );
gData.horizontalSpan = 2;
this.userNameComposite.setLayoutData( gData );
setVisibility( this.userNameComposite, false );
// The user email composite
this.userEmailComposite
= new FieldComposite( this.entryGroup,
Messages.getString("AccessControlRuleDialog.user_email_label") ); //$NON-NLS-1$
gData = new GridData( SWT.FILL, SWT.CENTER, true, false );
gData.horizontalSpan = 2;
this.userEmailComposite.setLayoutData( gData );
setVisibility( this.userEmailComposite, false );
// The SAML composite
this.samlComposite = new SAMLComposite( this.entryGroup );
gData = new GridData( SWT.FILL, SWT.CENTER, true, false );
gData.horizontalSpan = 2;
gData.exclude = true;
this.samlComposite.setLayoutData( gData );
setVisibility( this.samlComposite, false );
}
/**
* Helper method to update the dialog widgets when the actor type is changed.
*/
void updateDialogContents( final ActorType newType ) {
// Fill in the actor DN data
String actorID = this.entry.getActor().getID();
this.actorDNCertComposite.setDN( actorID != null ? actorID : "" ); //$NON-NLS-1$
// Fill in the actor CA data
String actorCA = this.entry.getActor().getCA();
this.actorCACertComposite.setDN( actorCA != null ? actorCA : "" ); //$NON-NLS-1$
// Make the old widgets invisible
if ( this.type.equals( ActorType.ANYBODY ) ) {
// Nothing to do
} else if ( this.type.equals( ActorType.CA_ANY_DN_ANY ) ) {
// Nothing to do
} else if ( this.type.equals( ActorType.CA_NAME_DN_ANY ) ) {
setVisibility( this.actorCACertComposite, false );
} else if ( this.type.equals( ActorType.CA_NAME_DN_PATTERN ) ) {
//
} else if ( this.type.equals( ActorType.CA_NAME_DN_NAME ) ) {
setVisibility( this.actorDNCertComposite, false );
setVisibility( this.actorCACertComposite, false );
} else if ( this.type.equals( ActorType.GROUP_PATTERN ) ) {
//
} else if ( this.type.equals( ActorType.GROUP_NAME ) ) {
setVisibility( this.groupNameComposite, false );
} else if ( this.type.equals( ActorType.USER_PATTERN ) ) {
//
} else if ( this.type.equals( ActorType.USER_NAME ) ) {
setVisibility( this.userNameComposite, false );
} else if ( this.type.equals( ActorType.USER_EMAIL ) ) {
setVisibility( this.userEmailComposite, false );
} else if ( this.type.equals( ActorType.SAML_ATTRIBUTE ) ) {
setVisibility( this.samlComposite, false );
}
// Make the right widgets visible
if ( newType.equals( ActorType.ANYBODY ) ) {
// Nothing to do
} else if ( newType.equals( ActorType.CA_ANY_DN_ANY ) ) {
// Nothing to do
} else if ( newType.equals( ActorType.CA_NAME_DN_ANY ) ) {
setVisibility( this.actorCACertComposite, true );
} else if ( newType.equals( ActorType.CA_NAME_DN_PATTERN ) ) {
//
} else if ( newType.equals( ActorType.CA_NAME_DN_NAME ) ) {
setVisibility( this.actorDNCertComposite, true );
setVisibility( this.actorCACertComposite, true );
} else if ( newType.equals( ActorType.GROUP_PATTERN ) ) {
//
} else if ( newType.equals( ActorType.GROUP_NAME ) ) {
setVisibility( this.groupNameComposite, true );
} else if ( newType.equals( ActorType.USER_PATTERN ) ) {
//
} else if ( newType.equals( ActorType.USER_NAME ) ) {
setVisibility( this.userNameComposite, true );
} else if ( newType.equals( ActorType.USER_EMAIL ) ) {
setVisibility( this.userEmailComposite, true );
} else if ( newType.equals( ActorType.SAML_ATTRIBUTE ) ) {
setVisibility( this.samlComposite, true );
}
// this.actorDNText.setText();
// this.actorCAText.setText();
this.type = newType;
this.entryGroup.layout();
}
/**
* Helper method to hide or make visible a control.
*/
private void setVisibility( final Control control, final boolean visible ) {
control.setVisible( visible );
( ( GridData ) control.getLayoutData() ).exclude = ! visible;
}
/**
* Helper method to get the selected actorType. May return null if
* the selected type was not found.
*/
ActorType getSelectedActorType( final String selectedItem ) {
ActorType result = null;
IACLActor actor = this.entry.getActor();
ActorType[] aTypes = actor.getSupportedTypes();
for ( ActorType aType : aTypes ) {
String name = aType.getName();
if ( name.equals( selectedItem ) ) {
result = aType;
break;
}
}
return result;
}
/**
* SelectionAdapter used for opening the <code>GridFileDialog</code> when
* selecting a certificate file.
*/
class CertFileSelectionAdapter extends SelectionAdapter {
private Combo widget;
/**
* Constructs a SelectionAdapter for a given combo widget.
*
* @param widget the combo widget where the filename is stored.
*/
public CertFileSelectionAdapter( final Combo widget ) {
super();
this.widget = widget;
}
@Override
public void widgetSelected( final SelectionEvent e ) {
String filename = this.widget.getText();
filename = showFileDialog( filename,
Messages.getString("AccessControlRuleDialog.file_dialog_title" ) ); //$NON-NLS-1$ );
if ( filename != null ) {
this.widget.setText( filename );
}
}
}
/**
* Show a dialog for selecting a file.
*
* @param path the initial path to be set on the dialog.
* @param title the title of the dialog window.
* @return the chosen file or <code>null</code> if "Cancel" was pressed.
*/
protected String showFileDialog( final String path, final String title ) {
String[] filterExtensions = { "*.pem", "*.p12", "*;*.*" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
String[] filterNames = { "Base64 encoded certificate", //$NON-NLS-1$
"PKCS#12 encoded certificate", //$NON-NLS-1$
"All Files" }; //$NON-NLS-1$
FileDialog fileDialog = new FileDialog( getShell(), SWT.OPEN | SWT.SINGLE );
fileDialog.setFilterExtensions( filterExtensions );
fileDialog.setFilterNames( filterNames );
fileDialog.setFileName( path );
fileDialog.setText( title );
String selected = fileDialog.open();
return selected;
}
/**
* A composite holding all the widgets necessary for displaying or entering
* a certificate.
*/
class CertificateComposite extends Composite {
/** The text field displaying the certificate DN */
private Text dnText;
/** The combo-box for selecting the certificate file */
private StoredCombo certFileCombo;
/**
* Constructs a certificate composite with the given parent.
*
* @param parent the parent composite where this collection of widgets should live.
* @param label a string used as a label for the field.
*/
CertificateComposite( final Composite parent, final String label ) {
super( parent, SWT.NONE );
this.setLayout( new GridLayout( 2, false ) );
GridData gData;
URL openFileIcon = Activator.getDefault().getBundle().getEntry( "icons/obj16/open_file.gif" ); //$NON-NLS-1$
Image openFileImage = ImageDescriptor.createFromURL( openFileIcon ).createImage();
// The certificate DN widgets
Label dnLabel = new Label( this, SWT.LEAD );
gData = new GridData( SWT.LEAD, SWT.CENTER, false, false );
dnLabel.setLayoutData( gData );
dnLabel.setText( label );
this.dnText = new Text( this, SWT.READ_ONLY | SWT.LEAD );
gData = new GridData( SWT.FILL, SWT.CENTER, true, false );
this.dnText.setLayoutData( gData );
// The certificate file widgets
Label certFileLabel = new Label( this, SWT.TRAIL);
gData = new GridData( SWT.FILL, SWT.CENTER, false, false );
certFileLabel.setLayoutData( gData );
certFileLabel.setText( Messages.getString("AccessControlRuleDialog.dn_file_label") ); //$NON-NLS-1$
Composite dnComp = new Composite( this, SWT.NONE );
dnComp.setLayout( new GridLayout( 2, false ) );
gData = new GridData( SWT.FILL, SWT.FILL, true, false );
dnComp.setLayoutData( gData );
this.certFileCombo = new StoredCombo( dnComp, SWT.DROP_DOWN | SWT.LEAD );
gData = new GridData( SWT.FILL, SWT.CENTER, true, false );
this.certFileCombo.setLayoutData( gData );
Button dnFileButton = new Button( dnComp, SWT.PUSH );
dnFileButton.setImage( openFileImage );
gData = new GridData();
dnFileButton.setLayoutData( gData );
dnFileButton.setToolTipText(
Messages.getString("AccessControlRuleDialog.dn_file_button_tooltip" ) ); //$NON-NLS-1$
dnFileButton.addSelectionListener( new CertFileSelectionAdapter( this.certFileCombo ) );
}
/**
* Sets the content of the text widget displaying the certificate's DN.
*
* @param text the text string to set.
*/
void setDN( final String text ) {
this.dnText.setText( text );
}
/**
* Returns the content of certificate file combo-box.
*
* @return the path of the certificate file which was selected by the user.
*/
String getCertificateFile() {
return this.certFileCombo.getText();
}
}
/**
* A composite holding a label and a combo-box for entering text.
*/
class FieldComposite extends Composite {
/** The combo-box for entering the data */
private StoredCombo combo;
/**
* Constructs a composite for entering data, with the given parent.
*
* @param parent the parent composite where this collection of widgets should live.
* @param label a string used as a label for the field.
*/
FieldComposite( final Composite parent, final String label ) {
super( parent, SWT.NONE );
this.setLayout( new GridLayout( 2, false ) );
GridData gData;
Label dnLabel = new Label( this, SWT.LEAD );
gData = new GridData( SWT.LEAD, SWT.CENTER, false, false );
dnLabel.setLayoutData( gData );
dnLabel.setText( label );
this.combo = new StoredCombo( this, SWT.DROP_DOWN | SWT.LEAD );
gData = new GridData( SWT.FILL, SWT.CENTER, true, false );
this.combo.setLayoutData( gData );
}
/**
* Sets the content of the data field.
*
* @param text the text string to set.
*/
void setText( final String text ) {
this.combo.setText( text );
}
/**
* Returns the content of the combo-box.
*
* @return the text entered by the user.
*/
String getText() {
return this.combo.getText();
}
}
/**
* A composite holding the widgets necessary for entering a SAML attribute.
*/
class SAMLComposite extends Composite {
/** The SAML attribute composite. */
private FieldComposite samlAttr;
/** The SAML value composite. */
private FieldComposite samlValue;
/**
* Constructs a composite for a SAML attribute, with the given parent.
*
* @param parent the parent composite where this collection of widgets should live.
*/
SAMLComposite( final Composite parent ) {
super( parent, SWT.NONE );
this.setLayout( new GridLayout( 1, false ) );
GridData gData;
this.samlAttr
= new FieldComposite( this,
Messages.getString("AccessControlRuleDialog.SAML_attribute_label") ); //$NON-NLS-1$
gData = new GridData( SWT.FILL, SWT.CENTER, true, false );
this.samlAttr.setLayoutData( gData );
this.samlValue
= new FieldComposite( this,
Messages.getString("AccessControlRuleDialog.SAML_value_label") ); //$NON-NLS-1$
gData = new GridData( SWT.FILL, SWT.CENTER, true, false );
this.samlValue.setLayoutData( gData );
}
/**
* Sets the SAML attribute field.
*
* @param attr the attribute to set.
*/
void setAttribute( final String attr ) {
this.samlAttr.setText( attr );
}
/**
* Sets the SAML value field.
*
* @param value the attribute value to set.
*/
void setValue( final String value ) {
this.samlValue.setText( value );
}
/**
* Returns the SAML attribute field.
*
* @return the attribute entered by the user.
*/
String getAttribute() {
return this.samlAttr.getText();
}
/**
* Returns the SAML attribute value field.
*
* @return the attribute value entered by the user.
*/
String getValue() {
return this.samlValue.getText();
}
}
}