CE-882 Updated test - passes real-world scenarios we need for story

This commit is contained in:
2024-04-25 12:08:02 -05:00
parent bc47f8b80c
commit 21657b918c
5 changed files with 306 additions and 385 deletions

View File

@ -22,20 +22,24 @@
package com.kingsrook.qqq.backend.module.rdbms.sharing; package com.kingsrook.qqq.backend.module.rdbms.sharing;
import java.util.List;
import com.kingsrook.qqq.backend.core.exceptions.QException; import com.kingsrook.qqq.backend.core.exceptions.QException;
import com.kingsrook.qqq.backend.core.instances.QInstanceEnricher; import com.kingsrook.qqq.backend.core.instances.QInstanceEnricher;
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.joins.JoinOn;
import com.kingsrook.qqq.backend.core.model.metadata.joins.JoinType;
import com.kingsrook.qqq.backend.core.model.metadata.joins.QJoinMetaData;
import com.kingsrook.qqq.backend.core.model.metadata.possiblevalues.QPossibleValueSource; import com.kingsrook.qqq.backend.core.model.metadata.possiblevalues.QPossibleValueSource;
import com.kingsrook.qqq.backend.core.model.metadata.security.MultiRecordSecurityLock;
import com.kingsrook.qqq.backend.core.model.metadata.security.QSecurityKeyType; import com.kingsrook.qqq.backend.core.model.metadata.security.QSecurityKeyType;
import com.kingsrook.qqq.backend.core.model.metadata.security.RecordSecurityLock; import com.kingsrook.qqq.backend.core.model.metadata.security.RecordSecurityLock;
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData; import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
import com.kingsrook.qqq.backend.module.rdbms.TestUtils; import com.kingsrook.qqq.backend.module.rdbms.TestUtils;
import com.kingsrook.qqq.backend.module.rdbms.model.metadata.RDBMSTableBackendDetails; import com.kingsrook.qqq.backend.module.rdbms.model.metadata.RDBMSTableBackendDetails;
import com.kingsrook.qqq.backend.module.rdbms.sharing.model.Asset; import com.kingsrook.qqq.backend.module.rdbms.sharing.model.Asset;
import com.kingsrook.qqq.backend.module.rdbms.sharing.model.AssetAudienceInt;
import com.kingsrook.qqq.backend.module.rdbms.sharing.model.Audience;
import com.kingsrook.qqq.backend.module.rdbms.sharing.model.Client; import com.kingsrook.qqq.backend.module.rdbms.sharing.model.Client;
import com.kingsrook.qqq.backend.module.rdbms.sharing.model.Group; import com.kingsrook.qqq.backend.module.rdbms.sharing.model.Group;
import com.kingsrook.qqq.backend.module.rdbms.sharing.model.SharedAsset;
import com.kingsrook.qqq.backend.module.rdbms.sharing.model.User; import com.kingsrook.qqq.backend.module.rdbms.sharing.model.User;
@ -47,6 +51,11 @@ public class SharingMetaDataProvider
public static final String USER_ID_KEY_TYPE = "userIdKey"; public static final String USER_ID_KEY_TYPE = "userIdKey";
public static final String USER_ID_ALL_ACCESS_KEY_TYPE = "userIdAllAccessKey"; public static final String USER_ID_ALL_ACCESS_KEY_TYPE = "userIdAllAccessKey";
public static final String GROUP_ID_KEY_TYPE = "groupIdKey";
public static final String GROUP_ID_ALL_ACCESS_KEY_TYPE = "groupIdAllAccessKey";
private static final String ASSET_JOIN_SHARED_ASSET = "assetJoinSharedAsset";
/******************************************************************************* /*******************************************************************************
@ -58,30 +67,58 @@ public class SharingMetaDataProvider
.withName(USER_ID_KEY_TYPE) .withName(USER_ID_KEY_TYPE)
.withAllAccessKeyName(USER_ID_ALL_ACCESS_KEY_TYPE)); .withAllAccessKeyName(USER_ID_ALL_ACCESS_KEY_TYPE));
qInstance.addSecurityKeyType(new QSecurityKeyType()
.withName(GROUP_ID_KEY_TYPE)
.withAllAccessKeyName(GROUP_ID_ALL_ACCESS_KEY_TYPE));
qInstance.addTable(new QTableMetaData() qInstance.addTable(new QTableMetaData()
.withName(Asset.TABLE_NAME) .withName(Asset.TABLE_NAME)
.withPrimaryKeyField("id") .withPrimaryKeyField("id")
.withBackendName(TestUtils.DEFAULT_BACKEND_NAME) .withBackendName(TestUtils.DEFAULT_BACKEND_NAME)
.withBackendDetails(new RDBMSTableBackendDetails().withTableName("asset"))
.withFieldsFromEntity(Asset.class) .withFieldsFromEntity(Asset.class)
.withRecordSecurityLock(new RecordSecurityLock()
.withSecurityKeyType(USER_ID_KEY_TYPE) ////////////////////////////////////////
.withFieldName("userId"))); // This is original - just owner/user //
////////////////////////////////////////
// .withRecordSecurityLock(new RecordSecurityLock()
// .withSecurityKeyType(USER_ID_KEY_TYPE)
// .withFieldName("userId")));
.withRecordSecurityLock(new MultiRecordSecurityLock()
.withOperator(MultiRecordSecurityLock.BooleanOperator.OR)
.withLock(new RecordSecurityLock()
.withSecurityKeyType(USER_ID_KEY_TYPE)
.withFieldName("userId"))
.withLock(new RecordSecurityLock()
.withSecurityKeyType(USER_ID_KEY_TYPE)
.withFieldName("sharedAsset.userId")
.withJoinNameChain(List.of(ASSET_JOIN_SHARED_ASSET)))
.withLock(new RecordSecurityLock()
.withSecurityKeyType(GROUP_ID_KEY_TYPE)
.withFieldName("sharedAsset.groupId")
.withJoinNameChain(List.of(ASSET_JOIN_SHARED_ASSET)))
));
QInstanceEnricher.setInferredFieldBackendNames(qInstance.getTable(Asset.TABLE_NAME)); QInstanceEnricher.setInferredFieldBackendNames(qInstance.getTable(Asset.TABLE_NAME));
qInstance.addTable(new QTableMetaData() qInstance.addTable(new QTableMetaData()
.withName(Audience.TABLE_NAME) .withName(SharedAsset.TABLE_NAME)
.withBackendDetails(new RDBMSTableBackendDetails().withTableName("shared_asset"))
.withPrimaryKeyField("id") .withPrimaryKeyField("id")
.withBackendName(TestUtils.DEFAULT_BACKEND_NAME) .withBackendName(TestUtils.DEFAULT_BACKEND_NAME)
.withFieldsFromEntity(Audience.class)); .withFieldsFromEntity(SharedAsset.class)
QInstanceEnricher.setInferredFieldBackendNames(qInstance.getTable(Audience.TABLE_NAME)); .withRecordSecurityLock(new MultiRecordSecurityLock()
.withOperator(MultiRecordSecurityLock.BooleanOperator.OR)
qInstance.addTable(new QTableMetaData() .withLock(new RecordSecurityLock()
.withName(AssetAudienceInt.TABLE_NAME) .withSecurityKeyType(USER_ID_KEY_TYPE)
.withBackendDetails(new RDBMSTableBackendDetails().withTableName("asset_audience_int")) .withHint(RecordSecurityLock.QueryHint.DO_NOT_PUT_CRITERIA_IN_JOIN_ON)
.withPrimaryKeyField("id") .withFieldName("userId"))
.withBackendName(TestUtils.DEFAULT_BACKEND_NAME) .withLock(new RecordSecurityLock()
.withFieldsFromEntity(AssetAudienceInt.class)); .withSecurityKeyType(GROUP_ID_KEY_TYPE)
QInstanceEnricher.setInferredFieldBackendNames(qInstance.getTable(AssetAudienceInt.TABLE_NAME)); .withHint(RecordSecurityLock.QueryHint.DO_NOT_PUT_CRITERIA_IN_JOIN_ON)
.withFieldName("groupId"))
));
QInstanceEnricher.setInferredFieldBackendNames(qInstance.getTable(SharedAsset.TABLE_NAME));
qInstance.addTable(new QTableMetaData() qInstance.addTable(new QTableMetaData()
.withName(User.TABLE_NAME) .withName(User.TABLE_NAME)
@ -111,7 +148,14 @@ public class SharingMetaDataProvider
qInstance.addPossibleValueSource(QPossibleValueSource.newForTable(Group.TABLE_NAME)); qInstance.addPossibleValueSource(QPossibleValueSource.newForTable(Group.TABLE_NAME));
qInstance.addPossibleValueSource(QPossibleValueSource.newForTable(Client.TABLE_NAME)); qInstance.addPossibleValueSource(QPossibleValueSource.newForTable(Client.TABLE_NAME));
qInstance.addPossibleValueSource(QPossibleValueSource.newForTable(Asset.TABLE_NAME)); qInstance.addPossibleValueSource(QPossibleValueSource.newForTable(Asset.TABLE_NAME));
qInstance.addPossibleValueSource(QPossibleValueSource.newForTable(Audience.TABLE_NAME));
qInstance.addJoin(new QJoinMetaData()
.withName(ASSET_JOIN_SHARED_ASSET)
.withLeftTable(Asset.TABLE_NAME)
.withRightTable(SharedAsset.TABLE_NAME)
.withType(JoinType.ONE_TO_MANY)
.withJoinOn(new JoinOn("id", "assetId"))
);
} }
} }

View File

@ -22,7 +22,7 @@
package com.kingsrook.qqq.backend.module.rdbms.sharing; package com.kingsrook.qqq.backend.module.rdbms.sharing;
import java.util.ArrayList; import java.sql.SQLException;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import com.kingsrook.qqq.backend.core.actions.tables.InsertAction; import com.kingsrook.qqq.backend.core.actions.tables.InsertAction;
@ -31,17 +31,21 @@ import com.kingsrook.qqq.backend.core.context.QContext;
import com.kingsrook.qqq.backend.core.exceptions.QException; import com.kingsrook.qqq.backend.core.exceptions.QException;
import com.kingsrook.qqq.backend.core.model.actions.tables.insert.InsertInput; import com.kingsrook.qqq.backend.core.model.actions.tables.insert.InsertInput;
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryInput; import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryInput;
import com.kingsrook.qqq.backend.core.model.data.QRecord;
import com.kingsrook.qqq.backend.core.model.data.QRecordEntity; import com.kingsrook.qqq.backend.core.model.data.QRecordEntity;
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.security.RecordSecurityLock;
import com.kingsrook.qqq.backend.core.model.session.QSession; import com.kingsrook.qqq.backend.core.model.session.QSession;
import com.kingsrook.qqq.backend.module.rdbms.TestUtils; import com.kingsrook.qqq.backend.module.rdbms.TestUtils;
import com.kingsrook.qqq.backend.module.rdbms.sharing.model.Asset; import com.kingsrook.qqq.backend.module.rdbms.sharing.model.Asset;
import com.kingsrook.qqq.backend.module.rdbms.sharing.model.AssetAudienceInt;
import com.kingsrook.qqq.backend.module.rdbms.sharing.model.Audience;
import com.kingsrook.qqq.backend.module.rdbms.sharing.model.Group; import com.kingsrook.qqq.backend.module.rdbms.sharing.model.Group;
import com.kingsrook.qqq.backend.module.rdbms.sharing.model.SharedAsset;
import com.kingsrook.qqq.backend.module.rdbms.sharing.model.User; import com.kingsrook.qqq.backend.module.rdbms.sharing.model.User;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import static com.kingsrook.qqq.backend.module.rdbms.sharing.SharingMetaDataProvider.GROUP_ID_KEY_TYPE;
import static com.kingsrook.qqq.backend.module.rdbms.sharing.SharingMetaDataProvider.USER_ID_ALL_ACCESS_KEY_TYPE;
import static com.kingsrook.qqq.backend.module.rdbms.sharing.SharingMetaDataProvider.USER_ID_KEY_TYPE;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
@ -50,6 +54,24 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
*******************************************************************************/ *******************************************************************************/
public class SharingTest public class SharingTest
{ {
//////////////
// user ids //
//////////////
public static final int HOMER_ID = 1;
public static final int MARGE_ID = 2;
public static final int BART_ID = 3;
public static final int LISA_ID = 4;
public static final int BURNS_ID = 5;
///////////////
// group ids //
///////////////
public static final int SIMPSONS_ID = 1;
public static final int POWER_PLANT_ID = 2;
public static final int BOGUS_GROUP_ID = Integer.MAX_VALUE;
/******************************************************************************* /*******************************************************************************
** **
*******************************************************************************/ *******************************************************************************/
@ -76,48 +98,35 @@ public class SharingTest
QContext.getQSession().withSecurityKeyValue(SharingMetaDataProvider.USER_ID_ALL_ACCESS_KEY_TYPE, true); QContext.getQSession().withSecurityKeyValue(SharingMetaDataProvider.USER_ID_ALL_ACCESS_KEY_TYPE, true);
List<QRecordEntity> userList = List.of( List<QRecordEntity> userList = List.of(
new User().withId(100).withUsername("homer"), new User().withId(HOMER_ID).withUsername("homer"),
new User().withId(101).withUsername("marge"), new User().withId(MARGE_ID).withUsername("marge"),
new User().withId(102).withUsername("bart"), new User().withId(BART_ID).withUsername("bart"),
new User().withId(103).withUsername("lisa"), new User().withId(LISA_ID).withUsername("lisa"),
new User().withId(110).withUsername("burns")); new User().withId(BURNS_ID).withUsername("burns"));
new InsertAction().execute(new InsertInput(User.TABLE_NAME).withRecordEntities(userList)); new InsertAction().execute(new InsertInput(User.TABLE_NAME).withRecordEntities(userList));
List<QRecordEntity> groupList = List.of( List<QRecordEntity> groupList = List.of(
new Group().withId(200).withName("simpsons"), new Group().withId(SIMPSONS_ID).withName("simpsons"),
new Group().withId(201).withName("powerplant")); new Group().withId(POWER_PLANT_ID).withName("powerplant"));
new InsertAction().execute(new InsertInput(Group.TABLE_NAME).withRecordEntities(groupList)); new InsertAction().execute(new InsertInput(Group.TABLE_NAME).withRecordEntities(groupList));
List<QRecordEntity> assetList = List.of( List<QRecordEntity> assetList = List.of(
new Asset().withId(3000).withName("742evergreen").withUserId(100), new Asset().withId(1).withName("742evergreen").withUserId(HOMER_ID),
new Asset().withId(3001).withName("beer").withUserId(100), new Asset().withId(2).withName("beer").withUserId(HOMER_ID),
new Asset().withId(3010).withName("bed").withUserId(101), new Asset().withId(3).withName("car").withUserId(MARGE_ID),
new Asset().withId(3020).withName("skateboard").withUserId(102), new Asset().withId(4).withName("skateboard").withUserId(BART_ID),
new Asset().withId(3030).withName("saxamaphone").withUserId(103)); new Asset().withId(5).withName("santaslittlehelper").withUserId(BART_ID),
new Asset().withId(6).withName("saxamaphone").withUserId(LISA_ID),
new Asset().withId(7).withName("radiation").withUserId(BURNS_ID));
new InsertAction().execute(new InsertInput(Asset.TABLE_NAME).withRecordEntities(assetList)); new InsertAction().execute(new InsertInput(Asset.TABLE_NAME).withRecordEntities(assetList));
List<QRecordEntity> assetAudienceIntList = List.of( List<QRecordEntity> sharedAssetList = List.of(
// homer shares his house with the simpson family (group) new SharedAsset().withAssetId(1).withGroupId(SIMPSONS_ID), // homer shares his house with the simpson family (group)
new AssetAudienceInt().withAssetId(3000).withAudienceId(200), new SharedAsset().withAssetId(3).withUserId(HOMER_ID), // marge shares a car with homer
new SharedAsset().withAssetId(5).withGroupId(SIMPSONS_ID), // bart shares santa's little helper with the whole family
// marge shares a bed with homer new SharedAsset().withAssetId(7).withGroupId(POWER_PLANT_ID) // burns shares radiation with the power plant
new AssetAudienceInt().withAssetId(3010).withAudienceId(100)
); );
new InsertAction().execute(new InsertInput(AssetAudienceInt.TABLE_NAME).withRecordEntities(assetAudienceIntList)); new InsertAction().execute(new InsertInput(SharedAsset.TABLE_NAME).withRecordEntities(sharedAssetList));
List<QRecordEntity> audienceList = new ArrayList<>();
for(QRecordEntity entity : userList)
{
User user = (User) entity;
audienceList.add(new Audience().withId(user.getId()).withName(user.getUsername()).withType("user"));
}
for(QRecordEntity entity : groupList)
{
Group group = (Group) entity;
audienceList.add(new Audience().withId(group.getId()).withName(group.getName()).withType("group"));
}
new InsertAction().execute(new InsertInput(Audience.TABLE_NAME).withRecordEntities(audienceList));
QContext.getQSession().withSecurityKeyValues(new HashMap<>()); QContext.getQSession().withSecurityKeyValues(new HashMap<>());
} }
@ -128,22 +137,127 @@ public class SharingTest
** **
*******************************************************************************/ *******************************************************************************/
@Test @Test
void test() throws QException void testAssetWithUserIdOnlySecurityKey() throws QException
{ {
////////////////////////////////////////////////////////////////////
// update the asset table to change its lock to only be on userId //
////////////////////////////////////////////////////////////////////
QContext.getQInstance().getTable(Asset.TABLE_NAME)
.withRecordSecurityLocks(List.of(new RecordSecurityLock()
.withSecurityKeyType(USER_ID_KEY_TYPE)
.withFieldName("userId")));
////////////////////////////////////////////////////////
// with nothing in session, make sure we find nothing //
////////////////////////////////////////////////////////
assertEquals(0, new QueryAction().execute(new QueryInput(Asset.TABLE_NAME)).getRecords().size()); assertEquals(0, new QueryAction().execute(new QueryInput(Asset.TABLE_NAME)).getRecords().size());
////////////////////////////////////
// marge direct owner only of car //
////////////////////////////////////
QContext.getQSession().withSecurityKeyValues(new HashMap<>()); QContext.getQSession().withSecurityKeyValues(new HashMap<>());
QContext.getQSession().withSecurityKeyValue(SharingMetaDataProvider.USER_ID_KEY_TYPE, 101); QContext.getQSession().withSecurityKeyValue(USER_ID_KEY_TYPE, MARGE_ID);
assertEquals(1, new QueryAction().execute(new QueryInput(Asset.TABLE_NAME)).getRecords().size()); assertEquals(1, new QueryAction().execute(new QueryInput(Asset.TABLE_NAME)).getRecords().size());
/////////////////////////////////////////////////
// homer direct owner of 742evergreen and beer //
/////////////////////////////////////////////////
QContext.getQSession().withSecurityKeyValues(new HashMap<>()); QContext.getQSession().withSecurityKeyValues(new HashMap<>());
QContext.getQSession().withSecurityKeyValue(SharingMetaDataProvider.USER_ID_KEY_TYPE, 100); QContext.getQSession().withSecurityKeyValue(USER_ID_KEY_TYPE, HOMER_ID);
assertEquals(2, new QueryAction().execute(new QueryInput(Asset.TABLE_NAME)).getRecords().size()); assertEquals(2, new QueryAction().execute(new QueryInput(Asset.TABLE_NAME)).getRecords().size());
/////////////////////////////////////////////////////
// marge & homer - own car, 742evergreen, and beer //
/////////////////////////////////////////////////////
QContext.getQSession().withSecurityKeyValues(new HashMap<>()); QContext.getQSession().withSecurityKeyValues(new HashMap<>());
QContext.getQSession().withSecurityKeyValue(SharingMetaDataProvider.USER_ID_KEY_TYPE, 100); QContext.getQSession().withSecurityKeyValue(USER_ID_KEY_TYPE, HOMER_ID);
QContext.getQSession().withSecurityKeyValue(SharingMetaDataProvider.USER_ID_KEY_TYPE, 101); QContext.getQSession().withSecurityKeyValue(USER_ID_KEY_TYPE, MARGE_ID);
assertEquals(3, new QueryAction().execute(new QueryInput(Asset.TABLE_NAME)).getRecords().size()); assertEquals(3, new QueryAction().execute(new QueryInput(Asset.TABLE_NAME)).getRecords().size());
} }
/*******************************************************************************
** normally (?) maybe we wouldn't query sharedAsset directly (we'd instead query
** for asset, and understand that there's a security lock coming from sharedAsset),
** but this test is here as we build up making a more complex lock like that.
*******************************************************************************/
@Test
void testSharedAssetDirectly() throws QException
{
////////////////////////////////////////////////////////
// with nothing in session, make sure we find nothing //
////////////////////////////////////////////////////////
assertEquals(0, new QueryAction().execute(new QueryInput(SharedAsset.TABLE_NAME)).getRecords().size());
/////////////////////////////////////
// homer has a car shared with him //
/////////////////////////////////////
QContext.getQSession().withSecurityKeyValues(new HashMap<>());
QContext.getQSession().withSecurityKeyValue(USER_ID_KEY_TYPE, HOMER_ID);
assertEquals(1, new QueryAction().execute(new QueryInput(SharedAsset.TABLE_NAME)).getRecords().size());
/////////////////////////////////////////////////////////////////////////////////////////
// now put homer's groups in the session as well - and we should find 742evergreen too //
/////////////////////////////////////////////////////////////////////////////////////////
QContext.getQSession().withSecurityKeyValues(new HashMap<>());
QContext.getQSession().withSecurityKeyValue(USER_ID_KEY_TYPE, HOMER_ID);
QContext.getQSession().withSecurityKeyValue(GROUP_ID_KEY_TYPE, SIMPSONS_ID);
QContext.getQSession().withSecurityKeyValue(GROUP_ID_KEY_TYPE, POWER_PLANT_ID);
List<QRecord> records = new QueryAction().execute(new QueryInput(SharedAsset.TABLE_NAME)).getRecords();
assertEquals(4, records.size());
}
/*******************************************************************************
** real-world use-case (e.g., why sharing concept exists) - query the asset table
**
*******************************************************************************/
@Test
void testAssetsWithLockThroughSharing() throws QException, SQLException
{
////////////////////////////////////////////////////////
// with nothing in session, make sure we find nothing //
////////////////////////////////////////////////////////
assertEquals(0, new QueryAction().execute(new QueryInput(Asset.TABLE_NAME)).getRecords().size());
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// homer has a car shared with him and 2 things he owns himself - so w/ only his userId in session (and no groups), should find those 3 //
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
QContext.getQSession().withSecurityKeyValues(new HashMap<>());
QContext.getQSession().withSecurityKeyValue(USER_ID_KEY_TYPE, HOMER_ID);
assertEquals(3, new QueryAction().execute(new QueryInput(Asset.TABLE_NAME)).getRecords().size());
//////////////////////////////////////////////////////////////////////
// add a group that matches nothing now, just to ensure same result //
//////////////////////////////////////////////////////////////////////
QContext.getQSession().withSecurityKeyValue(GROUP_ID_KEY_TYPE, BOGUS_GROUP_ID);
assertEquals(3, new QueryAction().execute(new QueryInput(Asset.TABLE_NAME)).getRecords().size());
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// now put homer's groups in the session as well - and we should find the 3 from above, plus a shared family asset and shared power-plant asset //
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
QContext.getQSession().withSecurityKeyValues(new HashMap<>());
QContext.getQSession().withSecurityKeyValue(USER_ID_KEY_TYPE, HOMER_ID);
QContext.getQSession().withSecurityKeyValue(GROUP_ID_KEY_TYPE, SIMPSONS_ID);
QContext.getQSession().withSecurityKeyValue(GROUP_ID_KEY_TYPE, POWER_PLANT_ID);
assertEquals(5, new QueryAction().execute(new QueryInput(Asset.TABLE_NAME)).getRecords().size());
}
/*******************************************************************************
**
*******************************************************************************/
@Test
void testAllAccessKeys() throws QException
{
///////////////////////////////////////////////////////////////
// with user-id all access key, should get all asset records //
///////////////////////////////////////////////////////////////
QContext.getQSession().withSecurityKeyValues(new HashMap<>());
QContext.getQSession().withSecurityKeyValue(USER_ID_ALL_ACCESS_KEY_TYPE, true);
assertEquals(7, new QueryAction().execute(new QueryInput(Asset.TABLE_NAME)).getRecords().size());
}
} }

View File

@ -1,226 +0,0 @@
/*
* QQQ - Low-code Application Framework for Engineers.
* Copyright (C) 2021-2024. Kingsrook, LLC
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
* contact@kingsrook.com
* https://github.com/Kingsrook/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.kingsrook.qqq.backend.module.rdbms.sharing.model;
import java.time.Instant;
import com.kingsrook.qqq.backend.core.model.data.QField;
import com.kingsrook.qqq.backend.core.model.data.QRecord;
import com.kingsrook.qqq.backend.core.model.data.QRecordEntity;
/*******************************************************************************
** QRecord Entity for AssetAudienceInt table
*******************************************************************************/
public class AssetAudienceInt extends QRecordEntity
{
public static final String TABLE_NAME = "AssetAudienceInt";
@QField(isEditable = false)
private Integer id;
@QField(isEditable = false)
private Instant createDate;
@QField(isEditable = false)
private Instant modifyDate;
@QField(possibleValueSourceName = Asset.TABLE_NAME)
private Integer assetId;
@QField(possibleValueSourceName = Audience.TABLE_NAME)
private Integer audienceId;
/*******************************************************************************
** Default constructor
*******************************************************************************/
public AssetAudienceInt()
{
}
/*******************************************************************************
** Constructor that takes a QRecord
*******************************************************************************/
public AssetAudienceInt(QRecord record)
{
populateFromQRecord(record);
}
/*******************************************************************************
** Getter for id
*******************************************************************************/
public Integer getId()
{
return (this.id);
}
/*******************************************************************************
** Setter for id
*******************************************************************************/
public void setId(Integer id)
{
this.id = id;
}
/*******************************************************************************
** Fluent setter for id
*******************************************************************************/
public AssetAudienceInt withId(Integer id)
{
this.id = id;
return (this);
}
/*******************************************************************************
** Getter for createDate
*******************************************************************************/
public Instant getCreateDate()
{
return (this.createDate);
}
/*******************************************************************************
** Setter for createDate
*******************************************************************************/
public void setCreateDate(Instant createDate)
{
this.createDate = createDate;
}
/*******************************************************************************
** Fluent setter for createDate
*******************************************************************************/
public AssetAudienceInt withCreateDate(Instant createDate)
{
this.createDate = createDate;
return (this);
}
/*******************************************************************************
** Getter for modifyDate
*******************************************************************************/
public Instant getModifyDate()
{
return (this.modifyDate);
}
/*******************************************************************************
** Setter for modifyDate
*******************************************************************************/
public void setModifyDate(Instant modifyDate)
{
this.modifyDate = modifyDate;
}
/*******************************************************************************
** Fluent setter for modifyDate
*******************************************************************************/
public AssetAudienceInt withModifyDate(Instant modifyDate)
{
this.modifyDate = modifyDate;
return (this);
}
/*******************************************************************************
** Getter for assetId
*******************************************************************************/
public Integer getAssetId()
{
return (this.assetId);
}
/*******************************************************************************
** Setter for assetId
*******************************************************************************/
public void setAssetId(Integer assetId)
{
this.assetId = assetId;
}
/*******************************************************************************
** Fluent setter for assetId
*******************************************************************************/
public AssetAudienceInt withAssetId(Integer assetId)
{
this.assetId = assetId;
return (this);
}
/*******************************************************************************
** Getter for audienceId
*******************************************************************************/
public Integer getAudienceId()
{
return (this.audienceId);
}
/*******************************************************************************
** Setter for audienceId
*******************************************************************************/
public void setAudienceId(Integer audienceId)
{
this.audienceId = audienceId;
}
/*******************************************************************************
** Fluent setter for audienceId
*******************************************************************************/
public AssetAudienceInt withAudienceId(Integer audienceId)
{
this.audienceId = audienceId;
return (this);
}
}

View File

@ -29,11 +29,11 @@ import com.kingsrook.qqq.backend.core.model.data.QRecordEntity;
/******************************************************************************* /*******************************************************************************
** QRecord Entity for Audience table ** QRecord Entity for SharedAsset table
*******************************************************************************/ *******************************************************************************/
public class Audience extends QRecordEntity public class SharedAsset extends QRecordEntity
{ {
public static final String TABLE_NAME = "Audience"; public static final String TABLE_NAME = "SharedAsset";
@QField(isEditable = false) @QField(isEditable = false)
private Integer id; private Integer id;
@ -44,21 +44,20 @@ public class Audience extends QRecordEntity
@QField(isEditable = false) @QField(isEditable = false)
private Instant modifyDate; private Instant modifyDate;
@QField() @QField(possibleValueSourceName = Asset.TABLE_NAME)
private String type; private Integer assetId;
@QField() @QField(possibleValueSourceName = User.TABLE_NAME)
private String name; private Integer userId;
@QField()
private String securityKey;
@QField(possibleValueSourceName = Group.TABLE_NAME)
private Integer groupId;
/******************************************************************************* /*******************************************************************************
** Default constructor ** Default constructor
*******************************************************************************/ *******************************************************************************/
public Audience() public SharedAsset()
{ {
} }
@ -67,7 +66,7 @@ public class Audience extends QRecordEntity
/******************************************************************************* /*******************************************************************************
** Constructor that takes a QRecord ** Constructor that takes a QRecord
*******************************************************************************/ *******************************************************************************/
public Audience(QRecord record) public SharedAsset(QRecord record)
{ {
populateFromQRecord(record); populateFromQRecord(record);
} }
@ -96,7 +95,7 @@ public class Audience extends QRecordEntity
/******************************************************************************* /*******************************************************************************
** Fluent setter for id ** Fluent setter for id
*******************************************************************************/ *******************************************************************************/
public Audience withId(Integer id) public SharedAsset withId(Integer id)
{ {
this.id = id; this.id = id;
return (this); return (this);
@ -127,7 +126,7 @@ public class Audience extends QRecordEntity
/******************************************************************************* /*******************************************************************************
** Fluent setter for createDate ** Fluent setter for createDate
*******************************************************************************/ *******************************************************************************/
public Audience withCreateDate(Instant createDate) public SharedAsset withCreateDate(Instant createDate)
{ {
this.createDate = createDate; this.createDate = createDate;
return (this); return (this);
@ -158,7 +157,7 @@ public class Audience extends QRecordEntity
/******************************************************************************* /*******************************************************************************
** Fluent setter for modifyDate ** Fluent setter for modifyDate
*******************************************************************************/ *******************************************************************************/
public Audience withModifyDate(Instant modifyDate) public SharedAsset withModifyDate(Instant modifyDate)
{ {
this.modifyDate = modifyDate; this.modifyDate = modifyDate;
return (this); return (this);
@ -167,93 +166,94 @@ public class Audience extends QRecordEntity
/******************************************************************************* /*******************************************************************************
** Getter for type ** Getter for assetId
*******************************************************************************/ *******************************************************************************/
public String getType() public Integer getAssetId()
{ {
return (this.type); return (this.assetId);
} }
/******************************************************************************* /*******************************************************************************
** Setter for type ** Setter for assetId
*******************************************************************************/ *******************************************************************************/
public void setType(String type) public void setAssetId(Integer assetId)
{ {
this.type = type; this.assetId = assetId;
} }
/******************************************************************************* /*******************************************************************************
** Fluent setter for type ** Fluent setter for assetId
*******************************************************************************/ *******************************************************************************/
public Audience withType(String type) public SharedAsset withAssetId(Integer assetId)
{ {
this.type = type; this.assetId = assetId;
return (this);
}
/*******************************************************************************
** Getter for userId
*******************************************************************************/
public Integer getUserId()
{
return (this.userId);
}
/*******************************************************************************
** Setter for userId
*******************************************************************************/
public void setUserId(Integer userId)
{
this.userId = userId;
}
/*******************************************************************************
** Fluent setter for userId
*******************************************************************************/
public SharedAsset withUserId(Integer userId)
{
this.userId = userId;
return (this); return (this);
} }
/******************************************************************************* /*******************************************************************************
** Getter for name ** Getter for groupId
*******************************************************************************/ *******************************************************************************/
public String getName() public Integer getGroupId()
{ {
return (this.name); return (this.groupId);
} }
/******************************************************************************* /*******************************************************************************
** Setter for name ** Setter for groupId
*******************************************************************************/ *******************************************************************************/
public void setName(String name) public void setGroupId(Integer groupId)
{ {
this.name = name; this.groupId = groupId;
} }
/******************************************************************************* /*******************************************************************************
** Fluent setter for name ** Fluent setter for groupId
*******************************************************************************/ *******************************************************************************/
public Audience withName(String name) public SharedAsset withGroupId(Integer groupId)
{ {
this.name = name; this.groupId = groupId;
return (this);
}
/*******************************************************************************
** Getter for securityKey
*******************************************************************************/
public String getSecurityKey()
{
return (this.securityKey);
}
/*******************************************************************************
** Setter for securityKey
*******************************************************************************/
public void setSecurityKey(String securityKey)
{
this.securityKey = securityKey;
}
/*******************************************************************************
** Fluent setter for securityKey
*******************************************************************************/
public Audience withSecurityKey(String securityKey)
{
this.securityKey = securityKey;
return (this); return (this);
} }

View File

@ -22,64 +22,53 @@
DROP TABLE IF EXISTS `user`; DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` CREATE TABLE `user`
( (
id INTEGER AUTO_INCREMENT PRIMARY KEY, id INTEGER AUTO_INCREMENT PRIMARY KEY,
create_date TIMESTAMP DEFAULT now(), create_date TIMESTAMP DEFAULT NOW(),
modify_date TIMESTAMP DEFAULT now(), modify_date TIMESTAMP DEFAULT NOW(),
username VARCHAR(100) username VARCHAR(100)
); );
DROP TABLE IF EXISTS `group`; DROP TABLE IF EXISTS `group`;
CREATE TABLE `group` CREATE TABLE `group`
( (
id INTEGER AUTO_INCREMENT PRIMARY KEY, id INTEGER AUTO_INCREMENT PRIMARY KEY,
create_date TIMESTAMP DEFAULT now(), create_date TIMESTAMP DEFAULT NOW(),
modify_date TIMESTAMP DEFAULT now(), modify_date TIMESTAMP DEFAULT NOW(),
name VARCHAR(100), name VARCHAR(100),
client_id INTEGER client_id INTEGER
); );
DROP TABLE IF EXISTS `client`; DROP TABLE IF EXISTS `client`;
CREATE TABLE `client` CREATE TABLE `client`
( (
id INTEGER AUTO_INCREMENT PRIMARY KEY, id INTEGER AUTO_INCREMENT PRIMARY KEY,
create_date TIMESTAMP DEFAULT now(), create_date TIMESTAMP DEFAULT NOW(),
modify_date TIMESTAMP DEFAULT now(), modify_date TIMESTAMP DEFAULT NOW(),
name VARCHAR(100) name VARCHAR(100)
);
DROP TABLE IF EXISTS audience;
CREATE TABLE audience
(
id INT AUTO_INCREMENT primary key ,
create_date TIMESTAMP DEFAULT now(),
modify_date TIMESTAMP DEFAULT now(),
type VARCHAR(50),
name VARCHAR(100),
security_key VARCHAR(100)
); );
DROP TABLE IF EXISTS asset; DROP TABLE IF EXISTS asset;
CREATE TABLE asset CREATE TABLE asset
( (
id INT AUTO_INCREMENT primary key , id INT AUTO_INCREMENT PRIMARY KEY,
create_date TIMESTAMP DEFAULT now(), create_date TIMESTAMP DEFAULT NOW(),
modify_date TIMESTAMP DEFAULT now(), modify_date TIMESTAMP DEFAULT NOW(),
name VARCHAR(100), name VARCHAR(100),
user_id INTEGER user_id INTEGER
); );
DROP TABLE IF EXISTS asset_audience_int; DROP TABLE IF EXISTS shared_asset;
CREATE TABLE asset_audience_int CREATE TABLE shared_asset
( (
id INT AUTO_INCREMENT primary key , id INT AUTO_INCREMENT PRIMARY KEY,
create_date TIMESTAMP DEFAULT now(), create_date TIMESTAMP DEFAULT NOW(),
modify_date TIMESTAMP DEFAULT now(), modify_date TIMESTAMP DEFAULT NOW(),
asset_id INTEGER, asset_id INTEGER,
audience_id INTEGER user_id INTEGER,
group_id INTEGER
); );