private IWorkbenchAction newWindowAction;
private IWorkbenchAction preferences;
private IWorkbenchAction helpContentAction;
+ private IWorkbenchAction changePassword;
// private IWorkbenchAction aboutAction;
private final Boolean isRcp;
newWindowAction = ActionFactory.OPEN_NEW_WINDOW.create(window);
register(newWindowAction);
}
+
}
protected void fillMenuBar(IMenuManager menuBar) {
scope="prototype">
<property name="securityService" ref="securityService" />
</bean>
+ <bean id="org.argeo.security.ui.openChangePasswordDialog" class="org.argeo.security.ui.commands.OpenChangePasswordDialog"
+ scope="prototype">
+ <property name="securityService" ref="securityService" />
+ </bean>
</beans>
id="org.argeo.security.ui.addRole"
name="AddRole">
</command>
+ <command
+ defaultHandler="org.argeo.eclipse.spring.SpringCommandHandler"
+ id="org.argeo.security.ui.openChangePasswordDialog"
+ name="OpenChangePasswordDialog">
+ </command>
</extension>
<extension
id="menu:org.eclipse.ui.main.menu"
</command>
</toolbar>
</menuContribution>
+ <menuContribution
+ allPopups="false"
+ locationURI="toolbar:org.eclipse.ui.main.toolbar">
+ <toolbar
+ id="org.argeo.security.ui.mainToolbar">
+ <command
+ commandId="org.argeo.security.ui.openChangePasswordDialog"
+ disabledIcon="icons/password.gif"
+ icon="icons/password.gif"
+ label="Change password"
+ style="push"
+ tooltip="Change password">
+ </command>
+ </toolbar>
+ </menuContribution>
</extension>
</plugin>
--- /dev/null
+package org.argeo.security.ui.commands;
+
+import org.argeo.security.ArgeoSecurityService;
+import org.argeo.security.ui.dialogs.ChangePasswordDialog;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+/** Opens the change password dialog. */
+public class OpenChangePasswordDialog extends AbstractHandler {
+ private ArgeoSecurityService securityService;
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ ChangePasswordDialog dialog = new ChangePasswordDialog(
+ HandlerUtil.getActiveShell(event), securityService);
+ dialog.open();
+ return null;
+ }
+
+ public void setSecurityService(ArgeoSecurityService securityService) {
+ this.securityService = securityService;
+ }
+
+}
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.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
// Call the adapter to handle the callbacks
if (!isCancelled())
internalHandle();
+ else
+ // clear callbacks are when cancelling
+ for (Callback callback : callbacks)
+ if (callback instanceof PasswordCallback)
+ ((PasswordCallback) callback).setPassword(null);
+ else if (callback instanceof NameCallback)
+ ((NameCallback) callback).setName(null);
}
}, true, new NullProgressMonitor(), Display.getDefault());
} catch (final Exception e) {
--- /dev/null
+package org.argeo.security.ui.dialogs;
+
+import org.argeo.ArgeoException;
+import org.argeo.security.ArgeoSecurityService;
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.jface.dialogs.TitleAreaDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
+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.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+/** Dialog to change the current user password */
+public class ChangePasswordDialog extends TitleAreaDialog {
+ private Text currentPassword, newPassword1, newPassword2;
+ private ArgeoSecurityService securityService;
+
+ public ChangePasswordDialog(Shell parentShell,
+ ArgeoSecurityService securityService) {
+ super(parentShell);
+ this.securityService = securityService;
+ }
+
+ protected Point getInitialSize() {
+ return new Point(300, 250);
+ }
+
+ protected Control createDialogArea(Composite parent) {
+ Composite dialogarea = (Composite) super.createDialogArea(parent);
+ dialogarea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ Composite composite = new Composite(dialogarea, SWT.NONE);
+ composite.setLayout(new GridLayout(2, false));
+ composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+ currentPassword = createLP(composite, "Current password");
+ newPassword1 = createLP(composite, "New password");
+ newPassword2 = createLP(composite, "Repeat new password");
+
+ setMessage("Change password", IMessageProvider.INFORMATION);
+ parent.pack();
+ return composite;
+ }
+
+ @Override
+ protected void okPressed() {
+ if (!newPassword1.getText().equals(newPassword2.getText()))
+ throw new ArgeoException("Passwords are different");
+ securityService.updateCurrentUserPassword(currentPassword.getText(),
+ newPassword1.getText());
+ close();
+ }
+
+ /** Creates label and password. */
+ protected Text createLP(Composite parent, String label) {
+ new Label(parent, SWT.NONE).setText(label);
+ Text text = new Text(parent, SWT.SINGLE | SWT.LEAD | SWT.PASSWORD
+ | SWT.BORDER);
+ text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+ return text;
+ }
+
+ protected void configureShell(Shell shell) {
+ super.configureShell(shell);
+ shell.setText("Change password");
+ }
+
+}
}
protected Point getInitialSize() {
- return new Point(300, 200);
+ return new Point(300, 250);
}
protected Control createDialogArea(Composite parent) {
Composite dialogarea = (Composite) super.createDialogArea(parent);
- dialogarea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ // dialogarea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,
+ // true));
Composite composite = new Composite(dialogarea, SWT.NONE);
composite.setLayout(new GridLayout(2, false));
- composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
createCallbackHandlers(composite);
+ parent.pack();
return composite;
}
<optional>true</optional>
</dependency>
+<!-- <dependency>-->
+<!-- <groupId>org.apache.commons</groupId>-->
+<!-- <artifactId>com.springsource.org.apache.commons.codec</artifactId>-->
+<!-- </dependency>-->
+
<!-- TEST -->
<dependency>
<groupId>org.junit</groupId>
public ArgeoUser getUserWithPassword(String username);
public String getDefaultRole();
+
+ /** Validates a raw password against an encoded one. */
+ public Boolean isPasswordValid(String encoded, String raw);
+
+ /** Encodes a raw password. */
+ public String encodePassword(String raw);
}
public void updateCurrentUserPassword(String oldPassword, String newPassword) {
SimpleArgeoUser user = new SimpleArgeoUser(getCurrentUser());
- if (!user.getPassword().equals(oldPassword))
+ if (!securityDao.isPasswordValid(user.getPassword(), oldPassword))
throw new ArgeoException("Old password is not correct.");
- user.setPassword(newPassword);
+ user.setPassword(securityDao.encodePassword(newPassword));
securityDao.update(user);
}
import static org.argeo.security.core.ArgeoUserDetails.createSimpleArgeoUser;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;
+import java.util.Random;
import javax.naming.Name;
import javax.naming.NamingException;
import org.springframework.security.ldap.populator.DefaultLdapAuthoritiesPopulator;
import org.springframework.security.ldap.search.FilterBasedLdapUserSearch;
import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
+import org.springframework.security.providers.ldap.authenticator.LdapShaPasswordEncoder;
import org.springframework.security.userdetails.UserDetails;
import org.springframework.security.userdetails.UserDetailsManager;
import org.springframework.security.userdetails.UserDetailsService;
private LdapUserDetailsService ldapUserDetailsService;
private List<UserNatureMapper> userNatureMappers;
+ private LdapShaPasswordEncoder ldapShaPasswordEncoder = new LdapShaPasswordEncoder();
+ private Random random;
+
+ public ArgeoSecurityDaoLdap(BaseLdapPathContextSource contextSource) {
+ this.contextSource = contextSource;
+ ldapTemplate = new LdapTemplate(this.contextSource);
+ try {
+ random = SecureRandom.getInstance("SHA1PRNG");
+ } catch (NoSuchAlgorithmException e) {
+ random = new Random(System.currentTimeMillis());
+ }
+ }
+
public void afterPropertiesSet() throws Exception {
if (usernameMapper == null)
usernameMapper = new DefaultLdapUsernameToDnMapper(userBase,
}
}
- public ArgeoSecurityDaoLdap(BaseLdapPathContextSource contextSource) {
- this.contextSource = contextSource;
- ldapTemplate = new LdapTemplate(this.contextSource);
- }
-
public synchronized void create(ArgeoUser user) {
userDetailsManager.createUser(new ArgeoUserDetails(user));
}
return createSimpleArgeoUser(getDetails(uname));
}
-// public ArgeoUser getCurrentUser() {
-// ArgeoUser argeoUser = ArgeoUserDetails.securityContextUser();
-// if (argeoUser == null)
-// return null;
-// if (argeoUser.getRoles().contains(defaultRole))
-// argeoUser.getRoles().remove(defaultRole);
-// return argeoUser;
-// }
+ // public ArgeoUser getCurrentUser() {
+ // ArgeoUser argeoUser = ArgeoUserDetails.securityContextUser();
+ // if (argeoUser == null)
+ // return null;
+ // if (argeoUser.getRoles().contains(defaultRole))
+ // argeoUser.getRoles().remove(defaultRole);
+ // return argeoUser;
+ // }
@SuppressWarnings("unchecked")
public synchronized List<ArgeoUser> listUsers() {
ldapTemplate.unbind(dn);
}
+ public Boolean isPasswordValid(String encoded, String raw) {
+ return ldapShaPasswordEncoder.isPasswordValid(encoded, raw, null);
+ }
+
+ public String encodePassword(String raw) {
+ byte[] salt = null;
+ // TODO: check that Linux auth supports SSHA
+ // byte[] salt = new byte[16];
+ // random.nextBytes(salt);
+ return ldapShaPasswordEncoder.encodePassword(raw, salt);
+ }
+
protected String convertRoleToGroup(String role) {
String group = role;
if (group.startsWith(rolePrefix)) {