diff --git a/src/main/java/com/kingsrook/qqq/backend/core/actions/ActionHelper.java b/src/main/java/com/kingsrook/qqq/backend/core/actions/ActionHelper.java new file mode 100644 index 00000000..dcde44a6 --- /dev/null +++ b/src/main/java/com/kingsrook/qqq/backend/core/actions/ActionHelper.java @@ -0,0 +1,33 @@ +/* + * Copyright © 2021-2022. Kingsrook LLC . 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"); + } + } + +} diff --git a/src/main/java/com/kingsrook/qqq/backend/core/actions/DeleteAction.java b/src/main/java/com/kingsrook/qqq/backend/core/actions/DeleteAction.java index 7b488342..48d5e48a 100644 --- a/src/main/java/com/kingsrook/qqq/backend/core/actions/DeleteAction.java +++ b/src/main/java/com/kingsrook/qqq/backend/core/actions/DeleteAction.java @@ -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.model.actions.delete.DeleteRequest; 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.QModuleDispatcher; -import com.kingsrook.qqq.backend.core.modules.interfaces.QModuleInterface; +import com.kingsrook.qqq.backend.core.modules.QBackendModuleDispatcher; +import com.kingsrook.qqq.backend.core.modules.interfaces.QBackendModuleInterface; /******************************************************************************* @@ -24,11 +23,10 @@ public class DeleteAction *******************************************************************************/ public DeleteResult execute(DeleteRequest deleteRequest) throws QException { - QModuleDispatcher qModuleDispatcher = new QModuleDispatcher(); + ActionHelper.validateSession(deleteRequest); - QBackendMetaData backend = deleteRequest.getBackend(); - - QModuleInterface qModule = qModuleDispatcher.getQModule(backend); + QBackendModuleDispatcher qBackendModuleDispatcher = new QBackendModuleDispatcher(); + QBackendModuleInterface qModule = qBackendModuleDispatcher.getQModule(deleteRequest.getBackend()); // todo pre-customization - just get to modify the request? DeleteResult deleteResult = qModule.getDeleteInterface().execute(deleteRequest); // todo post-customization - can do whatever w/ the result if you want diff --git a/src/main/java/com/kingsrook/qqq/backend/core/actions/InsertAction.java b/src/main/java/com/kingsrook/qqq/backend/core/actions/InsertAction.java index 9b3baf30..e0489d2d 100644 --- a/src/main/java/com/kingsrook/qqq/backend/core/actions/InsertAction.java +++ b/src/main/java/com/kingsrook/qqq/backend/core/actions/InsertAction.java @@ -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.model.actions.insert.InsertRequest; 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.QModuleDispatcher; -import com.kingsrook.qqq.backend.core.modules.interfaces.QModuleInterface; +import com.kingsrook.qqq.backend.core.modules.QBackendModuleDispatcher; +import com.kingsrook.qqq.backend.core.modules.interfaces.QBackendModuleInterface; /******************************************************************************* @@ -24,11 +23,10 @@ public class InsertAction *******************************************************************************/ public InsertResult execute(InsertRequest insertRequest) throws QException { - QModuleDispatcher qModuleDispatcher = new QModuleDispatcher(); + ActionHelper.validateSession(insertRequest); - QBackendMetaData backend = insertRequest.getBackend(); - - QModuleInterface qModule = qModuleDispatcher.getQModule(backend); + QBackendModuleDispatcher qBackendModuleDispatcher = new QBackendModuleDispatcher(); + QBackendModuleInterface qModule = qBackendModuleDispatcher.getQModule(insertRequest.getBackend()); // todo pre-customization - just get to modify the request? InsertResult insertResult = qModule.getInsertInterface().execute(insertRequest); // todo post-customization - can do whatever w/ the result if you want diff --git a/src/main/java/com/kingsrook/qqq/backend/core/actions/MetaDataAction.java b/src/main/java/com/kingsrook/qqq/backend/core/actions/MetaDataAction.java index 4f8bc8b3..80bbb9e9 100644 --- a/src/main/java/com/kingsrook/qqq/backend/core/actions/MetaDataAction.java +++ b/src/main/java/com/kingsrook/qqq/backend/core/actions/MetaDataAction.java @@ -25,6 +25,8 @@ public class MetaDataAction *******************************************************************************/ public MetaDataResult execute(MetaDataRequest metaDataRequest) throws QException { + ActionHelper.validateSession(metaDataRequest); + // todo pre-customization - just get to modify the request? MetaDataResult metaDataResult = new MetaDataResult(); diff --git a/src/main/java/com/kingsrook/qqq/backend/core/actions/QueryAction.java b/src/main/java/com/kingsrook/qqq/backend/core/actions/QueryAction.java index a801c7b9..be1aab1e 100644 --- a/src/main/java/com/kingsrook/qqq/backend/core/actions/QueryAction.java +++ b/src/main/java/com/kingsrook/qqq/backend/core/actions/QueryAction.java @@ -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.model.actions.query.QueryRequest; 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.QModuleDispatcher; -import com.kingsrook.qqq.backend.core.modules.interfaces.QModuleInterface; +import com.kingsrook.qqq.backend.core.modules.QBackendModuleDispatcher; +import com.kingsrook.qqq.backend.core.modules.interfaces.QBackendModuleInterface; /******************************************************************************* @@ -24,11 +23,10 @@ public class QueryAction *******************************************************************************/ public QueryResult execute(QueryRequest queryRequest) throws QException { - QModuleDispatcher qModuleDispatcher = new QModuleDispatcher(); + ActionHelper.validateSession(queryRequest); - QBackendMetaData backend = queryRequest.getBackend(); - - QModuleInterface qModule = qModuleDispatcher.getQModule(backend); + QBackendModuleDispatcher qBackendModuleDispatcher = new QBackendModuleDispatcher(); + QBackendModuleInterface qModule = qBackendModuleDispatcher.getQModule(queryRequest.getBackend()); // todo pre-customization - just get to modify the request? QueryResult queryResult = qModule.getQueryInterface().execute(queryRequest); // todo post-customization - can do whatever w/ the result if you want diff --git a/src/main/java/com/kingsrook/qqq/backend/core/actions/RunFunctionAction.java b/src/main/java/com/kingsrook/qqq/backend/core/actions/RunFunctionAction.java index 59980b81..4cf0c620 100644 --- a/src/main/java/com/kingsrook/qqq/backend/core/actions/RunFunctionAction.java +++ b/src/main/java/com/kingsrook/qqq/backend/core/actions/RunFunctionAction.java @@ -35,6 +35,8 @@ public class RunFunctionAction *******************************************************************************/ public RunFunctionResult execute(RunFunctionRequest runFunctionRequest) throws QException { + ActionHelper.validateSession(runFunctionRequest); + /////////////////////////////////////////////////////// // todo - shouldn't meta-data validation catch this? // /////////////////////////////////////////////////////// @@ -109,6 +111,7 @@ public class RunFunctionAction if(runFunctionRequest.getRecords() == null) { QueryRequest queryRequest = new QueryRequest(runFunctionRequest.getInstance()); + queryRequest.setSession(runFunctionRequest.getSession()); queryRequest.setTableName(inputMetaData.getRecordListMetaData().getTableName()); // todo - handle this being async (e.g., http) diff --git a/src/main/java/com/kingsrook/qqq/backend/core/actions/RunProcessAction.java b/src/main/java/com/kingsrook/qqq/backend/core/actions/RunProcessAction.java index a91586ae..80874fa5 100644 --- a/src/main/java/com/kingsrook/qqq/backend/core/actions/RunProcessAction.java +++ b/src/main/java/com/kingsrook/qqq/backend/core/actions/RunProcessAction.java @@ -27,6 +27,8 @@ public class RunProcessAction *******************************************************************************/ public RunProcessResult execute(RunProcessRequest runProcessRequest) throws QException { + ActionHelper.validateSession(runProcessRequest); + /////////////////////////////////////////////////////// // todo - shouldn't meta-data validation catch this? // /////////////////////////////////////////////////////// diff --git a/src/main/java/com/kingsrook/qqq/backend/core/actions/TableMetaDataAction.java b/src/main/java/com/kingsrook/qqq/backend/core/actions/TableMetaDataAction.java index 2e6e40b9..a12c5433 100644 --- a/src/main/java/com/kingsrook/qqq/backend/core/actions/TableMetaDataAction.java +++ b/src/main/java/com/kingsrook/qqq/backend/core/actions/TableMetaDataAction.java @@ -24,6 +24,8 @@ public class TableMetaDataAction *******************************************************************************/ public TableMetaDataResult execute(TableMetaDataRequest tableMetaDataRequest) throws QException { + ActionHelper.validateSession(tableMetaDataRequest); + // todo pre-customization - just get to modify the request? TableMetaDataResult tableMetaDataResult = new TableMetaDataResult(); diff --git a/src/main/java/com/kingsrook/qqq/backend/core/model/actions/AbstractQRequest.java b/src/main/java/com/kingsrook/qqq/backend/core/model/actions/AbstractQRequest.java index 8e4a192f..4b3423e5 100644 --- a/src/main/java/com/kingsrook/qqq/backend/core/model/actions/AbstractQRequest.java +++ b/src/main/java/com/kingsrook/qqq/backend/core/model/actions/AbstractQRequest.java @@ -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.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.session.QSession; /******************************************************************************* @@ -17,7 +19,7 @@ import com.kingsrook.qqq.backend.core.model.metadata.QInstance; public abstract class AbstractQRequest { 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 // // noting that this will also enrich any missing metaData // //////////////////////////////////////////////////////////// - if(! instance.getHasBeenValidated()) + if(!instance.getHasBeenValidated()) { try { @@ -57,6 +59,16 @@ public abstract class AbstractQRequest + /******************************************************************************* + ** + *******************************************************************************/ + public QAuthenticationMetaData getAuthenticationMetaData() + { + return (instance.getAuthentication()); + } + + + /******************************************************************************* ** Getter for instance ** @@ -76,4 +88,26 @@ public abstract class AbstractQRequest { this.instance = instance; } + + + + /******************************************************************************* + ** Getter for session + ** + *******************************************************************************/ + public QSession getSession() + { + return session; + } + + + + /******************************************************************************* + ** Setter for session + ** + *******************************************************************************/ + public void setSession(QSession session) + { + this.session = session; + } } diff --git a/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/QAuthenticationMetaData.java b/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/QAuthenticationMetaData.java new file mode 100644 index 00000000..177258ef --- /dev/null +++ b/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/QAuthenticationMetaData.java @@ -0,0 +1,164 @@ +/* + * Copyright © 2021-2021. Kingsrook LLC . 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 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 getValues() + { + return values; + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + public void setValues(Map values) + { + this.values = values; + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + public QAuthenticationMetaData withVales(Map values) + { + this.values = values; + return (this); + } + +} diff --git a/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/QInstance.java b/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/QInstance.java index 57c4cafd..f0d5bbb1 100644 --- a/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/QInstance.java +++ b/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/QInstance.java @@ -27,6 +27,8 @@ public class QInstance @JsonIgnore private Map backends = new HashMap<>(); + private QAuthenticationMetaData authentication = null; + private Map tables = new HashMap<>(); private Map 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; + } } diff --git a/src/main/java/com/kingsrook/qqq/backend/core/model/session/QSession.java b/src/main/java/com/kingsrook/qqq/backend/core/model/session/QSession.java new file mode 100644 index 00000000..ad49fe10 --- /dev/null +++ b/src/main/java/com/kingsrook/qqq/backend/core/model/session/QSession.java @@ -0,0 +1,130 @@ +/* + * Copyright © 2021-2022. Kingsrook LLC . 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 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 getValues() + { + return values; + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + public void setValues(Map values) + { + this.values = values; + } + +} diff --git a/src/main/java/com/kingsrook/qqq/backend/core/model/session/QUser.java b/src/main/java/com/kingsrook/qqq/backend/core/model/session/QUser.java new file mode 100644 index 00000000..b5ff0dd5 --- /dev/null +++ b/src/main/java/com/kingsrook/qqq/backend/core/model/session/QUser.java @@ -0,0 +1,59 @@ +/* + * Copyright © 2021-2022. Kingsrook LLC . 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; + } +} diff --git a/src/main/java/com/kingsrook/qqq/backend/core/modules/QAuthenticationModuleDispatcher.java b/src/main/java/com/kingsrook/qqq/backend/core/modules/QAuthenticationModuleDispatcher.java new file mode 100644 index 00000000..60bda692 --- /dev/null +++ b/src/main/java/com/kingsrook/qqq/backend/core/modules/QAuthenticationModuleDispatcher.java @@ -0,0 +1,72 @@ +/* + * Copyright © 2021-2021. Kingsrook LLC . 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 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)); + } + } +} diff --git a/src/main/java/com/kingsrook/qqq/backend/core/modules/QModuleDispatcher.java b/src/main/java/com/kingsrook/qqq/backend/core/modules/QBackendModuleDispatcher.java similarity index 76% rename from src/main/java/com/kingsrook/qqq/backend/core/modules/QModuleDispatcher.java rename to src/main/java/com/kingsrook/qqq/backend/core/modules/QBackendModuleDispatcher.java index 9051b18f..485aaaa0 100644 --- a/src/main/java/com/kingsrook/qqq/backend/core/modules/QModuleDispatcher.java +++ b/src/main/java/com/kingsrook/qqq/backend/core/modules/QBackendModuleDispatcher.java @@ -9,7 +9,7 @@ import java.util.HashMap; import java.util.Map; import com.kingsrook.qqq.backend.core.exceptions.QModuleDispatchException; 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. ** *******************************************************************************/ -public class QModuleDispatcher +public class QBackendModuleDispatcher { private Map backendTypeToModuleClassNameMap; @@ -28,11 +28,11 @@ public class QModuleDispatcher /******************************************************************************* ** *******************************************************************************/ - public QModuleDispatcher() + public QBackendModuleDispatcher() { backendTypeToModuleClassNameMap = new HashMap<>(); - backendTypeToModuleClassNameMap.put("mock", "com.kingsrook.qqq.backend.core.modules.mock.MockModule"); - backendTypeToModuleClassNameMap.put("rdbms", "com.kingsrook.qqq.backend.module.rdbms.RDBSMModule"); + backendTypeToModuleClassNameMap.put("mock", "com.kingsrook.qqq.backend.core.modules.mock.MockBackendModule"); + backendTypeToModuleClassNameMap.put("rdbms", "com.kingsrook.qqq.backend.module.rdbms.RDBMSBackendModule"); // 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 { @@ -52,7 +52,7 @@ public class QModuleDispatcher } Class moduleClass = Class.forName(className); - return (QModuleInterface) moduleClass.getDeclaredConstructor().newInstance(); + return (QBackendModuleInterface) moduleClass.getDeclaredConstructor().newInstance(); } catch(QModuleDispatchException qmde) { @@ -60,7 +60,7 @@ public class QModuleDispatcher } 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)); } } } diff --git a/src/main/java/com/kingsrook/qqq/backend/core/modules/defaults/FullyAnonymousAuthenticationModule.java b/src/main/java/com/kingsrook/qqq/backend/core/modules/defaults/FullyAnonymousAuthenticationModule.java new file mode 100644 index 00000000..b73ef4d8 --- /dev/null +++ b/src/main/java/com/kingsrook/qqq/backend/core/modules/defaults/FullyAnonymousAuthenticationModule.java @@ -0,0 +1,60 @@ +/* + * Copyright © 2021-2022. Kingsrook LLC . 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 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); + } +} diff --git a/src/main/java/com/kingsrook/qqq/backend/core/modules/interfaces/QAuthenticationModuleInterface.java b/src/main/java/com/kingsrook/qqq/backend/core/modules/interfaces/QAuthenticationModuleInterface.java new file mode 100644 index 00000000..07d656e5 --- /dev/null +++ b/src/main/java/com/kingsrook/qqq/backend/core/modules/interfaces/QAuthenticationModuleInterface.java @@ -0,0 +1,28 @@ +/* + * Copyright © 2021-2021. Kingsrook LLC . 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 context); + + + /******************************************************************************* + ** + *******************************************************************************/ + boolean isSessionValid(QSession session); +} diff --git a/src/main/java/com/kingsrook/qqq/backend/core/modules/interfaces/QModuleInterface.java b/src/main/java/com/kingsrook/qqq/backend/core/modules/interfaces/QBackendModuleInterface.java similarity index 93% rename from src/main/java/com/kingsrook/qqq/backend/core/modules/interfaces/QModuleInterface.java rename to src/main/java/com/kingsrook/qqq/backend/core/modules/interfaces/QBackendModuleInterface.java index 1fdc856b..ed4d2827 100644 --- a/src/main/java/com/kingsrook/qqq/backend/core/modules/interfaces/QModuleInterface.java +++ b/src/main/java/com/kingsrook/qqq/backend/core/modules/interfaces/QBackendModuleInterface.java @@ -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. ** *******************************************************************************/ -public interface QModuleInterface +public interface QBackendModuleInterface { /******************************************************************************* ** diff --git a/src/main/java/com/kingsrook/qqq/backend/core/modules/mock/MockAuthenticationModule.java b/src/main/java/com/kingsrook/qqq/backend/core/modules/mock/MockAuthenticationModule.java new file mode 100644 index 00000000..77ff0be5 --- /dev/null +++ b/src/main/java/com/kingsrook/qqq/backend/core/modules/mock/MockAuthenticationModule.java @@ -0,0 +1,65 @@ +/* + * Copyright © 2021-2022. Kingsrook LLC . 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 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); + } +} diff --git a/src/main/java/com/kingsrook/qqq/backend/core/modules/mock/MockModule.java b/src/main/java/com/kingsrook/qqq/backend/core/modules/mock/MockBackendModule.java similarity index 91% rename from src/main/java/com/kingsrook/qqq/backend/core/modules/mock/MockModule.java rename to src/main/java/com/kingsrook/qqq/backend/core/modules/mock/MockBackendModule.java index 9ec1170d..964d5d55 100644 --- a/src/main/java/com/kingsrook/qqq/backend/core/modules/mock/MockModule.java +++ b/src/main/java/com/kingsrook/qqq/backend/core/modules/mock/MockBackendModule.java @@ -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.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; @@ -18,7 +18,7 @@ import com.kingsrook.qqq.backend.core.modules.interfaces.QueryInterface; ** tests over all the actions available through the QModuleInterface. ** *******************************************************************************/ -public class MockModule implements QModuleInterface +public class MockBackendModule implements QBackendModuleInterface { /******************************************************************************* ** diff --git a/src/test/java/com/kingsrook/qqq/backend/core/actions/DeleteActionTest.java b/src/test/java/com/kingsrook/qqq/backend/core/actions/DeleteActionTest.java index 46d12c4d..b8f81c96 100644 --- a/src/test/java/com/kingsrook/qqq/backend/core/actions/DeleteActionTest.java +++ b/src/test/java/com/kingsrook/qqq/backend/core/actions/DeleteActionTest.java @@ -32,6 +32,7 @@ class DeleteActionTest public void test() throws QException { DeleteRequest request = new DeleteRequest(TestUtils.defineInstance()); + request.setSession(TestUtils.getMockSession()); request.setTableName("person"); request.setPrimaryKeys(List.of(1, 2)); DeleteResult result = new DeleteAction().execute(request); diff --git a/src/test/java/com/kingsrook/qqq/backend/core/actions/InsertActionTest.java b/src/test/java/com/kingsrook/qqq/backend/core/actions/InsertActionTest.java index af5b756d..395ae60c 100644 --- a/src/test/java/com/kingsrook/qqq/backend/core/actions/InsertActionTest.java +++ b/src/test/java/com/kingsrook/qqq/backend/core/actions/InsertActionTest.java @@ -32,6 +32,7 @@ class InsertActionTest public void test() throws QException { InsertRequest request = new InsertRequest(TestUtils.defineInstance()); + request.setSession(TestUtils.getMockSession()); request.setTableName("person"); List records =new ArrayList<>(); QRecord record = new QRecord(); diff --git a/src/test/java/com/kingsrook/qqq/backend/core/actions/MetaDataActionTest.java b/src/test/java/com/kingsrook/qqq/backend/core/actions/MetaDataActionTest.java index a092f058..62f5b36f 100644 --- a/src/test/java/com/kingsrook/qqq/backend/core/actions/MetaDataActionTest.java +++ b/src/test/java/com/kingsrook/qqq/backend/core/actions/MetaDataActionTest.java @@ -27,6 +27,7 @@ class MetaDataActionTest public void test() throws QException { MetaDataRequest request = new MetaDataRequest(TestUtils.defineInstance()); + request.setSession(TestUtils.getMockSession()); MetaDataResult result = new MetaDataAction().execute(request); assertNotNull(result); assertNotNull(result.getTables()); diff --git a/src/test/java/com/kingsrook/qqq/backend/core/actions/QueryActionTest.java b/src/test/java/com/kingsrook/qqq/backend/core/actions/QueryActionTest.java index 6e603ebd..f0561024 100644 --- a/src/test/java/com/kingsrook/qqq/backend/core/actions/QueryActionTest.java +++ b/src/test/java/com/kingsrook/qqq/backend/core/actions/QueryActionTest.java @@ -29,6 +29,7 @@ class QueryActionTest public void test() throws QException { QueryRequest request = new QueryRequest(TestUtils.defineInstance()); + request.setSession(TestUtils.getMockSession()); request.setTableName("person"); QueryResult result = new QueryAction().execute(request); assertNotNull(result); diff --git a/src/test/java/com/kingsrook/qqq/backend/core/actions/RunFunctionTest.java b/src/test/java/com/kingsrook/qqq/backend/core/actions/RunFunctionTest.java index 3968e267..54e6cc78 100644 --- a/src/test/java/com/kingsrook/qqq/backend/core/actions/RunFunctionTest.java +++ b/src/test/java/com/kingsrook/qqq/backend/core/actions/RunFunctionTest.java @@ -38,6 +38,7 @@ public class RunFunctionTest { TestCallback callback = new TestCallback(); RunFunctionRequest request = new RunFunctionRequest(TestUtils.defineInstance()); + request.setSession(TestUtils.getMockSession()); request.setProcessName("greet"); request.setFunctionName("prepare"); request.setCallback(callback); diff --git a/src/test/java/com/kingsrook/qqq/backend/core/actions/TableMetaDataActionTest.java b/src/test/java/com/kingsrook/qqq/backend/core/actions/TableMetaDataActionTest.java index 90d3be01..9615fdb6 100644 --- a/src/test/java/com/kingsrook/qqq/backend/core/actions/TableMetaDataActionTest.java +++ b/src/test/java/com/kingsrook/qqq/backend/core/actions/TableMetaDataActionTest.java @@ -31,6 +31,7 @@ class TableMetaDataActionTest public void test() throws QException { TableMetaDataRequest request = new TableMetaDataRequest(TestUtils.defineInstance()); + request.setSession(TestUtils.getMockSession()); request.setTableName("person"); TableMetaDataResult result = new TableMetaDataAction().execute(request); assertNotNull(result); @@ -50,6 +51,7 @@ class TableMetaDataActionTest { assertThrows(QUserFacingException.class, () -> { TableMetaDataRequest request = new TableMetaDataRequest(TestUtils.defineInstance()); + request.setSession(TestUtils.getMockSession()); request.setTableName("willNotBeFound"); new TableMetaDataAction().execute(request); }); diff --git a/src/test/java/com/kingsrook/qqq/backend/core/modules/QModuleDispatcherTest.java b/src/test/java/com/kingsrook/qqq/backend/core/modules/QBackendModuleDispatcherTest.java similarity index 83% rename from src/test/java/com/kingsrook/qqq/backend/core/modules/QModuleDispatcherTest.java rename to src/test/java/com/kingsrook/qqq/backend/core/modules/QBackendModuleDispatcherTest.java index 106207a0..22d0c18a 100644 --- a/src/test/java/com/kingsrook/qqq/backend/core/modules/QModuleDispatcherTest.java +++ b/src/test/java/com/kingsrook/qqq/backend/core/modules/QBackendModuleDispatcherTest.java @@ -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.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 org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; @@ -17,7 +17,7 @@ import static org.junit.jupiter.api.Assertions.*; ** Unit test for QModuleDispatcher ** *******************************************************************************/ -class QModuleDispatcherTest +class QBackendModuleDispatcherTest { /******************************************************************************* @@ -27,7 +27,7 @@ class QModuleDispatcherTest @Test public void test_getQModule_valid() throws QModuleDispatchException { - QModuleInterface qModule = new QModuleDispatcher().getQModule(TestUtils.defineBackend()); + QBackendModuleInterface qModule = new QBackendModuleDispatcher().getQModule(TestUtils.defineBackend()); assertNotNull(qModule); } @@ -44,7 +44,7 @@ class QModuleDispatcherTest { QBackendMetaData qBackendMetaData = TestUtils.defineBackend(); qBackendMetaData.setType("aTypeThatWontEverExist"); - new QModuleDispatcher().getQModule(qBackendMetaData); + new QBackendModuleDispatcher().getQModule(qBackendMetaData); }); } diff --git a/src/test/java/com/kingsrook/qqq/backend/core/utils/TestUtils.java b/src/test/java/com/kingsrook/qqq/backend/core/utils/TestUtils.java index f447c8f4..85126407 100644 --- a/src/test/java/com/kingsrook/qqq/backend/core/utils/TestUtils.java +++ b/src/test/java/com/kingsrook/qqq/backend/core/utils/TestUtils.java @@ -6,6 +6,7 @@ package com.kingsrook.qqq.backend.core.utils; 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.QCodeReference; 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.QRecordListMetaData; 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() { QInstance qInstance = new QInstance(); + qInstance.setAuthentication(defineAuthentication()); qInstance.addBackend(defineBackend()); qInstance.addTable(defineTablePerson()); 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. *******************************************************************************/ @@ -109,4 +126,14 @@ public class TestUtils ); } + + + /******************************************************************************* + ** + *******************************************************************************/ + public static QSession getMockSession() + { + MockAuthenticationModule mockAuthenticationModule = new MockAuthenticationModule(); + return (mockAuthenticationModule.createSession(null)); + } }