X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;f=org.argeo.cms%2Fsrc%2Forg%2Fargeo%2Fcms%2Fwidgets%2Fauth%2FCmsLogin.java;h=8f00c457708d31322bde2b1937a286dc3de78b9e;hb=c873a0359345503b8e3ca07828bd99d525ec7cc0;hp=366e80c2b9e1ba5663360ed343b76980b4fd523e;hpb=d3cb756645f72b4476e0e00247736a8a8405299f;p=lgpl%2Fargeo-commons.git diff --git a/org.argeo.cms/src/org/argeo/cms/widgets/auth/CmsLogin.java b/org.argeo.cms/src/org/argeo/cms/widgets/auth/CmsLogin.java index 366e80c2b..8f00c4577 100644 --- a/org.argeo.cms/src/org/argeo/cms/widgets/auth/CmsLogin.java +++ b/org.argeo.cms/src/org/argeo/cms/widgets/auth/CmsLogin.java @@ -1,34 +1,49 @@ package org.argeo.cms.widgets.auth; +import static org.argeo.cms.CmsMsg.password; +import static org.argeo.cms.CmsMsg.username; import static org.argeo.cms.auth.AuthConstants.LOGIN_CONTEXT_ANONYMOUS; import static org.argeo.cms.auth.AuthConstants.LOGIN_CONTEXT_USER; +import static org.argeo.cms.internal.kernel.Activator.getNodeState; import java.io.IOException; +import java.util.List; +import java.util.Locale; import javax.security.auth.Subject; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.LanguageCallback; import javax.security.auth.callback.NameCallback; import javax.security.auth.callback.PasswordCallback; import javax.security.auth.callback.UnsupportedCallbackException; +import javax.security.auth.login.FailedLoginException; import javax.security.auth.login.LoginContext; import javax.security.auth.login.LoginException; -import org.argeo.cms.CmsException; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.argeo.cms.CmsMsg; import org.argeo.cms.CmsStyles; import org.argeo.cms.CmsView; import org.argeo.cms.auth.CurrentUser; import org.argeo.cms.auth.HttpRequestCallback; +import org.argeo.cms.i18n.LocaleUtils; +import org.argeo.cms.internal.auth.LocaleChoice; import org.argeo.cms.util.CmsUtils; +import org.argeo.eclipse.ui.dialogs.ErrorFeedback; import org.eclipse.rap.rwt.RWT; import org.eclipse.swt.SWT; import org.eclipse.swt.events.MouseAdapter; import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.events.TraverseEvent; import org.eclipse.swt.events.TraverseListener; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; @@ -36,20 +51,52 @@ import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; public class CmsLogin implements CmsStyles, CallbackHandler { - private Text username, password; + private final static Log log = LogFactory.getLog(CmsLogin.class); + + private Composite parent; + private Text usernameT, passwordT; private Composite credentialsBlock; + private final SelectionListener loginSelectionListener; + + private final Locale defaultLocale; + private LocaleChoice localeChoice = null; private final CmsView cmsView; public CmsLogin(CmsView cmsView) { this.cmsView = cmsView; + defaultLocale = getNodeState().getDefaultLocale(); + List locales = getNodeState().getLocales(); + if (locales != null) + localeChoice = new LocaleChoice(locales, defaultLocale); + loginSelectionListener = new SelectionListener() { + private static final long serialVersionUID = -8832133363830973578L; + + @Override + public void widgetSelected(SelectionEvent e) { + login(); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + } + }; } protected boolean isAnonymous() { return CurrentUser.isAnonymous(cmsView.getSubject()); } + public final void createUi(Composite parent) { + this.parent = parent; + createContents(parent); + } + protected void createContents(Composite parent) { + defaultCreateContents(parent); + } + + public final void defaultCreateContents(Composite parent) { parent.setLayout(CmsUtils.noSpaceGridLayout()); Composite credentialsBlock = createCredentialsBlock(parent); if (parent instanceof Shell) { @@ -58,7 +105,7 @@ public class CmsLogin implements CmsStyles, CallbackHandler { } } - protected final Composite createCredentialsBlock(Composite parent) { + public final Composite createCredentialsBlock(Composite parent) { if (isAnonymous()) { return anonymousUi(parent); } else { @@ -71,6 +118,8 @@ public class CmsLogin implements CmsStyles, CallbackHandler { } protected Composite userUi(Composite parent) { + Locale locale = localeChoice == null ? this.defaultLocale + : localeChoice.getSelectedLocale(); credentialsBlock = new Composite(parent, SWT.NONE); credentialsBlock.setLayout(new GridLayout()); credentialsBlock.setLayoutData(CmsUtils.fillAll()); @@ -79,7 +128,7 @@ public class CmsLogin implements CmsStyles, CallbackHandler { Label l = new Label(credentialsBlock, SWT.NONE); l.setData(RWT.CUSTOM_VARIANT, CMS_USER_MENU_ITEM); - l.setText(CmsMsg.logout.lead()); + l.setText(CmsMsg.logout.lead(locale)); GridData lData = CmsUtils.fillWidth(); lData.widthHint = 120; l.setLayoutData(lData); @@ -100,6 +149,8 @@ public class CmsLogin implements CmsStyles, CallbackHandler { } protected Composite anonymousUi(Composite parent) { + Locale locale = localeChoice == null ? this.defaultLocale + : localeChoice.getSelectedLocale(); // We need a composite for the traversal credentialsBlock = new Composite(parent, SWT.NONE); credentialsBlock.setLayout(new GridLayout()); @@ -109,20 +160,20 @@ public class CmsLogin implements CmsStyles, CallbackHandler { parent.setData(RWT.CUSTOM_VARIANT, CMS_USER_MENU); // new Label(this, SWT.NONE).setText(CmsMsg.username.lead()); - username = new Text(credentialsBlock, SWT.BORDER); - username.setMessage(CmsMsg.username.lead()); - username.setData(RWT.CUSTOM_VARIANT, CMS_LOGIN_DIALOG_USERNAME); + usernameT = new Text(credentialsBlock, SWT.BORDER); + usernameT.setMessage(username.lead(locale)); + usernameT.setData(RWT.CUSTOM_VARIANT, CMS_LOGIN_DIALOG_USERNAME); GridData gd = CmsUtils.fillWidth(); gd.widthHint = textWidth; - username.setLayoutData(gd); + usernameT.setLayoutData(gd); // new Label(this, SWT.NONE).setText(CmsMsg.password.lead()); - password = new Text(credentialsBlock, SWT.BORDER | SWT.PASSWORD); - password.setMessage(CmsMsg.password.lead()); - password.setData(RWT.CUSTOM_VARIANT, CMS_LOGIN_DIALOG_PASSWORD); + passwordT = new Text(credentialsBlock, SWT.BORDER | SWT.PASSWORD); + passwordT.setMessage(password.lead(locale)); + passwordT.setData(RWT.CUSTOM_VARIANT, CMS_LOGIN_DIALOG_PASSWORD); gd = CmsUtils.fillWidth(); gd.widthHint = textWidth; - password.setLayoutData(gd); + passwordT.setLayoutData(gd); TraverseListener tl = new TraverseListener() { private static final long serialVersionUID = -1158892811534971856L; @@ -133,15 +184,78 @@ public class CmsLogin implements CmsStyles, CallbackHandler { } }; credentialsBlock.addTraverseListener(tl); - username.addTraverseListener(tl); - password.addTraverseListener(tl); + usernameT.addTraverseListener(tl); + passwordT.addTraverseListener(tl); parent.setTabList(new Control[] { credentialsBlock }); - credentialsBlock.setTabList(new Control[] { username, password }); - credentialsBlock.setFocus(); + credentialsBlock.setTabList(new Control[] { usernameT, passwordT }); + // credentialsBlock.setFocus(); + + extendsCredentialsBlock(credentialsBlock, locale, + loginSelectionListener); + if (localeChoice != null) + createLocalesBlock(credentialsBlock); return credentialsBlock; } - protected void login() { + /** + * To be overridden in order to provide custome login button and other + * links. + */ + protected void extendsCredentialsBlock(Composite credentialsBlock, + Locale selectedLocale, SelectionListener loginSelectionListener) { + + } + + protected void updateLocale(Locale selectedLocale) { + // save already entered values + String usernameStr = usernameT.getText(); + char[] pwd = passwordT.getTextChars(); + + for (Control child : parent.getChildren()) + child.dispose(); + createContents(parent); + if (parent.getParent() != null) + parent.getParent().layout(); + else + parent.layout(); + usernameT.setText(usernameStr); + passwordT.setTextChars(pwd); + } + + protected Composite createLocalesBlock(final Composite parent) { + Composite c = new Composite(parent, SWT.NONE); + c.setLayout(CmsUtils.noSpaceGridLayout()); + c.setLayoutData(CmsUtils.fillAll()); + + SelectionListener selectionListener = new SelectionAdapter() { + private static final long serialVersionUID = 4891637813567806762L; + + public void widgetSelected(SelectionEvent event) { + Button button = (Button) event.widget; + if (button.getSelection()) { + localeChoice.setSelectedIndex((Integer) event.widget + .getData()); + updateLocale(localeChoice.getSelectedLocale()); + } + }; + }; + + List locales = localeChoice.getLocales(); + for (Integer i = 0; i < locales.size(); i++) { + Locale locale = locales.get(i); + Button button = new Button(c, SWT.RADIO); + button.setData(i); + button.setText(LocaleUtils.lead(locale.getDisplayName(locale), + locale) + " (" + locale + ")"); + // button.addListener(SWT.Selection, listener); + button.addSelectionListener(selectionListener); + if (i == localeChoice.getSelectedIndex()) + button.setSelection(true); + } + return c; + } + + protected boolean login() { Subject subject = cmsView.getSubject(); LoginContext loginContext; try { @@ -151,10 +265,21 @@ public class CmsLogin implements CmsStyles, CallbackHandler { new LoginContext(LOGIN_CONTEXT_ANONYMOUS, subject).logout(); loginContext = new LoginContext(LOGIN_CONTEXT_USER, subject, this); loginContext.login(); - } catch (LoginException e1) { - throw new CmsException("Cannot authenticate", e1); + } catch (FailedLoginException e) { + log.warn(e.getMessage()); + try { + Thread.sleep(3000); + } catch (InterruptedException e2) { + // silent + } +// ErrorFeedback.show("Login failed", e); + return false; + } catch (LoginException e) { + log.error("Cannot login", e); + return false; } cmsView.authChange(loginContext); + return true; } protected void logout() { @@ -167,12 +292,16 @@ public class CmsLogin implements CmsStyles, CallbackHandler { UnsupportedCallbackException { for (Callback callback : callbacks) { if (callback instanceof NameCallback) - ((NameCallback) callback).setName(username.getText()); + ((NameCallback) callback).setName(usernameT.getText()); else if (callback instanceof PasswordCallback) - ((PasswordCallback) callback).setPassword(password + ((PasswordCallback) callback).setPassword(passwordT .getTextChars()); else if (callback instanceof HttpRequestCallback) ((HttpRequestCallback) callback).setRequest(RWT.getRequest()); + else if (callback instanceof LanguageCallback + && localeChoice != null) + ((LanguageCallback) callback).setLocale(localeChoice + .getSelectedLocale()); } }