Checkpoint: support for authentication; initial process tests

This commit is contained in:
Darin Kelkhoff
2022-02-15 18:20:13 -06:00
parent 7b10abc106
commit e7c2cf9b94
3 changed files with 62 additions and 17 deletions

View File

@ -7,6 +7,7 @@ package com.kingsrook.qqq.backend.javalin;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import com.kingsrook.qqq.backend.core.actions.DeleteAction; import com.kingsrook.qqq.backend.core.actions.DeleteAction;
@ -14,20 +15,25 @@ import com.kingsrook.qqq.backend.core.actions.InsertAction;
import com.kingsrook.qqq.backend.core.actions.MetaDataAction; import com.kingsrook.qqq.backend.core.actions.MetaDataAction;
import com.kingsrook.qqq.backend.core.actions.QueryAction; import com.kingsrook.qqq.backend.core.actions.QueryAction;
import com.kingsrook.qqq.backend.core.actions.TableMetaDataAction; import com.kingsrook.qqq.backend.core.actions.TableMetaDataAction;
import com.kingsrook.qqq.backend.core.exceptions.QModuleDispatchException;
import com.kingsrook.qqq.backend.core.exceptions.QUserFacingException; import com.kingsrook.qqq.backend.core.exceptions.QUserFacingException;
import com.kingsrook.qqq.backend.core.model.actions.DeleteRequest; import com.kingsrook.qqq.backend.core.model.actions.AbstractQRequest;
import com.kingsrook.qqq.backend.core.model.actions.DeleteResult; import com.kingsrook.qqq.backend.core.model.actions.delete.DeleteRequest;
import com.kingsrook.qqq.backend.core.model.actions.InsertRequest; import com.kingsrook.qqq.backend.core.model.actions.delete.DeleteResult;
import com.kingsrook.qqq.backend.core.model.actions.InsertResult; import com.kingsrook.qqq.backend.core.model.actions.insert.InsertRequest;
import com.kingsrook.qqq.backend.core.model.actions.MetaDataRequest; import com.kingsrook.qqq.backend.core.model.actions.insert.InsertResult;
import com.kingsrook.qqq.backend.core.model.actions.MetaDataResult; import com.kingsrook.qqq.backend.core.model.actions.metadata.MetaDataRequest;
import com.kingsrook.qqq.backend.core.model.actions.QQueryFilter; import com.kingsrook.qqq.backend.core.model.actions.metadata.MetaDataResult;
import com.kingsrook.qqq.backend.core.model.actions.QueryRequest; import com.kingsrook.qqq.backend.core.model.actions.metadata.table.TableMetaDataRequest;
import com.kingsrook.qqq.backend.core.model.actions.QueryResult; import com.kingsrook.qqq.backend.core.model.actions.metadata.table.TableMetaDataResult;
import com.kingsrook.qqq.backend.core.model.actions.TableMetaDataRequest; import com.kingsrook.qqq.backend.core.model.actions.query.QQueryFilter;
import com.kingsrook.qqq.backend.core.model.actions.TableMetaDataResult; 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.data.QRecord; import com.kingsrook.qqq.backend.core.model.data.QRecord;
import com.kingsrook.qqq.backend.core.model.metadata.QInstance; import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
import com.kingsrook.qqq.backend.core.model.session.QSession;
import com.kingsrook.qqq.backend.core.modules.QAuthenticationModuleDispatcher;
import com.kingsrook.qqq.backend.core.modules.interfaces.QAuthenticationModuleInterface;
import com.kingsrook.qqq.backend.core.utils.ExceptionUtils; import com.kingsrook.qqq.backend.core.utils.ExceptionUtils;
import com.kingsrook.qqq.backend.core.utils.JsonUtils; import com.kingsrook.qqq.backend.core.utils.JsonUtils;
import com.kingsrook.qqq.backend.core.utils.StringUtils; import com.kingsrook.qqq.backend.core.utils.StringUtils;
@ -52,6 +58,7 @@ import static io.javalin.apibuilder.ApiBuilder.post;
public class QJavalinImplementation public class QJavalinImplementation
{ {
private static final Logger LOG = LogManager.getLogger(QJavalinImplementation.class); private static final Logger LOG = LogManager.getLogger(QJavalinImplementation.class);
private static final int SESSION_COOKIE_AGE = 60 * 60 * 24;
private static QInstance qInstance; private static QInstance qInstance;
@ -141,6 +148,25 @@ public class QJavalinImplementation
/*******************************************************************************
**
*******************************************************************************/
private static void setupSession(Context context, AbstractQRequest request) throws QModuleDispatchException
{
QAuthenticationModuleDispatcher qAuthenticationModuleDispatcher = new QAuthenticationModuleDispatcher();
QAuthenticationModuleInterface authenticationModule = qAuthenticationModuleDispatcher.getQModule(request.getAuthenticationMetaData());
// todo - does this need some per-provider logic actually? mmm...
Map<String, String> authenticationContext = new HashMap<>();
authenticationContext.put("sessionId", context.cookie("sessionId"));
QSession session = authenticationModule.createSession(authenticationContext);
request.setSession(session);
context.cookie("sessionId", session.getIdReference(), SESSION_COOKIE_AGE);
}
/******************************************************************************* /*******************************************************************************
** **
*******************************************************************************/ *******************************************************************************/
@ -153,6 +179,7 @@ public class QJavalinImplementation
primaryKeys.add(context.pathParam("id")); primaryKeys.add(context.pathParam("id"));
DeleteRequest deleteRequest = new DeleteRequest(qInstance); DeleteRequest deleteRequest = new DeleteRequest(qInstance);
setupSession(context, deleteRequest);
deleteRequest.setTableName(table); deleteRequest.setTableName(table);
deleteRequest.setPrimaryKeys(primaryKeys); deleteRequest.setPrimaryKeys(primaryKeys);
@ -202,6 +229,7 @@ public class QJavalinImplementation
} }
InsertRequest insertRequest = new InsertRequest(qInstance); InsertRequest insertRequest = new InsertRequest(qInstance);
setupSession(context, insertRequest);
insertRequest.setTableName(table); insertRequest.setTableName(table);
insertRequest.setRecords(recordList); insertRequest.setRecords(recordList);
@ -231,7 +259,6 @@ public class QJavalinImplementation
/******************************************************************************* /*******************************************************************************
* *
* Filter parameter is a serialized QQueryFilter object, that is to say: * Filter parameter is a serialized QQueryFilter object, that is to say:
*
* <pre> * <pre>
* filter= * filter=
* {"criteria":[ * {"criteria":[
@ -248,6 +275,7 @@ public class QJavalinImplementation
try try
{ {
QueryRequest queryRequest = new QueryRequest(qInstance); QueryRequest queryRequest = new QueryRequest(qInstance);
setupSession(context, queryRequest);
queryRequest.setTableName(context.pathParam("table")); queryRequest.setTableName(context.pathParam("table"));
queryRequest.setSkip(integerQueryParam(context, "skip")); queryRequest.setSkip(integerQueryParam(context, "skip"));
queryRequest.setLimit(integerQueryParam(context, "limit")); queryRequest.setLimit(integerQueryParam(context, "limit"));
@ -279,6 +307,7 @@ public class QJavalinImplementation
try try
{ {
MetaDataRequest metaDataRequest = new MetaDataRequest(qInstance); MetaDataRequest metaDataRequest = new MetaDataRequest(qInstance);
setupSession(context, metaDataRequest);
MetaDataAction metaDataAction = new MetaDataAction(); MetaDataAction metaDataAction = new MetaDataAction();
MetaDataResult metaDataResult = metaDataAction.execute(metaDataRequest); MetaDataResult metaDataResult = metaDataAction.execute(metaDataRequest);
@ -300,6 +329,7 @@ public class QJavalinImplementation
try try
{ {
TableMetaDataRequest tableMetaDataRequest = new TableMetaDataRequest(qInstance); TableMetaDataRequest tableMetaDataRequest = new TableMetaDataRequest(qInstance);
setupSession(context, tableMetaDataRequest);
tableMetaDataRequest.setTableName(context.pathParam("table")); tableMetaDataRequest.setTableName(context.pathParam("table"));
TableMetaDataAction tableMetaDataAction = new TableMetaDataAction(); TableMetaDataAction tableMetaDataAction = new TableMetaDataAction();
TableMetaDataResult tableMetaDataResult = tableMetaDataAction.execute(tableMetaDataRequest); TableMetaDataResult tableMetaDataResult = tableMetaDataAction.execute(tableMetaDataRequest);
@ -331,7 +361,7 @@ public class QJavalinImplementation
LOG.warn("Exception in javalin request", e); LOG.warn("Exception in javalin request", e);
e.printStackTrace(); e.printStackTrace();
context.status(HttpStatus.INTERNAL_SERVER_ERROR_500) context.status(HttpStatus.INTERNAL_SERVER_ERROR_500)
.result("{\"error\":\"" + e.getClass().getSimpleName() + "\"}"); .result("{\"error\":\"" + e.getClass().getSimpleName() + " (" + e.getMessage() + ")\"}");
} }
} }

View File

@ -26,7 +26,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
/******************************************************************************* /*******************************************************************************
** Unit terst for the QJavalinImplementation ** Unit test for the QJavalinImplementation
** **
** based on https://javalin.io/tutorials/testing - starts a javalin instance ** based on https://javalin.io/tutorials/testing - starts a javalin instance
** and actually makes http requests into it. ** and actually makes http requests into it.

View File

@ -8,12 +8,13 @@ package com.kingsrook.qqq.backend.javalin;
import java.io.InputStream; import java.io.InputStream;
import java.sql.Connection; import java.sql.Connection;
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.QInstance; import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
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.QFieldMetaData; import com.kingsrook.qqq.backend.core.model.metadata.QFieldMetaData;
import com.kingsrook.qqq.backend.core.model.metadata.QFieldType; import com.kingsrook.qqq.backend.core.model.metadata.QFieldType;
import com.kingsrook.qqq.backend.core.model.metadata.QTableMetaData; import com.kingsrook.qqq.backend.core.model.metadata.QTableMetaData;
import com.kingsrook.qqq.backend.module.rdbms.RDBSMBackendMetaData; import com.kingsrook.qqq.backend.module.rdbms.RDBMSBackendMetaData;
import com.kingsrook.qqq.backend.module.rdbms.jdbc.ConnectionManager; import com.kingsrook.qqq.backend.module.rdbms.jdbc.ConnectionManager;
import com.kingsrook.qqq.backend.module.rdbms.jdbc.QueryManager; import com.kingsrook.qqq.backend.module.rdbms.jdbc.QueryManager;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
@ -35,7 +36,7 @@ public class TestUtils
public static void primeTestDatabase() throws Exception public static void primeTestDatabase() throws Exception
{ {
ConnectionManager connectionManager = new ConnectionManager(); ConnectionManager connectionManager = new ConnectionManager();
Connection connection = connectionManager.getConnection(new RDBSMBackendMetaData(TestUtils.defineBackend())); Connection connection = connectionManager.getConnection(new RDBMSBackendMetaData(TestUtils.defineBackend()));
InputStream primeTestDatabaseSqlStream = TestUtils.class.getResourceAsStream("/prime-test-database.sql"); InputStream primeTestDatabaseSqlStream = TestUtils.class.getResourceAsStream("/prime-test-database.sql");
assertNotNull(primeTestDatabaseSqlStream); assertNotNull(primeTestDatabaseSqlStream);
List<String> lines = (List<String>) IOUtils.readLines(primeTestDatabaseSqlStream); List<String> lines = (List<String>) IOUtils.readLines(primeTestDatabaseSqlStream);
@ -55,7 +56,7 @@ public class TestUtils
public static void runTestSql(String sql, QueryManager.ResultSetProcessor resultSetProcessor) throws Exception public static void runTestSql(String sql, QueryManager.ResultSetProcessor resultSetProcessor) throws Exception
{ {
ConnectionManager connectionManager = new ConnectionManager(); ConnectionManager connectionManager = new ConnectionManager();
Connection connection = connectionManager.getConnection(new RDBSMBackendMetaData(defineBackend())); Connection connection = connectionManager.getConnection(new RDBMSBackendMetaData(defineBackend()));
QueryManager.executeStatement(connection, sql, resultSetProcessor); QueryManager.executeStatement(connection, sql, resultSetProcessor);
} }
@ -68,6 +69,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());
return (qInstance); return (qInstance);
@ -75,6 +77,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 h2 rdbms backend ** Define the h2 rdbms backend
** **