Eclipse 4 change password command
authorMathieu Baudier <mbaudier@argeo.org>
Tue, 13 Nov 2018 13:31:55 +0000 (14:31 +0100)
committerMathieu Baudier <mbaudier@argeo.org>
Tue, 13 Nov 2018 13:31:55 +0000 (14:31 +0100)
org.argeo.cms.e4/src/org/argeo/cms/e4/handlers/ChangePassword.java [new file with mode: 0644]
org.argeo.cms.ui/src/org/argeo/cms/ui/dialogs/CmsMessageDialog.java

diff --git a/org.argeo.cms.e4/src/org/argeo/cms/e4/handlers/ChangePassword.java b/org.argeo.cms.e4/src/org/argeo/cms/e4/handlers/ChangePassword.java
new file mode 100644 (file)
index 0000000..3784093
--- /dev/null
@@ -0,0 +1,138 @@
+package org.argeo.cms.e4.handlers;
+
+import static org.argeo.cms.CmsMsg.changePassword;
+import static org.argeo.cms.CmsMsg.currentPassword;
+import static org.argeo.cms.CmsMsg.newPassword;
+import static org.argeo.cms.CmsMsg.passwordChanged;
+import static org.argeo.cms.CmsMsg.repeatNewPassword;
+
+import java.security.AccessController;
+import java.util.Arrays;
+
+import javax.inject.Inject;
+import javax.naming.InvalidNameException;
+import javax.naming.ldap.LdapName;
+import javax.security.auth.Subject;
+import javax.security.auth.x500.X500Principal;
+import javax.transaction.UserTransaction;
+
+import org.argeo.cms.CmsException;
+import org.argeo.cms.ui.dialogs.CmsMessageDialog;
+import org.argeo.eclipse.ui.dialogs.ErrorFeedback;
+import org.argeo.node.security.CryptoKeyring;
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.jface.dialogs.Dialog;
+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.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.osgi.service.useradmin.User;
+import org.osgi.service.useradmin.UserAdmin;
+
+public class ChangePassword {
+       @Inject
+       private UserAdmin userAdmin;
+       @Inject
+       private UserTransaction userTransaction;
+       @Inject
+       private CryptoKeyring keyring = null;
+
+       @Execute
+       public void execute() {
+               ChangePasswordDialog dialog = new ChangePasswordDialog(Display.getCurrent().getActiveShell(), userAdmin);
+               if (dialog.open() == Dialog.OK) {
+                       new CmsMessageDialog(Display.getCurrent().getActiveShell(), passwordChanged.lead(),
+                                       CmsMessageDialog.INFORMATION).open();
+               }
+       }
+
+       protected void changePassword(char[] oldPassword, char[] newPassword) {
+               Subject subject = Subject.getSubject(AccessController.getContext());
+               String name = subject.getPrincipals(X500Principal.class).iterator().next().toString();
+               LdapName dn;
+               try {
+                       dn = new LdapName(name);
+               } catch (InvalidNameException e) {
+                       throw new CmsException("Invalid user dn " + name, e);
+               }
+               User user = (User) userAdmin.getRole(dn.toString());
+               if (!user.hasCredential(null, oldPassword))
+                       throw new CmsException("Invalid password");
+               if (Arrays.equals(newPassword, new char[0]))
+                       throw new CmsException("New password empty");
+               try {
+                       userTransaction.begin();
+                       user.getCredentials().put(null, newPassword);
+                       if (keyring != null) {
+                               keyring.changePassword(oldPassword, newPassword);
+                               // TODO change secret keys in the CMS session
+                       }
+                       userTransaction.commit();
+               } catch (Exception e) {
+                       try {
+                               userTransaction.rollback();
+                       } catch (Exception e1) {
+                               e1.printStackTrace();
+                       }
+                       if (e instanceof RuntimeException)
+                               throw (RuntimeException) e;
+                       else
+                               throw new CmsException("Cannot change password", e);
+               }
+       }
+
+       class ChangePasswordDialog extends CmsMessageDialog {
+               private Text oldPassword, newPassword1, newPassword2;
+
+               public ChangePasswordDialog(Shell parentShell, UserAdmin securityService) {
+                       super(parentShell, changePassword.lead(), CONFIRM);
+               }
+
+               protected Point getInitialSize() {
+                       return new Point(400, 450);
+               }
+
+               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));
+                       oldPassword = createLP(composite, currentPassword.lead());
+                       newPassword1 = createLP(composite, newPassword.lead());
+                       newPassword2 = createLP(composite, repeatNewPassword.lead());
+
+                       parent.pack();
+                       oldPassword.setFocus();
+                       return composite;
+               }
+
+               @Override
+               protected void okPressed() {
+                       try {
+                               if (!newPassword1.getText().equals(newPassword2.getText()))
+                                       throw new CmsException("New passwords are different");
+                               changePassword(oldPassword.getTextChars(), newPassword1.getTextChars());
+                               closeShell(OK);
+                       } catch (Exception e) {
+                               ErrorFeedback.show("Cannot change password", e);
+                       }
+               }
+
+               /** 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;
+               }
+
+       }
+
+}
index 6e1fc261c2eddb1201a47146f092720011d742c7..21d4792ddb9e4eff83fd02a6f3b3c3490ed10c2c 100644 (file)
@@ -68,15 +68,23 @@ public class CmsMessageDialog extends LightweightDialog {
                        Button cancel = new Button(buttons, SWT.FLAT);
                        cancel.setText(CmsMsg.cancel.lead());
                        cancel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
-                       cancel.addSelectionListener((Selected) (e) -> closeShell(CANCEL));
+                       cancel.addSelectionListener((Selected) (e) -> cancelPressed());
 
                        Button ok = new Button(buttons, SWT.FLAT);
                        ok.setText(CmsMsg.ok.lead());
                        ok.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
-                       ok.addSelectionListener((Selected) (e) -> closeShell(OK));
+                       ok.addSelectionListener((Selected) (e) -> okPressed());
                }
                // pack();
-               return messageLbl;
+               return body;
+       }
+
+       protected void okPressed() {
+               closeShell(OK);
+       }
+
+       protected void cancelPressed() {
+               closeShell(CANCEL);
        }
 
        protected Point getInitialSize() {