/* * Copyright (C) 2007-2012 Argeo GmbH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.argeo.cms.ui.workbench.commands; 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 static org.eclipse.jface.dialogs.IMessageProvider.INFORMATION; import java.security.AccessController; import java.util.Arrays; 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.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.argeo.cms.CmsException; import org.argeo.eclipse.ui.dialogs.ErrorFeedback; import org.argeo.node.security.CryptoKeyring; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.MessageDialog; 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; import org.eclipse.ui.handlers.HandlerUtil; import org.osgi.service.useradmin.User; import org.osgi.service.useradmin.UserAdmin; /** Open the change password dialog */ public class OpenChangePasswordDialog extends AbstractHandler { private final static Log log = LogFactory.getLog(OpenChangePasswordDialog.class); private UserAdmin userAdmin; private UserTransaction userTransaction; private CryptoKeyring keyring = null; public Object execute(ExecutionEvent event) throws ExecutionException { ChangePasswordDialog dialog = new ChangePasswordDialog(HandlerUtil.getActiveShell(event), userAdmin); if (dialog.open() == Dialog.OK) { MessageDialog.openInformation(HandlerUtil.getActiveShell(event), passwordChanged.lead(), passwordChanged.lead()); } return null; } @SuppressWarnings("unchecked") 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) { log.error("Could not roll back", e1); } if (e instanceof RuntimeException) throw (RuntimeException) e; else throw new CmsException("Cannot change password", e); } } class ChangePasswordDialog extends TitleAreaDialog { private static final long serialVersionUID = -6963970583882720962L; private Text oldPassword, newPassword1, newPassword2; public ChangePasswordDialog(Shell parentShell, UserAdmin securityService) { super(parentShell); } 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()); setMessage(changePassword.lead(), INFORMATION); 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()); close(); } 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; } protected void configureShell(Shell shell) { super.configureShell(shell); shell.setText(changePassword.lead()); } } public void setUserAdmin(UserAdmin userAdmin) { this.userAdmin = userAdmin; } public void setUserTransaction(UserTransaction userTransaction) { this.userTransaction = userTransaction; } public void setKeyring(CryptoKeyring keyring) { this.keyring = keyring; } }