mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-17 20:50:44 +00:00
implementation of record security locks, and permissions
This commit is contained in:
@ -41,6 +41,9 @@ import com.kingsrook.qqq.backend.core.actions.dashboard.RenderWidgetAction;
|
||||
import com.kingsrook.qqq.backend.core.actions.metadata.MetaDataAction;
|
||||
import com.kingsrook.qqq.backend.core.actions.metadata.ProcessMetaDataAction;
|
||||
import com.kingsrook.qqq.backend.core.actions.metadata.TableMetaDataAction;
|
||||
import com.kingsrook.qqq.backend.core.actions.permissions.PermissionCheckResult;
|
||||
import com.kingsrook.qqq.backend.core.actions.permissions.PermissionsHelper;
|
||||
import com.kingsrook.qqq.backend.core.actions.permissions.TablePermissionSubType;
|
||||
import com.kingsrook.qqq.backend.core.actions.reporting.ExportAction;
|
||||
import com.kingsrook.qqq.backend.core.actions.tables.CountAction;
|
||||
import com.kingsrook.qqq.backend.core.actions.tables.DeleteAction;
|
||||
@ -54,6 +57,7 @@ import com.kingsrook.qqq.backend.core.exceptions.QAuthenticationException;
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QInstanceValidationException;
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QModuleDispatchException;
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QNotFoundException;
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QPermissionDeniedException;
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QUserFacingException;
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QValueException;
|
||||
import com.kingsrook.qqq.backend.core.instances.QInstanceValidator;
|
||||
@ -86,6 +90,7 @@ import com.kingsrook.qqq.backend.core.model.actions.widgets.RenderWidgetOutput;
|
||||
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.fields.QFieldMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.processes.QProcessMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.session.QSession;
|
||||
import com.kingsrook.qqq.backend.core.modules.authentication.QAuthenticationModuleDispatcher;
|
||||
@ -331,7 +336,6 @@ public class QJavalinImplementation
|
||||
QAuthenticationModuleDispatcher qAuthenticationModuleDispatcher = new QAuthenticationModuleDispatcher();
|
||||
QAuthenticationModuleInterface authenticationModule = qAuthenticationModuleDispatcher.getQModule(input.getAuthenticationMetaData());
|
||||
|
||||
boolean needToSetSessionIdCookie = false;
|
||||
try
|
||||
{
|
||||
Map<String, String> authenticationContext = new HashMap<>();
|
||||
@ -345,7 +349,6 @@ public class QJavalinImplementation
|
||||
// first, look for a sessionId cookie //
|
||||
////////////////////////////////////////
|
||||
authenticationContext.put(SESSION_ID_COOKIE_NAME, sessionIdCookieValue);
|
||||
needToSetSessionIdCookie = true;
|
||||
}
|
||||
else if(authorizationHeaderValue != null)
|
||||
{
|
||||
@ -360,7 +363,6 @@ public class QJavalinImplementation
|
||||
{
|
||||
authorizationHeaderValue = authorizationHeaderValue.replaceFirst(basicPrefix, "");
|
||||
authenticationContext.put(BASIC_AUTH_NAME, authorizationHeaderValue);
|
||||
needToSetSessionIdCookie = true;
|
||||
}
|
||||
else if(authorizationHeaderValue.startsWith(bearerPrefix))
|
||||
{
|
||||
@ -383,7 +385,7 @@ public class QJavalinImplementation
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// if we got a session id cookie in, then send it back with updated cookie age //
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
if(needToSetSessionIdCookie)
|
||||
if(authenticationModule.usesSessionIdCookie())
|
||||
{
|
||||
context.cookie(SESSION_ID_COOKIE_NAME, session.getIdReference(), SESSION_COOKIE_AGE);
|
||||
}
|
||||
@ -395,7 +397,7 @@ public class QJavalinImplementation
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// if exception caught, clear out the cookie so the frontend will reauthorize //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
if(needToSetSessionIdCookie)
|
||||
if(authenticationModule.usesSessionIdCookie())
|
||||
{
|
||||
context.removeCookie(SESSION_ID_COOKIE_NAME);
|
||||
}
|
||||
@ -446,6 +448,8 @@ public class QJavalinImplementation
|
||||
deleteInput.setTableName(table);
|
||||
deleteInput.setPrimaryKeys(primaryKeys);
|
||||
|
||||
PermissionsHelper.checkTablePermissionThrowing(deleteInput, TablePermissionSubType.DELETE);
|
||||
|
||||
DeleteAction deleteAction = new DeleteAction();
|
||||
DeleteOutput deleteResult = deleteAction.execute(deleteInput);
|
||||
|
||||
@ -466,7 +470,14 @@ public class QJavalinImplementation
|
||||
{
|
||||
try
|
||||
{
|
||||
String table = context.pathParam("table");
|
||||
String table = context.pathParam("table");
|
||||
|
||||
UpdateInput updateInput = new UpdateInput(qInstance);
|
||||
setupSession(context, updateInput);
|
||||
updateInput.setTableName(table);
|
||||
|
||||
PermissionsHelper.checkTablePermissionThrowing(updateInput, TablePermissionSubType.EDIT);
|
||||
|
||||
List<QRecord> recordList = new ArrayList<>();
|
||||
QRecord record = new QRecord();
|
||||
record.setTableName(table);
|
||||
@ -494,12 +505,8 @@ public class QJavalinImplementation
|
||||
}
|
||||
|
||||
QTableMetaData tableMetaData = qInstance.getTable(table);
|
||||
|
||||
record.setValue(tableMetaData.getPrimaryKeyField(), context.pathParam("primaryKey"));
|
||||
|
||||
UpdateInput updateInput = new UpdateInput(qInstance);
|
||||
setupSession(context, updateInput);
|
||||
updateInput.setTableName(table);
|
||||
updateInput.setRecords(recordList);
|
||||
|
||||
UpdateAction updateAction = new UpdateAction();
|
||||
@ -522,7 +529,13 @@ public class QJavalinImplementation
|
||||
{
|
||||
try
|
||||
{
|
||||
String table = context.pathParam("table");
|
||||
String table = context.pathParam("table");
|
||||
InsertInput insertInput = new InsertInput(qInstance);
|
||||
setupSession(context, insertInput);
|
||||
insertInput.setTableName(table);
|
||||
|
||||
PermissionsHelper.checkTablePermissionThrowing(insertInput, TablePermissionSubType.INSERT);
|
||||
|
||||
List<QRecord> recordList = new ArrayList<>();
|
||||
QRecord record = new QRecord();
|
||||
record.setTableName(table);
|
||||
@ -536,10 +549,6 @@ public class QJavalinImplementation
|
||||
record.setValue(String.valueOf(entry.getKey()), (Serializable) entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
InsertInput insertInput = new InsertInput(qInstance);
|
||||
setupSession(context, insertInput);
|
||||
insertInput.setTableName(table);
|
||||
insertInput.setRecords(recordList);
|
||||
|
||||
InsertAction insertAction = new InsertAction();
|
||||
@ -577,6 +586,8 @@ public class QJavalinImplementation
|
||||
getInput.setShouldGenerateDisplayValues(true);
|
||||
getInput.setShouldTranslatePossibleValues(true);
|
||||
|
||||
PermissionsHelper.checkTablePermissionThrowing(getInput, TablePermissionSubType.READ);
|
||||
|
||||
// todo - validate that the primary key is of the proper type (e.g,. not a string for an id field)
|
||||
// and throw a 400-series error (tell the user bad-request), rather than, we're doing a 500 (server error)
|
||||
|
||||
@ -624,6 +635,8 @@ public class QJavalinImplementation
|
||||
setupSession(context, countInput);
|
||||
countInput.setTableName(context.pathParam("table"));
|
||||
|
||||
PermissionsHelper.checkTablePermissionThrowing(countInput, TablePermissionSubType.READ);
|
||||
|
||||
String filter = stringQueryParam(context, "filter");
|
||||
if(!StringUtils.hasContent(filter))
|
||||
{
|
||||
@ -673,6 +686,8 @@ public class QJavalinImplementation
|
||||
queryInput.setSkip(integerQueryParam(context, "skip"));
|
||||
queryInput.setLimit(integerQueryParam(context, "limit"));
|
||||
|
||||
PermissionsHelper.checkTablePermissionThrowing(queryInput, TablePermissionSubType.READ);
|
||||
|
||||
String filter = stringQueryParam(context, "filter");
|
||||
if(!StringUtils.hasContent(filter))
|
||||
{
|
||||
@ -727,7 +742,22 @@ public class QJavalinImplementation
|
||||
{
|
||||
TableMetaDataInput tableMetaDataInput = new TableMetaDataInput(qInstance);
|
||||
setupSession(context, tableMetaDataInput);
|
||||
tableMetaDataInput.setTableName(context.pathParam("table"));
|
||||
|
||||
String tableName = context.pathParam("table");
|
||||
QTableMetaData table = qInstance.getTable(tableName);
|
||||
if(table == null)
|
||||
{
|
||||
throw (new QNotFoundException("Table [" + tableName + "] was not found."));
|
||||
}
|
||||
|
||||
PermissionCheckResult permissionCheckResult = PermissionsHelper.getPermissionCheckResult(tableMetaDataInput, table);
|
||||
if(permissionCheckResult.equals(PermissionCheckResult.DENY_HIDE))
|
||||
{
|
||||
// not found? or permission denied... hmm
|
||||
throw (new QNotFoundException("Table [" + tableName + "] was not found."));
|
||||
}
|
||||
|
||||
tableMetaDataInput.setTableName(tableName);
|
||||
TableMetaDataAction tableMetaDataAction = new TableMetaDataAction();
|
||||
TableMetaDataOutput tableMetaDataOutput = tableMetaDataAction.execute(tableMetaDataInput);
|
||||
|
||||
@ -750,7 +780,16 @@ public class QJavalinImplementation
|
||||
{
|
||||
ProcessMetaDataInput processMetaDataInput = new ProcessMetaDataInput(qInstance);
|
||||
setupSession(context, processMetaDataInput);
|
||||
processMetaDataInput.setProcessName(context.pathParam("processName"));
|
||||
|
||||
String processName = context.pathParam("processName");
|
||||
QProcessMetaData process = qInstance.getProcess(processName);
|
||||
if(process == null)
|
||||
{
|
||||
throw (new QNotFoundException("Process [" + processName + "] was not found."));
|
||||
}
|
||||
PermissionsHelper.checkProcessPermissionThrowing(processMetaDataInput, processName);
|
||||
|
||||
processMetaDataInput.setProcessName(processName);
|
||||
ProcessMetaDataAction processMetaDataAction = new ProcessMetaDataAction();
|
||||
ProcessMetaDataOutput processMetaDataOutput = processMetaDataAction.execute(processMetaDataInput);
|
||||
|
||||
@ -778,6 +817,8 @@ public class QJavalinImplementation
|
||||
.withSession(insertInput.getSession())
|
||||
.withWidgetMetaData(qInstance.getWidget(context.pathParam("name")));
|
||||
|
||||
// todo permission?
|
||||
|
||||
//////////////////////////
|
||||
// process query string //
|
||||
//////////////////////////
|
||||
@ -856,6 +897,8 @@ public class QJavalinImplementation
|
||||
exportInput.setFilename(filename);
|
||||
exportInput.setLimit(limit);
|
||||
|
||||
PermissionsHelper.checkTablePermissionThrowing(exportInput, TablePermissionSubType.READ);
|
||||
|
||||
String fields = stringQueryParam(context, "fields");
|
||||
if(StringUtils.hasContent(fields))
|
||||
{
|
||||
@ -1137,6 +1180,12 @@ public class QJavalinImplementation
|
||||
return;
|
||||
}
|
||||
|
||||
if(e instanceof QPermissionDeniedException)
|
||||
{
|
||||
respondWithError(context, HttpStatus.Code.FORBIDDEN, e.getMessage()); // 403
|
||||
return;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
// default exception handling //
|
||||
////////////////////////////////
|
||||
|
@ -45,6 +45,7 @@ import com.kingsrook.qqq.backend.core.actions.async.AsyncJobManager;
|
||||
import com.kingsrook.qqq.backend.core.actions.async.AsyncJobState;
|
||||
import com.kingsrook.qqq.backend.core.actions.async.AsyncJobStatus;
|
||||
import com.kingsrook.qqq.backend.core.actions.async.JobGoingAsyncException;
|
||||
import com.kingsrook.qqq.backend.core.actions.permissions.PermissionsHelper;
|
||||
import com.kingsrook.qqq.backend.core.actions.processes.QProcessCallback;
|
||||
import com.kingsrook.qqq.backend.core.actions.processes.RunProcessAction;
|
||||
import com.kingsrook.qqq.backend.core.actions.reporting.GenerateReportAction;
|
||||
@ -53,7 +54,9 @@ import com.kingsrook.qqq.backend.core.actions.values.QValueFormatter;
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QModuleDispatchException;
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QNotFoundException;
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QPermissionDeniedException;
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QUserFacingException;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.AbstractActionInput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.processes.ProcessState;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.processes.QUploadedFile;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.processes.RunProcessInput;
|
||||
@ -185,6 +188,8 @@ public class QJavalinProcessHandler
|
||||
/////////////////////////////////////////////
|
||||
ReportInput reportInput = new ReportInput(QJavalinImplementation.qInstance);
|
||||
QJavalinImplementation.setupSession(context, reportInput);
|
||||
PermissionsHelper.checkReportPermissionThrowing(reportInput, reportName);
|
||||
|
||||
reportInput.setReportFormat(reportFormat);
|
||||
reportInput.setReportName(reportName);
|
||||
reportInput.setInputValues(null); // todo!
|
||||
@ -293,12 +298,19 @@ public class QJavalinProcessHandler
|
||||
|
||||
RunProcessInput runProcessInput = new RunProcessInput(QJavalinImplementation.qInstance);
|
||||
QJavalinImplementation.setupSession(context, runProcessInput);
|
||||
|
||||
runProcessInput.setProcessName(processName);
|
||||
runProcessInput.setFrontendStepBehavior(RunProcessInput.FrontendStepBehavior.BREAK);
|
||||
runProcessInput.setProcessUUID(processUUID);
|
||||
runProcessInput.setStartAfterStep(startAfterStep);
|
||||
populateRunProcessRequestWithValuesFromContext(context, runProcessInput);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// important to do this check AFTER the runProcessInput is populated with values from context - //
|
||||
// e.g., in case things like a reportName are set in here //
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
PermissionsHelper.checkProcessPermissionThrowing(runProcessInput, processName);
|
||||
|
||||
////////////////////////////////////////
|
||||
// run the process as an async action //
|
||||
////////////////////////////////////////
|
||||
@ -321,6 +333,10 @@ public class QJavalinProcessHandler
|
||||
{
|
||||
resultForCaller.put("jobUUID", jgae.getJobUUID());
|
||||
}
|
||||
catch(QPermissionDeniedException pde)
|
||||
{
|
||||
QJavalinImplementation.handleException(context, pde);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
@ -549,55 +565,68 @@ public class QJavalinProcessHandler
|
||||
*******************************************************************************/
|
||||
public static void processStatus(Context context)
|
||||
{
|
||||
String processUUID = context.pathParam("processUUID");
|
||||
String jobUUID = context.pathParam("jobUUID");
|
||||
|
||||
Map<String, Object> resultForCaller = new HashMap<>();
|
||||
resultForCaller.put("processUUID", processUUID);
|
||||
|
||||
LOG.debug("Request for status of process " + processUUID + ", job " + jobUUID);
|
||||
Optional<AsyncJobStatus> optionalJobStatus = new AsyncJobManager().getJobStatus(jobUUID);
|
||||
if(optionalJobStatus.isEmpty())
|
||||
try
|
||||
{
|
||||
serializeRunProcessExceptionForCaller(resultForCaller, new RuntimeException("Could not find status of process step job"));
|
||||
}
|
||||
else
|
||||
{
|
||||
AsyncJobStatus jobStatus = optionalJobStatus.get();
|
||||
AbstractActionInput input = new AbstractActionInput(QJavalinImplementation.qInstance);
|
||||
QJavalinImplementation.setupSession(context, input);
|
||||
|
||||
resultForCaller.put("jobStatus", jobStatus);
|
||||
LOG.debug("Job status is " + jobStatus.getState() + " for " + jobUUID);
|
||||
// todo... get process values? PermissionsHelper.checkProcessPermissionThrowing(input, context.pathParam("processName"));
|
||||
|
||||
if(jobStatus.getState().equals(AsyncJobState.COMPLETE))
|
||||
String processUUID = context.pathParam("processUUID");
|
||||
String jobUUID = context.pathParam("jobUUID");
|
||||
|
||||
resultForCaller.put("processUUID", processUUID);
|
||||
|
||||
LOG.debug("Request for status of process " + processUUID + ", job " + jobUUID);
|
||||
Optional<AsyncJobStatus> optionalJobStatus = new AsyncJobManager().getJobStatus(jobUUID);
|
||||
if(optionalJobStatus.isEmpty())
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
// if the job is complete, get the process result from state provider, and return it //
|
||||
// this output should look like it did if the job finished synchronously!! //
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
Optional<ProcessState> processState = RunProcessAction.getState(processUUID);
|
||||
if(processState.isPresent())
|
||||
serializeRunProcessExceptionForCaller(resultForCaller, new RuntimeException("Could not find status of process step job"));
|
||||
}
|
||||
else
|
||||
{
|
||||
AsyncJobStatus jobStatus = optionalJobStatus.get();
|
||||
|
||||
resultForCaller.put("jobStatus", jobStatus);
|
||||
LOG.debug("Job status is " + jobStatus.getState() + " for " + jobUUID);
|
||||
|
||||
if(jobStatus.getState().equals(AsyncJobState.COMPLETE))
|
||||
{
|
||||
RunProcessOutput runProcessOutput = new RunProcessOutput(processState.get());
|
||||
serializeRunProcessResultForCaller(resultForCaller, runProcessOutput);
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
// if the job is complete, get the process result from state provider, and return it //
|
||||
// this output should look like it did if the job finished synchronously!! //
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
Optional<ProcessState> processState = RunProcessAction.getState(processUUID);
|
||||
if(processState.isPresent())
|
||||
{
|
||||
RunProcessOutput runProcessOutput = new RunProcessOutput(processState.get());
|
||||
serializeRunProcessResultForCaller(resultForCaller, runProcessOutput);
|
||||
}
|
||||
else
|
||||
{
|
||||
serializeRunProcessExceptionForCaller(resultForCaller, new RuntimeException("Could not find results for process " + processUUID));
|
||||
}
|
||||
}
|
||||
else
|
||||
else if(jobStatus.getState().equals(AsyncJobState.ERROR))
|
||||
{
|
||||
serializeRunProcessExceptionForCaller(resultForCaller, new RuntimeException("Could not find results for process " + processUUID));
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// if the job had an error (e.g., a process step threw), "nicely" serialize its exception for the caller //
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
if(jobStatus.getCaughtException() != null)
|
||||
{
|
||||
serializeRunProcessExceptionForCaller(resultForCaller, jobStatus.getCaughtException());
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(jobStatus.getState().equals(AsyncJobState.ERROR))
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// if the job had an error (e.g., a process step threw), "nicely" serialize its exception for the caller //
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
if(jobStatus.getCaughtException() != null)
|
||||
{
|
||||
serializeRunProcessExceptionForCaller(resultForCaller, jobStatus.getCaughtException());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
context.result(JsonUtils.toJson(resultForCaller));
|
||||
context.result(JsonUtils.toJson(resultForCaller));
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
serializeRunProcessExceptionForCaller(resultForCaller, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -609,6 +638,10 @@ public class QJavalinProcessHandler
|
||||
{
|
||||
try
|
||||
{
|
||||
AbstractActionInput input = new AbstractActionInput(QJavalinImplementation.qInstance);
|
||||
QJavalinImplementation.setupSession(context, input);
|
||||
// todo - need process values? PermissionsHelper.checkProcessPermissionThrowing(input, context.pathParam("processName"));
|
||||
|
||||
String processUUID = context.pathParam("processUUID");
|
||||
Integer skip = Objects.requireNonNullElse(QJavalinImplementation.integerQueryParam(context, "skip"), 0);
|
||||
Integer limit = Objects.requireNonNullElse(QJavalinImplementation.integerQueryParam(context, "limit"), 20);
|
||||
|
@ -29,10 +29,13 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import com.kingsrook.qqq.backend.core.actions.customizers.QCodeLoader;
|
||||
import com.kingsrook.qqq.backend.core.actions.permissions.PermissionsHelper;
|
||||
import com.kingsrook.qqq.backend.core.actions.permissions.TablePermissionSubType;
|
||||
import com.kingsrook.qqq.backend.core.actions.scripts.StoreAssociatedScriptAction;
|
||||
import com.kingsrook.qqq.backend.core.actions.scripts.TestScriptActionInterface;
|
||||
import com.kingsrook.qqq.backend.core.actions.tables.GetAction;
|
||||
import com.kingsrook.qqq.backend.core.actions.tables.QueryAction;
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QNotFoundException;
|
||||
import com.kingsrook.qqq.backend.core.instances.QInstanceEnricher;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.scripts.StoreAssociatedScriptInput;
|
||||
@ -75,6 +78,7 @@ public class QJavalinScriptsHandler
|
||||
*******************************************************************************/
|
||||
public static void defineRecordRoutes()
|
||||
{
|
||||
// todo - do we want some generic "developer mode" permission??
|
||||
get("/developer", QJavalinScriptsHandler::getRecordDeveloperMode);
|
||||
post("/developer/associatedScript/{fieldName}", QJavalinScriptsHandler::storeRecordAssociatedScript);
|
||||
get("/developer/associatedScript/{fieldName}/{scriptRevisionId}/logs", QJavalinScriptsHandler::getAssociatedScriptLogs);
|
||||
@ -100,6 +104,8 @@ public class QJavalinScriptsHandler
|
||||
getInput.setShouldGenerateDisplayValues(true);
|
||||
getInput.setShouldTranslatePossibleValues(true);
|
||||
|
||||
PermissionsHelper.checkTablePermissionThrowing(getInput, TablePermissionSubType.READ);
|
||||
|
||||
// todo - validate that the primary key is of the proper type (e.g,. not a string for an id field)
|
||||
// and throw a 400-series error (tell the user bad-request), rather than, we're doing a 500 (server error)
|
||||
|
||||
@ -217,6 +223,8 @@ public class QJavalinScriptsHandler
|
||||
{
|
||||
try
|
||||
{
|
||||
getReferencedRecordToEnsureAccess(context);
|
||||
|
||||
String scriptRevisionId = context.pathParam("scriptRevisionId");
|
||||
|
||||
QueryInput queryInput = new QueryInput(QJavalinImplementation.qInstance);
|
||||
@ -247,6 +255,40 @@ public class QJavalinScriptsHandler
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private static void getReferencedRecordToEnsureAccess(Context context) throws QException
|
||||
{
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// make sure user can get the record they're trying to do a related action for //
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
String tableName = context.pathParam("table");
|
||||
QTableMetaData table = QJavalinImplementation.qInstance.getTable(tableName);
|
||||
GetInput getInput = new GetInput(QJavalinImplementation.qInstance);
|
||||
getInput.setTableName(tableName);
|
||||
QJavalinImplementation.setupSession(context, getInput);
|
||||
PermissionsHelper.checkTablePermissionThrowing(getInput, TablePermissionSubType.READ);
|
||||
|
||||
String primaryKey = context.pathParam("primaryKey");
|
||||
getInput.setPrimaryKey(primaryKey);
|
||||
|
||||
GetAction getAction = new GetAction();
|
||||
GetOutput getOutput = getAction.execute(getInput);
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// throw a not found error if the record isn't found //
|
||||
///////////////////////////////////////////////////////
|
||||
QRecord record = getOutput.getRecord();
|
||||
if(record == null)
|
||||
{
|
||||
throw (new QNotFoundException("Could not find " + table.getLabel() + " with "
|
||||
+ table.getFields().get(table.getPrimaryKeyField()).getLabel() + " of " + primaryKey));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@ -258,12 +300,15 @@ public class QJavalinScriptsHandler
|
||||
{
|
||||
StoreAssociatedScriptInput input = new StoreAssociatedScriptInput(QJavalinImplementation.qInstance);
|
||||
QJavalinImplementation.setupSession(context, input);
|
||||
|
||||
input.setCode(context.formParam("contents"));
|
||||
input.setCommitMessage(context.formParam("commitMessage"));
|
||||
input.setFieldName(context.pathParam("fieldName"));
|
||||
input.setTableName(context.pathParam("table"));
|
||||
input.setRecordPrimaryKey(context.pathParam("primaryKey"));
|
||||
|
||||
PermissionsHelper.checkTablePermissionThrowing(input, TablePermissionSubType.EDIT); // todo ... is this enough??
|
||||
|
||||
StoreAssociatedScriptOutput output = new StoreAssociatedScriptOutput();
|
||||
|
||||
StoreAssociatedScriptAction storeAssociatedScriptAction = new StoreAssociatedScriptAction();
|
||||
@ -288,6 +333,8 @@ public class QJavalinScriptsHandler
|
||||
|
||||
try
|
||||
{
|
||||
getReferencedRecordToEnsureAccess(context);
|
||||
|
||||
TestScriptInput input = new TestScriptInput(QJavalinImplementation.qInstance);
|
||||
QJavalinImplementation.setupSession(context, input);
|
||||
|
||||
|
Reference in New Issue
Block a user