View Javadoc
1   package org.argeo.cms.e4.handlers;
2   
3   import static org.argeo.cms.CmsMsg.changePassword;
4   import static org.argeo.cms.CmsMsg.currentPassword;
5   import static org.argeo.cms.CmsMsg.newPassword;
6   import static org.argeo.cms.CmsMsg.passwordChanged;
7   import static org.argeo.cms.CmsMsg.repeatNewPassword;
8   
9   import java.util.Arrays;
10  
11  import javax.inject.Inject;
12  import javax.naming.InvalidNameException;
13  import javax.naming.ldap.LdapName;
14  import javax.transaction.UserTransaction;
15  
16  import org.argeo.api.security.CryptoKeyring;
17  import org.argeo.cms.CmsException;
18  import org.argeo.cms.auth.CurrentUser;
19  import org.argeo.cms.ui.dialogs.CmsMessageDialog;
20  import org.argeo.eclipse.ui.dialogs.ErrorFeedback;
21  import org.eclipse.e4.core.di.annotations.Execute;
22  import org.eclipse.e4.core.di.annotations.Optional;
23  import org.eclipse.jface.dialogs.Dialog;
24  import org.eclipse.swt.SWT;
25  import org.eclipse.swt.layout.GridData;
26  import org.eclipse.swt.layout.GridLayout;
27  import org.eclipse.swt.widgets.Composite;
28  import org.eclipse.swt.widgets.Control;
29  import org.eclipse.swt.widgets.Display;
30  import org.eclipse.swt.widgets.Label;
31  import org.eclipse.swt.widgets.Shell;
32  import org.eclipse.swt.widgets.Text;
33  import org.osgi.service.useradmin.User;
34  import org.osgi.service.useradmin.UserAdmin;
35  
36  /** Change the password of the logged-in user. */
37  public class ChangePassword {
38  	@Inject
39  	private UserAdmin userAdmin;
40  	@Inject
41  	private UserTransaction userTransaction;
42  	@Inject
43  	@Optional
44  	private CryptoKeyring keyring = null;
45  
46  	@Execute
47  	public void execute() {
48  		ChangePasswordDialog dialog = new ChangePasswordDialog(Display.getCurrent().getActiveShell(), userAdmin);
49  		if (dialog.open() == Dialog.OK) {
50  			new CmsMessageDialog(Display.getCurrent().getActiveShell(), passwordChanged.lead(),
51  					CmsMessageDialog.INFORMATION).open();
52  		}
53  	}
54  
55  	protected void changePassword(char[] oldPassword, char[] newPassword) {
56  		String name = CurrentUser.getUsername();
57  		LdapName dn;
58  		try {
59  			dn = new LdapName(name);
60  		} catch (InvalidNameException e) {
61  			throw new CmsException("Invalid user dn " + name, e);
62  		}
63  		User user = (User) userAdmin.getRole(dn.toString());
64  		if (!user.hasCredential(null, oldPassword))
65  			throw new CmsException("Invalid password");
66  		if (Arrays.equals(newPassword, new char[0]))
67  			throw new CmsException("New password empty");
68  		try {
69  			userTransaction.begin();
70  			user.getCredentials().put(null, newPassword);
71  			if (keyring != null) {
72  				keyring.changePassword(oldPassword, newPassword);
73  				// TODO change secret keys in the CMS session
74  			}
75  			userTransaction.commit();
76  		} catch (Exception e) {
77  			try {
78  				userTransaction.rollback();
79  			} catch (Exception e1) {
80  				e1.printStackTrace();
81  			}
82  			if (e instanceof RuntimeException)
83  				throw (RuntimeException) e;
84  			else
85  				throw new CmsException("Cannot change password", e);
86  		}
87  	}
88  
89  	class ChangePasswordDialog extends CmsMessageDialog {
90  		private Text oldPassword, newPassword1, newPassword2;
91  
92  		public ChangePasswordDialog(Shell parentShell, UserAdmin securityService) {
93  			super(parentShell, changePassword.lead(), CONFIRM);
94  		}
95  
96  //		protected Point getInitialSize() {
97  //			return new Point(400, 450);
98  //		}
99  
100 		protected Control createDialogArea(Composite parent) {
101 			Composite dialogarea = (Composite) super.createDialogArea(parent);
102 			dialogarea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
103 			Composite composite = new Composite(dialogarea, SWT.NONE);
104 			composite.setLayout(new GridLayout(2, false));
105 			composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
106 			oldPassword = createLP(composite, currentPassword.lead());
107 			newPassword1 = createLP(composite, newPassword.lead());
108 			newPassword2 = createLP(composite, repeatNewPassword.lead());
109 
110 //			parent.pack();
111 			oldPassword.setFocus();
112 			return composite;
113 		}
114 
115 		@Override
116 		protected void okPressed() {
117 			try {
118 				if (!newPassword1.getText().equals(newPassword2.getText()))
119 					throw new CmsException("New passwords are different");
120 				changePassword(oldPassword.getTextChars(), newPassword1.getTextChars());
121 				closeShell(OK);
122 			} catch (Exception e) {
123 				ErrorFeedback.show("Cannot change password", e);
124 			}
125 		}
126 
127 		/** Creates label and password. */
128 		protected Text createLP(Composite parent, String label) {
129 			new Label(parent, SWT.NONE).setText(label);
130 			Text text = new Text(parent, SWT.SINGLE | SWT.LEAD | SWT.PASSWORD | SWT.BORDER);
131 			text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
132 			return text;
133 		}
134 
135 	}
136 
137 }