IDEMPIERE-2944 Preserve iDempiere session between sucessive webservice calls / integrate peer review from hengsin
AP2-330 Web services loggin. Fix thread safety.
This commit is contained in:
parent
48b927327a
commit
2fce02d02e
|
@ -65,11 +65,8 @@ public class CompositeServiceImpl extends AbstractService implements CompositeSe
|
|||
*/
|
||||
@Override
|
||||
public CompositeResponsesDocument compositeOperation(CompositeRequestDocument reqs) {
|
||||
boolean connected = getCompiereService().isConnected();
|
||||
|
||||
try {
|
||||
if (!connected)
|
||||
getCompiereService().connect();
|
||||
getCompiereService().connect();
|
||||
|
||||
CompositeResponsesDocument ret = CompositeResponsesDocument.Factory.newInstance();
|
||||
CompositeResponses resps = ret.addNewCompositeResponses();
|
||||
|
@ -124,8 +121,7 @@ public class CompositeServiceImpl extends AbstractService implements CompositeSe
|
|||
|
||||
return ret;
|
||||
} finally {
|
||||
if (!connected)
|
||||
getCompiereService().disconnect();
|
||||
getCompiereService().disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@ public class MWebService extends X_WS_WebService
|
|||
* @param webServiceValue
|
||||
* @return Table
|
||||
*/
|
||||
public static MWebService get (Properties ctx, String webServiceValue)
|
||||
public static synchronized MWebService get (Properties ctx, String webServiceValue)
|
||||
{
|
||||
if (webServiceValue == null)
|
||||
return null;
|
||||
|
|
|
@ -79,13 +79,13 @@ public class CompiereService {
|
|||
|
||||
public final String dateFormatOnlyForCtx = "yyyy-MM-dd";
|
||||
|
||||
private boolean m_connected;
|
||||
private int m_connectCount;
|
||||
|
||||
/**
|
||||
*
|
||||
* @return AD_Client_ID of current request
|
||||
*/
|
||||
public int getAD_Client_ID() {
|
||||
public synchronized int getAD_Client_ID() {
|
||||
return m_AD_Client_ID;
|
||||
}
|
||||
|
||||
|
@ -93,7 +93,7 @@ public class CompiereService {
|
|||
*
|
||||
* @return AD_Org_ID of current request
|
||||
*/
|
||||
public int getAD_Org_ID() {
|
||||
public synchronized int getAD_Org_ID() {
|
||||
return m_AD_Org_ID;
|
||||
}
|
||||
|
||||
|
@ -101,7 +101,7 @@ public class CompiereService {
|
|||
*
|
||||
* @return context of current request
|
||||
*/
|
||||
public Properties getCtx() {
|
||||
public synchronized Properties getCtx() {
|
||||
return Env.getCtx();
|
||||
}
|
||||
|
||||
|
@ -111,7 +111,7 @@ public class CompiereService {
|
|||
public CompiereService()
|
||||
{
|
||||
m_loggedin = false;
|
||||
m_connected = false;
|
||||
m_connectCount = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -119,69 +119,51 @@ public class CompiereService {
|
|||
*/
|
||||
public void connect()
|
||||
{
|
||||
if (!m_connected)
|
||||
{
|
||||
CompiereUtil.initWeb();
|
||||
|
||||
m_connected = true;
|
||||
|
||||
ServerContext.setCurrentInstance(new Properties());
|
||||
Env.setContext(getCtx(), "#AD_Language", "en_US" );
|
||||
m_language = Language.getLanguage("en_US");
|
||||
|
||||
dateFormat = DisplayType.getDateFormat(DisplayType.Date, m_language);
|
||||
dateTimeFormat = DisplayType.getDateFormat(DisplayType.DateTime, m_language);
|
||||
timeFormat = DisplayType.getDateFormat(DisplayType.Time, m_language);
|
||||
dateFormatJDBC = DisplayType.getDateFormat_JDBC();
|
||||
dateTimeFormatJDBC = DisplayType.getTimestampFormat_Default();
|
||||
timeFormatJDBC = DisplayType.getTimeFormat_Default();
|
||||
}
|
||||
CompiereUtil.initWeb();
|
||||
|
||||
ServerContext.setCurrentInstance(new Properties());
|
||||
Env.setContext(getCtx(), "#AD_Language", "en_US" );
|
||||
m_language = Language.getLanguage("en_US");
|
||||
|
||||
dateFormat = DisplayType.getDateFormat(DisplayType.Date, m_language);
|
||||
dateTimeFormat = DisplayType.getDateFormat(DisplayType.DateTime, m_language);
|
||||
timeFormat = DisplayType.getDateFormat(DisplayType.Time, m_language);
|
||||
dateFormatJDBC = DisplayType.getDateFormat_JDBC();
|
||||
dateTimeFormatJDBC = DisplayType.getTimestampFormat_Default();
|
||||
timeFormatJDBC = DisplayType.getTimeFormat_Default();
|
||||
|
||||
m_connectCount++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increase connect count
|
||||
*/
|
||||
public synchronized void connectCacheInstance()
|
||||
{
|
||||
m_connectCount++;
|
||||
}
|
||||
|
||||
/**
|
||||
* cleanup request
|
||||
*/
|
||||
public void disconnect()
|
||||
public synchronized void disconnect()
|
||||
{
|
||||
m_connectCount--;
|
||||
// TODO: create a thread that checks expired connected compiereservices and log them out
|
||||
if (isExpired()) {
|
||||
synchronized (csMap) {
|
||||
//save session in cache
|
||||
String key = getKey(m_AD_Client_ID,
|
||||
m_AD_Org_ID,
|
||||
m_userName,
|
||||
m_AD_Role_ID,
|
||||
m_M_Warehouse_ID,
|
||||
m_locale,
|
||||
m_password,
|
||||
m_IPAddress);
|
||||
if (csMap.containsKey(key)) {
|
||||
csMap.remove(key.toString());
|
||||
ctxMap.remove(key.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if started
|
||||
*/
|
||||
public boolean isConnected()
|
||||
{
|
||||
return m_connected;
|
||||
expungeIfExpire();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Language of current request
|
||||
*/
|
||||
public Language getLanguage() {
|
||||
public synchronized Language getLanguage() {
|
||||
return m_language;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if already logged in
|
||||
*/
|
||||
public boolean isLoggedIn() {
|
||||
public synchronized boolean isLoggedIn() {
|
||||
return m_loggedin;
|
||||
}
|
||||
|
||||
|
@ -195,7 +177,7 @@ public class CompiereService {
|
|||
* @param AD_Org_ID org
|
||||
* @param M_Warehouse_ID warehouse
|
||||
*/
|
||||
private String checkLogin (Properties ctx, int AD_User_ID, int AD_Role_ID, int AD_Client_ID, int AD_Org_ID, int M_Warehouse_ID)
|
||||
private synchronized String checkLogin (Properties ctx, int AD_User_ID, int AD_Role_ID, int AD_Client_ID, int AD_Org_ID, int M_Warehouse_ID)
|
||||
{
|
||||
// Get Login Info
|
||||
String loginInfo = null;
|
||||
|
@ -261,7 +243,7 @@ public class CompiereService {
|
|||
* @param Lang
|
||||
* @return true if login is successful
|
||||
*/
|
||||
public boolean login( int AD_User_ID, int AD_Role_ID, int AD_Client_ID, int AD_Org_ID, int M_Warehouse_ID, String Lang ) {
|
||||
public synchronized boolean login( int AD_User_ID, int AD_Role_ID, int AD_Client_ID, int AD_Org_ID, int M_Warehouse_ID, String Lang ) {
|
||||
m_loggedin = false;
|
||||
String loginInfo = checkLogin (getCtx(), AD_User_ID, AD_Role_ID, AD_Client_ID, AD_Org_ID, M_Warehouse_ID );
|
||||
if (loginInfo == null)
|
||||
|
@ -341,7 +323,7 @@ public class CompiereService {
|
|||
*
|
||||
* @return AD_User_ID of current request
|
||||
*/
|
||||
public int getAD_User_ID() {
|
||||
public synchronized int getAD_User_ID() {
|
||||
return m_AD_User_ID;
|
||||
}
|
||||
|
||||
|
@ -349,7 +331,7 @@ public class CompiereService {
|
|||
*
|
||||
* @return AD_Role_ID of current request
|
||||
*/
|
||||
public int getAD_Role_ID() {
|
||||
public synchronized int getAD_Role_ID() {
|
||||
return m_AD_Role_ID;
|
||||
}
|
||||
|
||||
|
@ -357,7 +339,7 @@ public class CompiereService {
|
|||
*
|
||||
* @return locale code of current request
|
||||
*/
|
||||
public String getLocale() {
|
||||
public synchronized String getLocale() {
|
||||
return m_locale;
|
||||
}
|
||||
|
||||
|
@ -365,7 +347,7 @@ public class CompiereService {
|
|||
*
|
||||
* @return M_Warehouse_ID of current request
|
||||
*/
|
||||
public int getM_Warehouse_ID() {
|
||||
public synchronized int getM_Warehouse_ID() {
|
||||
return m_M_Warehouse_ID;
|
||||
}
|
||||
|
||||
|
@ -373,43 +355,43 @@ public class CompiereService {
|
|||
*
|
||||
* @return logged in user name of current request
|
||||
*/
|
||||
public String getUserName() {
|
||||
public synchronized String getUserName() {
|
||||
return m_userName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return set password
|
||||
*/
|
||||
public void setPassword(String pass) {
|
||||
public synchronized void setPassword(String pass) {
|
||||
m_password = pass;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return logged in password of current request
|
||||
*/
|
||||
public String getPassword() {
|
||||
public synchronized String getPassword() {
|
||||
return m_password;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return set expiry minutes
|
||||
*/
|
||||
public void setExpiryMinutes(int expiryMinutes) {
|
||||
public synchronized void setExpiryMinutes(int expiryMinutes) {
|
||||
m_expiryMinutes = expiryMinutes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return logged in expiry minutes of current request
|
||||
*/
|
||||
public int getExpiryMinutes() {
|
||||
public synchronized int getExpiryMinutes() {
|
||||
return m_expiryMinutes;
|
||||
}
|
||||
|
||||
public void refreshLastAuthorizationTime() {
|
||||
public synchronized void refreshLastAuthorizationTime() {
|
||||
m_lastAuthorizationTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public void setIPAddress(String remoteAddr) {
|
||||
public synchronized void setIPAddress(String remoteAddr) {
|
||||
m_IPAddress = remoteAddr;
|
||||
}
|
||||
|
||||
|
@ -427,9 +409,7 @@ public class CompiereService {
|
|||
if (csMap.containsKey(key)) {
|
||||
l_cs = csMap.get(key);
|
||||
if (l_cs != null) {
|
||||
if (l_cs.isExpired()) {
|
||||
csMap.remove(key);
|
||||
ctxMap.remove(key);
|
||||
if (l_cs.expungeIfExpire()) {
|
||||
l_cs = null;
|
||||
} else {
|
||||
Properties cachedCtx = ctxMap.get(key);
|
||||
|
@ -463,13 +443,13 @@ public class CompiereService {
|
|||
return key.toString();
|
||||
}
|
||||
|
||||
private boolean isExpired() {
|
||||
private synchronized boolean expungeIfExpire() {
|
||||
boolean expired =
|
||||
(
|
||||
(getExpiryMinutes() <= 0)
|
||||
|| (m_lastAuthorizationTime + (getExpiryMinutes() * 60000) <= System.currentTimeMillis())
|
||||
);
|
||||
if (m_connected && expired)
|
||||
if (m_connectCount==0 && expired)
|
||||
{
|
||||
synchronized (csMap) {
|
||||
String key = getKey(m_AD_Client_ID,
|
||||
|
@ -480,15 +460,25 @@ public class CompiereService {
|
|||
m_locale,
|
||||
m_password,
|
||||
m_IPAddress);
|
||||
if (ctxMap.containsKey(key)) {
|
||||
Properties cachedCtx = ctxMap.get(key);
|
||||
Env.getCtx().putAll(cachedCtx);
|
||||
if (csMap.containsKey(key)) {
|
||||
csMap.remove(key);
|
||||
}
|
||||
if (log.isLoggable(Level.INFO)) log.info("Closing expired/invalid " + this);
|
||||
Env.logout();
|
||||
ServerContext.dispose();
|
||||
if (ctxMap.containsKey(key)) {
|
||||
Properties cachedCtx = ctxMap.remove(key);
|
||||
Properties currentCtx = ServerContext.getCurrentInstance();
|
||||
try {
|
||||
ServerContext.setCurrentInstance(cachedCtx);
|
||||
if (log.isLoggable(Level.INFO)) log.info("Closing expired/invalid " + this);
|
||||
Env.logout();
|
||||
} finally {
|
||||
if (currentCtx == cachedCtx) {
|
||||
ServerContext.dispose();
|
||||
} else {
|
||||
ServerContext.setCurrentInstance(currentCtx);
|
||||
}
|
||||
}
|
||||
}
|
||||
m_loggedin = false;
|
||||
m_connected = false;
|
||||
}
|
||||
}
|
||||
return expired;
|
||||
|
|
|
@ -168,13 +168,9 @@ public class ModelADServiceImpl extends AbstractService implements ModelADServic
|
|||
* use the runProcess web service
|
||||
*/
|
||||
public StandardResponseDocument setDocAction(ModelSetDocActionRequestDocument req) {
|
||||
boolean connected = getCompiereService().isConnected();
|
||||
|
||||
boolean manageTrx = this.manageTrx;
|
||||
Trx trx=null;
|
||||
try {
|
||||
if (!connected)
|
||||
getCompiereService().connect();
|
||||
getCompiereService().connect();
|
||||
|
||||
StandardResponseDocument ret = StandardResponseDocument.Factory.newInstance();
|
||||
StandardResponse resp = ret.addNewStandardResponse();
|
||||
|
@ -289,9 +285,6 @@ public class ModelADServiceImpl extends AbstractService implements ModelADServic
|
|||
if (manageTrx && !trx.commit())
|
||||
return rollbackAndSetError(trx, resp, ret, true, "Cannot commit after docAction");
|
||||
|
||||
if (manageTrx)
|
||||
trx.close();
|
||||
|
||||
// resp.setError("");
|
||||
resp.setIsError(false);
|
||||
|
||||
|
@ -304,9 +297,8 @@ public class ModelADServiceImpl extends AbstractService implements ModelADServic
|
|||
} finally {
|
||||
if (manageTrx && trx != null)
|
||||
trx.close();
|
||||
|
||||
if (!connected)
|
||||
getCompiereService().disconnect();
|
||||
|
||||
getCompiereService().disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -390,11 +382,8 @@ public class ModelADServiceImpl extends AbstractService implements ModelADServic
|
|||
|
||||
|
||||
public RunProcessResponseDocument runProcess(ModelRunProcessRequestDocument req) {
|
||||
boolean connected = getCompiereService().isConnected();
|
||||
|
||||
try {
|
||||
if (!connected)
|
||||
getCompiereService().connect();
|
||||
getCompiereService().connect();
|
||||
|
||||
RunProcessResponseDocument resbadlogin = RunProcessResponseDocument.Factory.newInstance();
|
||||
RunProcessResponse rbadlogin = resbadlogin.addNewRunProcessResponse();
|
||||
|
@ -430,17 +419,13 @@ public class ModelADServiceImpl extends AbstractService implements ModelADServic
|
|||
requestCtx.put(serviceType+"_Summary", response.getRunProcessResponse().getSummary());
|
||||
return response;
|
||||
} finally {
|
||||
if (!connected)
|
||||
getCompiereService().disconnect();
|
||||
getCompiereService().disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
public WindowTabDataDocument getList(ModelGetListRequestDocument req) {
|
||||
boolean connected = getCompiereService().isConnected();
|
||||
|
||||
try {
|
||||
if (!connected)
|
||||
getCompiereService().connect();
|
||||
getCompiereService().connect();
|
||||
|
||||
WindowTabDataDocument resdoc = WindowTabDataDocument.Factory.newInstance();
|
||||
WindowTabData res = resdoc.addNewWindowTabData();
|
||||
|
@ -649,20 +634,14 @@ public class ModelADServiceImpl extends AbstractService implements ModelADServic
|
|||
|
||||
return resdoc;
|
||||
} finally {
|
||||
if (!connected)
|
||||
getCompiereService().disconnect();
|
||||
getCompiereService().disconnect();
|
||||
}
|
||||
} // getList
|
||||
|
||||
public StandardResponseDocument deleteData(ModelCRUDRequestDocument req) {
|
||||
boolean connected = getCompiereService().isConnected();
|
||||
|
||||
Trx trx = null;
|
||||
boolean manageTrx = this.manageTrx;
|
||||
|
||||
try {
|
||||
if (!connected)
|
||||
getCompiereService().connect();
|
||||
getCompiereService().connect();
|
||||
|
||||
StandardResponseDocument ret = StandardResponseDocument.Factory.newInstance();
|
||||
StandardResponse resp = ret.addNewStandardResponse();
|
||||
|
@ -727,8 +706,7 @@ public class ModelADServiceImpl extends AbstractService implements ModelADServic
|
|||
if (manageTrx && trx != null)
|
||||
trx.close();
|
||||
|
||||
if (!connected)
|
||||
getCompiereService().disconnect();
|
||||
getCompiereService().disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -740,15 +718,9 @@ public class ModelADServiceImpl extends AbstractService implements ModelADServic
|
|||
}
|
||||
|
||||
public StandardResponseDocument createData(ModelCRUDRequestDocument req) {
|
||||
|
||||
boolean connected = getCompiereService().isConnected();
|
||||
|
||||
Trx trx = null;
|
||||
boolean manageTrx = this.manageTrx;
|
||||
|
||||
try {
|
||||
if (!connected)
|
||||
getCompiereService().connect();
|
||||
getCompiereService().connect();
|
||||
|
||||
StandardResponseDocument ret = StandardResponseDocument.Factory.newInstance();
|
||||
StandardResponse resp = ret.addNewStandardResponse();
|
||||
|
@ -849,21 +821,15 @@ public class ModelADServiceImpl extends AbstractService implements ModelADServic
|
|||
if (manageTrx && trx != null)
|
||||
trx.close();
|
||||
|
||||
if (!connected)
|
||||
getCompiereService().disconnect();
|
||||
getCompiereService().disconnect();
|
||||
|
||||
}
|
||||
} // createData
|
||||
|
||||
public StandardResponseDocument createUpdateData(ModelCRUDRequestDocument req) {
|
||||
boolean connected = getCompiereService().isConnected();
|
||||
|
||||
Trx trx = null;
|
||||
boolean manageTrx = this.manageTrx;
|
||||
|
||||
try {
|
||||
if (!connected)
|
||||
getCompiereService().connect();
|
||||
getCompiereService().connect();
|
||||
|
||||
StandardResponseDocument ret = StandardResponseDocument.Factory.newInstance();
|
||||
StandardResponse resp = ret.addNewStandardResponse();
|
||||
|
@ -1058,8 +1024,7 @@ public class ModelADServiceImpl extends AbstractService implements ModelADServic
|
|||
if (manageTrx && trx != null)
|
||||
trx.close();
|
||||
|
||||
if (!connected)
|
||||
getCompiereService().disconnect();
|
||||
getCompiereService().disconnect();
|
||||
}
|
||||
} // createUpdateData
|
||||
|
||||
|
@ -1234,14 +1199,9 @@ public class ModelADServiceImpl extends AbstractService implements ModelADServic
|
|||
}
|
||||
|
||||
public StandardResponseDocument updateData(ModelCRUDRequestDocument req){
|
||||
boolean connected = getCompiereService().isConnected();
|
||||
|
||||
Trx trx = null;
|
||||
boolean manageTrx = this.manageTrx;
|
||||
|
||||
try {
|
||||
if (!connected)
|
||||
getCompiereService().connect();
|
||||
getCompiereService().connect();
|
||||
|
||||
StandardResponseDocument ret = StandardResponseDocument.Factory.newInstance();
|
||||
StandardResponse resp = ret.addNewStandardResponse();
|
||||
|
@ -1323,17 +1283,13 @@ public class ModelADServiceImpl extends AbstractService implements ModelADServic
|
|||
if (manageTrx && trx != null)
|
||||
trx.close();
|
||||
|
||||
if (!connected)
|
||||
getCompiereService().disconnect();
|
||||
getCompiereService().disconnect();
|
||||
}
|
||||
} // updateData
|
||||
|
||||
public WindowTabDataDocument readData(ModelCRUDRequestDocument req) {
|
||||
boolean connected = getCompiereService().isConnected();
|
||||
|
||||
try {
|
||||
if (!connected)
|
||||
getCompiereService().connect();
|
||||
getCompiereService().connect();
|
||||
|
||||
WindowTabDataDocument ret = WindowTabDataDocument.Factory.newInstance();
|
||||
WindowTabData resp = ret.addNewWindowTabData();
|
||||
|
@ -1423,19 +1379,14 @@ public class ModelADServiceImpl extends AbstractService implements ModelADServic
|
|||
|
||||
return ret;
|
||||
} finally {
|
||||
if (!connected)
|
||||
getCompiereService().disconnect();
|
||||
getCompiereService().disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
public WindowTabDataDocument queryData(ModelCRUDRequestDocument req) {
|
||||
boolean connected = getCompiereService().isConnected();
|
||||
|
||||
boolean manageTrx = this.manageTrx;
|
||||
Trx trx=null;
|
||||
try {
|
||||
if (!connected)
|
||||
getCompiereService().connect();
|
||||
getCompiereService().connect();
|
||||
|
||||
CompiereService m_cs = getCompiereService();
|
||||
WindowTabDataDocument ret = WindowTabDataDocument.Factory.newInstance();
|
||||
|
@ -1589,8 +1540,7 @@ public class ModelADServiceImpl extends AbstractService implements ModelADServic
|
|||
if (manageTrx && trx != null)
|
||||
trx.close();
|
||||
|
||||
if (!connected)
|
||||
getCompiereService().disconnect();
|
||||
getCompiereService().disconnect();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,6 +14,8 @@
|
|||
package org.idempiere.webservices;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
@ -38,8 +40,9 @@ import org.compiere.model.MWebService;
|
|||
import org.compiere.model.MWebServiceType;
|
||||
import org.compiere.model.PO;
|
||||
import org.compiere.model.POInfo;
|
||||
import org.compiere.model.Query;
|
||||
import org.compiere.model.X_WS_WebServiceMethod;
|
||||
import org.compiere.model.X_WS_WebServiceTypeAccess;
|
||||
import org.compiere.util.CCache;
|
||||
import org.compiere.util.DB;
|
||||
import org.compiere.util.Env;
|
||||
import org.compiere.util.KeyNamePair;
|
||||
|
@ -64,7 +67,9 @@ import org.idempiere.webservices.fault.IdempiereServiceFault;
|
|||
*/
|
||||
public class AbstractService {
|
||||
|
||||
private static final String ROLE_ACCESS_SQL = "SELECT IsActive FROM WS_WebServiceTypeAccess WHERE AD_Role_ID=? "
|
||||
private static final String ROLE_ACCESS_SQL = "SELECT IsActive FROM WS_WebServiceTypeAccess WHERE AD_Role_ID IN ("
|
||||
+ "SELECT AD_Role_ID FROM AD_Role WHERE AD_Role_ID=? UNION "
|
||||
+ "SELECT Included_Role_ID as AD_Role_ID FROM AD_Role_Included WHERE AD_Role_ID=?) "
|
||||
+ "AND WS_WebServiceType_ID=?";
|
||||
private static final String COMPIERE_SERVICE = "CompiereService";
|
||||
@Resource
|
||||
|
@ -91,6 +96,7 @@ public class AbstractService {
|
|||
if (cachedCs != null) {
|
||||
m_cs = cachedCs;
|
||||
req.setAttribute(COMPIERE_SERVICE, cachedCs);
|
||||
m_cs.connectCacheInstance();
|
||||
return authenticate(webService, method, serviceType, cachedCs); // already logged with same data
|
||||
}
|
||||
}
|
||||
|
@ -201,6 +207,9 @@ public class AbstractService {
|
|||
return authenticate(webService, method, serviceType, m_cs);
|
||||
}
|
||||
|
||||
private static CCache<String,MWebServiceType> s_WebServiceTypeCache = new CCache<String,MWebServiceType>(MWebServiceType.Table_Name, 10, 60); //60 minutes
|
||||
private static CCache<String,Boolean> s_RoleAccessCache = new CCache<>(X_WS_WebServiceTypeAccess.Table_Name, 60, 60);
|
||||
|
||||
/**
|
||||
* Authenticate user for requested service type
|
||||
* @param webServiceValue
|
||||
|
@ -219,28 +228,59 @@ public class AbstractService {
|
|||
if (m_webservicemethod == null || !m_webservicemethod.isActive())
|
||||
return "Method " + methodValue + " not registered";
|
||||
|
||||
MWebServiceType m_webservicetype = new Query(m_cs.getCtx(), MWebServiceType.Table_Name,
|
||||
"AD_Client_ID IN (0,?) AND WS_WebService_ID=? AND WS_WebServiceMethod_ID=? AND Value=?",
|
||||
null)
|
||||
.setOnlyActiveRecords(true)
|
||||
.setParameters(m_cs.getAD_Client_ID(), m_webservice.getWS_WebService_ID(), m_webservicemethod.getWS_WebServiceMethod_ID(), serviceTypeValue)
|
||||
.setOrderBy("AD_Client_ID DESC") // IDEMPIERE-3394 give precedence to tenant defined if there are system+tenant
|
||||
.first();
|
||||
MWebServiceType m_webservicetype = null;
|
||||
String key = m_cs.getAD_Client_ID() + "|" + m_webservice.getWS_WebService_ID() + "|"
|
||||
+ m_webservicemethod.getWS_WebServiceMethod_ID() + "|" + serviceTypeValue;
|
||||
synchronized (s_WebServiceTypeCache) {
|
||||
m_webservicetype = s_WebServiceTypeCache.get(key);
|
||||
if (m_webservicetype == null) {
|
||||
final String sql = "SELECT * FROM WS_WebServiceType " + "WHERE AD_Client_ID=? " + "AND WS_WebService_ID=? "
|
||||
+ "AND WS_WebServiceMethod_ID=? " + "AND Value=? " + "AND IsActive='Y'";
|
||||
PreparedStatement pstmt = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
pstmt = DB.prepareStatement(sql, null);
|
||||
pstmt.setInt(1, m_cs.getAD_Client_ID());
|
||||
pstmt.setInt(2, m_webservice.getWS_WebService_ID());
|
||||
pstmt.setInt(3, m_webservicemethod.getWS_WebServiceMethod_ID());
|
||||
pstmt.setString(4, serviceTypeValue);
|
||||
rs = pstmt.executeQuery();
|
||||
if (rs.next()) {
|
||||
m_webservicetype = new MWebServiceType(m_cs.getCtx(), rs, null);
|
||||
s_WebServiceTypeCache.put(key, m_webservicetype);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new IdempiereServiceFault(e.getClass().toString() + " " + e.getMessage() + " sql=" + sql, e.getCause(), new QName(
|
||||
"authenticate"));
|
||||
} finally {
|
||||
DB.close(rs, pstmt);
|
||||
rs = null;
|
||||
pstmt = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_webservicetype == null)
|
||||
return "Service type " + serviceTypeValue + " not configured";
|
||||
|
||||
getHttpServletRequest().setAttribute("MWebServiceType", m_webservicetype);
|
||||
|
||||
// Check if role has access on web-service
|
||||
String hasAccess = DB.getSQLValueStringEx(null, ROLE_ACCESS_SQL,
|
||||
Env.getAD_Role_ID( m_cs.getCtx()),
|
||||
m_webservicetype.get_ID());
|
||||
|
||||
if (!"Y".equals(hasAccess))
|
||||
{
|
||||
return "Web Service Error: Login role does not have access to the service type";
|
||||
}
|
||||
int AD_Role_ID = Env.getAD_Role_ID( m_cs.getCtx());
|
||||
key = AD_Role_ID + "|" + m_webservicetype.get_ID();
|
||||
synchronized (s_RoleAccessCache) {
|
||||
Boolean bAccess = s_RoleAccessCache.get(key);
|
||||
if (bAccess == null) {
|
||||
// Check if role has access on web-service
|
||||
String hasAccess = DB.getSQLValueStringEx(null, ROLE_ACCESS_SQL,
|
||||
AD_Role_ID, AD_Role_ID, m_webservicetype.get_ID());
|
||||
bAccess = "Y".equals(hasAccess);
|
||||
s_RoleAccessCache.put(key, bAccess);
|
||||
}
|
||||
if (!bAccess.booleanValue())
|
||||
{
|
||||
return "Web Service Error: Login role does not have access to the service type";
|
||||
}
|
||||
}
|
||||
|
||||
String ret=invokeLoginValidator(null, m_cs.getCtx(), m_webservicetype, IWSValidator.TIMING_ON_AUTHORIZATION);
|
||||
if(ret!=null && ret.length()>0)
|
||||
|
|
Loading…
Reference in New Issue