blob: 25054007a7b83834f4781025c13770295c590f6f [file] [log] [blame]
/*
* Copyright (c) 2013, 2015 Eike Stepper (Berlin, Germany) and others.
* 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
*
* Contributors:
* Christian W. Damus (CEA LIST) - initial API and implementation
*/
package org.eclipse.emf.cdo.security.internal.ui.handlers;
import org.eclipse.emf.cdo.admin.CDOAdminClientRepository;
import org.eclipse.emf.cdo.common.model.CDOPackageRegistryPopulator;
import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.net4j.CDONet4jSession;
import org.eclipse.emf.cdo.net4j.CDONet4jSessionConfiguration;
import org.eclipse.emf.cdo.security.User;
import org.eclipse.emf.cdo.security.internal.ui.editor.CDOSecurityFormEditor;
import org.eclipse.emf.cdo.security.internal.ui.messages.Messages;
import org.eclipse.emf.cdo.security.ui.ISecurityManagementContext;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.ui.CDOEditorInput;
import org.eclipse.emf.cdo.ui.CDOEditorUtil;
import org.eclipse.emf.cdo.view.CDOView;
import org.eclipse.emf.internal.cdo.session.CDOSessionFactory;
import org.eclipse.net4j.util.ObjectUtil;
import org.eclipse.net4j.util.StringUtil;
import org.eclipse.net4j.util.container.IManagedContainer;
import org.eclipse.net4j.util.container.IPluginContainer;
import org.eclipse.net4j.util.security.CredentialsProviderFactory;
import org.eclipse.net4j.util.security.IPasswordCredentialsProvider;
import org.eclipse.net4j.util.security.NotAuthenticatedException;
import org.eclipse.net4j.util.ui.UIUtil;
import org.eclipse.net4j.util.ui.handlers.LongRunningHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IPartListener;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.handlers.HandlerUtil;
import org.eclipse.ui.statushandlers.StatusManager;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
/**
* "Manage Security" command handler, which opens the Security Manager editor
* in the context of the currently selected {@link CDOSession}, with the help
* of an optional {@link ISecurityManagementContext} adapter.
*
* @author Christian W. Damus (CEA LIST)
*/
public class ManageSecurityHandler extends LongRunningHandler
{
private IWorkbenchPart part;
private ISecurityManagementContext context;
private CDOSession session;
public ManageSecurityHandler()
{
}
@Override
protected void extractEventDetails(ExecutionEvent event)
{
super.extractEventDetails(event);
part = HandlerUtil.getActivePart(event);
context = getContext(event);
}
@Override
protected void preRun() throws Exception
{
if (part == null)
{
// No workbench page available in which to open the editor
cancel();
return;
}
setSession(getSession());
if (session != null && !session.isClosed())
{
final IWorkbenchPage page = part.getSite().getPage();
IEditorPart existing = findEditor(page, session);
if (existing != null)
{
// Activate this editor and we're done
cancel();
page.activate(existing);
}
}
}
protected CDOSession getSession()
{
return UIUtil.adaptElement(getSelection(), CDOSession.class);
}
protected void setSession(CDOSession session)
{
this.session = session;
}
@Override
protected void doExecute(IProgressMonitor progressMonitor) throws Exception
{
// Open a new security editor
final CDOView[] view = new CDOView[] { context.connect(session) };
if (view[0] == null || view[0].isClosed())
{
showWarning(Messages.ManageSecurityHandler_0, Messages.ManageSecurityHandler_1);
return;
}
try
{
final CDOResource resource = context.getSecurityResource(view[0]);
if (resource == null)
{
showWarning(Messages.ManageSecurityHandler_0, Messages.ManageSecurityHandler_2);
}
else
{
UIUtil.getDisplay().syncExec(new Runnable()
{
public void run()
{
IEditorInput input = CDOEditorUtil.createCDOEditorInput(view[0], resource.getPath(), false);
try
{
IEditorPart editor = part.getSite().getPage().openEditor(input, CDOSecurityFormEditor.ID);
if (editor != null)
{
hookCloseListener(editor, context, view[0]);
view[0] = null; // Don't disconnect it until later
}
}
catch (PartInitException e)
{
StatusManager.getManager().handle(e.getStatus(), StatusManager.SHOW);
}
}
});
}
}
finally
{
if (view[0] != null)
{
context.disconnect(view[0]);
}
}
}
protected void showWarning(final String title, final String message)
{
UIUtil.getDisplay().syncExec(new Runnable()
{
public void run()
{
MessageDialog.openWarning(part.getSite().getShell(), title, message);
}
});
}
IEditorPart findEditor(IWorkbenchPage page, CDOSession session)
{
for (IEditorReference next : page.getEditorReferences())
{
if (CDOSecurityFormEditor.ID.equals(next.getId()))
{
IEditorPart candidate = next.getEditor(false);
if (candidate != null)
{
IEditorInput input = candidate.getEditorInput();
if (input instanceof CDOEditorInput)
{
CDOView view = ((CDOEditorInput)input).getView();
if (view != null && !view.isClosed() && session.equals(view.getSession()))
{
return candidate;
}
}
}
}
}
return null;
}
ISecurityManagementContext getContext(ExecutionEvent event)
{
ISecurityManagementContext result = null;
IWorkbenchPart part = HandlerUtil.getActivePart(event);
if (part != null)
{
result = part.getAdapter(ISecurityManagementContext.class);
}
if (result == null)
{
result = ISecurityManagementContext.DEFAULT;
}
return result;
}
private void hookCloseListener(final IEditorPart editor, final ISecurityManagementContext context, final CDOView view)
{
final IWorkbenchPage page = editor.getSite().getPage();
page.addPartListener(new IPartListener()
{
private final IEditorInput input = editor.getEditorInput();
private final Set<IEditorPart> openEditors = new java.util.HashSet<IEditorPart>();
{
openEditors.add(editor);
}
public void partClosed(IWorkbenchPart part)
{
openEditors.remove(part);
if (openEditors.isEmpty())
{
// No more editors using this view
context.disconnect(view);
page.removePartListener(this);
}
}
public void partOpened(IWorkbenchPart part)
{
if (part instanceof IEditorPart)
{
IEditorPart editor = (IEditorPart)part;
if (input.equals(editor.getEditorInput()))
{
// The user opened the advanced-mode editor from the form editor
openEditors.add(editor);
}
}
}
public void partDeactivated(IWorkbenchPart part)
{
// Pass
}
public void partBroughtToTop(IWorkbenchPart part)
{
// Pass
}
public void partActivated(IWorkbenchPart part)
{
// Pass
}
});
}
/**
* A specialized handler that gets or creates a session in the context of a repository in the
* CDO Administration view.
*
* @author Christian W. Damus (CEA LIST)
*/
public static class Sessionless extends ManageSecurityHandler implements CDOAdminClientRepository.SessionConfigurator
{
private static final AtomicInteger NEXT_SESSION_NUMBER = new AtomicInteger();
public void prepare(CDONet4jSessionConfiguration configuration)
{
IPasswordCredentialsProvider credentialsProvider = getCredentialsProvider();
configuration.setCredentialsProvider(credentialsProvider);
}
@Override
protected CDOSession getSession()
{
return getExistingAdminSession(getRepository());
}
@Override
protected void doExecute(IProgressMonitor progressMonitor) throws Exception
{
CDOAdminClientRepository repository = getRepository();
CDOSession session = getExistingAdminSession(repository);
if (session == null)
{
session = openSession(getRepository());
setSession(session);
}
if (session != null)
{
super.doExecute(progressMonitor);
}
}
protected CDOAdminClientRepository getRepository()
{
return UIUtil.adaptElement(getSelection(), CDOAdminClientRepository.class);
}
protected CDOSession getExistingAdminSession(CDOAdminClientRepository repository)
{
for (Object element : IPluginContainer.INSTANCE.getElements(CDOSessionFactory.PRODUCT_GROUP))
{
CDONet4jSession session = ObjectUtil.tryCast(element, CDONet4jSession.class);
// If there's no user ID, then the repository doesn't require authentication,
// so we can use that session
if (session != null && !session.isClosed()
&& (User.ADMINISTRATOR.equals(session.getUserID()) || StringUtil.isEmpty(session.getUserID()))
&& ObjectUtil.equals(session.getRepositoryInfo().getUUID(), repository.getUUID()))
{
return session;
}
}
return null;
}
protected CDOSession openSession(CDOAdminClientRepository repository)
{
try
{
CDONet4jSession result = repository.openSession(this);
if (result != null)
{
CDOPackageRegistryPopulator.populate(result.getPackageRegistry());
// Add this session to the shared container so that it may appear in the CDO Sessions view
String description = "session" + NEXT_SESSION_NUMBER.incrementAndGet(); //$NON-NLS-1$
IPluginContainer.INSTANCE.putElement(CDOSessionFactory.PRODUCT_GROUP, "security", description, result); //$NON-NLS-1$
}
return result;
}
catch (NotAuthenticatedException e)
{
// User cancelled authentication
return null;
}
}
protected IPasswordCredentialsProvider getCredentialsProvider()
{
IManagedContainer container = IPluginContainer.INSTANCE;
String productGroup = CredentialsProviderFactory.PRODUCT_GROUP;
String factoryType = "interactive"; //$NON-NLS-1$
IPasswordCredentialsProvider credentialsProvider = (IPasswordCredentialsProvider)container
.getElement(productGroup, factoryType, null);
if (credentialsProvider == null)
{
credentialsProvider = UIUtil.createInteractiveCredentialsProvider();
}
return credentialsProvider;
}
}
}