lbl.setText(label);
lbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
Text txt = new Text(parent, SWT.LEAD | SWT.BORDER);
- txt.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false));
+ txt.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+ if (txt != null)
+ txt.addModifyListener(modifyListener);
+ return txt;
+ }
+
+ public static Text createGridLP(Composite parent, String label,
+ ModifyListener modifyListener) {
+ Label lbl = new Label(parent, SWT.LEAD);
+ lbl.setText(label);
+ lbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
+ Text txt = new Text(parent, SWT.LEAD | SWT.BORDER | SWT.PASSWORD);
+ txt.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
if (txt != null)
txt.addModifyListener(modifyListener);
return txt;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
-/** !Generic error dialog to be used in try/catch blocks*/
+/** !Generic error dialog to be used in try/catch blocks */
public class Error extends TitleAreaDialog {
private final static Log log = LogFactory.getLog(Error.class);
private final Throwable exception;
public static void show(String message, Throwable e) {
- new Error(Display.getDefault().getActiveShell(), message, e).open();
+ new Error(Display.getCurrent().getActiveShell(), message, e).open();
}
public static void show(String message) {
- new Error(Display.getDefault().getActiveShell(), message, null).open();
+ new Error(Display.getCurrent().getActiveShell(), message, null).open();
}
public Error(Shell parentShell, String message, Throwable e) {
IMessageProvider.ERROR);
if (exception != null) {
- Text stack = new Text(composite, SWT.MULTI | SWT.LEAD
- | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
+ Text stack = new Text(composite, SWT.MULTI | SWT.LEAD | SWT.BORDER
+ | SWT.V_SCROLL | SWT.H_SCROLL);
stack.setEditable(false);
stack.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
StringWriter sw = new StringWriter();
</property>
</bean>
- <bean id="passwordEncoder"
- class="org.springframework.security.providers.ldap.authenticator.LdapShaPasswordEncoder" />
+ <bean id="passwordEncoder" class="org.argeo.security.ldap.ArgeoLdapShaPasswordEncoder">
+ <property name="useSalt" value="${argeo.ldap.password.useSalt}" />
+ </bean>
<bean id="contextSource"
class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
argeo.ldap.groupBase=ou=Roles
argeo.ldap.groupRoleAttribute=cn
argeo.ldap.groupMemberAttribute=member
+
+argeo.ldap.password.useSalt=false
\ No newline at end of file
NameCallback nameCallback = new NameCallback("User");
PasswordCallback passwordCallback = new PasswordCallback("Password",
false);
- NameCallback urlCallback = new NameCallback("Site URL");
+
+ // NameCallback urlCallback = new NameCallback("Site URL");
if (callbackHandler == null) {
throw new LoginException("No call back handler available");
}
try {
callbackHandler.handle(new Callback[] { label, nameCallback,
- passwordCallback, urlCallback });
+ passwordCallback });
} catch (Exception e) {
LoginException le = new LoginException("Callback handling failed");
le.initCause(e);
if (passwordCallback.getPassword() != null) {
password = String.valueOf(passwordCallback.getPassword());
}
- String url = urlCallback.getName();
+
+ // String url = urlCallback.getName();
// TODO: set it via system properties
String workspace = null;
- // UsernamePasswordAuthenticationToken credentials = new
- // UsernamePasswordAuthenticationToken(
- // username, password);
SiteAuthenticationToken credentials = new SiteAuthenticationToken(
- username, password, url, workspace);
+ username, password, null, workspace);
try {
Authentication authentication = authenticationManager
<bean id="openArgeoUserEditor"
class="org.argeo.security.ui.admin.commands.OpenArgeoUserEditor"
scope="prototype" />
+
<bean id="newArgeoUserEditor" class="org.argeo.security.ui.admin.commands.NewUser"
- scope="prototype" />
+ scope="prototype">
+ <property name="session" ref="nodeSession" />
+ <property name="userDetailsManager" ref="userDetailsManager" />
+ </bean>
+
<bean id="addRole" class="org.argeo.security.ui.admin.commands.AddRole"
scope="prototype">
<property name="userAdminService" ref="userAdminService" />
</bean>
+
<bean id="refreshUsersList" class="org.argeo.security.ui.admin.commands.RefreshUsersList"
scope="prototype" />
</beans>
package org.argeo.security.ui.admin.commands;
+import javax.jcr.Session;
+
import org.argeo.security.ui.admin.wizards.NewUserWizard;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.ui.handlers.HandlerUtil;
+import org.springframework.security.userdetails.UserDetailsManager;
/** Command handler to set visible or open a Argeo user. */
public class NewUser extends AbstractHandler {
+ private Session session;
+ private UserDetailsManager userDetailsManager;
public Object execute(ExecutionEvent event) throws ExecutionException {
try {
- NewUserWizard newUserWizard = new NewUserWizard();
+ NewUserWizard newUserWizard = new NewUserWizard(session,
+ userDetailsManager);
WizardDialog dialog = new WizardDialog(
HandlerUtil.getActiveShell(event), newUserWizard);
dialog.open();
}
return null;
}
+
+ public void setSession(Session session) {
+ this.session = session;
+ }
+
+ public void setUserDetailsManager(UserDetailsManager userDetailsManager) {
+ this.userDetailsManager = userDetailsManager;
+ }
+
}
package org.argeo.security.ui.admin.wizards;
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+
+import org.argeo.ArgeoException;
import org.argeo.eclipse.ui.EclipseUiUtils;
+import org.argeo.jcr.ArgeoNames;
import org.argeo.security.UserAdminService;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Text;
public class MainUserInfoWizardPage extends WizardPage implements
- ModifyListener {
- private Text username, firstName, lastName, primaryEmail;
+ ModifyListener, ArgeoNames {
+ private Text username, firstName, lastName, primaryEmail, password1,
+ password2;
public MainUserInfoWizardPage() {
super("Main");
@Override
public void createControl(Composite parent) {
- parent.setLayout(new FillLayout());
Composite composite = new Composite(parent, SWT.NONE);
composite.setLayout(new GridLayout(2, false));
username = EclipseUiUtils.createGridLT(composite, "Username", this);
primaryEmail = EclipseUiUtils.createGridLT(composite, "Email", this);
firstName = EclipseUiUtils.createGridLT(composite, "First name", this);
lastName = EclipseUiUtils.createGridLT(composite, "Last name", this);
+ password1 = EclipseUiUtils.createGridLP(composite, "Password", this);
+ password2 = EclipseUiUtils.createGridLP(composite, "Repeat password",
+ this);
setControl(composite);
}
return "Specify a first name";
if (lastName.getText().trim().equals(""))
return "Specify a last name";
+ if (password1.getText().trim().equals(""))
+ return "Specify a password";
+ if (password2.getText().trim().equals(""))
+ return "Repeat the password";
+ if (!password2.getText().equals(password1.getText()))
+ return "Passwords are different";
return null;
}
- @Override
- public boolean canFlipToNextPage() {
- // TODO Auto-generated method stub
- return super.canFlipToNextPage();
+ public String getUsername() {
+ return username.getText();
}
- @Override
- public boolean isPageComplete() {
- // TODO Auto-generated method stub
- return super.isPageComplete();
+ public String getPassword() {
+ return password1.getText();
}
+ public void mapToProfileNode(Node up) {
+ try {
+ up.setProperty(ARGEO_PRIMARY_EMAIL, primaryEmail.getText());
+ up.setProperty(ARGEO_FIRST_NAME, firstName.getText());
+ up.setProperty(ARGEO_LAST_NAME, lastName.getText());
+
+ // derived values
+ // TODO add wizard pages to do it
+ up.setProperty(Property.JCR_TITLE, firstName.getText() + " "
+ + lastName.getText());
+ up.setProperty(Property.JCR_DESCRIPTION, "");
+ } catch (RepositoryException e) {
+ throw new ArgeoException("Cannot map to " + up, e);
+ }
+ }
}
package org.argeo.security.ui.admin.wizards;
+import javax.jcr.Node;
+import javax.jcr.Session;
+
+import org.argeo.eclipse.ui.dialogs.Error;
+import org.argeo.jcr.ArgeoNames;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.security.jcr.JcrUserDetails;
import org.eclipse.jface.wizard.Wizard;
+import org.springframework.security.GrantedAuthority;
+import org.springframework.security.userdetails.UserDetailsManager;
+/** Wizard to create a new user */
public class NewUserWizard extends Wizard {
+ private String homeBasePath = "/home";
+ private Session session;
+ private UserDetailsManager userDetailsManager;
+
+ // pages
private MainUserInfoWizardPage mainUserInfo;
+ public NewUserWizard(Session session, UserDetailsManager userDetailsManager) {
+ this.session = session;
+ this.userDetailsManager = userDetailsManager;
+ }
+
@Override
public void addPages() {
mainUserInfo = new MainUserInfoWizardPage();
@Override
public boolean performFinish() {
- return false;
+ try {
+ String username = mainUserInfo.getUsername();
+ Node userHome = JcrUtils.createUserHome(session, homeBasePath,
+ username);
+ Node userProfile = userHome.getNode(ArgeoNames.ARGEO_PROFILE);
+ mainUserInfo.mapToProfileNode(userProfile);
+ String password = mainUserInfo.getPassword();
+ JcrUserDetails jcrUserDetails = new JcrUserDetails(
+ userHome.getPath(), username, password, true, true, true,
+ true, new GrantedAuthority[0]);
+ session.save();
+ userDetailsManager.createUser(jcrUserDetails);
+ return true;
+ } catch (Exception e) {
+ JcrUtils.discardQuietly(session);
+ Error.show("Cannot create new user", e);
+ return false;
+ }
+ }
+
+ public void setSession(Session session) {
+ this.session = session;
}
}
// Full screen, see
// http://dev.eclipse.org/newslists/news.eclipse.technology.rap/msg02697.html
configurer.setShellStyle(SWT.NONE);
- Rectangle bounds = Display.getDefault().getBounds();
+ Rectangle bounds = Display.getCurrent().getBounds();
configurer.setInitialSize(new Point(bounds.width, bounds.height));
}
package org.argeo.security.ui.rap;
+import java.security.Principal;
+
+import javax.security.auth.Subject;
+import javax.security.auth.login.LoginException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.ArgeoException;
+import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.GroupMarker;
+import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.ICoolBarManager;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.action.ToolBarManager;
+import org.eclipse.rwt.RWT;
import org.eclipse.swt.SWT;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction;
import org.eclipse.ui.application.ActionBarAdvisor;
import org.eclipse.ui.application.IActionBarConfigurer;
public class SecureActionBarAdvisor extends ActionBarAdvisor {
- private IWorkbenchAction exitAction;
+ private final static Log log = LogFactory
+ .getLog(SecureActionBarAdvisor.class);
+
+ private IAction logoutAction;
private IWorkbenchAction openPerspectiveDialogAction;
private IWorkbenchAction showViewMenuAction;
private IWorkbenchAction preferences;
private IWorkbenchAction saveAllAction;
private IWorkbenchAction closeAllAction;
- // private final Boolean isRcp;
-
public SecureActionBarAdvisor(IActionBarConfigurer configurer, Boolean isRcp) {
super(configurer);
- // this.isRcp = isRcp;
}
protected void makeActions(IWorkbenchWindow window) {
showViewMenuAction = ActionFactory.SHOW_VIEW_MENU.create(window);
register(showViewMenuAction);
- exitAction = ActionFactory.QUIT.create(window);
- register(exitAction);
+ // logoutAction = ActionFactory.QUIT.create(window);
+
+ Subject subject = null;
+ try {
+ subject = SecureRapActivator.getLoginContext().getSubject();
+ } catch (LoginException e1) {
+ throw new ArgeoException("Cannot retrieve subject", e1);
+ }
+ final Principal principal = subject.getPrincipals().iterator().next();
+
+ logoutAction = new Action() {
+ public String getId() {
+ return SecureRapActivator.ID + ".logoutAction";
+ }
+
+ public String getText() {
+ return "Logout " + principal.getName();
+ }
+
+ public void run() {
+ try {
+ Subject subject = SecureRapActivator.getLoginContext()
+ .getSubject();
+ String subjectStr = subject.toString();
+ SecureRapActivator.getLoginContext().logout();
+ log.info(subjectStr + " logged out");
+ } catch (LoginException e) {
+ log.error("Error when logging out", e);
+ }
+ try {
+ RWT.getRequest().getSession().setMaxInactiveInterval(1);
+ PlatformUI.getWorkbench().close();
+ } catch (Exception e) {
+ if (log.isTraceEnabled())
+ log.trace("Error when invalidating session", e);
+ }
+ }
+
+ };
+ register(logoutAction);
- // Save semantiocs
+ // Save semantics
saveAction = ActionFactory.SAVE.create(window);
register(saveAction);
saveAllAction = ActionFactory.SAVE_ALL.create(window);
fileMenu.add(closeAllAction);
fileMenu.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
fileMenu.add(new Separator());
- fileMenu.add(exitAction);
+ fileMenu.add(logoutAction);
// Edit
editMenu.add(preferences);
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.argeo.eclipse.ui.dialogs.Error;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.rwt.lifecycle.IEntryPoint;
import org.eclipse.rwt.service.SessionStoreEvent;
import org.eclipse.rwt.service.SessionStoreListener;
}
}
- if (subject == null) {
- // IStatus status = new Status(IStatus.ERROR,
- // "org.argeo.security.application", "Login is mandatory",
- // loginException);
- // ErrorDialog.openError(null, "Error", "Shutdown...", status);
- // return status.getSeverity();
-
- // TODO: log as anonymous
- }
-
if (subject != null) {
returnCode = (Integer) Subject.doAs(subject,
getRunAction(display));
return -1;
}
} catch (Exception e) {
- // e.printStackTrace();
- IStatus status = new Status(IStatus.ERROR,
- "org.argeo.security.rcp", "Login failed", e);
- ErrorDialog.openError(null, "Error", "Shutdown...", status);
- return returnCode;
- } finally {
- display.dispose();
- }
+ log.error("Unexpected error",e);
+ return -1;
+ }
+// finally {
+// display.dispose();
+// }
}
@SuppressWarnings("rawtypes")
private PrivilegedAction getRunAction(final Display display) {
return new PrivilegedAction() {
-
public Object run() {
int result = createAndRunWorkbench(display);
return new Integer(result);
public class SecureRapActivator implements BundleActivator {
+ public final static String ID = "org.argeo.security.ui.rap";
public final static String CONTEXT_SPRING = "SPRING";
private static final String JAAS_CONFIG_FILE = "/META-INF/jaas_default.txt";
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jface.dialogs.IDialogConstants;
-import org.eclipse.jface.dialogs.TitleAreaDialog;
+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.widgets.Display;
import org.eclipse.swt.widgets.Shell;
-public abstract class AbstractLoginDialog extends TitleAreaDialog implements
+public abstract class AbstractLoginDialog extends TrayDialog implements
CallbackHandler {
boolean processCallbacks = false;
public class DefaultLoginDialog extends AbstractLoginDialog {
public DefaultLoginDialog() {
- this(Display.getDefault().getActiveShell());
+ this(Display.getCurrent().getActiveShell());
}
protected DefaultLoginDialog(Shell parentShell) {
}
protected Point getInitialSize() {
- return new Point(300, 350);
+ return new Point(300, 150);
}
protected Control createDialogArea(Composite parent) {
dialogMessageType = IMessageProvider.ERROR;
break;
}
- setMessage(callback.getMessage(), dialogMessageType);
+ //setMessage(callback.getMessage(), dialogMessageType);
}
public void internalHandle() {
--- /dev/null
+package org.argeo.security.ldap;
+
+import org.springframework.security.providers.ldap.authenticator.LdapShaPasswordEncoder;
+
+/**
+ * {@link LdapShaPasswordEncoder} allowing to configure the usage of salt (APache
+ * Directory Server 1.0 does not support bind with SSHA)
+ */
+public class ArgeoLdapShaPasswordEncoder extends LdapShaPasswordEncoder {
+ private Boolean useSalt = true;
+
+ @Override
+ public String encodePassword(String rawPass, Object salt) {
+ return super.encodePassword(rawPass, useSalt ? salt : null);
+ }
+
+ public void setUseSalt(Boolean useSalt) {
+ this.useSalt = useSalt;
+ }
+
+}