import javax.servlet.http.HttpServletResponse;
import org.argeo.api.NodeConstants;
-import org.argeo.cms.auth.CmsSessionId;
+import org.argeo.api.cms.CmsSessionId;
import org.argeo.cms.auth.HttpRequestCallback;
import org.argeo.cms.auth.HttpRequestCallbackHandler;
import org.osgi.service.useradmin.Authorization;
import javax.servlet.http.HttpServletResponse;
import org.argeo.api.NodeConstants;
-import org.argeo.cms.auth.CmsSessionId;
+import org.argeo.api.cms.CmsSessionId;
import org.argeo.cms.auth.CurrentUser;
import org.argeo.cms.auth.HttpRequestCallback;
import org.argeo.cms.auth.HttpRequestCallbackHandler;
import java.util.Set;
import java.util.TreeSet;
-import org.argeo.cms.auth.CmsSession;
+import org.argeo.api.cms.CmsSession;
import org.osgi.service.useradmin.Authorization;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
--- /dev/null
+package org.argeo.cms.ui.workbench.rap;
+
+import java.util.Locale;
+import java.util.UUID;
+
+import javax.security.auth.Subject;
+import javax.security.auth.login.LoginContext;
+import javax.security.auth.login.LoginException;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.api.NodeConstants;
+import org.argeo.api.cms.CmsImageManager;
+import org.argeo.api.cms.CmsView;
+import org.argeo.api.cms.UxContext;
+import org.argeo.cms.CmsException;
+import org.argeo.cms.auth.CurrentUser;
+import org.argeo.cms.swt.CmsSwtUtils;
+import org.argeo.cms.swt.SimpleSwtUxContext;
+import org.argeo.cms.swt.auth.CmsLogin;
+import org.argeo.cms.swt.auth.CmsLoginShell;
+import org.argeo.eclipse.ui.specific.UiContext;
+import org.eclipse.rap.rwt.RWT;
+import org.eclipse.rap.rwt.application.EntryPoint;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+
+public class LoginEntryPoint implements EntryPoint, CmsView {
+ protected final static String HEADER_WWW_AUTHENTICATE = "WWW-Authenticate";
+ protected final static String HEADER_AUTHORIZATION = "Authorization";
+ private final static Log log = LogFactory.getLog(LoginEntryPoint.class);
+ private LoginContext loginContext;
+ private UxContext uxContext = null;
+ private String uid;
+
+ @Override
+ public int createUI() {
+ uid = UUID.randomUUID().toString();
+ final Display display = createDisplay();
+// UiContext.setData(CmsView.KEY, this);
+
+ CmsLoginShell loginShell = createCmsLoginShell();
+ CmsSwtUtils.registerCmsView(loginShell.getShell(), this);
+ try {
+ // try pre-auth
+ loginContext = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER, loginShell);
+ loginContext.login();
+ } catch (LoginException e) {
+ loginShell.createUi();
+ loginShell.open();
+
+ // HttpServletRequest request = RWT.getRequest();
+ // String authorization = request.getHeader(HEADER_AUTHORIZATION);
+ // if (authorization == null ||
+ // !authorization.startsWith("Negotiate")) {
+ // HttpServletResponse response = RWT.getResponse();
+ // response.setStatus(401);
+ // response.setHeader(HEADER_WWW_AUTHENTICATE, "Negotiate");
+ // response.setDateHeader("Date", System.currentTimeMillis());
+ // response.setDateHeader("Expires", System.currentTimeMillis() +
+ // (24 * 60 * 60 * 1000));
+ // response.setHeader("Accept-Ranges", "bytes");
+ // response.setHeader("Connection", "Keep-Alive");
+ // response.setHeader("Keep-Alive", "timeout=5, max=97");
+ // // response.setContentType("text/html; charset=UTF-8");
+ // }
+
+ while (!loginShell.getShell().isDisposed()) {
+ if (!display.readAndDispatch())
+ display.sleep();
+ }
+ }
+
+ if (CurrentUser.getUsername(getSubject()) == null)
+ return -1;
+ uxContext = new SimpleSwtUxContext();
+ return postLogin();
+ }
+
+ protected Display createDisplay() {
+ return new Display();
+ }
+
+ protected int postLogin() {
+ return 0;
+ }
+
+ protected HttpServletRequest getRequest() {
+ return RWT.getRequest();
+ }
+
+ protected CmsLoginShell createCmsLoginShell() {
+ return new CmsLoginShell(this) {
+
+ @Override
+ public void createContents(Composite parent) {
+ LoginEntryPoint.this.createLoginPage(parent, this);
+ }
+
+ @Override
+ protected void extendsCredentialsBlock(Composite credentialsBlock, Locale selectedLocale,
+ SelectionListener loginSelectionListener) {
+ LoginEntryPoint.this.extendsCredentialsBlock(credentialsBlock, selectedLocale, loginSelectionListener);
+ }
+
+ };
+ }
+
+ /**
+ * To be overridden. CmsLogin#createCredentialsBlock() should be called at some
+ * point in order to create the credentials composite. In order to use the
+ * default layout, call CmsLogin#defaultCreateContents() but <b>not</b>
+ * CmsLogin#createContent(), since it would lead to a stack overflow.
+ */
+ protected void createLoginPage(Composite parent, CmsLogin login) {
+ login.defaultCreateContents(parent);
+ }
+
+ protected void extendsCredentialsBlock(Composite credentialsBlock, Locale selectedLocale,
+ SelectionListener loginSelectionListener) {
+
+ }
+
+ @Override
+ public String getUid() {
+ return uid;
+ }
+
+ @Override
+ public void navigateTo(String state) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void authChange(LoginContext loginContext) {
+ if (loginContext == null)
+ throw new CmsException("Login context cannot be null");
+ // logout previous login context
+ if (this.loginContext != null)
+ try {
+ this.loginContext.logout();
+ } catch (LoginException e1) {
+ log.warn("Could not log out: " + e1);
+ }
+ this.loginContext = loginContext;
+ }
+
+ @Override
+ public void logout() {
+ if (loginContext == null)
+ throw new CmsException("Login context should not bet null");
+ try {
+ CurrentUser.logoutCmsSession(loginContext.getSubject());
+ loginContext.logout();
+ } catch (LoginException e) {
+ throw new CmsException("Cannot log out", e);
+ }
+ }
+
+ @Override
+ public void exception(Throwable e) {
+ // TODO Auto-generated method stub
+
+ }
+
+ // @Override
+ // public LoginContext getLoginContext() {
+ // return loginContext;
+ // }
+
+ protected Subject getSubject() {
+ return loginContext.getSubject();
+ }
+
+ @Override
+ public boolean isAnonymous() {
+ return CurrentUser.isAnonymous(getSubject());
+ }
+
+ public CmsImageManager getImageManager() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public UxContext getUxContext() {
+ return uxContext;
+ }
+}
\ No newline at end of file
import org.argeo.cms.CmsMsg;
import org.argeo.cms.auth.CurrentUser;
import org.argeo.cms.ui.util.CmsUiUtils;
-import org.argeo.cms.ui.util.LoginEntryPoint;
import org.eclipse.rap.rwt.RWT;
import org.eclipse.rap.rwt.client.service.JavaScriptExecutor;
import org.eclipse.swt.SWT;
import org.argeo.cms.CmsMsg;
import org.argeo.cms.auth.CurrentUser;
import org.argeo.cms.ui.util.CmsUiUtils;
-import org.argeo.cms.ui.util.LoginEntryPoint;
import org.eclipse.rap.rwt.RWT;
import org.eclipse.rap.rwt.client.service.JavaScriptExecutor;
import org.eclipse.swt.SWT;
--- /dev/null
+package org.argeo.cms.ui.workbench;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.TrayDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.operation.ModalContext;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.osgi.framework.FrameworkUtil;
+
+/** Base for login dialogs */
+@Deprecated
+public abstract class AbstractLoginDialog extends TrayDialog implements CallbackHandler {
+ private static final long serialVersionUID = -8046708963512717709L;
+
+ private final static Log log = LogFactory.getLog(AbstractLoginDialog.class);
+
+ private Thread modalContextThread = null;
+ boolean processCallbacks = false;
+ boolean isCancelled = false;
+ Callback[] callbackArray;
+
+ protected final Callback[] getCallbacks() {
+ return this.callbackArray;
+ }
+
+ public abstract void internalHandle();
+
+ public boolean isCancelled() {
+ return isCancelled;
+ }
+
+ protected AbstractLoginDialog(Shell parentShell) {
+ super(parentShell);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * javax.security.auth.callback.CallbackHandler#handle(javax.security.auth
+ * .callback.Callback[])
+ */
+ public void handle(final Callback[] callbacks) throws IOException {
+ // clean previous usage
+ if (processCallbacks) {
+ // this handler was already used
+ processCallbacks = false;
+ }
+
+ if (modalContextThread != null) {
+ try {
+ modalContextThread.join(1000);
+ } catch (InterruptedException e) {
+ // silent
+ }
+ modalContextThread = null;
+ }
+
+ // initialize
+ this.callbackArray = callbacks;
+ final Display display = Display.getDefault();
+ display.syncExec(new Runnable() {
+
+ public void run() {
+ isCancelled = false;
+ setBlockOnOpen(false);
+ open();
+
+ final Button okButton = getButton(IDialogConstants.OK_ID);
+ okButton.setText("Login");
+ okButton.addSelectionListener(new SelectionListener() {
+ private static final long serialVersionUID = -200281625679096775L;
+
+ public void widgetSelected(final SelectionEvent event) {
+ processCallbacks = true;
+ }
+
+ public void widgetDefaultSelected(final SelectionEvent event) {
+ // nothing to do
+ }
+ });
+ final Button cancel = getButton(IDialogConstants.CANCEL_ID);
+ cancel.addSelectionListener(new SelectionListener() {
+ private static final long serialVersionUID = -3826030278084915815L;
+
+ public void widgetSelected(final SelectionEvent event) {
+ isCancelled = true;
+ processCallbacks = true;
+ }
+
+ public void widgetDefaultSelected(final SelectionEvent event) {
+ // nothing to do
+ }
+ });
+ }
+ });
+ try {
+ ModalContext.setAllowReadAndDispatch(true); // Works for now.
+ ModalContext.run(new IRunnableWithProgress() {
+
+ public void run(final IProgressMonitor monitor) {
+ modalContextThread = Thread.currentThread();
+ // Wait here until OK or cancel is pressed, then let it rip.
+ // The event
+ // listener
+ // is responsible for closing the dialog (in the
+ // loginSucceeded
+ // event).
+ while (!processCallbacks && (modalContextThread != null)
+ && (modalContextThread == Thread.currentThread())
+ && FrameworkUtil.getBundle(AbstractLoginDialog.class).getBundleContext() != null) {
+ // Note: SecurityUiPlugin.getDefault() != null is false
+ // when the OSGi runtime is shut down
+ try {
+ Thread.sleep(100);
+ // if (display.isDisposed()) {
+ // log.warn("Display is disposed, killing login
+ // dialog thread");
+ // throw new ThreadDeath();
+ // }
+ } catch (final Exception e) {
+ // do nothing
+ }
+ }
+ processCallbacks = false;
+ // Call the adapter to handle the callbacks
+ if (!isCancelled())
+ internalHandle();
+ else
+ // clear callbacks are when cancelling
+ for (Callback callback : callbacks)
+ if (callback instanceof PasswordCallback) {
+ char[] arr = ((PasswordCallback) callback).getPassword();
+ if (arr != null) {
+ Arrays.fill(arr, '*');
+ ((PasswordCallback) callback).setPassword(null);
+ }
+ } else if (callback instanceof NameCallback)
+ ((NameCallback) callback).setName(null);
+ }
+ }, true, new NullProgressMonitor(), Display.getDefault());
+ } catch (ThreadDeath e) {
+ isCancelled = true;
+ log.debug("Thread " + Thread.currentThread().getId() + " died");
+ throw e;
+ } catch (Exception e) {
+ isCancelled = true;
+ IOException ioe = new IOException("Unexpected issue in login dialog, see root cause for more details");
+ ioe.initCause(e);
+ throw ioe;
+ } finally {
+ // so that the modal thread dies
+ processCallbacks = true;
+ // try {
+ // // wait for the modal context thread to gracefully exit
+ // modalContextThread.join();
+ // } catch (InterruptedException ie) {
+ // // silent
+ // }
+ modalContextThread = null;
+ }
+ }
+
+ protected void configureShell(Shell shell) {
+ super.configureShell(shell);
+ shell.setText("Authentication");
+ }
+}
--- /dev/null
+package org.argeo.cms.ui.workbench;
+
+import javax.security.auth.callback.CallbackHandler;
+
+import org.argeo.cms.swt.auth.CompositeCallbackHandler;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+
+/** Default authentication dialog, to be used as {@link CallbackHandler}. */
+@Deprecated
+public class DefaultLoginDialog extends AbstractLoginDialog {
+ private static final long serialVersionUID = -8551827590693035734L;
+
+ public DefaultLoginDialog() {
+ this(Display.getCurrent().getActiveShell());
+ }
+
+ public DefaultLoginDialog(Shell parentShell) {
+ super(parentShell);
+ }
+
+ protected Point getInitialSize() {
+ return new Point(350, 180);
+ }
+
+ @Override
+ protected Control createContents(Composite parent) {
+ Control control = super.createContents(parent);
+ parent.pack();
+
+ // Move the dialog to the center of the top level shell.
+ Rectangle shellBounds;
+ if (Display.getCurrent().getActiveShell() != null) // RCP
+ shellBounds = Display.getCurrent().getActiveShell().getBounds();
+ else
+ shellBounds = Display.getCurrent().getBounds();// RAP
+ Point dialogSize = parent.getSize();
+ int x = shellBounds.x + (shellBounds.width - dialogSize.x) / 2;
+ int y = shellBounds.y + (shellBounds.height - dialogSize.y) / 2;
+ parent.setLocation(x, y);
+ return control;
+ }
+
+ protected Control createDialogArea(Composite parent) {
+ Composite dialogarea = (Composite) super.createDialogArea(parent);
+ CompositeCallbackHandler composite = new CompositeCallbackHandler(
+ dialogarea, SWT.NONE);
+ composite.setLayout(new GridLayout(2, false));
+ composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+ composite.createCallbackHandlers(getCallbacks());
+ return composite;
+ }
+
+ public void internalHandle() {
+ }
+}
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.argeo.cms.CmsException;
-import org.argeo.cms.ui.widgets.auth.DefaultLoginDialog;
import org.eclipse.core.runtime.ILogListener;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import javax.jcr.Session;
import javax.jcr.security.Privilege;
-import org.argeo.cms.ui.useradmin.PickUpUserDialog;
import org.argeo.cms.auth.UserAdminUtils;
+import org.argeo.cms.swt.useradmin.PickUpUserDialog;
import org.argeo.eclipse.ui.EclipseUiException;
import org.argeo.eclipse.ui.EclipseUiUtils;
import org.argeo.jcr.JcrUtils;
import org.argeo.cms.CmsException;
import org.argeo.cms.auth.UserAdminUtils;
import org.argeo.cms.jcr.CmsJcrUtils;
-import org.argeo.cms.ui.util.CmsUiUtils;
+import org.argeo.cms.swt.CmsSwtUtils;
import org.argeo.cms.ui.workbench.CmsWorkbenchStyles;
import org.argeo.cms.ui.workbench.internal.useradmin.SecurityAdminImages;
import org.argeo.cms.ui.workbench.internal.useradmin.UserAdminWrapper;
Text text = toolkit.createText(parent, value, SWT.NONE);
text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
text.setEditable(false);
- CmsUiUtils.style(text, CmsWorkbenchStyles.WORKBENCH_FORM_TEXT);
+ CmsSwtUtils.style(text, CmsWorkbenchStyles.WORKBENCH_FORM_TEXT);
return text;
}
import org.argeo.cms.ui.workbench.internal.useradmin.providers.RoleIconLP;
import org.argeo.cms.ui.workbench.internal.useradmin.providers.UserFilter;
import org.argeo.cms.ui.workbench.internal.useradmin.providers.UserTableDefaultDClickListener;
-import org.argeo.cms.ui.util.CmsUiUtils;
import org.argeo.cms.auth.UserAdminUtils;
+import org.argeo.cms.swt.CmsSwtUtils;
import org.argeo.eclipse.ui.ColumnDefinition;
import org.argeo.eclipse.ui.EclipseUiUtils;
import org.argeo.eclipse.ui.parts.LdifUsersTable;
lbl.setFont(EclipseUiUtils.getBoldFont(parent));
Text text = toolkit.createText(parent, value, SWT.BORDER);
text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
- CmsUiUtils.style(text, CmsWorkbenchStyles.WORKBENCH_FORM_TEXT);
+ CmsSwtUtils.style(text, CmsWorkbenchStyles.WORKBENCH_FORM_TEXT);
return text;
}
Text text = toolkit.createText(parent, value, SWT.NONE);
text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
text.setEditable(false);
- CmsUiUtils.style(text, CmsWorkbenchStyles.WORKBENCH_FORM_TEXT);
+ CmsSwtUtils.style(text, CmsWorkbenchStyles.WORKBENCH_FORM_TEXT);
return text;
}
}
import javax.naming.ldap.LdapName;
+import org.argeo.api.cms.CmsSession;
import org.argeo.cms.CmsException;
-import org.argeo.cms.auth.CmsSession;
import org.argeo.cms.ui.workbench.WorkbenchUiPlugin;
import org.argeo.eclipse.ui.ColumnViewerComparator;
import org.argeo.eclipse.ui.specific.EclipseUiSpecificUtils;
private static final long serialVersionUID = -5234573509093747505L;
public String getText(Object element) {
- return ((CmsSession) element).getAuthorization().toString();
+ return ((CmsSession) element).getDisplayName();
}
public String getToolTipText(Object element) {