feat(saved): saved, shared, starred, scheduled and widget analyses, export, SQL handoff
Extension 1.4.0: saved analyses of every kind re-run as the viewer (fields they cannot analyze are dropped), owner-or-shared READ through core record locks with owner-only writes (and a database CHECK so a private row can never lose its read owner), personal stars, schedules that run as the owner and mail only recipients who could run the analysis themselves, CSV/XLSX export, the SQL Workbench handoff, an analysis dashboard widget, and an Analyses home built from standard widgets. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
43c7571864
commit
d2c9871d98
42 files changed
+3786
-296
No files matched your search
@@ -125,7 +125,7 @@ class DataAnalysisSecurityTest
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
** Saved, star and run locks hide others even when the shared flag is true.
|
||||
** Shared saved rows are readable; private stars, schedules and runs remain owner-locked.
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
void ownerIsolation() throws Exception
|
||||
@@ -142,12 +142,12 @@ class DataAnalysisSecurityTest
|
||||
TestSupport.insert(DataAnalysisTables.SCHEDULE, new QRecord().withValue("saved_id", mine.getValue("id")));
|
||||
TestSupport.insert(DataAnalysisTables.SCHEDULE, new QRecord().withValue("saved_id", other.getValue("id")));
|
||||
QContext.init(instance, TestSupport.user("alice").withPermissions("data_analysis.saved.read", "data_analysis.run.read"));
|
||||
assertThat(query(DataAnalysisTables.SAVED)).extracting(r -> r.getValueString("owner_user_id")).containsExactly("alice");
|
||||
assertThat(query(DataAnalysisTables.SAVED)).extracting(r -> r.getValueString("owner_user_id")).containsExactly("alice", "bob");
|
||||
assertThat(query(DataAnalysisTables.SAVED_STAR)).extracting(r -> r.getValueString("user_id")).containsExactly("alice");
|
||||
assertThat(query(DataAnalysisTables.RUN)).extracting(r -> r.getValueString("user_id")).containsExactly("alice");
|
||||
assertThat(query(DataAnalysisTables.SCHEDULE)).extracting(r -> r.getValue("saved_id")).containsExactly(mine.getValue("id"));
|
||||
QContext.init(instance, TestSupport.user("alice").withPermissions("data_analysis.saved.read", "data_analysis.admin"));
|
||||
assertThat(query(DataAnalysisTables.SAVED)).hasSize(1);
|
||||
assertThat(query(DataAnalysisTables.SAVED)).hasSize(2);
|
||||
QContext.getQSession().withSecurityKeyValue("data_analysis.admin", true);
|
||||
assertThat(query(DataAnalysisTables.SAVED)).hasSize(2);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user