/* ********************************************************************** ** ** Copyright notice ** ** ** ** (c) 2005-2009 RSSOwl Development Team ** ** http://www.rssowl.org/ ** ** ** ** All rights reserved ** ** ** ** This program and the accompanying materials are made available under ** ** the terms of the Eclipse Public License v1.0 which accompanies this ** ** distribution, and is available at: ** ** http://www.rssowl.org/legal/epl-v10.html ** ** ** ** The algorithm to measure the strength of the master password was ** ** taken from the Firefox sourcecode and is licensed under the Mozilla ** ** Public License (MPL). ** ** ** ** A copy is found in the file epl-v10.html and important notices to the ** ** license from the team is found in the textfile LICENSE.txt distributed ** ** in this package. ** ** ** ** This copyright notice MUST APPEAR in all copies of the file! ** ** ** ** Contributors: ** ** RSSOwl Development Team - initial API and implementation ** ** ** ** ********************************************************************** */ package org.rssowl.ui.internal.dialogs; import org.eclipse.equinox.security.storage.provider.PasswordProvider; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.IMessageProvider; import org.eclipse.jface.dialogs.TitleAreaDialog; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.resource.LocalResourceManager; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.ProgressBar; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import org.rssowl.ui.internal.OwlUI; import org.rssowl.ui.internal.util.LayoutUtils; /** * Dialog to ask for the master password used to encrypt credentials. Supports a * mode to create a new master password and to ask for an existing one. * * @author bpasero */ @SuppressWarnings("restriction") public class MasterPasswordDialog extends TitleAreaDialog { private final LocalResourceManager fResources; private Text fPassword; private Text fPasswordConfirmed; private String fPasswordValue; private final int fStyle; private ProgressBar fQualityBar; /** * @param parentShell * @param style */ public MasterPasswordDialog(Shell parentShell, int style) { super(parentShell); fStyle = style; fResources = new LocalResourceManager(JFaceResources.getResources()); } /** * @return the master password or <code>null</code> if none. */ public String getMasterPassword() { return fPasswordValue; } /* * @see org.eclipse.jface.dialogs.TitleAreaDialog#close() */ @Override public boolean close() { fResources.dispose(); return super.close(); } /* * @see org.eclipse.jface.dialogs.Dialog#buttonPressed(int) */ @Override protected void buttonPressed(int buttonId) { /* User pressed OK Button */ if (buttonId == IDialogConstants.OK_ID) fPasswordValue = fPassword.getText(); super.buttonPressed(buttonId); } /* * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell) */ @Override protected void configureShell(Shell shell) { super.configureShell(shell); if ((fStyle & PasswordProvider.CREATE_NEW_PASSWORD) != 0) shell.setText(Messages.MasterPasswordDialog_ENTER_MASTER_PASSWORD_TITLE); else shell.setText(Messages.MasterPasswordDialog_ENTER_MASTER_PASSWORD); } /* * @see org.eclipse.jface.dialogs.Dialog#create() */ @Override public void create() { super.create(); if ((fStyle & PasswordProvider.CREATE_NEW_PASSWORD) != 0) getButton(IDialogConstants.OK_ID).setEnabled(false); } /* * @see org.eclipse.jface.dialogs.TitleAreaDialog#createDialogArea(org.eclipse.swt.widgets.Composite) */ @Override protected Control createDialogArea(Composite parent) { /* Separator */ new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL).setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false)); /* Composite to hold all components */ Composite composite = new Composite(parent, SWT.NONE); composite.setLayout(LayoutUtils.createGridLayout(2, 5, 10)); composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); /* Title */ setTitle(Messages.MasterPasswordDialog_MASTER_PASSWORD); /* Title Image */ if ((fStyle & PasswordProvider.CREATE_NEW_PASSWORD) != 0) { setTitleImage(OwlUI.getImage(fResources, "icons/wizban/new_value_wiz.png")); //$NON-NLS-1$ setMessage(Messages.MasterPasswordDialog_REMEMBER_PASSWORD, IMessageProvider.WARNING); } else { setTitleImage(OwlUI.getImage(fResources, "icons/wizban/login_wiz.png")); //$NON-NLS-1$ setMessage(Messages.MasterPasswordDialog_MASTER_PASSWORD_INFO, IMessageProvider.INFORMATION); } /* Username Label */ Label passwordLabel = new Label(composite, SWT.NONE); passwordLabel.setText(Messages.MasterPasswordDialog_PASSWORD); passwordLabel.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, true)); /* Password input field */ fPassword = new Text(composite, SWT.SINGLE | SWT.BORDER | SWT.PASSWORD); fPassword.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true)); fPassword.setFocus(); if ((fStyle & PasswordProvider.CREATE_NEW_PASSWORD) != 0) { fPassword.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { boolean enabled = fPassword.getText().equals(fPasswordConfirmed.getText()) && fPassword.getText().length() > 0; getButton(IDialogConstants.OK_ID).setEnabled(enabled); updateQualityBar(); } }); } /* Confirm Password Label */ if ((fStyle & PasswordProvider.CREATE_NEW_PASSWORD) != 0) { Label confirmPasswordLabel = new Label(composite, SWT.NONE); confirmPasswordLabel.setText(Messages.MasterPasswordDialog_CONFIRM_PASSWORD); confirmPasswordLabel.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, true)); /* Confirm Password input field */ fPasswordConfirmed = new Text(composite, SWT.SINGLE | SWT.BORDER | SWT.PASSWORD); fPasswordConfirmed.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true)); fPasswordConfirmed.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { boolean enabled = fPassword.getText().equals(fPasswordConfirmed.getText()) && fPassword.getText().length() > 0; getButton(IDialogConstants.OK_ID).setEnabled(enabled); } }); /* Spacer */ new Label(composite, SWT.NONE); new Label(composite, SWT.NONE); /* Password Quality Meter */ Label passwordQuality = new Label(composite, SWT.NONE); passwordQuality.setText(Messages.MasterPasswordDialog_PASSWORD_QUALITY); passwordQuality.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, true)); fQualityBar = new ProgressBar(composite, SWT.HORIZONTAL); fQualityBar.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true)); fQualityBar.setMinimum(0); fQualityBar.setMaximum(100); } /* Separator */ Label separator = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL); separator.setLayoutData(new GridData(SWT.FILL, SWT.END, true, true)); applyDialogFont(composite); return composite; } private void updateQualityBar() { String pw = fPassword.getText(); int score = 0; /* 1.) Length: password-length*10 - 20 (Max 20) */ score += Math.min(20, (pw.length() * 10) - 20); /* 2.) Numbers: no-of-numerics * 10 (Max 30) */ int numericsCount = 0; for (int i = 0; i < pw.length(); i++) { if (Character.isDigit(pw.charAt(i))) numericsCount++; } score += Math.min(30, numericsCount * 10); /* 3.) Symbols: no-of-symbols * 15 (Max 45) */ int symbolCount = 0; for (int i = 0; i < pw.length(); i++) { if (!Character.isLetterOrDigit(pw.charAt(i))) symbolCount++; } score += Math.min(45, symbolCount * 15); /* 4.) Uppercase: no-of-Uppercase * 10 (Max 30) */ int upperCaseCount = 0; for (int i = 0; i < pw.length(); i++) { if (Character.isUpperCase(pw.charAt(i))) upperCaseCount++; } score += Math.min(30, upperCaseCount * 10); fQualityBar.setSelection(score); } /* * @see org.eclipse.jface.window.Window#getShellStyle() */ @Override protected int getShellStyle() { int style = SWT.TITLE | SWT.BORDER | SWT.APPLICATION_MODAL | SWT.CLOSE | getDefaultOrientation(); return style; } /* * @see org.eclipse.jface.dialogs.Dialog#initializeBounds() */ @Override protected void initializeBounds() { super.initializeBounds(); Shell shell = getShell(); /* Minimum Size */ int minWidth = convertHorizontalDLUsToPixels(OwlUI.MIN_DIALOG_WIDTH_DLU); int minHeight = shell.computeSize(minWidth, SWT.DEFAULT).y; /* Required Size */ Point requiredSize = shell.computeSize(SWT.DEFAULT, SWT.DEFAULT); shell.setSize(Math.max(minWidth, requiredSize.x), Math.max(minHeight, requiredSize.y)); LayoutUtils.positionShell(shell); } }