@@ -367,3 +367,159 @@ func TestAsset_Types(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAsset_TenantIsolation(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
org1Owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
org2Owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
|
||||
profileID := factory.CreateUser(org1Owner)
|
||||
|
||||
var createResult struct {
|
||||
CreateAsset struct {
|
||||
AssetEdge struct {
|
||||
Node struct {
|
||||
ID string `json:"id"`
|
||||
} `json:"node"`
|
||||
} `json:"assetEdge"`
|
||||
} `json:"createAsset"`
|
||||
}
|
||||
|
||||
err := org1Owner.Execute(`
|
||||
mutation($input: CreateAssetInput!) {
|
||||
createAsset(input: $input) {
|
||||
assetEdge { node { id } }
|
||||
}
|
||||
}
|
||||
`, map[string]any{
|
||||
"input": map[string]any{
|
||||
"organizationId": org1Owner.GetOrganizationID().String(),
|
||||
"name": "Org1 Asset",
|
||||
"amount": 1,
|
||||
"ownerId": profileID,
|
||||
"assetType": "VIRTUAL",
|
||||
"dataTypesStored": "Test data",
|
||||
},
|
||||
}, &createResult)
|
||||
require.NoError(t, err)
|
||||
|
||||
assetID := createResult.CreateAsset.AssetEdge.Node.ID
|
||||
|
||||
t.Run("cannot read asset from another organization", func(t *testing.T) {
|
||||
query := `
|
||||
query($id: ID!) {
|
||||
node(id: $id) {
|
||||
... on Asset {
|
||||
id
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
var result struct {
|
||||
Node *struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
} `json:"node"`
|
||||
}
|
||||
|
||||
err := org2Owner.Execute(query, map[string]any{"id": assetID}, &result)
|
||||
testutil.AssertNodeNotAccessible(t, err, result.Node == nil, "asset")
|
||||
})
|
||||
|
||||
t.Run("cannot update asset from another organization", func(t *testing.T) {
|
||||
_, err := org2Owner.Do(`
|
||||
mutation($input: UpdateAssetInput!) {
|
||||
updateAsset(input: $input) {
|
||||
asset { id }
|
||||
}
|
||||
}
|
||||
`, map[string]any{
|
||||
"input": map[string]any{
|
||||
"id": assetID,
|
||||
"name": "Hijacked Asset",
|
||||
},
|
||||
})
|
||||
require.Error(t, err, "Should not be able to update asset from another org")
|
||||
})
|
||||
|
||||
t.Run("cannot delete asset from another organization", func(t *testing.T) {
|
||||
_, err := org2Owner.Do(`
|
||||
mutation($input: DeleteAssetInput!) {
|
||||
deleteAsset(input: $input) {
|
||||
deletedAssetId
|
||||
}
|
||||
}
|
||||
`, map[string]any{
|
||||
"input": map[string]any{
|
||||
"assetId": assetID,
|
||||
},
|
||||
})
|
||||
require.Error(t, err, "Should not be able to delete asset from another org")
|
||||
})
|
||||
|
||||
t.Run("cannot create asset referencing an owner from another organization", func(t *testing.T) {
|
||||
org2ProfileID := factory.CreateUser(org2Owner)
|
||||
|
||||
_, err := org1Owner.Do(`
|
||||
mutation($input: CreateAssetInput!) {
|
||||
createAsset(input: $input) {
|
||||
assetEdge { node { id } }
|
||||
}
|
||||
}
|
||||
`, map[string]any{
|
||||
"input": map[string]any{
|
||||
"organizationId": org1Owner.GetOrganizationID().String(),
|
||||
"name": factory.SafeName("Asset"),
|
||||
"amount": 1,
|
||||
"ownerId": org2ProfileID,
|
||||
"assetType": "VIRTUAL",
|
||||
"dataTypesStored": "Test data",
|
||||
},
|
||||
})
|
||||
require.Error(t, err, "must not accept an ownerId belonging to another organization")
|
||||
})
|
||||
|
||||
t.Run("cannot create asset referencing a thirdParty from another organization", func(t *testing.T) {
|
||||
org2ThirdPartyID := factory.NewThirdParty(org2Owner).WithName("Org2 ThirdParty").Create()
|
||||
|
||||
_, err := org1Owner.Do(`
|
||||
mutation($input: CreateAssetInput!) {
|
||||
createAsset(input: $input) {
|
||||
assetEdge { node { id } }
|
||||
}
|
||||
}
|
||||
`, map[string]any{
|
||||
"input": map[string]any{
|
||||
"organizationId": org1Owner.GetOrganizationID().String(),
|
||||
"name": factory.SafeName("Asset"),
|
||||
"amount": 1,
|
||||
"ownerId": profileID,
|
||||
"assetType": "VIRTUAL",
|
||||
"dataTypesStored": "Test data",
|
||||
"thirdPartyIds": []string{org2ThirdPartyID},
|
||||
},
|
||||
})
|
||||
require.Error(t, err, "must not accept a thirdPartyId belonging to another organization")
|
||||
})
|
||||
|
||||
t.Run("cannot update asset to reference a thirdParty from another organization", func(t *testing.T) {
|
||||
org2ThirdPartyID := factory.NewThirdParty(org2Owner).WithName("Org2 ThirdParty for Update").Create()
|
||||
|
||||
_, err := org1Owner.Do(`
|
||||
mutation($input: UpdateAssetInput!) {
|
||||
updateAsset(input: $input) {
|
||||
asset { id }
|
||||
}
|
||||
}
|
||||
`, map[string]any{
|
||||
"input": map[string]any{
|
||||
"id": assetID,
|
||||
"thirdPartyIds": []string{org2ThirdPartyID},
|
||||
},
|
||||
})
|
||||
require.Error(t, err, "must not accept a thirdPartyId belonging to another organization")
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user