Checkpoint: Introducing authenticaion; re-orged some packages

This commit is contained in:
Darin Kelkhoff
2022-02-15 18:13:04 -06:00
parent b5e11176f6
commit 980f989779
28 changed files with 744 additions and 40 deletions

View File

@ -0,0 +1,33 @@
/*
* Copyright © 2021-2022. Kingsrook LLC <contact@kingsrook.com>. All Rights Reserved.
*/
package com.kingsrook.qqq.backend.core.actions;
import com.kingsrook.qqq.backend.core.exceptions.QException;
import com.kingsrook.qqq.backend.core.model.actions.AbstractQRequest;
import com.kingsrook.qqq.backend.core.modules.QAuthenticationModuleDispatcher;
import com.kingsrook.qqq.backend.core.modules.interfaces.QAuthenticationModuleInterface;
/*******************************************************************************
**
*******************************************************************************/
public class ActionHelper
{
/*******************************************************************************
**
*******************************************************************************/
public static void validateSession(AbstractQRequest request) throws QException
{
QAuthenticationModuleDispatcher qAuthenticationModuleDispatcher = new QAuthenticationModuleDispatcher();
QAuthenticationModuleInterface authenticationModule = qAuthenticationModuleDispatcher.getQModule(request.getAuthenticationMetaData());
if(!authenticationModule.isSessionValid(request.getSession()))
{
throw new QException("Invalid session in request");
}
}
}

View File

@ -8,9 +8,8 @@ package com.kingsrook.qqq.backend.core.actions;
import com.kingsrook.qqq.backend.core.exceptions.QException; import com.kingsrook.qqq.backend.core.exceptions.QException;
import com.kingsrook.qqq.backend.core.model.actions.delete.DeleteRequest; import com.kingsrook.qqq.backend.core.model.actions.delete.DeleteRequest;
import com.kingsrook.qqq.backend.core.model.actions.delete.DeleteResult; import com.kingsrook.qqq.backend.core.model.actions.delete.DeleteResult;
import com.kingsrook.qqq.backend.core.model.metadata.QBackendMetaData; import com.kingsrook.qqq.backend.core.modules.QBackendModuleDispatcher;
import com.kingsrook.qqq.backend.core.modules.QModuleDispatcher; import com.kingsrook.qqq.backend.core.modules.interfaces.QBackendModuleInterface;
import com.kingsrook.qqq.backend.core.modules.interfaces.QModuleInterface;
/******************************************************************************* /*******************************************************************************
@ -24,11 +23,10 @@ public class DeleteAction
*******************************************************************************/ *******************************************************************************/
public DeleteResult execute(DeleteRequest deleteRequest) throws QException public DeleteResult execute(DeleteRequest deleteRequest) throws QException
{ {
QModuleDispatcher qModuleDispatcher = new QModuleDispatcher(); ActionHelper.validateSession(deleteRequest);
QBackendMetaData backend = deleteRequest.getBackend(); QBackendModuleDispatcher qBackendModuleDispatcher = new QBackendModuleDispatcher();
QBackendModuleInterface qModule = qBackendModuleDispatcher.getQModule(deleteRequest.getBackend());
QModuleInterface qModule = qModuleDispatcher.getQModule(backend);
// todo pre-customization - just get to modify the request? // todo pre-customization - just get to modify the request?
DeleteResult deleteResult = qModule.getDeleteInterface().execute(deleteRequest); DeleteResult deleteResult = qModule.getDeleteInterface().execute(deleteRequest);
// todo post-customization - can do whatever w/ the result if you want // todo post-customization - can do whatever w/ the result if you want

View File

@ -8,9 +8,8 @@ package com.kingsrook.qqq.backend.core.actions;
import com.kingsrook.qqq.backend.core.exceptions.QException; import com.kingsrook.qqq.backend.core.exceptions.QException;
import com.kingsrook.qqq.backend.core.model.actions.insert.InsertRequest; import com.kingsrook.qqq.backend.core.model.actions.insert.InsertRequest;
import com.kingsrook.qqq.backend.core.model.actions.insert.InsertResult; import com.kingsrook.qqq.backend.core.model.actions.insert.InsertResult;
import com.kingsrook.qqq.backend.core.model.metadata.QBackendMetaData; import com.kingsrook.qqq.backend.core.modules.QBackendModuleDispatcher;
import com.kingsrook.qqq.backend.core.modules.QModuleDispatcher; import com.kingsrook.qqq.backend.core.modules.interfaces.QBackendModuleInterface;
import com.kingsrook.qqq.backend.core.modules.interfaces.QModuleInterface;
/******************************************************************************* /*******************************************************************************
@ -24,11 +23,10 @@ public class InsertAction
*******************************************************************************/ *******************************************************************************/
public InsertResult execute(InsertRequest insertRequest) throws QException public InsertResult execute(InsertRequest insertRequest) throws QException
{ {
QModuleDispatcher qModuleDispatcher = new QModuleDispatcher(); ActionHelper.validateSession(insertRequest);
QBackendMetaData backend = insertRequest.getBackend(); QBackendModuleDispatcher qBackendModuleDispatcher = new QBackendModuleDispatcher();
QBackendModuleInterface qModule = qBackendModuleDispatcher.getQModule(insertRequest.getBackend());
QModuleInterface qModule = qModuleDispatcher.getQModule(backend);
// todo pre-customization - just get to modify the request? // todo pre-customization - just get to modify the request?
InsertResult insertResult = qModule.getInsertInterface().execute(insertRequest); InsertResult insertResult = qModule.getInsertInterface().execute(insertRequest);
// todo post-customization - can do whatever w/ the result if you want // todo post-customization - can do whatever w/ the result if you want

View File

@ -25,6 +25,8 @@ public class MetaDataAction
*******************************************************************************/ *******************************************************************************/
public MetaDataResult execute(MetaDataRequest metaDataRequest) throws QException public MetaDataResult execute(MetaDataRequest metaDataRequest) throws QException
{ {
ActionHelper.validateSession(metaDataRequest);
// todo pre-customization - just get to modify the request? // todo pre-customization - just get to modify the request?
MetaDataResult metaDataResult = new MetaDataResult(); MetaDataResult metaDataResult = new MetaDataResult();

View File

@ -8,9 +8,8 @@ package com.kingsrook.qqq.backend.core.actions;
import com.kingsrook.qqq.backend.core.exceptions.QException; import com.kingsrook.qqq.backend.core.exceptions.QException;
import com.kingsrook.qqq.backend.core.model.actions.query.QueryRequest; import com.kingsrook.qqq.backend.core.model.actions.query.QueryRequest;
import com.kingsrook.qqq.backend.core.model.actions.query.QueryResult; import com.kingsrook.qqq.backend.core.model.actions.query.QueryResult;
import com.kingsrook.qqq.backend.core.model.metadata.QBackendMetaData; import com.kingsrook.qqq.backend.core.modules.QBackendModuleDispatcher;
import com.kingsrook.qqq.backend.core.modules.QModuleDispatcher; import com.kingsrook.qqq.backend.core.modules.interfaces.QBackendModuleInterface;
import com.kingsrook.qqq.backend.core.modules.interfaces.QModuleInterface;
/******************************************************************************* /*******************************************************************************
@ -24,11 +23,10 @@ public class QueryAction
*******************************************************************************/ *******************************************************************************/
public QueryResult execute(QueryRequest queryRequest) throws QException public QueryResult execute(QueryRequest queryRequest) throws QException
{ {
QModuleDispatcher qModuleDispatcher = new QModuleDispatcher(); ActionHelper.validateSession(queryRequest);
QBackendMetaData backend = queryRequest.getBackend(); QBackendModuleDispatcher qBackendModuleDispatcher = new QBackendModuleDispatcher();
QBackendModuleInterface qModule = qBackendModuleDispatcher.getQModule(queryRequest.getBackend());
QModuleInterface qModule = qModuleDispatcher.getQModule(backend);
// todo pre-customization - just get to modify the request? // todo pre-customization - just get to modify the request?
QueryResult queryResult = qModule.getQueryInterface().execute(queryRequest); QueryResult queryResult = qModule.getQueryInterface().execute(queryRequest);
// todo post-customization - can do whatever w/ the result if you want // todo post-customization - can do whatever w/ the result if you want

View File

@ -35,6 +35,8 @@ public class RunFunctionAction
*******************************************************************************/ *******************************************************************************/
public RunFunctionResult execute(RunFunctionRequest runFunctionRequest) throws QException public RunFunctionResult execute(RunFunctionRequest runFunctionRequest) throws QException
{ {
ActionHelper.validateSession(runFunctionRequest);
/////////////////////////////////////////////////////// ///////////////////////////////////////////////////////
// todo - shouldn't meta-data validation catch this? // // todo - shouldn't meta-data validation catch this? //
/////////////////////////////////////////////////////// ///////////////////////////////////////////////////////
@ -109,6 +111,7 @@ public class RunFunctionAction
if(runFunctionRequest.getRecords() == null) if(runFunctionRequest.getRecords() == null)
{ {
QueryRequest queryRequest = new QueryRequest(runFunctionRequest.getInstance()); QueryRequest queryRequest = new QueryRequest(runFunctionRequest.getInstance());
queryRequest.setSession(runFunctionRequest.getSession());
queryRequest.setTableName(inputMetaData.getRecordListMetaData().getTableName()); queryRequest.setTableName(inputMetaData.getRecordListMetaData().getTableName());
// todo - handle this being async (e.g., http) // todo - handle this being async (e.g., http)

View File

@ -27,6 +27,8 @@ public class RunProcessAction
*******************************************************************************/ *******************************************************************************/
public RunProcessResult execute(RunProcessRequest runProcessRequest) throws QException public RunProcessResult execute(RunProcessRequest runProcessRequest) throws QException
{ {
ActionHelper.validateSession(runProcessRequest);
/////////////////////////////////////////////////////// ///////////////////////////////////////////////////////
// todo - shouldn't meta-data validation catch this? // // todo - shouldn't meta-data validation catch this? //
/////////////////////////////////////////////////////// ///////////////////////////////////////////////////////

View File

@ -24,6 +24,8 @@ public class TableMetaDataAction
*******************************************************************************/ *******************************************************************************/
public TableMetaDataResult execute(TableMetaDataRequest tableMetaDataRequest) throws QException public TableMetaDataResult execute(TableMetaDataRequest tableMetaDataRequest) throws QException
{ {
ActionHelper.validateSession(tableMetaDataRequest);
// todo pre-customization - just get to modify the request? // todo pre-customization - just get to modify the request?
TableMetaDataResult tableMetaDataResult = new TableMetaDataResult(); TableMetaDataResult tableMetaDataResult = new TableMetaDataResult();

View File

@ -7,7 +7,9 @@ package com.kingsrook.qqq.backend.core.model.actions;
import com.kingsrook.qqq.backend.core.exceptions.QInstanceValidationException; import com.kingsrook.qqq.backend.core.exceptions.QInstanceValidationException;
import com.kingsrook.qqq.backend.core.instances.QInstanceValidator; import com.kingsrook.qqq.backend.core.instances.QInstanceValidator;
import com.kingsrook.qqq.backend.core.model.metadata.QAuthenticationMetaData;
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;
/******************************************************************************* /*******************************************************************************
@ -17,7 +19,7 @@ import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
public abstract class AbstractQRequest public abstract class AbstractQRequest
{ {
protected QInstance instance; protected QInstance instance;
// todo session protected QSession session;
@ -41,7 +43,7 @@ public abstract class AbstractQRequest
// if this instance hasn't been validated yet, do so now // // if this instance hasn't been validated yet, do so now //
// noting that this will also enrich any missing metaData // // noting that this will also enrich any missing metaData //
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
if(! instance.getHasBeenValidated()) if(!instance.getHasBeenValidated())
{ {
try try
{ {
@ -57,6 +59,16 @@ public abstract class AbstractQRequest
/*******************************************************************************
**
*******************************************************************************/
public QAuthenticationMetaData getAuthenticationMetaData()
{
return (instance.getAuthentication());
}
/******************************************************************************* /*******************************************************************************
** Getter for instance ** Getter for instance
** **
@ -76,4 +88,26 @@ public abstract class AbstractQRequest
{ {
this.instance = instance; this.instance = instance;
} }
/*******************************************************************************
** Getter for session
**
*******************************************************************************/
public QSession getSession()
{
return session;
}
/*******************************************************************************
** Setter for session
**
*******************************************************************************/
public void setSession(QSession session)
{
this.session = session;
}
} }

View File

@ -0,0 +1,164 @@
/*
* Copyright © 2021-2021. Kingsrook LLC <contact@kingsrook.com>. All Rights Reserved.
*/
package com.kingsrook.qqq.backend.core.model.metadata;
import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonFilter;
/*******************************************************************************
** Meta-data to provide details of an authentication provider (e.g., google, saml,
** etc) within a qqq instance
**
*******************************************************************************/
public class QAuthenticationMetaData
{
private String name;
private String type;
@JsonFilter("secretsFilter")
private Map<String, String> values;
/*******************************************************************************
**
*******************************************************************************/
public String getValue(String key)
{
if(values == null)
{
return null;
}
return values.get(key);
}
/*******************************************************************************
**
*******************************************************************************/
public void setValue(String key, String value)
{
if(values == null)
{
values = new HashMap<>();
}
values.put(key, value);
}
/*******************************************************************************
**
*******************************************************************************/
public QAuthenticationMetaData withValue(String key, String value)
{
if(values == null)
{
values = new HashMap<>();
}
values.put(key, value);
return (this);
}
/*******************************************************************************
**
*******************************************************************************/
public String getName()
{
return name;
}
/*******************************************************************************
**
*******************************************************************************/
public void setName(String name)
{
this.name = name;
}
/*******************************************************************************
**
*******************************************************************************/
public QAuthenticationMetaData withName(String name)
{
this.name = name;
return (this);
}
/*******************************************************************************
** Getter for type
**
*******************************************************************************/
public String getType()
{
return type;
}
/*******************************************************************************
** Setter for type
**
*******************************************************************************/
public void setType(String type)
{
this.type = type;
}
/*******************************************************************************
**
*******************************************************************************/
public QAuthenticationMetaData withType(String type)
{
this.type = type;
return (this);
}
/*******************************************************************************
**
*******************************************************************************/
public Map<String, String> getValues()
{
return values;
}
/*******************************************************************************
**
*******************************************************************************/
public void setValues(Map<String, String> values)
{
this.values = values;
}
/*******************************************************************************
**
*******************************************************************************/
public QAuthenticationMetaData withVales(Map<String, String> values)
{
this.values = values;
return (this);
}
}

View File

@ -27,6 +27,8 @@ public class QInstance
@JsonIgnore @JsonIgnore
private Map<String, QBackendMetaData> backends = new HashMap<>(); private Map<String, QBackendMetaData> backends = new HashMap<>();
private QAuthenticationMetaData authentication = null;
private Map<String, QTableMetaData> tables = new HashMap<>(); private Map<String, QTableMetaData> tables = new HashMap<>();
private Map<String, QProcessMetaData> processes = new HashMap<>(); private Map<String, QProcessMetaData> processes = new HashMap<>();
@ -257,4 +259,24 @@ public class QInstance
} }
/*******************************************************************************
** Getter for authentication
**
*******************************************************************************/
public QAuthenticationMetaData getAuthentication()
{
return authentication;
}
/*******************************************************************************
** Setter for authentication
**
*******************************************************************************/
public void setAuthentication(QAuthenticationMetaData authentication)
{
this.authentication = authentication;
}
} }

View File

@ -0,0 +1,130 @@
/*
* Copyright © 2021-2022. Kingsrook LLC <contact@kingsrook.com>. All Rights Reserved.
*/
package com.kingsrook.qqq.backend.core.model.session;
import java.util.HashMap;
import java.util.Map;
/*******************************************************************************
**
*******************************************************************************/
public class QSession
{
private String idReference;
private QUser user;
// implementation-specific custom values
private Map<String, String> values;
/*******************************************************************************
** Getter for idReference
**
*******************************************************************************/
public String getIdReference()
{
return idReference;
}
/*******************************************************************************
** Setter for idReference
**
*******************************************************************************/
public void setIdReference(String idReference)
{
this.idReference = idReference;
}
/*******************************************************************************
** Getter for user
**
*******************************************************************************/
public QUser getUser()
{
return user;
}
/*******************************************************************************
** Setter for user
**
*******************************************************************************/
public void setUser(QUser user)
{
this.user = user;
}
/*******************************************************************************
**
*******************************************************************************/
public String getValue(String key)
{
if(values == null)
{
return null;
}
return values.get(key);
}
/*******************************************************************************
**
*******************************************************************************/
public void setValue(String key, String value)
{
if(values == null)
{
values = new HashMap<>();
}
values.put(key, value);
}
/*******************************************************************************
**
*******************************************************************************/
public QSession withValue(String key, String value)
{
if(values == null)
{
values = new HashMap<>();
}
values.put(key, value);
return (this);
}
/*******************************************************************************
**
*******************************************************************************/
public Map<String, String> getValues()
{
return values;
}
/*******************************************************************************
**
*******************************************************************************/
public void setValues(Map<String, String> values)
{
this.values = values;
}
}

View File

@ -0,0 +1,59 @@
/*
* Copyright © 2021-2022. Kingsrook LLC <contact@kingsrook.com>. All Rights Reserved.
*/
package com.kingsrook.qqq.backend.core.model.session;
/*******************************************************************************
**
*******************************************************************************/
public class QUser
{
private String idReference;
private String fullName;
/*******************************************************************************
** Getter for idReference
**
*******************************************************************************/
public String getIdReference()
{
return idReference;
}
/*******************************************************************************
** Setter for idReference
**
*******************************************************************************/
public void setIdReference(String idReference)
{
this.idReference = idReference;
}
/*******************************************************************************
** Getter for fullName
**
*******************************************************************************/
public String getFullName()
{
return fullName;
}
/*******************************************************************************
** Setter for fullName
**
*******************************************************************************/
public void setFullName(String fullName)
{
this.fullName = fullName;
}
}

View File

@ -0,0 +1,72 @@
/*
* Copyright © 2021-2021. Kingsrook LLC <contact@kingsrook.com>. All Rights Reserved.
*/
package com.kingsrook.qqq.backend.core.modules;
import java.util.HashMap;
import java.util.Map;
import com.kingsrook.qqq.backend.core.exceptions.QModuleDispatchException;
import com.kingsrook.qqq.backend.core.model.metadata.QAuthenticationMetaData;
import com.kingsrook.qqq.backend.core.modules.interfaces.QAuthenticationModuleInterface;
/*******************************************************************************
** This class is responsible for loading an authentication module, by its name, and
** returning an instance.
**
** TODO - make this mapping runtime-bound, not pre-compiled in.
**
*******************************************************************************/
public class QAuthenticationModuleDispatcher
{
private Map<String, String> authenticationTypeToModuleClassNameMap;
/*******************************************************************************
**
*******************************************************************************/
public QAuthenticationModuleDispatcher()
{
authenticationTypeToModuleClassNameMap = new HashMap<>();
authenticationTypeToModuleClassNameMap.put("mock", "com.kingsrook.qqq.backend.core.modules.mock.MockAuthenticationModule");
authenticationTypeToModuleClassNameMap.put("fullyAnonymous", "com.kingsrook.qqq.backend.core.modules.defaults.FullyAnonymousAuthenticationModule");
authenticationTypeToModuleClassNameMap.put("TODO:google", "com.kingsrook.qqq.authentication.module.google.GoogleAuthenticationModule");
// todo - let user define custom type -> classes
}
/*******************************************************************************
**
*******************************************************************************/
public QAuthenticationModuleInterface getQModule(QAuthenticationMetaData authenticationMetaData) throws QModuleDispatchException
{
if(authenticationMetaData == null)
{
throw (new QModuleDispatchException("No authentication meta data defined."));
}
try
{
String className = authenticationTypeToModuleClassNameMap.get(authenticationMetaData.getType());
if(className == null)
{
throw (new QModuleDispatchException("Unrecognized authentication type [" + authenticationMetaData.getType() + "] in dispatcher."));
}
Class<?> moduleClass = Class.forName(className);
return (QAuthenticationModuleInterface) moduleClass.getDeclaredConstructor().newInstance();
}
catch(QModuleDispatchException qmde)
{
throw (qmde);
}
catch(Exception e)
{
throw (new QModuleDispatchException("Error getting authentication module of type: " + authenticationMetaData.getType(), e));
}
}
}

View File

@ -9,7 +9,7 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import com.kingsrook.qqq.backend.core.exceptions.QModuleDispatchException; import com.kingsrook.qqq.backend.core.exceptions.QModuleDispatchException;
import com.kingsrook.qqq.backend.core.model.metadata.QBackendMetaData; import com.kingsrook.qqq.backend.core.model.metadata.QBackendMetaData;
import com.kingsrook.qqq.backend.core.modules.interfaces.QModuleInterface; import com.kingsrook.qqq.backend.core.modules.interfaces.QBackendModuleInterface;
/******************************************************************************* /*******************************************************************************
@ -19,7 +19,7 @@ import com.kingsrook.qqq.backend.core.modules.interfaces.QModuleInterface;
** TODO - make this mapping runtime-bound, not pre-compiled in. ** TODO - make this mapping runtime-bound, not pre-compiled in.
** **
*******************************************************************************/ *******************************************************************************/
public class QModuleDispatcher public class QBackendModuleDispatcher
{ {
private Map<String, String> backendTypeToModuleClassNameMap; private Map<String, String> backendTypeToModuleClassNameMap;
@ -28,11 +28,11 @@ public class QModuleDispatcher
/******************************************************************************* /*******************************************************************************
** **
*******************************************************************************/ *******************************************************************************/
public QModuleDispatcher() public QBackendModuleDispatcher()
{ {
backendTypeToModuleClassNameMap = new HashMap<>(); backendTypeToModuleClassNameMap = new HashMap<>();
backendTypeToModuleClassNameMap.put("mock", "com.kingsrook.qqq.backend.core.modules.mock.MockModule"); backendTypeToModuleClassNameMap.put("mock", "com.kingsrook.qqq.backend.core.modules.mock.MockBackendModule");
backendTypeToModuleClassNameMap.put("rdbms", "com.kingsrook.qqq.backend.module.rdbms.RDBSMModule"); backendTypeToModuleClassNameMap.put("rdbms", "com.kingsrook.qqq.backend.module.rdbms.RDBMSBackendModule");
// todo - let user define custom type -> classes // todo - let user define custom type -> classes
} }
@ -41,7 +41,7 @@ public class QModuleDispatcher
/******************************************************************************* /*******************************************************************************
** **
*******************************************************************************/ *******************************************************************************/
public QModuleInterface getQModule(QBackendMetaData backend) throws QModuleDispatchException public QBackendModuleInterface getQModule(QBackendMetaData backend) throws QModuleDispatchException
{ {
try try
{ {
@ -52,7 +52,7 @@ public class QModuleDispatcher
} }
Class<?> moduleClass = Class.forName(className); Class<?> moduleClass = Class.forName(className);
return (QModuleInterface) moduleClass.getDeclaredConstructor().newInstance(); return (QBackendModuleInterface) moduleClass.getDeclaredConstructor().newInstance();
} }
catch(QModuleDispatchException qmde) catch(QModuleDispatchException qmde)
{ {
@ -60,7 +60,7 @@ public class QModuleDispatcher
} }
catch(Exception e) catch(Exception e)
{ {
throw (new QModuleDispatchException("Error getting q backend module of type: " + backend.getType(), e)); throw (new QModuleDispatchException("Error getting backend module of type: " + backend.getType(), e));
} }
} }
} }

View File

@ -0,0 +1,60 @@
/*
* Copyright © 2021-2022. Kingsrook LLC <contact@kingsrook.com>. All Rights Reserved.
*/
package com.kingsrook.qqq.backend.core.modules.defaults;
import java.util.Map;
import java.util.UUID;
import com.kingsrook.qqq.backend.core.model.session.QSession;
import com.kingsrook.qqq.backend.core.model.session.QUser;
import com.kingsrook.qqq.backend.core.modules.interfaces.QAuthenticationModuleInterface;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
/*******************************************************************************
**
*******************************************************************************/
public class FullyAnonymousAuthenticationModule implements QAuthenticationModuleInterface
{
private static final Logger logger = LogManager.getLogger(FullyAnonymousAuthenticationModule.class);
/*******************************************************************************
**
*******************************************************************************/
@Override
public QSession createSession(Map<String, String> context)
{
QUser qUser = new QUser();
qUser.setIdReference("anonymous");
qUser.setFullName("Anonymous");
QSession qSession = new QSession();
if (context.get("sessionId") != null)
{
qSession.setIdReference(context.get("sessionId"));
}
else
{
qSession.setIdReference("Session:" + UUID.randomUUID());
}
qSession.setUser(qUser);
return (qSession);
}
/*******************************************************************************
**
*******************************************************************************/
@Override
public boolean isSessionValid(QSession session)
{
return (true);
}
}

View File

@ -0,0 +1,28 @@
/*
* Copyright © 2021-2021. Kingsrook LLC <contact@kingsrook.com>. All Rights Reserved.
*/
package com.kingsrook.qqq.backend.core.modules.interfaces;
import java.util.Map;
import com.kingsrook.qqq.backend.core.model.session.QSession;
/*******************************************************************************
** Interface that a QAuthenticationModule must implement.
**
*******************************************************************************/
public interface QAuthenticationModuleInterface
{
/*******************************************************************************
**
*******************************************************************************/
QSession createSession(Map<String, String> context);
/*******************************************************************************
**
*******************************************************************************/
boolean isSessionValid(QSession session);
}

View File

@ -6,13 +6,13 @@ package com.kingsrook.qqq.backend.core.modules.interfaces;
/******************************************************************************* /*******************************************************************************
** Interface that a QModule must implement. ** Interface that a QBackendModule must implement.
** **
** Note, methods all have a default version, which throws a 'not implement' ** Note, methods all have a default version, which throws a 'not implemented'
** exception. ** exception.
** **
*******************************************************************************/ *******************************************************************************/
public interface QModuleInterface public interface QBackendModuleInterface
{ {
/******************************************************************************* /*******************************************************************************
** **

View File

@ -0,0 +1,65 @@
/*
* Copyright © 2021-2022. Kingsrook LLC <contact@kingsrook.com>. All Rights Reserved.
*/
package com.kingsrook.qqq.backend.core.modules.mock;
import java.util.Map;
import java.util.UUID;
import com.kingsrook.qqq.backend.core.model.session.QSession;
import com.kingsrook.qqq.backend.core.model.session.QUser;
import com.kingsrook.qqq.backend.core.modules.interfaces.QAuthenticationModuleInterface;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
/*******************************************************************************
**
*******************************************************************************/
public class MockAuthenticationModule implements QAuthenticationModuleInterface
{
private static final Logger logger = LogManager.getLogger(MockAuthenticationModule.class);
/*******************************************************************************
**
*******************************************************************************/
@Override
public QSession createSession(Map<String, String> context)
{
QUser qUser = new QUser();
qUser.setIdReference("User:" + (System.currentTimeMillis() % 10_000));
qUser.setFullName("John Smith");
QSession qSession = new QSession();
qSession.setIdReference("Session:" + UUID.randomUUID());
qSession.setUser(qUser);
return (qSession);
}
/*******************************************************************************
**
*******************************************************************************/
@Override
public boolean isSessionValid(QSession session)
{
if(session == null)
{
logger.info("Session is null, which is not valid.");
return (false);
}
if(session.getValue("isInvalid") != null)
{
logger.info("Session contains the valid 'isInvalid', which is not valid.");
return (false);
}
return (true);
}
}

View File

@ -7,7 +7,7 @@ package com.kingsrook.qqq.backend.core.modules.mock;
import com.kingsrook.qqq.backend.core.modules.interfaces.DeleteInterface; import com.kingsrook.qqq.backend.core.modules.interfaces.DeleteInterface;
import com.kingsrook.qqq.backend.core.modules.interfaces.InsertInterface; import com.kingsrook.qqq.backend.core.modules.interfaces.InsertInterface;
import com.kingsrook.qqq.backend.core.modules.interfaces.QModuleInterface; import com.kingsrook.qqq.backend.core.modules.interfaces.QBackendModuleInterface;
import com.kingsrook.qqq.backend.core.modules.interfaces.QueryInterface; import com.kingsrook.qqq.backend.core.modules.interfaces.QueryInterface;
@ -18,7 +18,7 @@ import com.kingsrook.qqq.backend.core.modules.interfaces.QueryInterface;
** tests over all the actions available through the QModuleInterface. ** tests over all the actions available through the QModuleInterface.
** **
*******************************************************************************/ *******************************************************************************/
public class MockModule implements QModuleInterface public class MockBackendModule implements QBackendModuleInterface
{ {
/******************************************************************************* /*******************************************************************************
** **

View File

@ -32,6 +32,7 @@ class DeleteActionTest
public void test() throws QException public void test() throws QException
{ {
DeleteRequest request = new DeleteRequest(TestUtils.defineInstance()); DeleteRequest request = new DeleteRequest(TestUtils.defineInstance());
request.setSession(TestUtils.getMockSession());
request.setTableName("person"); request.setTableName("person");
request.setPrimaryKeys(List.of(1, 2)); request.setPrimaryKeys(List.of(1, 2));
DeleteResult result = new DeleteAction().execute(request); DeleteResult result = new DeleteAction().execute(request);

View File

@ -32,6 +32,7 @@ class InsertActionTest
public void test() throws QException public void test() throws QException
{ {
InsertRequest request = new InsertRequest(TestUtils.defineInstance()); InsertRequest request = new InsertRequest(TestUtils.defineInstance());
request.setSession(TestUtils.getMockSession());
request.setTableName("person"); request.setTableName("person");
List<QRecord> records =new ArrayList<>(); List<QRecord> records =new ArrayList<>();
QRecord record = new QRecord(); QRecord record = new QRecord();

View File

@ -27,6 +27,7 @@ class MetaDataActionTest
public void test() throws QException public void test() throws QException
{ {
MetaDataRequest request = new MetaDataRequest(TestUtils.defineInstance()); MetaDataRequest request = new MetaDataRequest(TestUtils.defineInstance());
request.setSession(TestUtils.getMockSession());
MetaDataResult result = new MetaDataAction().execute(request); MetaDataResult result = new MetaDataAction().execute(request);
assertNotNull(result); assertNotNull(result);
assertNotNull(result.getTables()); assertNotNull(result.getTables());

View File

@ -29,6 +29,7 @@ class QueryActionTest
public void test() throws QException public void test() throws QException
{ {
QueryRequest request = new QueryRequest(TestUtils.defineInstance()); QueryRequest request = new QueryRequest(TestUtils.defineInstance());
request.setSession(TestUtils.getMockSession());
request.setTableName("person"); request.setTableName("person");
QueryResult result = new QueryAction().execute(request); QueryResult result = new QueryAction().execute(request);
assertNotNull(result); assertNotNull(result);

View File

@ -38,6 +38,7 @@ public class RunFunctionTest
{ {
TestCallback callback = new TestCallback(); TestCallback callback = new TestCallback();
RunFunctionRequest request = new RunFunctionRequest(TestUtils.defineInstance()); RunFunctionRequest request = new RunFunctionRequest(TestUtils.defineInstance());
request.setSession(TestUtils.getMockSession());
request.setProcessName("greet"); request.setProcessName("greet");
request.setFunctionName("prepare"); request.setFunctionName("prepare");
request.setCallback(callback); request.setCallback(callback);

View File

@ -31,6 +31,7 @@ class TableMetaDataActionTest
public void test() throws QException public void test() throws QException
{ {
TableMetaDataRequest request = new TableMetaDataRequest(TestUtils.defineInstance()); TableMetaDataRequest request = new TableMetaDataRequest(TestUtils.defineInstance());
request.setSession(TestUtils.getMockSession());
request.setTableName("person"); request.setTableName("person");
TableMetaDataResult result = new TableMetaDataAction().execute(request); TableMetaDataResult result = new TableMetaDataAction().execute(request);
assertNotNull(result); assertNotNull(result);
@ -50,6 +51,7 @@ class TableMetaDataActionTest
{ {
assertThrows(QUserFacingException.class, () -> { assertThrows(QUserFacingException.class, () -> {
TableMetaDataRequest request = new TableMetaDataRequest(TestUtils.defineInstance()); TableMetaDataRequest request = new TableMetaDataRequest(TestUtils.defineInstance());
request.setSession(TestUtils.getMockSession());
request.setTableName("willNotBeFound"); request.setTableName("willNotBeFound");
new TableMetaDataAction().execute(request); new TableMetaDataAction().execute(request);
}); });

View File

@ -7,7 +7,7 @@ package com.kingsrook.qqq.backend.core.modules;
import com.kingsrook.qqq.backend.core.exceptions.QModuleDispatchException; import com.kingsrook.qqq.backend.core.exceptions.QModuleDispatchException;
import com.kingsrook.qqq.backend.core.model.metadata.QBackendMetaData; import com.kingsrook.qqq.backend.core.model.metadata.QBackendMetaData;
import com.kingsrook.qqq.backend.core.modules.interfaces.QModuleInterface; import com.kingsrook.qqq.backend.core.modules.interfaces.QBackendModuleInterface;
import com.kingsrook.qqq.backend.core.utils.TestUtils; import com.kingsrook.qqq.backend.core.utils.TestUtils;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
@ -17,7 +17,7 @@ import static org.junit.jupiter.api.Assertions.*;
** Unit test for QModuleDispatcher ** Unit test for QModuleDispatcher
** **
*******************************************************************************/ *******************************************************************************/
class QModuleDispatcherTest class QBackendModuleDispatcherTest
{ {
/******************************************************************************* /*******************************************************************************
@ -27,7 +27,7 @@ class QModuleDispatcherTest
@Test @Test
public void test_getQModule_valid() throws QModuleDispatchException public void test_getQModule_valid() throws QModuleDispatchException
{ {
QModuleInterface qModule = new QModuleDispatcher().getQModule(TestUtils.defineBackend()); QBackendModuleInterface qModule = new QBackendModuleDispatcher().getQModule(TestUtils.defineBackend());
assertNotNull(qModule); assertNotNull(qModule);
} }
@ -44,7 +44,7 @@ class QModuleDispatcherTest
{ {
QBackendMetaData qBackendMetaData = TestUtils.defineBackend(); QBackendMetaData qBackendMetaData = TestUtils.defineBackend();
qBackendMetaData.setType("aTypeThatWontEverExist"); qBackendMetaData.setType("aTypeThatWontEverExist");
new QModuleDispatcher().getQModule(qBackendMetaData); new QBackendModuleDispatcher().getQModule(qBackendMetaData);
}); });
} }

View File

@ -6,6 +6,7 @@ package com.kingsrook.qqq.backend.core.utils;
import java.util.List; import java.util.List;
import com.kingsrook.qqq.backend.core.model.metadata.QAuthenticationMetaData;
import com.kingsrook.qqq.backend.core.model.metadata.QBackendMetaData; import com.kingsrook.qqq.backend.core.model.metadata.QBackendMetaData;
import com.kingsrook.qqq.backend.core.model.metadata.QCodeReference; import com.kingsrook.qqq.backend.core.model.metadata.QCodeReference;
import com.kingsrook.qqq.backend.core.model.metadata.QCodeType; import com.kingsrook.qqq.backend.core.model.metadata.QCodeType;
@ -21,6 +22,8 @@ import com.kingsrook.qqq.backend.core.model.metadata.processes.QOutputView;
import com.kingsrook.qqq.backend.core.model.metadata.processes.QProcessMetaData; import com.kingsrook.qqq.backend.core.model.metadata.processes.QProcessMetaData;
import com.kingsrook.qqq.backend.core.model.metadata.processes.QRecordListMetaData; import com.kingsrook.qqq.backend.core.model.metadata.processes.QRecordListMetaData;
import com.kingsrook.qqq.backend.core.model.metadata.processes.QRecordListView; import com.kingsrook.qqq.backend.core.model.metadata.processes.QRecordListView;
import com.kingsrook.qqq.backend.core.model.session.QSession;
import com.kingsrook.qqq.backend.core.modules.mock.MockAuthenticationModule;
/******************************************************************************* /*******************************************************************************
@ -36,6 +39,7 @@ public class TestUtils
public static QInstance defineInstance() public static QInstance defineInstance()
{ {
QInstance qInstance = new QInstance(); QInstance qInstance = new QInstance();
qInstance.setAuthentication(defineAuthentication());
qInstance.addBackend(defineBackend()); qInstance.addBackend(defineBackend());
qInstance.addTable(defineTablePerson()); qInstance.addTable(defineTablePerson());
qInstance.addProcess(defineProcessGreetPeople()); qInstance.addProcess(defineProcessGreetPeople());
@ -44,6 +48,19 @@ public class TestUtils
/*******************************************************************************
** Define the authentication used in standard tests - using 'mock' type.
**
*******************************************************************************/
private static QAuthenticationMetaData defineAuthentication()
{
return new QAuthenticationMetaData()
.withName("mock")
.withType("mock");
}
/******************************************************************************* /*******************************************************************************
** Define the backend used in standard tests - using 'mock' type. ** Define the backend used in standard tests - using 'mock' type.
*******************************************************************************/ *******************************************************************************/
@ -109,4 +126,14 @@ public class TestUtils
); );
} }
/*******************************************************************************
**
*******************************************************************************/
public static QSession getMockSession()
{
MockAuthenticationModule mockAuthenticationModule = new MockAuthenticationModule();
return (mockAuthenticationModule.createSession(null));
}
} }