mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-18 13:10:44 +00:00
CE-1068 - Add creating an automated-session for a user, to use those security keys while running a report
This commit is contained in:
@ -42,7 +42,7 @@ import com.kingsrook.qqq.backend.core.utils.collections.MutableMap;
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public class QSession implements Serializable
|
public class QSession implements Serializable, Cloneable
|
||||||
{
|
{
|
||||||
private String idReference;
|
private String idReference;
|
||||||
private QUser user;
|
private QUser user;
|
||||||
@ -68,6 +68,58 @@ public class QSession implements Serializable
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Override
|
||||||
|
public QSession clone() throws CloneNotSupportedException
|
||||||
|
{
|
||||||
|
QSession clone = (QSession) super.clone();
|
||||||
|
|
||||||
|
if(user != null)
|
||||||
|
{
|
||||||
|
clone.user = user.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(permissions != null)
|
||||||
|
{
|
||||||
|
clone.permissions = new HashSet<>();
|
||||||
|
clone.permissions.addAll(permissions);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(securityKeyValues != null)
|
||||||
|
{
|
||||||
|
clone.securityKeyValues = new HashMap<>();
|
||||||
|
for(Map.Entry<String, List<Serializable>> entry : securityKeyValues.entrySet())
|
||||||
|
{
|
||||||
|
List<Serializable> cloneValues = entry.getValue() == null ? null : new ArrayList<>(entry.getValue());
|
||||||
|
clone.securityKeyValues.put(entry.getKey(), cloneValues);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(backendVariants != null)
|
||||||
|
{
|
||||||
|
clone.backendVariants = new HashMap<>();
|
||||||
|
clone.backendVariants.putAll(backendVariants);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(values != null)
|
||||||
|
{
|
||||||
|
clone.values = new HashMap<>();
|
||||||
|
clone.values.putAll(values);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(valuesForFrontend != null)
|
||||||
|
{
|
||||||
|
clone.valuesForFrontend = new HashMap<>();
|
||||||
|
clone.valuesForFrontend.putAll(valuesForFrontend);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (clone);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Default constructor, puts a uuid in the session
|
** Default constructor, puts a uuid in the session
|
||||||
**
|
**
|
||||||
|
@ -25,13 +25,24 @@ package com.kingsrook.qqq.backend.core.model.session;
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public class QUser
|
public class QUser implements Cloneable
|
||||||
{
|
{
|
||||||
private String idReference;
|
private String idReference;
|
||||||
private String fullName;
|
private String fullName;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Override
|
||||||
|
public QUser clone() throws CloneNotSupportedException
|
||||||
|
{
|
||||||
|
return (QUser) super.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Getter for idReference
|
** Getter for idReference
|
||||||
**
|
**
|
||||||
|
@ -24,6 +24,7 @@ package com.kingsrook.qqq.backend.core.modules.authentication;
|
|||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import com.kingsrook.qqq.backend.core.exceptions.QAuthenticationException;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
import com.kingsrook.qqq.backend.core.model.session.QSession;
|
import com.kingsrook.qqq.backend.core.model.session.QSession;
|
||||||
|
|
||||||
@ -62,4 +63,14 @@ public interface QAuthenticationModuleCustomizerInterface
|
|||||||
//////////
|
//////////
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
default void customizeAutomatedSessionForUser(QInstance qInstance, QSession automatedSessionForUser, Serializable userId) throws QAuthenticationException
|
||||||
|
{
|
||||||
|
//////////
|
||||||
|
// noop //
|
||||||
|
//////////
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -22,12 +22,15 @@
|
|||||||
package com.kingsrook.qqq.backend.core.modules.authentication;
|
package com.kingsrook.qqq.backend.core.modules.authentication;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import com.kingsrook.qqq.backend.core.context.QContext;
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.AccessTokenException;
|
import com.kingsrook.qqq.backend.core.exceptions.AccessTokenException;
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QAuthenticationException;
|
import com.kingsrook.qqq.backend.core.exceptions.QAuthenticationException;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.authentication.QAuthenticationMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.authentication.QAuthenticationMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.model.session.QSession;
|
import com.kingsrook.qqq.backend.core.model.session.QSession;
|
||||||
|
import com.kingsrook.qqq.backend.core.utils.ValueUtils;
|
||||||
import org.apache.commons.lang.NotImplementedException;
|
import org.apache.commons.lang.NotImplementedException;
|
||||||
|
|
||||||
|
|
||||||
@ -49,6 +52,27 @@ public interface QAuthenticationModuleInterface
|
|||||||
boolean isSessionValid(QInstance instance, QSession session);
|
boolean isSessionValid(QInstance instance, QSession session);
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
default QSession createAutomatedSessionForUser(QInstance qInstance, Serializable userId) throws QAuthenticationException
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
QSession clone = QContext.getQSession().clone();
|
||||||
|
if(clone.getUser() != null)
|
||||||
|
{
|
||||||
|
clone.getUser().setIdReference(ValueUtils.getValueAsString(userId));
|
||||||
|
}
|
||||||
|
return clone;
|
||||||
|
}
|
||||||
|
catch(CloneNotSupportedException e)
|
||||||
|
{
|
||||||
|
throw (new QAuthenticationException("Cloning session failed", e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
package com.kingsrook.qqq.backend.core.modules.authentication.implementations;
|
package com.kingsrook.qqq.backend.core.modules.authentication.implementations;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.security.interfaces.RSAPublicKey;
|
import java.security.interfaces.RSAPublicKey;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
@ -622,7 +623,7 @@ public class Auth0AuthenticationModule implements QAuthenticationModuleInterface
|
|||||||
// set security keys in the session from the JWT //
|
// set security keys in the session from the JWT //
|
||||||
///////////////////////////////////////////////////
|
///////////////////////////////////////////////////
|
||||||
setSecurityKeysInSessionFromJwtPayload(qInstance, payload, qSession);
|
setSecurityKeysInSessionFromJwtPayload(qInstance, payload, qSession);
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
// allow customizer to do custom things here, if so desired //
|
// allow customizer to do custom things here, if so desired //
|
||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
@ -1108,4 +1109,20 @@ public class Auth0AuthenticationModule implements QAuthenticationModuleInterface
|
|||||||
return (null);
|
return (null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** e.g., if a scheduled job needs to run as a user (say, a report)...
|
||||||
|
*******************************************************************************/
|
||||||
|
@Override
|
||||||
|
public QSession createAutomatedSessionForUser(QInstance qInstance, Serializable userId) throws QAuthenticationException
|
||||||
|
{
|
||||||
|
QSession automatedSessionForUser = QAuthenticationModuleInterface.super.createAutomatedSessionForUser(qInstance, userId);
|
||||||
|
if(getCustomizer() != null)
|
||||||
|
{
|
||||||
|
getCustomizer().customizeAutomatedSessionForUser(qInstance, automatedSessionForUser, userId);
|
||||||
|
}
|
||||||
|
return (automatedSessionForUser);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ import java.util.List;
|
|||||||
import com.kingsrook.qqq.backend.core.actions.processes.BackendStep;
|
import com.kingsrook.qqq.backend.core.actions.processes.BackendStep;
|
||||||
import com.kingsrook.qqq.backend.core.actions.processes.QProcessCallbackFactory;
|
import com.kingsrook.qqq.backend.core.actions.processes.QProcessCallbackFactory;
|
||||||
import com.kingsrook.qqq.backend.core.actions.processes.RunProcessAction;
|
import com.kingsrook.qqq.backend.core.actions.processes.RunProcessAction;
|
||||||
|
import com.kingsrook.qqq.backend.core.context.QContext;
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QUserFacingException;
|
import com.kingsrook.qqq.backend.core.exceptions.QUserFacingException;
|
||||||
import com.kingsrook.qqq.backend.core.logging.QLogger;
|
import com.kingsrook.qqq.backend.core.logging.QLogger;
|
||||||
@ -34,7 +35,11 @@ import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepOutp
|
|||||||
import com.kingsrook.qqq.backend.core.model.actions.processes.RunProcessInput;
|
import com.kingsrook.qqq.backend.core.model.actions.processes.RunProcessInput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.processes.RunProcessOutput;
|
import com.kingsrook.qqq.backend.core.model.actions.processes.RunProcessOutput;
|
||||||
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
import com.kingsrook.qqq.backend.core.model.savedreports.ScheduledReport;
|
import com.kingsrook.qqq.backend.core.model.savedreports.ScheduledReport;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.session.QSession;
|
||||||
|
import com.kingsrook.qqq.backend.core.modules.authentication.QAuthenticationModuleDispatcher;
|
||||||
|
import com.kingsrook.qqq.backend.core.modules.authentication.QAuthenticationModuleInterface;
|
||||||
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
||||||
import com.kingsrook.qqq.backend.core.utils.JsonUtils;
|
import com.kingsrook.qqq.backend.core.utils.JsonUtils;
|
||||||
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
||||||
@ -69,6 +74,11 @@ public class RunScheduledReportExecuteStep implements BackendStep
|
|||||||
ScheduledReport scheduledReport = new ScheduledReport(records.get(0));
|
ScheduledReport scheduledReport = new ScheduledReport(records.get(0));
|
||||||
scheduledReportId = scheduledReport.getId();
|
scheduledReportId = scheduledReport.getId();
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// get the schedule's user - as that will drive the security key we need to apply //
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
updateSessionForUser(scheduledReport.getUserId());
|
||||||
|
|
||||||
/////////////////////////////////////////////
|
/////////////////////////////////////////////
|
||||||
// run the process that renders the report //
|
// run the process that renders the report //
|
||||||
/////////////////////////////////////////////
|
/////////////////////////////////////////////
|
||||||
@ -110,4 +120,34 @@ public class RunScheduledReportExecuteStep implements BackendStep
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
private void updateSessionForUser(String userId) throws QException
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
QInstance qInstance = QContext.getQInstance();
|
||||||
|
QAuthenticationModuleDispatcher qAuthenticationModuleDispatcher = new QAuthenticationModuleDispatcher();
|
||||||
|
QAuthenticationModuleInterface authenticationModule = qAuthenticationModuleDispatcher.getQModule(qInstance.getAuthentication());
|
||||||
|
|
||||||
|
///////////////////////////////////////
|
||||||
|
// create automated-session for user //
|
||||||
|
///////////////////////////////////////
|
||||||
|
QSession session = authenticationModule.createAutomatedSessionForUser(qInstance, userId);
|
||||||
|
|
||||||
|
/////////////////////////////////////////////
|
||||||
|
// set that session in the current context //
|
||||||
|
/////////////////////////////////////////////
|
||||||
|
QContext.setQSession(session);
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
LOG.warn("Error setting up user session for running scheduled report", e, logPair("userId", userId));
|
||||||
|
throw (new QException("Error setting up user session for running scheduled report", e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user