|
From: <go...@us...> - 2013-03-31 12:38:17
|
Revision: 16193
http://unicore.svn.sourceforge.net/unicore/?rev=16193&view=rev
Author: golbi
Date: 2013-03-31 12:38:05 +0000 (Sun, 31 Mar 2013)
Log Message:
-----------
i18n support, localization of the web part
Modified Paths:
--------------
unity/trunk/core/src/main/java/pl/edu/icm/unity/server/utils/UnityServerConfiguration.java
unity/trunk/core/src/main/resources/META-INF/components.xml
unity/trunk/distribution/src/test/resources/unityServer.conf
unity/trunk/engine/src/main/java/pl/edu/icm/unity/engine/authz/AuthorizationManagerImpl.java
unity/trunk/engine/src/test/java/pl/edu/icm/unity/engine/DBIntegrationTestBase.java
unity/trunk/web-admin/src/main/resources/META-INF/components.xml
unity/trunk/web-common/src/main/java/pl/edu/icm/unity/webui/UnityVaadinServlet.java
unity/trunk/web-common/src/main/java/pl/edu/icm/unity/webui/WebSession.java
unity/trunk/web-common/src/main/java/pl/edu/icm/unity/webui/authn/AuthenticationProcessor.java
unity/trunk/web-common/src/main/java/pl/edu/icm/unity/webui/authn/AuthenticationUI.java
unity/trunk/web-common/src/main/java/pl/edu/icm/unity/webui/authn/extensions/PasswordRetrieval.java
unity/trunk/web-common/src/main/java/pl/edu/icm/unity/webui/authn/extensions/PasswordRetrievalFactory.java
unity/trunk/web-common/src/main/resources/META-INF/components.xml
Added Paths:
-----------
unity/trunk/core/src/main/java/pl/edu/icm/unity/server/authn/InvocationContext.java
unity/trunk/core/src/main/java/pl/edu/icm/unity/server/utils/UnityMessageBundles.java
unity/trunk/core/src/main/java/pl/edu/icm/unity/server/utils/UnityMessageSource.java
unity/trunk/web-admin/src/main/resources/pl/
unity/trunk/web-admin/src/main/resources/pl/edu/
unity/trunk/web-admin/src/main/resources/pl/edu/icm/
unity/trunk/web-admin/src/main/resources/pl/edu/icm/unity/
unity/trunk/web-admin/src/main/resources/pl/edu/icm/unity/webadmin/
unity/trunk/web-admin/src/main/resources/pl/edu/icm/unity/webadmin/messages/
unity/trunk/web-admin/src/main/resources/pl/edu/icm/unity/webadmin/messages/messages.properties
unity/trunk/web-common/src/main/java/pl/edu/icm/unity/webui/authn/LocaleChoiceComponent.java
unity/trunk/web-common/src/main/resources/pl/
unity/trunk/web-common/src/main/resources/pl/edu/
unity/trunk/web-common/src/main/resources/pl/edu/icm/
unity/trunk/web-common/src/main/resources/pl/edu/icm/unity/
unity/trunk/web-common/src/main/resources/pl/edu/icm/unity/webui/
unity/trunk/web-common/src/main/resources/pl/edu/icm/unity/webui/messages/
unity/trunk/web-common/src/main/resources/pl/edu/icm/unity/webui/messages/messages.properties
unity/trunk/web-common/src/main/resources/pl/edu/icm/unity/webui/messages/messages_pl.properties
Removed Paths:
-------------
unity/trunk/core/src/main/java/pl/edu/icm/unity/server/authn/AuthenticationContext.java
Deleted: unity/trunk/core/src/main/java/pl/edu/icm/unity/server/authn/AuthenticationContext.java
===================================================================
--- unity/trunk/core/src/main/java/pl/edu/icm/unity/server/authn/AuthenticationContext.java 2013-03-30 14:49:55 UTC (rev 16192)
+++ unity/trunk/core/src/main/java/pl/edu/icm/unity/server/authn/AuthenticationContext.java 2013-03-31 12:38:05 UTC (rev 16193)
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2013 ICM Uniwersytet Warszawski All rights reserved.
- * See LICENCE.txt file for licensing information.
- */
-package pl.edu.icm.unity.server.authn;
-
-import java.io.Serializable;
-
-import pl.edu.icm.unity.exceptions.RuntimeEngineException;
-
-/**
- * Stores information about the authenticated user in thread local variable.
- *
- * The thread-local variable should be set up by the binding authentication code.
- * @author K. Benedyczak
- */
-public class AuthenticationContext implements Serializable
-{
- private static final long serialVersionUID = 1L;
-
- private static ThreadLocal<AuthenticationContext> threadLocal = new ThreadLocal<AuthenticationContext>();
-
- private AuthenticatedEntity euthenticatedEntity;
-
- public AuthenticationContext(AuthenticatedEntity entityId)
- {
- this.euthenticatedEntity = entityId;
- }
-
- public static void setCurrent(AuthenticationContext context)
- {
- threadLocal.set(context);
- }
-
- public static AuthenticationContext getCurrent()
- {
- AuthenticationContext ret = threadLocal.get();
- if (ret == null)
- throw new RuntimeEngineException("The current call has no authentication context set");
- return ret;
- }
-
- public AuthenticatedEntity getAuthenticatedEntity()
- {
- return euthenticatedEntity;
- }
-}
Copied: unity/trunk/core/src/main/java/pl/edu/icm/unity/server/authn/InvocationContext.java (from rev 16192, unity/trunk/core/src/main/java/pl/edu/icm/unity/server/authn/AuthenticationContext.java)
===================================================================
--- unity/trunk/core/src/main/java/pl/edu/icm/unity/server/authn/InvocationContext.java (rev 0)
+++ unity/trunk/core/src/main/java/pl/edu/icm/unity/server/authn/InvocationContext.java 2013-03-31 12:38:05 UTC (rev 16193)
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2013 ICM Uniwersytet Warszawski All rights reserved.
+ * See LICENCE.txt file for licensing information.
+ */
+package pl.edu.icm.unity.server.authn;
+
+import java.io.Serializable;
+import java.util.Locale;
+
+import pl.edu.icm.unity.exceptions.RuntimeEngineException;
+
+/**
+ * Stores thread-local information about the current request metadata in thread local variable.
+ * The thread-local variable should be set up by the binding authentication code.
+ * <p>
+ * The data stored includes authenticated user's identity and the selected locale.
+ * @author K. Benedyczak
+ */
+public class InvocationContext implements Serializable
+{
+ private static final long serialVersionUID = 1L;
+
+ private static ThreadLocal<InvocationContext> threadLocal = new ThreadLocal<InvocationContext>();
+
+ private AuthenticatedEntity authenticatedEntity;
+ private Locale locale;
+
+ public static void setCurrent(InvocationContext context)
+ {
+ threadLocal.set(context);
+ }
+
+ public static InvocationContext getCurrent()
+ {
+ InvocationContext ret = threadLocal.get();
+ if (ret == null)
+ throw new RuntimeEngineException("The current call has no invocation context set");
+ return ret;
+ }
+
+ public AuthenticatedEntity getAuthenticatedEntity()
+ {
+ return authenticatedEntity;
+ }
+
+ public void setAuthenticatedEntity(AuthenticatedEntity authenticatedEntity)
+ {
+ this.authenticatedEntity = authenticatedEntity;
+ }
+
+ /**
+ * @return the locale
+ */
+ public Locale getLocale()
+ {
+ return locale;
+ }
+
+ public void setLocale(Locale locale)
+ {
+ this.locale = locale;
+ }
+}
Added: unity/trunk/core/src/main/java/pl/edu/icm/unity/server/utils/UnityMessageBundles.java
===================================================================
--- unity/trunk/core/src/main/java/pl/edu/icm/unity/server/utils/UnityMessageBundles.java (rev 0)
+++ unity/trunk/core/src/main/java/pl/edu/icm/unity/server/utils/UnityMessageBundles.java 2013-03-31 12:38:05 UTC (rev 16193)
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2013 ICM Uniwersytet Warszawski All rights reserved.
+ * See LICENCE file for licensing information.
+ */
+package pl.edu.icm.unity.server.utils;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+/**
+ * Trivial bean providing a list of Strings, being message bundle names.
+ * Unity modules define beans of this class. All such beans are used by the
+ * {@link UnityMessageSource} to build a composite, master message source.
+ * @author K. Benedyczak
+ */
+@Component
+public class UnityMessageBundles
+{
+ private List<String> bundles = new ArrayList<String>();
+
+ public List<String> getBundles()
+ {
+ return bundles;
+ }
+
+ @Autowired(required=false)
+ public void setBundles(List<String> bundles)
+ {
+ this.bundles = bundles;
+ }
+
+ @Autowired(required=false)
+ public void setBundle(String bundle)
+ {
+ this.bundles = Collections.singletonList(bundle);
+ }
+}
Added: unity/trunk/core/src/main/java/pl/edu/icm/unity/server/utils/UnityMessageSource.java
===================================================================
--- unity/trunk/core/src/main/java/pl/edu/icm/unity/server/utils/UnityMessageSource.java (rev 0)
+++ unity/trunk/core/src/main/java/pl/edu/icm/unity/server/utils/UnityMessageSource.java 2013-03-31 12:38:05 UTC (rev 16193)
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2013 ICM Uniwersytet Warszawski All rights reserved.
+ * See LICENCE file for licensing information.
+ */
+package pl.edu.icm.unity.server.utils;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.support.ResourceBundleMessageSource;
+import org.springframework.stereotype.Component;
+
+import pl.edu.icm.unity.server.authn.InvocationContext;
+
+/**
+ * Extension of the {@link ResourceBundleMessageSource} which
+ * automatically sets the proper locale from the {@link InvocationContext}
+ * and allows for an easier invocation using varargs.
+ * It also sets UTF-8 encoding and disables platform's locale fallback.
+ * @author K. Benedyczak
+ */
+@Component
+public class UnityMessageSource extends ResourceBundleMessageSource
+{
+ private UnityServerConfiguration config;
+
+ @Autowired
+ public UnityMessageSource(UnityServerConfiguration config,
+ List<UnityMessageBundles> bundles)
+ {
+ super();
+ this.config = config;
+ List<String> allBundles = new ArrayList<String>();
+ for (UnityMessageBundles bundle: bundles)
+ allBundles.addAll(bundle.getBundles());
+ setBasenames(allBundles.toArray(new String[allBundles.size()]));
+ setFallbackToSystemLocale(false);
+ setDefaultEncoding("UTF-8");
+ }
+
+ public String getMessage(String code, Object... args)
+ {
+ Locale loc = getLocale();
+ return super.getMessage(code, args, loc);
+ }
+
+
+ private Locale getLocale()
+ {
+ InvocationContext ctx = InvocationContext.getCurrent();
+ if (ctx == null)
+ return config.getDefaultLocale();
+ Locale ret = ctx.getLocale();
+ if (ret == null)
+ return config.getDefaultLocale();
+ return ret;
+ }
+}
Modified: unity/trunk/core/src/main/java/pl/edu/icm/unity/server/utils/UnityServerConfiguration.java
===================================================================
--- unity/trunk/core/src/main/java/pl/edu/icm/unity/server/utils/UnityServerConfiguration.java 2013-03-30 14:49:55 UTC (rev 16192)
+++ unity/trunk/core/src/main/java/pl/edu/icm/unity/server/utils/UnityServerConfiguration.java 2013-03-31 12:38:05 UTC (rev 16193)
@@ -9,7 +9,11 @@
package pl.edu.icm.unity.server.utils;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Locale;
import java.util.Map;
import java.util.Properties;
@@ -48,6 +52,8 @@
@DocumentationReferencePrefix
public static final String P = BASE_PREFIX + "core.";
+ public static final String ENABLED_LOCALES = "enabledLocales.";
+ public static final String DEFAULT_LOCALE = "defaultLocale";
public static final String MAIL_CONF = "mailConfig";
public static final String THREAD_POOL_SIZE = "threadPoolSize";
public static final String RECREATE_ENDPOINTS_ON_STARTUP = "recreateEndpointsOnStartup";
@@ -82,6 +88,12 @@
DocumentationCategory mainCat = new DocumentationCategory("General settings", "1");
DocumentationCategory otherCat = new DocumentationCategory("Other", "8");
+ defaults.put(ENABLED_LOCALES, new PropertyMD().setList(true).setCategory(mainCat).
+ setDescription("List of enabled locales. " +
+ "Each entry must have a language code as 'en' or 'pl' first, " +
+ "and then, after a space an optional, short name which will be presented in the UI. By default the 'en' locale is installed."));
+ defaults.put(DEFAULT_LOCALE, new PropertyMD("en").setCategory(mainCat).
+ setDescription("The default locale to be used. Must be one of the enabled locales."));
defaults.put(MAIL_CONF, new PropertyMD("conf/mail.properties").setPath().setCategory(mainCat).
setDescription("A configuration file for the mail notification subsystem."));
defaults.put(RECREATE_ENDPOINTS_ON_STARTUP, new PropertyMD("false").setDescription(
@@ -142,6 +154,8 @@
private UnityHttpServerConfiguration jp;
private IAuthnAndTrustConfiguration authnTrust;
private IClientConfiguration clientCfg;
+ private Map<String, Locale> enabledLocales;
+ private Locale defaultLocale;
@Autowired
public UnityServerConfiguration(Environment env, ConfigurationLocationProvider locProvider) throws ConfigurationException, IOException
@@ -151,6 +165,10 @@
authnTrust = new AuthnAndTrustProperties(properties,
P+TruststoreProperties.DEFAULT_PREFIX, P+CredentialProperties.DEFAULT_PREFIX);
clientCfg = new ClientProperties(properties, P+ClientProperties.DEFAULT_PREFIX, authnTrust);
+ enabledLocales = loadEnabledLocales();
+ defaultLocale = safeLocaleDecode(getValue(DEFAULT_LOCALE));
+ if (!isLocaleSupported(defaultLocale))
+ throw new ConfigurationException("The default locale is not amoung enabled ones.");
}
private static String getConfigurationFile(Environment env, ConfigurationLocationProvider locProvider)
@@ -167,6 +185,57 @@
return configFile;
}
+ /**
+ * @return map with enabled locales. Key is the user-friendly label.
+ */
+ private Map<String, Locale> loadEnabledLocales()
+ {
+ List<String> locales = getListOfValues(ENABLED_LOCALES);
+ if (locales.isEmpty())
+ {
+ locales = new ArrayList<String>();
+ locales.add("en English");
+ }
+ Map<String, Locale> ret = new LinkedHashMap<String, Locale>();
+ for (String locale: locales)
+ {
+ locale = locale.trim() + " ";
+ int split = locale.indexOf(' ');
+ String code = locale.substring(0, split);
+ String name = locale.substring(split).trim();
+ if (name.equals(""))
+ name = code;
+ Locale l = safeLocaleDecode(code);
+ ret.put(name, l);
+ }
+ return ret;
+ }
+
+ public boolean isLocaleSupported(Locale toSearch)
+ {
+ for (Locale l: enabledLocales.values())
+ if (l.equals(toSearch))
+ return true;
+ return false;
+ }
+
+ public static Locale safeLocaleDecode(String inputRaw)
+ {
+ if (inputRaw == null)
+ return Locale.ENGLISH;
+ Locale l;
+ String input = inputRaw.trim();
+ if (input.contains("_"))
+ {
+ String[] sp = input.split("_");
+ l = new Locale(sp[0], sp[1]);
+ } else
+ {
+ l = new Locale(input);
+ }
+ return l;
+ }
+
public UnityHttpServerConfiguration getJettyProperties()
{
return jp;
@@ -182,6 +251,16 @@
return clientCfg;
}
+ public Locale getDefaultLocale()
+ {
+ return defaultLocale;
+ }
+
+ public Map<String, Locale> getEnabledLocales()
+ {
+ return enabledLocales;
+ }
+
public Properties getProperties()
{
return properties;
Modified: unity/trunk/core/src/main/resources/META-INF/components.xml
===================================================================
--- unity/trunk/core/src/main/resources/META-INF/components.xml 2013-03-30 14:49:55 UTC (rev 16192)
+++ unity/trunk/core/src/main/resources/META-INF/components.xml 2013-03-31 12:38:05 UTC (rev 16193)
@@ -7,12 +7,14 @@
<context:annotation-config/>
<bean class="pl.edu.icm.unity.server.utils.UnityServerConfiguration"/>
<bean class="pl.edu.icm.unity.server.utils.ExecutorsService"/>
+ <bean class="pl.edu.icm.unity.server.utils.UnityMessageSource"/>
<bean class="pl.edu.icm.unity.server.registries.IdentityTypesRegistry"/>
<bean class="pl.edu.icm.unity.server.registries.AttributeValueTypesRegistry"/>
<bean class="pl.edu.icm.unity.server.registries.EndpointFactoriesRegistry"/>
<bean class="pl.edu.icm.unity.server.registries.AuthenticatorsRegistry"/>
+
<beans profile="production">
<bean class="pl.edu.icm.unity.server.utils.DefaultConfigurationLocation"/>
</beans>
Modified: unity/trunk/distribution/src/test/resources/unityServer.conf
===================================================================
--- unity/trunk/distribution/src/test/resources/unityServer.conf 2013-03-30 14:49:55 UTC (rev 16192)
+++ unity/trunk/distribution/src/test/resources/unityServer.conf 2013-03-31 12:38:05 UTC (rev 16193)
@@ -18,10 +18,16 @@
unityServer.core.truststore.keystorePassword=unicore
unityServer.core.truststore.keystoreFormat=JKS
+unityServer.core.enabledLocales.1=en English
+unityServer.core.enabledLocales.2=pl Polski
+unityServer.core.defaultLocale=en
+
unityServer.db.jdbcUrl=jdbc:h2:file:target/data/unitydb.bin
+
+
#######################################
# Credential definitions
#######################################
Modified: unity/trunk/engine/src/main/java/pl/edu/icm/unity/engine/authz/AuthorizationManagerImpl.java
===================================================================
--- unity/trunk/engine/src/main/java/pl/edu/icm/unity/engine/authz/AuthorizationManagerImpl.java 2013-03-30 14:49:55 UTC (rev 16192)
+++ unity/trunk/engine/src/main/java/pl/edu/icm/unity/engine/authz/AuthorizationManagerImpl.java 2013-03-31 12:38:05 UTC (rev 16193)
@@ -20,7 +20,7 @@
import pl.edu.icm.unity.db.DBSessionManager;
import pl.edu.icm.unity.exceptions.AuthorizationException;
import pl.edu.icm.unity.exceptions.RuntimeEngineException;
-import pl.edu.icm.unity.server.authn.AuthenticationContext;
+import pl.edu.icm.unity.server.authn.InvocationContext;
import pl.edu.icm.unity.sysattrs.SystemAttributeTypes;
import pl.edu.icm.unity.types.basic.Attribute;
import pl.edu.icm.unity.types.basic.Group;
@@ -146,7 +146,7 @@
public void checkAuthorization(boolean selfAccess, String groupPath, AuthzCapability... requiredCapabilities)
{
Group group = groupPath == null ? new Group("/") : new Group(groupPath);
- AuthenticationContext authnCtx = AuthenticationContext.getCurrent();
+ InvocationContext authnCtx = InvocationContext.getCurrent();
Set<AuthzRole> roles = establishRoles(authnCtx.getAuthenticatedEntity().getEntityId(), group);
Set<AuthzCapability> capabilities = getRoleCapabilities(roles, selfAccess);
@@ -159,7 +159,7 @@
@Override
public boolean isSelf(long subject)
{
- AuthenticationContext authnCtx = AuthenticationContext.getCurrent();
+ InvocationContext authnCtx = InvocationContext.getCurrent();
return authnCtx.getAuthenticatedEntity().getEntityId() == subject;
}
Modified: unity/trunk/engine/src/test/java/pl/edu/icm/unity/engine/DBIntegrationTestBase.java
===================================================================
--- unity/trunk/engine/src/test/java/pl/edu/icm/unity/engine/DBIntegrationTestBase.java 2013-03-30 14:49:55 UTC (rev 16192)
+++ unity/trunk/engine/src/test/java/pl/edu/icm/unity/engine/DBIntegrationTestBase.java 2013-03-31 12:38:05 UTC (rev 16193)
@@ -4,13 +4,15 @@
*/
package pl.edu.icm.unity.engine;
+import java.util.Locale;
+
import org.junit.After;
import org.junit.Before;
import pl.edu.icm.unity.engine.internal.EngineInitialization;
import pl.edu.icm.unity.exceptions.EngineException;
import pl.edu.icm.unity.server.authn.AuthenticatedEntity;
-import pl.edu.icm.unity.server.authn.AuthenticationContext;
+import pl.edu.icm.unity.server.authn.InvocationContext;
import pl.edu.icm.unity.server.authn.EntityWithCredential;
import pl.edu.icm.unity.stdext.identity.UsernameIdentity;
@@ -30,15 +32,16 @@
@After
public void clearAuthnCtx() throws EngineException
{
- AuthenticationContext.setCurrent(null);
+ InvocationContext.setCurrent(null);
}
protected void setupUserContext(String user) throws Exception
{
EntityWithCredential entity = identityResolver.resolveIdentity(user, new String[] {UsernameIdentity.ID},
EngineInitialization.DEFAULT_CREDENTIAL);
- AuthenticationContext virtualAdmin = new AuthenticationContext(
- new AuthenticatedEntity(entity.getEntityId()));
- AuthenticationContext.setCurrent(virtualAdmin);
+ InvocationContext virtualAdmin = new InvocationContext();
+ virtualAdmin.setAuthenticatedEntity(new AuthenticatedEntity(entity.getEntityId()));
+ virtualAdmin.setLocale(Locale.ENGLISH);
+ InvocationContext.setCurrent(virtualAdmin);
}
}
Modified: unity/trunk/web-admin/src/main/resources/META-INF/components.xml
===================================================================
--- unity/trunk/web-admin/src/main/resources/META-INF/components.xml 2013-03-30 14:49:55 UTC (rev 16192)
+++ unity/trunk/web-admin/src/main/resources/META-INF/components.xml 2013-03-31 12:38:05 UTC (rev 16193)
@@ -7,6 +7,10 @@
<context:annotation-config/>
<bean class="pl.edu.icm.unity.webadmin.WebAdminEndpointFactory"/>
+ <bean class="pl.edu.icm.unity.server.utils.UnityMessageBundles">
+ <property name="bundle" value="pl/edu/icm/unity/webadmin/messages/messages"/>
+ </bean>
+
<bean scope="prototype" id="WebAdminUI" class="pl.edu.icm.unity.webadmin.WebAdminUI"/>
</beans>
\ No newline at end of file
Added: unity/trunk/web-admin/src/main/resources/pl/edu/icm/unity/webadmin/messages/messages.properties
===================================================================
Modified: unity/trunk/web-common/src/main/java/pl/edu/icm/unity/webui/UnityVaadinServlet.java
===================================================================
--- unity/trunk/web-common/src/main/java/pl/edu/icm/unity/webui/UnityVaadinServlet.java 2013-03-30 14:49:55 UTC (rev 16192)
+++ unity/trunk/web-common/src/main/java/pl/edu/icm/unity/webui/UnityVaadinServlet.java 2013-03-31 12:38:05 UTC (rev 16193)
@@ -6,17 +6,21 @@
import java.io.IOException;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import javax.servlet.ServletException;
+import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.context.ApplicationContext;
-import pl.edu.icm.unity.server.authn.AuthenticationContext;
+import pl.edu.icm.unity.server.authn.AuthenticatedEntity;
+import pl.edu.icm.unity.server.authn.InvocationContext;
import pl.edu.icm.unity.server.endpoint.BindingAuthn;
+import pl.edu.icm.unity.server.utils.UnityServerConfiguration;
import pl.edu.icm.unity.types.endpoint.EndpointDescription;
import com.vaadin.server.DeploymentConfiguration;
@@ -26,6 +30,7 @@
import com.vaadin.server.VaadinServlet;
import com.vaadin.server.VaadinServletService;
+
/**
* Customization of the ordinary {@link VaadinServlet} using {@link VaadinUIProvider}
* @author K. Benedyczak
@@ -33,7 +38,9 @@
@SuppressWarnings("serial")
public class UnityVaadinServlet extends VaadinServlet
{
+ public static final String LANGUAGE_COOKIE = "language";
private transient ApplicationContext applicationContext;
+ private transient UnityServerConfiguration config;
private transient String uiBeanName;
private transient EndpointDescription description;
private transient List<Map<String, BindingAuthn>> authenticators;
@@ -47,34 +54,68 @@
this.uiBeanName = uiBeanName;
this.description = description;
this.authenticators = authenticators;
+ this.config = applicationContext.getBean(UnityServerConfiguration.class);
}
@Override
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
- setAuthenticationcontext(request);
+ InvocationContext ctx = setEmptyInvocationContext();
+ setAuthenticationContext(request, ctx);
+ setLocale(request, ctx);
try
{
super.service(request, response);
} finally
{
- AuthenticationContext.setCurrent(null);
+ InvocationContext.setCurrent(null);
}
}
-
- private void setAuthenticationcontext(HttpServletRequest request)
+
+ private InvocationContext setEmptyInvocationContext()
{
+ InvocationContext context = new InvocationContext();
+ InvocationContext.setCurrent(context);
+ return context;
+ }
+
+ private void setAuthenticationContext(HttpServletRequest request, InvocationContext ctx)
+ {
HttpSession session = request.getSession(false);
if (session != null)
{
- AuthenticationContext authnContext = (AuthenticationContext) session.getAttribute(
+ AuthenticatedEntity ae = (AuthenticatedEntity) session.getAttribute(
WebSession.USER_SESSION_KEY);
- if (authnContext != null)
- AuthenticationContext.setCurrent(authnContext);
+ if (ae != null)
+ ctx.setAuthenticatedEntity(ae);
}
}
+ /**
+ * Sets locale in invocation context. If there is cookie with selected and still supported
+ * locale then it is used. Otherwise a default locale is set.
+ * @param request
+ */
+ private void setLocale(HttpServletRequest request, InvocationContext context)
+ {
+ Cookie[] cookies = request.getCookies();
+ for (Cookie cookie: cookies)
+ {
+ if (LANGUAGE_COOKIE.equals(cookie.getName()))
+ {
+ String value = cookie.getValue();
+ Locale locale = UnityServerConfiguration.safeLocaleDecode(value);
+ if (config.isLocaleSupported(locale))
+ context.setLocale(locale);
+ else
+ context.setLocale(config.getDefaultLocale());
+ return;
+ }
+ }
+ context.setLocale(config.getDefaultLocale());
+ }
+
@Override
protected VaadinServletService createServletService(DeploymentConfiguration deploymentConfiguration)
{
Modified: unity/trunk/web-common/src/main/java/pl/edu/icm/unity/webui/WebSession.java
===================================================================
--- unity/trunk/web-common/src/main/java/pl/edu/icm/unity/webui/WebSession.java 2013-03-30 14:49:55 UTC (rev 16192)
+++ unity/trunk/web-common/src/main/java/pl/edu/icm/unity/webui/WebSession.java 2013-03-31 12:38:05 UTC (rev 16193)
@@ -4,6 +4,8 @@
*/
package pl.edu.icm.unity.webui;
+import pl.edu.icm.unity.server.authn.AuthenticatedEntity;
+
/**
* Holds information stored in the HTTP session.
* @author K. Benedyczak
@@ -11,11 +13,8 @@
public class WebSession
{
/**
- * Under this key this object is stored in the HTTP session
+ * Under this key, the object {@link AuthenticatedEntity}
+ * with authenticated user is stored in the session.
*/
- public static final String SESSION_KEY = WebSession.class.getName();
- /**
- * Under this key, the object with authenticated user is stored in the session
- */
public static final String USER_SESSION_KEY = WebSession.class.getName();
}
Modified: unity/trunk/web-common/src/main/java/pl/edu/icm/unity/webui/authn/AuthenticationProcessor.java
===================================================================
--- unity/trunk/web-common/src/main/java/pl/edu/icm/unity/webui/authn/AuthenticationProcessor.java 2013-03-30 14:49:55 UTC (rev 16192)
+++ unity/trunk/web-common/src/main/java/pl/edu/icm/unity/webui/authn/AuthenticationProcessor.java 2013-03-31 12:38:05 UTC (rev 16193)
@@ -8,7 +8,6 @@
import pl.edu.icm.unity.exceptions.AuthenticationException;
import pl.edu.icm.unity.server.authn.AuthenticatedEntity;
-import pl.edu.icm.unity.server.authn.AuthenticationContext;
import pl.edu.icm.unity.server.authn.AuthenticationResult;
import pl.edu.icm.unity.server.authn.AuthenticationResult.Status;
import pl.edu.icm.unity.webui.WebSession;
@@ -33,14 +32,14 @@
for (AuthenticationResult result: results)
{
if (result.getStatus() != Status.success)
- throw new AuthenticationException("Authentication failed");
+ throw new AuthenticationException("AuthenticationProcessor.authnFailed");
long curId = result.getAuthenticatedEntity().getEntityId();
if (entityId == null)
entityId = curId;
else
if (entityId != curId)
{
- throw new AuthenticationException("Two different users were authenticated");
+ throw new AuthenticationException("AuthenticationProcessor.authnWrongUsers");
}
}
logged(results.get(0).getAuthenticatedEntity());
@@ -53,16 +52,21 @@
if (vss == null)
throw new RuntimeException("BUG Can't get VaadinSession to store authenticated user's data.");
WrappedSession session = vss.getSession();
- AuthenticationContext authnContext = new AuthenticationContext(authenticatedEntity);
- session.setAttribute(WebSession.USER_SESSION_KEY, authnContext);
-
+ session.setAttribute(WebSession.USER_SESSION_KEY, authenticatedEntity);
UI ui = UI.getCurrent();
if (ui == null)
throw new RuntimeException("BUG Can't get UI to redirect the authenticated user.");
+ String origURL = getOriginalURL(session);
+
+ ui.getPage().open(origURL, "");
+ }
+
+ public static String getOriginalURL(WrappedSession session)
+ {
String origURL = (String) session.getAttribute(AuthenticationFilter.ORIGINAL_ADDRESS);
//String origFragment = (String) session.getAttribute(AuthenticationApp.ORIGINAL_FRAGMENT);
if (origURL == null)
- return;
+ throw new RuntimeException("No original address - this is not implemented yet.");
//origURL = DEFAULT_PORTAL_PATH;
//if (origFragment == null)
// origFragment = "";
@@ -70,6 +74,6 @@
// origFragment = "#" + origFragment;
//origURL = origURL+origFragment;
- ui.getPage().open(origURL, "");
+ return origURL;
}
}
Modified: unity/trunk/web-common/src/main/java/pl/edu/icm/unity/webui/authn/AuthenticationUI.java
===================================================================
--- unity/trunk/web-common/src/main/java/pl/edu/icm/unity/webui/authn/AuthenticationUI.java 2013-03-30 14:49:55 UTC (rev 16192)
+++ unity/trunk/web-common/src/main/java/pl/edu/icm/unity/webui/authn/AuthenticationUI.java 2013-03-31 12:38:05 UTC (rev 16193)
@@ -9,12 +9,14 @@
import java.util.List;
import java.util.Map;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import pl.edu.icm.unity.exceptions.AuthenticationException;
import pl.edu.icm.unity.server.authn.AuthenticationResult;
import pl.edu.icm.unity.server.endpoint.BindingAuthn;
+import pl.edu.icm.unity.server.utils.UnityMessageSource;
import pl.edu.icm.unity.types.authn.AuthenticatorSet;
import pl.edu.icm.unity.types.endpoint.EndpointDescription;
import pl.edu.icm.unity.webui.UnityWebUI;
@@ -46,7 +48,17 @@
private EndpointDescription description;
private List<Map<String, VaadinAuthentication>> authenticators;
+ private LocaleChoiceComponent localeChoice;
+ private UnityMessageSource msg;
+ @Autowired
+ public AuthenticationUI(LocaleChoiceComponent localeChoice, UnityMessageSource msg)
+ {
+ super();
+ this.localeChoice = localeChoice;
+ this.msg = msg;
+ }
+
@Override
public void configure(EndpointDescription description,
List<Map<String, BindingAuthn>> authenticators)
@@ -71,7 +83,12 @@
components[i] = buildAuthenticatorSetUI(authenticators.get(i),
description.getAuthenticatorSets().get(i));
Component all = buildAllSetsUI(components);
- setContent(all);
+
+ VerticalLayout main = new VerticalLayout();
+ main.addComponent(localeChoice);
+ main.addComponent(all);
+
+ setContent(main);
}
private Component buildAllSetsUI(Component... setComponents)
@@ -80,7 +97,8 @@
return setComponents[0];
TabSheet sheet = new TabSheet();
for (int i=0; i<setComponents.length; i++)
- sheet.addTab(setComponents[i], "Authentication option " + (i+1));
+ sheet.addTab(setComponents[i], msg.getMessage(
+ "AuthenticationUI.authnSet", i+1));
return sheet;
}
@@ -102,7 +120,7 @@
authenticatorsContainer.addComponent(vaadinAuth.getComponent());
}
- Button authenticateButton = new Button("Authenticate");
+ Button authenticateButton = new Button(msg.getMessage("AuthenticationUI.authnenticateButton"));
authenticateButton.addClickListener(new LoginButtonListener(authenticators, set, status));
mainContainer.addComponent(status);
@@ -158,7 +176,7 @@
AuthenticationProcessor.processResults(results);
} catch (AuthenticationException e)
{
- status.setValue(e.getMessage());
+ status.setValue(msg.getMessage(e.getMessage()));
}
}
}
@@ -170,7 +188,7 @@
public UsernameComponent()
{
- addComponent(new Label("Username:"));
+ addComponent(new Label(msg.getMessage("AuthenticationUI.username")));
username = new TextField();
addComponent(username);
}
Added: unity/trunk/web-common/src/main/java/pl/edu/icm/unity/webui/authn/LocaleChoiceComponent.java
===================================================================
--- unity/trunk/web-common/src/main/java/pl/edu/icm/unity/webui/authn/LocaleChoiceComponent.java (rev 0)
+++ unity/trunk/web-common/src/main/java/pl/edu/icm/unity/webui/authn/LocaleChoiceComponent.java 2013-03-31 12:38:05 UTC (rev 16193)
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2013 ICM Uniwersytet Warszawski All rights reserved.
+ * See LICENCE file for licensing information.
+ */
+package pl.edu.icm.unity.webui.authn;
+
+import java.util.Locale;
+import java.util.Map;
+
+import javax.servlet.http.Cookie;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.config.ConfigurableBeanFactory;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Component;
+
+import pl.edu.icm.unity.server.authn.InvocationContext;
+import pl.edu.icm.unity.server.utils.UnityMessageSource;
+import pl.edu.icm.unity.server.utils.UnityServerConfiguration;
+import pl.edu.icm.unity.webui.UnityVaadinServlet;
+
+import com.vaadin.data.Property;
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.server.Page;
+import com.vaadin.server.VaadinService;
+import com.vaadin.server.VaadinServletResponse;
+import com.vaadin.server.VaadinSession;
+import com.vaadin.ui.Alignment;
+import com.vaadin.ui.ComboBox;
+import com.vaadin.ui.FormLayout;
+
+
+/**
+ * Allows for choosing the language
+ * @author K. Benedyczak
+ */
+@SuppressWarnings("serial")
+@Component
+@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
+public class LocaleChoiceComponent extends FormLayout
+{
+ private ComboBox chooser;
+ private Map<String, Locale> selectableLocales;
+
+ @Autowired
+ public LocaleChoiceComponent(UnityServerConfiguration cfg, UnityMessageSource msg)
+ {
+ selectableLocales = cfg.getEnabledLocales();
+ if (selectableLocales.size() < 2)
+ {
+ return;
+ } else
+ {
+ chooser = new ComboBox(msg.getMessage("LanguageChoiceComponent.language"));
+ String selected = null;
+ Locale selectedLocale = InvocationContext.getCurrent().getLocale();
+ for (String locale: selectableLocales.keySet())
+ {
+ chooser.addItem(locale);
+ if (selectableLocales.get(locale).equals(selectedLocale))
+ selected = locale;
+ }
+ if (selected != null)
+ chooser.select(selected);
+ chooser.setTextInputAllowed(false);
+ chooser.setNullSelectionAllowed(false);
+ chooser.setImmediate(true);
+ chooser.addValueChangeListener(new Property.ValueChangeListener()
+ {
+ @Override
+ public void valueChange(ValueChangeEvent event)
+ {
+ String localeName = (String) chooser.getValue();
+ Locale l = selectableLocales.get(localeName);
+
+ Cookie languageCookie = new Cookie(UnityVaadinServlet.LANGUAGE_COOKIE,
+ l.toString());
+ languageCookie.setPath("/");
+ languageCookie.setMaxAge(3600*24*31);
+ ((VaadinServletResponse)VaadinService.getCurrentResponse()).addCookie(languageCookie);
+
+ VaadinSession vSession = VaadinSession.getCurrent();
+ String originalURL = AuthenticationProcessor.getOriginalURL(vSession.getSession());
+ VaadinService.getCurrent().closeSession(vSession);
+ Page.getCurrent().setLocation(originalURL);
+ }
+ });
+ addComponent(chooser);
+ setComponentAlignment(chooser, Alignment.TOP_RIGHT);
+ }
+ setSizeUndefined();
+ }
+}
Modified: unity/trunk/web-common/src/main/java/pl/edu/icm/unity/webui/authn/extensions/PasswordRetrieval.java
===================================================================
--- unity/trunk/web-common/src/main/java/pl/edu/icm/unity/webui/authn/extensions/PasswordRetrieval.java 2013-03-30 14:49:55 UTC (rev 16192)
+++ unity/trunk/web-common/src/main/java/pl/edu/icm/unity/webui/authn/extensions/PasswordRetrieval.java 2013-03-31 12:38:05 UTC (rev 16193)
@@ -15,6 +15,7 @@
import pl.edu.icm.unity.server.authn.AuthenticationResult.Status;
import pl.edu.icm.unity.server.authn.CredentialExchange;
import pl.edu.icm.unity.server.authn.CredentialRetrieval;
+import pl.edu.icm.unity.server.utils.UnityMessageSource;
import pl.edu.icm.unity.stdext.credential.PasswordExchange;
import pl.edu.icm.unity.webui.authn.VaadinAuthentication;
@@ -28,7 +29,13 @@
private UsernameProvider usernameProvider;
private PasswordExchange credentialExchange;
private PasswordField passwordField;
+ private UnityMessageSource msg;
+ public PasswordRetrieval(UnityMessageSource msg)
+ {
+ this.msg = msg;
+ }
+
@Override
public String getBindingName()
{
@@ -62,7 +69,7 @@
public Component getComponent()
{
HorizontalLayout container = new HorizontalLayout();
- container.addComponent(new Label("Password: "));
+ container.addComponent(new Label(msg.getMessage("PasswordRetrieval.password")));
passwordField = new PasswordField();
container.addComponent(passwordField);
return container;
@@ -81,7 +88,8 @@
String password = passwordField.getValue();
if (username.equals("") && password.equals(""))
{
- passwordField.setComponentError(new UserError("No value"));
+ passwordField.setComponentError(new UserError(
+ msg.getMessage("PasswordRetrieval.noPassword")));
return new AuthenticationResult(Status.notApplicable, null);
}
try
@@ -90,7 +98,8 @@
return new AuthenticationResult(Status.success, authenticatedEntity);
} catch (Exception e)
{
- passwordField.setComponentError(new UserError("Wrong username or password"));
+ passwordField.setComponentError(new UserError(
+ msg.getMessage("PasswordRetrieval.wrongPassword")));
return new AuthenticationResult(Status.deny, null);
}
}
Modified: unity/trunk/web-common/src/main/java/pl/edu/icm/unity/webui/authn/extensions/PasswordRetrievalFactory.java
===================================================================
--- unity/trunk/web-common/src/main/java/pl/edu/icm/unity/webui/authn/extensions/PasswordRetrievalFactory.java 2013-03-30 14:49:55 UTC (rev 16192)
+++ unity/trunk/web-common/src/main/java/pl/edu/icm/unity/webui/authn/extensions/PasswordRetrievalFactory.java 2013-03-31 12:38:05 UTC (rev 16193)
@@ -4,11 +4,13 @@
*/
package pl.edu.icm.unity.webui.authn.extensions;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import pl.edu.icm.unity.server.authn.CredentialExchange;
import pl.edu.icm.unity.server.authn.CredentialRetrieval;
import pl.edu.icm.unity.server.authn.CredentialRetrievalFactory;
+import pl.edu.icm.unity.server.utils.UnityMessageSource;
import pl.edu.icm.unity.stdext.credential.PasswordExchange;
import pl.edu.icm.unity.webui.authn.VaadinAuthentication;
@@ -20,6 +22,8 @@
public class PasswordRetrievalFactory implements CredentialRetrievalFactory
{
public static final String NAME = "web-password";
+ @Autowired
+ private UnityMessageSource msg;
@Override
public String getName()
@@ -30,13 +34,13 @@
@Override
public String getDescription()
{
- return "Allows for retrieving password typed in a web widget";
+ return "PasswordRetrievalFactory.desc";
}
@Override
public CredentialRetrieval newInstance()
{
- return new PasswordRetrieval();
+ return new PasswordRetrieval(msg);
}
@Override
Modified: unity/trunk/web-common/src/main/resources/META-INF/components.xml
===================================================================
--- unity/trunk/web-common/src/main/resources/META-INF/components.xml 2013-03-30 14:49:55 UTC (rev 16192)
+++ unity/trunk/web-common/src/main/resources/META-INF/components.xml 2013-03-31 12:38:05 UTC (rev 16193)
@@ -8,9 +8,13 @@
<bean class="pl.edu.icm.unity.webui.authn.extensions.PasswordRetrievalFactory"/>
+ <bean class="pl.edu.icm.unity.server.utils.UnityMessageBundles">
+ <property name="bundle" value="pl/edu/icm/unity/webui/messages/messages"/>
+ </bean>
<!-- Vaadin components - must have the prototype scope. The UI objects must also have the id set to the
simple name of its class -->
<bean scope="prototype" id="AuthenticationUI" class="pl.edu.icm.unity.webui.authn.AuthenticationUI"/>
+ <bean scope="prototype" class="pl.edu.icm.unity.webui.authn.LocaleChoiceComponent"/>
</beans>
\ No newline at end of file
Added: unity/trunk/web-common/src/main/resources/pl/edu/icm/unity/webui/messages/messages.properties
===================================================================
--- unity/trunk/web-common/src/main/resources/pl/edu/icm/unity/webui/messages/messages.properties (rev 0)
+++ unity/trunk/web-common/src/main/resources/pl/edu/icm/unity/webui/messages/messages.properties 2013-03-31 12:38:05 UTC (rev 16193)
@@ -0,0 +1,11 @@
+LanguageChoiceComponent.language=Language selection:
+AuthenticationUI.authnSet=Authentication option {0}
+AuthenticationUI.authnenticateButton=Authenticate
+AuthenticationUI.username=Username:
+AuthenticationProcessor.authnFailed=Authentication failed
+AuthenticationProcessor.authnWrongUsers=Two different users were authenticated
+
+PasswordRetrievalFactory.desc=Allows for retrieving password typed in a web widget
+PasswordRetrieval.password=Password:
+PasswordRetrieval.noPassword=Missing password
+PasswordRetrieval.wrongPassword=Wrong username or password
\ No newline at end of file
Added: unity/trunk/web-common/src/main/resources/pl/edu/icm/unity/webui/messages/messages_pl.properties
===================================================================
--- unity/trunk/web-common/src/main/resources/pl/edu/icm/unity/webui/messages/messages_pl.properties (rev 0)
+++ unity/trunk/web-common/src/main/resources/pl/edu/icm/unity/webui/messages/messages_pl.properties 2013-03-31 12:38:05 UTC (rev 16193)
@@ -0,0 +1,11 @@
+LanguageChoiceComponent.language=Wybór języka:
+AuthenticationUI.authnSet=Uwierzytelnianie nr {0}
+AuthenticationUI.authnenticateButton=Zaloguj
+AuthenticationUI.username=Nazwa użytkownika:
+AuthenticationProcessor.authnFailed=Błąd uwierzytelniania
+AuthenticationProcessor.authnWrongUsers=Uwierzytelniono jako dwóch różnych użytkowników
+
+PasswordRetrievalFactory.desc=Pozwala na pobieranie hasła za pomocą kontrolki interfejsu webowego
+PasswordRetrieval.password=Hasło:
+PasswordRetrieval.noPassword=Brak hasła
+PasswordRetrieval.wrongPassword=Zła nazwa użytkownika lub hasło
\ No newline at end of file
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|