Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion packages/sdk/src/model-meta-generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,8 @@ function getBackLink(field: DataModelField) {

const relName = getRelationName(field);

const sourceModel = field.$container as DataModel;
// in case of polymorphism, the source model is the base delegate model
const sourceModel = field.$inheritedFrom ?? (field.$container as DataModel);
const targetModel = field.type.reference.ref as DataModel;

for (const otherField of targetModel.fields) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,4 +208,64 @@ describe('Polymorphic Policy Test', () => {
await expect(db.asset.findUnique({ where: { id: vid1.id } })).toResolveNull();
await expect(db.asset.findUnique({ where: { id: vid2.id } })).toResolveTruthy();
});

it('interaction with connect', async () => {
const schema = `
model User {
id Int @id @default(autoincrement())
}

model Asset {
id Int @id @default(autoincrement())
assetType String
comments Comment[]

@@delegate(assetType)
@@allow('all', true)
}

model Post extends Asset {
title String
postType String
@@delegate(postType)
}

model RatedPost extends Post {
rating Int
}

model Comment {
id Int @id @default(autoincrement())
content String
asset Asset? @relation(fields: [assetId], references: [id])
assetId Int?
@@allow('read,create', true)
@@allow('update', auth().id == 1)
}
`;

const { enhance } = await loadSchema(schema);
const db = enhance();

const comment1 = await db.comment.create({
data: { content: 'Comment1' },
});

await expect(
db.ratedPost.create({ data: { title: 'Post1', rating: 5, comments: { connect: { id: comment1.id } } } })
).toBeRejectedByPolicy();

const post1 = await db.ratedPost.create({ data: { title: 'Post1', rating: 5 } });
await expect(
db.post.update({ where: { id: post1.id }, data: { comments: { connect: { id: comment1.id } } } })
).toBeRejectedByPolicy();
await expect(
db.ratedPost.update({ where: { id: post1.id }, data: { comments: { connect: { id: comment1.id } } } })
).toBeRejectedByPolicy();

const user1Db = enhance({ id: 1 });
await expect(
user1Db.ratedPost.update({ where: { id: post1.id }, data: { comments: { connect: { id: comment1.id } } } })
).toResolveTruthy();
});
});
87 changes: 87 additions & 0 deletions tests/regression/tests/issue-1674.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { loadSchema } from '@zenstackhq/testtools';
describe('issue 1674', () => {
it('regression', async () => {
const { prisma, enhance } = await loadSchema(
`
model User {
id String @id @default(cuid())
email String @unique @email @length(6, 32)
password String @password @omit
posts Post[]

// everybody can signup
@@allow('create', true)

// full access by self
@@allow('all', auth() == this)
}

model Blog {
id String @id @default(cuid())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt

post Post? @relation(fields: [postId], references: [id], onDelete: Cascade)
postId String?
}

model Post {
id String @id @default(cuid())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
title String @length(1, 256)
content String
published Boolean @default(false)
author User @relation(fields: [authorId], references: [id])
authorId String

blogs Blog[]

type String

// allow read for all signin users
@@allow('read', auth() != null && published)

// full access by author
@@allow('all', author == auth())

@@delegate(type)
}

model PostA extends Post {
}

model PostB extends Post {
}
`
);

const user = await prisma.user.create({
data: { email: '[email protected]', password: 'password' },
});

const blog = await prisma.blog.create({
data: {},
});

const db = enhance(user);
await expect(
db.postA.create({
data: {
content: 'content',
title: 'title',
blogs: {
connect: {
id: blog.id,
},
},
author: {
connect: {
id: user.id,
},
},
},
})
).toBeRejectedByPolicy();
});
});