PL-10002 REST request locale should be searched in the user language

This commit is contained in:
Maxim Gorbunkov 2017-11-21 14:40:38 +04:00
parent def13fc838
commit 4f4009a5f6
19 changed files with 255 additions and 65 deletions

View File

@ -841,6 +841,7 @@ create table SYS_REST_API_TOKEN (
AUTHENTICATION_BYTES longvarbinary,
EXPIRY timestamp,
USER_LOGIN varchar(50),
LOCALE varchar(200),
--
primary key (ID)
)^

View File

@ -900,6 +900,7 @@ create table SYS_REST_API_TOKEN (
AUTHENTICATION_BYTES image,
EXPIRY datetime,
USER_LOGIN varchar(50),
LOCALE varchar(200),
--
primary key (ID)
)^

View File

@ -914,6 +914,7 @@ create table SYS_REST_API_TOKEN (
AUTHENTICATION_BYTES longblob,
EXPIRY datetime(3),
USER_LOGIN varchar(50),
LOCALE varchar(200),
--
primary key (ID)
)^

View File

@ -691,6 +691,7 @@ create table SYS_REST_API_TOKEN (
AUTHENTICATION_BYTES blob,
EXPIRY timestamp,
USER_LOGIN varchar2(50),
LOCALE varchar2(200),
--
primary key (ID)
)^

View File

@ -875,6 +875,7 @@ create table SYS_REST_API_TOKEN (
AUTHENTICATION_BYTES bytea,
EXPIRY timestamp,
USER_LOGIN varchar(50),
LOCALE varchar(200),
--
primary key (ID)
)^

View File

@ -0,0 +1 @@
alter table SYS_REST_API_TOKEN add LOCALE varchar(200)^

View File

@ -0,0 +1 @@
alter table SYS_REST_API_TOKEN add LOCALE varchar(200)^

View File

@ -0,0 +1 @@
alter table SYS_REST_API_TOKEN add LOCALE varchar(200)^

View File

@ -0,0 +1 @@
alter table SYS_REST_API_TOKEN add LOCALE varchar2(200);

View File

@ -0,0 +1 @@
alter table SYS_REST_API_TOKEN add LOCALE varchar(200)^

View File

@ -16,6 +16,7 @@
package com.haulmont.cuba.restapi;
import com.google.common.base.Strings;
import com.haulmont.cuba.core.EntityManager;
import com.haulmont.cuba.core.Persistence;
import com.haulmont.cuba.core.Transaction;
@ -33,6 +34,7 @@ import com.haulmont.cuba.security.auth.AuthenticationManager;
import com.haulmont.cuba.security.global.NoUserSessionException;
import com.haulmont.cuba.security.global.UserSession;
import com.haulmont.cuba.security.sys.UserSessionManager;
import org.apache.commons.lang.LocaleUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@ -81,7 +83,7 @@ public class ServerTokenStoreImpl implements ServerTokenStore {
private ConcurrentHashMap<String, byte[]> tokenValueToAccessTokenStore = new ConcurrentHashMap<>();
private ConcurrentHashMap<String, byte[]> tokenValueToAuthenticationStore = new ConcurrentHashMap<>();
private ConcurrentHashMap<String, byte[]> authenticationToAccessTokenStore = new ConcurrentHashMap<>();
private ConcurrentHashMap<String, UUID> tokenValueToSessionIdStore = new ConcurrentHashMap<>();
private ConcurrentHashMap<String, RestUserSessionInfo> tokenValueToSessionInfoStore = new ConcurrentHashMap<>();
private ConcurrentHashMap<String, String> tokenValueToAuthenticationKeyStore = new ConcurrentHashMap<>();
private ConcurrentHashMap<String, String> tokenValueToUserLoginStore = new ConcurrentHashMap<>();
@ -107,7 +109,7 @@ public class ServerTokenStoreImpl implements ServerTokenStore {
@Override
public byte[] getState() {
if (tokenValueToAccessTokenStore.isEmpty() && tokenValueToAuthenticationStore.isEmpty() && authenticationToAccessTokenStore.isEmpty()
&& tokenValueToSessionIdStore.isEmpty() && tokenValueToAuthenticationKeyStore.isEmpty()
&& tokenValueToSessionInfoStore.isEmpty() && tokenValueToAuthenticationKeyStore.isEmpty()
&& tokenValueToUserLoginStore.isEmpty()) {
return new byte[0];
}
@ -120,7 +122,7 @@ public class ServerTokenStoreImpl implements ServerTokenStore {
oos.writeObject(tokenValueToAccessTokenStore);
oos.writeObject(tokenValueToAuthenticationStore);
oos.writeObject(authenticationToAccessTokenStore);
oos.writeObject(tokenValueToSessionIdStore);
oos.writeObject(tokenValueToSessionInfoStore);
oos.writeObject(tokenValueToAuthenticationKeyStore);
oos.writeObject(tokenValueToUserLoginStore);
} catch (IOException e) {
@ -146,7 +148,7 @@ public class ServerTokenStoreImpl implements ServerTokenStore {
tokenValueToAccessTokenStore = (ConcurrentHashMap<String, byte[]>) ois.readObject();
tokenValueToAuthenticationStore = (ConcurrentHashMap<String, byte[]>) ois.readObject();
authenticationToAccessTokenStore = (ConcurrentHashMap<String, byte[]>) ois.readObject();
tokenValueToSessionIdStore = (ConcurrentHashMap<String, UUID>) ois.readObject();
tokenValueToSessionInfoStore = (ConcurrentHashMap<String, RestUserSessionInfo>) ois.readObject();
tokenValueToAuthenticationKeyStore = (ConcurrentHashMap<String, String>) ois.readObject();
tokenValueToUserLoginStore = (ConcurrentHashMap<String, String>) ois.readObject();
} catch (IOException | ClassNotFoundException e) {
@ -157,10 +159,10 @@ public class ServerTokenStoreImpl implements ServerTokenStore {
}
});
clusterManagerAPI.addListener(TokenStorePutSessionMsg.class, new ClusterListenerAdapter<TokenStorePutSessionMsg>() {
clusterManagerAPI.addListener(TokenStorePutSessionInfoMsg.class, new ClusterListenerAdapter<TokenStorePutSessionInfoMsg>() {
@Override
public void receive(TokenStorePutSessionMsg message) {
_putSessionId(message.getTokenValue(), message.getSessionId());
public void receive(TokenStorePutSessionInfoMsg message) {
_putSessionInfo(message.getTokenValue(), message.getSessionInfo());
}
});
@ -223,12 +225,14 @@ public class ServerTokenStoreImpl implements ServerTokenStore {
String authenticationKey,
byte[] authenticationBytes,
Date tokenExpiry,
String userLogin) {
String userLogin,
Locale locale) {
storeAccessTokenToMemory(tokenValue, accessTokenBytes, authenticationKey, authenticationBytes, tokenExpiry, userLogin);
if (serverConfig.getRestStoreTokensInDb()) {
try (Transaction tx = persistence.getTransaction()) {
removeAccessTokenFromDatabase(tokenValue);
storeAccessTokenToDatabase(tokenValue, accessTokenBytes, authenticationKey, authenticationBytes, tokenExpiry, userLogin);
storeAccessTokenToDatabase(tokenValue, accessTokenBytes, authenticationKey, authenticationBytes,
tokenExpiry, userLogin, locale);
tx.commit();
}
}
@ -263,7 +267,8 @@ public class ServerTokenStoreImpl implements ServerTokenStore {
String authenticationKey,
byte[] authenticationBytes,
Date tokenExpiry,
String userLogin) {
String userLogin,
@Nullable Locale locale) {
try (Transaction tx = persistence.getTransaction()) {
EntityManager em = persistence.getEntityManager();
RestApiToken restApiToken = metadata.create(RestApiToken.class);
@ -273,6 +278,7 @@ public class ServerTokenStoreImpl implements ServerTokenStore {
restApiToken.setAuthenticationBytes(authenticationBytes);
restApiToken.setExpiry(tokenExpiry);
restApiToken.setUserLogin(userLogin);
restApiToken.setLocale(locale != null ? locale.toString() : null);
em.persist(restApiToken);
tx.commit();
}
@ -358,21 +364,33 @@ public class ServerTokenStoreImpl implements ServerTokenStore {
}
@Override
public UUID getSessionIdByTokenValue(String tokenValue) {
return tokenValueToSessionIdStore.get(tokenValue);
public RestUserSessionInfo getSessionInfoByTokenValue(String tokenValue) {
RestUserSessionInfo sessionInfo = tokenValueToSessionInfoStore.get(tokenValue);
if (sessionInfo == null && serverConfig.getRestStoreTokensInDb()) {
RestApiToken restApiToken = getRestApiTokenByTokenValueFromDatabase(tokenValue);
if (restApiToken != null) {
String localeStr = restApiToken.getLocale();
if (!Strings.isNullOrEmpty(localeStr)) {
Locale locale = LocaleUtils.toLocale(localeStr);
return new RestUserSessionInfo(null, locale);
}
}
}
return sessionInfo;
}
@Override
public UUID putSessionId(String tokenValue, UUID sessionId) {
UUID uuid = _putSessionId(tokenValue, sessionId);
clusterManagerAPI.send(new TokenStorePutSessionMsg(tokenValue, sessionId));
return uuid;
public RestUserSessionInfo putSessionInfo(String tokenValue, RestUserSessionInfo sessionInfo) {
RestUserSessionInfo info = _putSessionInfo(tokenValue, sessionInfo);
clusterManagerAPI.send(new TokenStorePutSessionInfoMsg(tokenValue, sessionInfo));
return info;
}
protected UUID _putSessionId(String tokenValue, UUID sessionId) {
protected RestUserSessionInfo _putSessionInfo(String tokenValue, RestUserSessionInfo sessionInfo) {
lock.writeLock().lock();
try {
return tokenValueToSessionIdStore.put(tokenValue, sessionId);
return tokenValueToSessionInfoStore.put(tokenValue, sessionInfo);
} finally {
lock.writeLock().unlock();
}
@ -388,7 +406,7 @@ public class ServerTokenStoreImpl implements ServerTokenStore {
}
protected void removeAccessTokenFromMemory(String tokenValue) {
UUID sessionId;
RestUserSessionInfo sessionInfo;
lock.writeLock().lock();
try {
tokenValueToAccessTokenStore.remove(tokenValue);
@ -398,13 +416,13 @@ public class ServerTokenStoreImpl implements ServerTokenStore {
if (authenticationKey != null) {
authenticationToAccessTokenStore.remove(authenticationKey);
}
sessionId = tokenValueToSessionIdStore.remove(tokenValue);
sessionInfo = tokenValueToSessionInfoStore.remove(tokenValue);
} finally {
lock.writeLock().unlock();
}
if (sessionId != null) {
if (sessionInfo != null) {
try {
UserSession session = userSessionManager.findSession(sessionId);
UserSession session = userSessionManager.findSession(sessionInfo.getId());
if (session != null) {
AppContext.setSecurityContext(new SecurityContext(session));
try {

View File

@ -22,20 +22,20 @@ import java.util.UUID;
/**
* Cluster message containing an information about the mapping between token value and middleware session
*/
public class TokenStorePutSessionMsg implements Serializable {
public class TokenStorePutSessionInfoMsg implements Serializable {
protected String tokenValue;
protected UUID sessionId;
protected RestUserSessionInfo sessionInfo;
public TokenStorePutSessionMsg(String tokenValue, UUID sessionId) {
public TokenStorePutSessionInfoMsg(String tokenValue, RestUserSessionInfo sessionInfo) {
this.tokenValue = tokenValue;
this.sessionId = sessionId;
this.sessionInfo = sessionInfo;
}
public String getTokenValue() {
return tokenValue;
}
public UUID getSessionId() {
return sessionId;
public RestUserSessionInfo getSessionInfo() {
return sessionInfo;
}
}

View File

@ -54,6 +54,9 @@ public class RestApiToken extends BaseUuidEntity implements Creatable{
@Column(name = "USER_LOGIN")
protected String userLogin;
@Column(name = "LOCALE")
protected String locale;
public String getAccessTokenValue() {
return accessTokenValue;
}
@ -121,4 +124,12 @@ public class RestApiToken extends BaseUuidEntity implements Creatable{
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
public String getLocale() {
return locale;
}
public void setLocale(String locale) {
this.locale = locale;
}
}

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2008-2017 Haulmont.
*
* 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 com.haulmont.cuba.restapi;
import com.haulmont.cuba.security.global.UserSession;
import java.io.Serializable;
import java.util.Locale;
import java.util.UUID;
public class RestUserSessionInfo implements Serializable {
protected UUID id;
protected Locale locale;
public RestUserSessionInfo(UserSession userSession) {
this.id = userSession.getId();
this.locale = userSession.getLocale();
}
public RestUserSessionInfo(UUID id, Locale locale) {
this.id = id;
this.locale = locale;
}
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
public Locale getLocale() {
return locale;
}
public void setLocale(Locale locale) {
this.locale = locale;
}
}

View File

@ -17,8 +17,8 @@
package com.haulmont.cuba.restapi;
import java.util.Date;
import java.util.Locale;
import java.util.Set;
import java.util.UUID;
/**
* OAuth token store for the REST API.
@ -31,15 +31,16 @@ public interface ServerTokenStore {
Set<String> getTokenValuesByUserLogin(String userLogin);
void storeAccessToken(String tokenValue, byte[] accessTokenBytes, String authenticationKey, byte[] authenticationBytes, Date tokenExpiry, String userLogin);
void storeAccessToken(String tokenValue, byte[] accessTokenBytes, String authenticationKey,
byte[] authenticationBytes, Date tokenExpiry, String userLogin, Locale locale);
byte[] getAccessTokenByTokenValue(String tokenValue);
byte[] getAuthenticationByTokenValue(String tokenValue);
UUID getSessionIdByTokenValue(String authenticationKey);
RestUserSessionInfo getSessionInfoByTokenValue(String tokenValue);
UUID putSessionId(String authenticationKey, UUID sessionId);
RestUserSessionInfo putSessionInfo(String tokenValue, RestUserSessionInfo sessionInfo);
void removeAccessToken(String tokenValue);

View File

@ -21,12 +21,14 @@ import com.haulmont.cuba.core.global.ClientType;
import com.haulmont.cuba.core.global.GlobalConfig;
import com.haulmont.cuba.core.sys.AppContext;
import com.haulmont.cuba.core.sys.SecurityContext;
import com.haulmont.cuba.restapi.RestUserSessionInfo;
import com.haulmont.cuba.restapi.ServerTokenStore;
import com.haulmont.cuba.security.app.TrustedClientService;
import com.haulmont.cuba.security.auth.AuthenticationService;
import com.haulmont.cuba.security.auth.TrustedClientCredentials;
import com.haulmont.cuba.security.global.LoginException;
import com.haulmont.cuba.security.global.UserSession;
import com.haulmont.restapi.common.RestAuthUtils;
import com.haulmont.restapi.config.RestApiConfig;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpHeaders;
@ -73,6 +75,9 @@ public class ClientProxyTokenStore implements TokenStore {
protected AuthenticationKeyGenerator authenticationKeyGenerator;
@Inject
protected RestAuthUtils restAuthUtils;
public void setAuthenticationKeyGenerator(AuthenticationKeyGenerator authenticationKeyGenerator) {
this.authenticationKeyGenerator = authenticationKeyGenerator;
}
@ -96,12 +101,18 @@ public class ClientProxyTokenStore implements TokenStore {
public void storeAccessToken(OAuth2AccessToken token, OAuth2Authentication authentication) {
String authenticationKey = authenticationKeyGenerator.extractKey(authentication);
String userLogin = authentication.getName();
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
HttpServletRequest request = attributes.getRequest();
Locale locale = restAuthUtils.extractLocaleFromRequestHeader(request);
serverTokenStore.storeAccessToken(token.getValue(),
serializeAccessToken(token),
authenticationKey,
serializeAuthentication(authentication),
token.getExpiration(),
userLogin);
userLogin,
locale);
processSession(authentication, token.getValue());
log.info("REST API access token stored: [{}] {}", authentication.getPrincipal(), token.getValue()) ;
}
@ -130,8 +141,8 @@ public class ClientProxyTokenStore implements TokenStore {
* the id doesn't exist in the middleware, then the trusted login attempt is performed.
*/
protected void processSession(OAuth2Authentication authentication, String tokenValue) {
UUID sessionId = serverTokenStore.getSessionIdByTokenValue(tokenValue);
RestUserSessionInfo sessionInfo = serverTokenStore.getSessionInfoByTokenValue(tokenValue);
UUID sessionId = sessionInfo != null ? sessionInfo.getId() : null;
if (sessionId == null) {
@SuppressWarnings("unchecked")
Map<String, String> userAuthenticationDetails =
@ -160,9 +171,11 @@ public class ClientProxyTokenStore implements TokenStore {
try {
ServletRequestAttributes attributes =
(ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
Locale locale = sessionInfo != null ?
sessionInfo.getLocale() :
null;
TrustedClientCredentials credentials = new TrustedClientCredentials(username,
restApiConfig.getTrustedClientPassword(), getDefaultLocale());
restApiConfig.getTrustedClientPassword(), locale);
credentials.setClientType(ClientType.REST_API);
if (attributes != null) {
HttpServletRequest request = attributes.getRequest();
@ -172,6 +185,11 @@ public class ClientProxyTokenStore implements TokenStore {
credentials.setClientInfo(makeClientInfo(""));
}
//if locale was not determined then use the user locale
if (locale == null) {
credentials.setOverrideLocale(false);
}
session = authenticationService.login(credentials).getSession();
} catch (LoginException e) {
throw new OAuth2Exception("Cannot login to the middleware");
@ -179,7 +197,7 @@ public class ClientProxyTokenStore implements TokenStore {
}
if (session != null) {
serverTokenStore.putSessionId(tokenValue, session.getId());
serverTokenStore.putSessionInfo(tokenValue, new RestUserSessionInfo(session));
AppContext.setSecurityContext(new SecurityContext(session));
}
}

View File

@ -17,18 +17,15 @@
package com.haulmont.restapi.auth;
import com.google.common.base.Strings;
import com.haulmont.cuba.core.global.Configuration;
import com.haulmont.cuba.core.global.Events;
import com.haulmont.cuba.core.global.GlobalConfig;
import com.haulmont.cuba.core.global.MessageTools;
import com.haulmont.cuba.core.global.*;
import com.haulmont.cuba.core.sys.AppContext;
import com.haulmont.cuba.core.sys.SecurityContext;
import com.haulmont.cuba.core.sys.UserInvocationContext;
import com.haulmont.restapi.common.RestAuthUtils;
import com.haulmont.restapi.events.AfterRestInvocationEvent;
import com.haulmont.restapi.events.BeforeRestInvocationEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetails;
@ -39,7 +36,6 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Locale;
import java.util.Map;
import java.util.UUID;
/**
@ -56,11 +52,16 @@ public class CubaRestLastSecurityFilter implements Filter {
@Inject
protected Configuration configuration;
@Inject
protected MessageTools messageTools;
@Inject
protected Events events;
@Inject
protected RestAuthUtils restAuthUtils;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// do nothing
@ -126,26 +127,14 @@ public class CubaRestLastSecurityFilter implements Filter {
* Method parses the request locale and sets it to the {@link UserInvocationContext}
*/
protected void parseRequestLocale(ServletRequest request) {
//Take the locale value either from the 'Accept-Language' http header or take the default one
Locale locale = null;
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
if (!Strings.isNullOrEmpty(httpServletRequest.getHeader(HttpHeaders.ACCEPT_LANGUAGE))) {
Locale requestLocale = request.getLocale();
GlobalConfig globalConfig = configuration.getConfig(GlobalConfig.class);
Map<String, Locale> availableLocales = globalConfig.getAvailableLocales();
if (availableLocales.values().contains(requestLocale)) {
locale = requestLocale;
}
}
if (locale == null) {
locale = messageTools.getDefaultLocale();
}
SecurityContext securityContext = AppContext.getSecurityContext();
if (securityContext != null) {
UUID sessionId = securityContext.getSessionId();
if (sessionId != null) {
UserInvocationContext.setRequestScopeInfo(sessionId, locale, null, null, null);
Locale locale = restAuthUtils.extractLocaleFromRequestHeader((HttpServletRequest) request);
if (locale != null) {
SecurityContext securityContext = AppContext.getSecurityContext();
if (securityContext != null) {
UUID sessionId = securityContext.getSessionId();
if (sessionId != null) {
UserInvocationContext.setRequestScopeInfo(sessionId, locale, null, null, null);
}
}
}
}

View File

@ -31,6 +31,7 @@ import com.haulmont.cuba.security.global.RestApiAccessDeniedException;
import com.haulmont.cuba.security.global.UserSession;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpHeaders;
import com.haulmont.restapi.common.RestAuthUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.AuthenticationProvider;
@ -49,6 +50,7 @@ import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
public class CubaUserAuthenticationProvider implements AuthenticationProvider, Serializable {
@ -66,6 +68,9 @@ public class CubaUserAuthenticationProvider implements AuthenticationProvider, S
@Inject
protected Configuration configuration;
@Inject
protected RestAuthUtils restAuthUtils;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
@ -89,11 +94,21 @@ public class CubaUserAuthenticationProvider implements AuthenticationProvider, S
try {
String passwordHash = passwordEncryption.getPlainHash((String) token.getCredentials());
LoginPasswordCredentials credentials = new LoginPasswordCredentials(login, passwordHash, request.getLocale());
LoginPasswordCredentials credentials = new LoginPasswordCredentials(login, passwordHash);
credentials.setIpAddress(ipAddress);
credentials.setClientType(ClientType.REST_API);
credentials.setClientInfo(makeClientInfo(request.getHeader(HttpHeaders.USER_AGENT)));
//if the locale value is explicitly passed in the Accept-Language header then set its value to the
//credentials. Otherwise, the locale of the user should be used
Locale locale = restAuthUtils.extractLocaleFromRequestHeader(request);
if (locale != null) {
credentials.setLocale(locale);
credentials.setOverrideLocale(true);
} else {
credentials.setOverrideLocale(false);
}
session = authenticationService.login(credentials).getSession();
} catch (AccountLockedException le) {
log.info("Blocked user login attempt: login={}, ip={}", login, ipAddress);

View File

@ -0,0 +1,72 @@
/*
* Copyright (c) 2008-2017 Haulmont.
*
* 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 com.haulmont.restapi.common;
import com.google.common.base.Strings;
import com.haulmont.cuba.core.global.Configuration;
import com.haulmont.cuba.core.global.GlobalConfig;
import com.haulmont.cuba.core.global.MessageTools;
import com.haulmont.cuba.core.global.UserSessionSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;
import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import java.util.Locale;
import java.util.Map;
/**
* REST API authentication utility class
*/
@Component("cuba_RestAuthUtils")
public class RestAuthUtils {
@Inject
protected Configuration configuration;
@Inject
protected UserSessionSource userSessionSource;
@Inject
protected MessageTools messageTools;
protected Logger log = LoggerFactory.getLogger(RestAuthUtils.class);
/**
* Method extracts locale information from the Accept-Language header. If no such header is specified or the
* passed locale is not among application available locales, then null is returned
*/
@Nullable
public Locale extractLocaleFromRequestHeader(HttpServletRequest request) {
Locale locale = null;
if (!Strings.isNullOrEmpty(request.getHeader(HttpHeaders.ACCEPT_LANGUAGE))) {
Locale requestLocale = request.getLocale();
GlobalConfig globalConfig = configuration.getConfig(GlobalConfig.class);
Map<String, Locale> availableLocales = globalConfig.getAvailableLocales();
if (availableLocales.values().contains(requestLocale)) {
locale = requestLocale;
} else {
log.warn("Locale {} passed in the Accept-Language header is not supported by the application. It was ignored.");
}
}
return locale;
}
}