@@ -627,4 +627,210 @@ model TwoEnumsOneModelTest {
627
627
await dropPostgresDb ( 'issue-632' ) ;
628
628
}
629
629
} ) ;
630
+
631
+ it ( 'issue 634' , async ( ) => {
632
+ const { prisma, withPolicy } = await loadSchema (
633
+ `
634
+ model User {
635
+ id String @id @default(uuid())
636
+ email String @unique
637
+ password String? @password @omit
638
+ name String?
639
+ orgs Organization[]
640
+ posts Post[]
641
+ groups Group[]
642
+ comments Comment[]
643
+ // can be created by anyone, even not logged in
644
+ @@allow('create', true)
645
+ // can be read by users in the same organization
646
+ @@allow('read', orgs?[members?[auth() == this]])
647
+ // full access by oneself
648
+ @@allow('all', auth() == this)
649
+ }
650
+
651
+ model Organization {
652
+ id String @id @default(uuid())
653
+ name String
654
+ members User[]
655
+ post Post[]
656
+ groups Group[]
657
+ comments Comment[]
658
+
659
+ // everyone can create a organization
660
+ @@allow('create', true)
661
+ // any user in the organization can read the organization
662
+ @@allow('read', members?[auth() == this])
663
+ }
664
+
665
+ abstract model organizationBaseEntity {
666
+ id String @id @default(uuid())
667
+ createdAt DateTime @default(now())
668
+ updatedAt DateTime @updatedAt
669
+ isDeleted Boolean @default(false) @omit
670
+ isPublic Boolean @default(false)
671
+ owner User @relation(fields: [ownerId], references: [id], onDelete: Cascade)
672
+ ownerId String
673
+ org Organization @relation(fields: [orgId], references: [id], onDelete: Cascade)
674
+ orgId String
675
+ groups Group[]
676
+
677
+ // when create, owner must be set to current user, and user must be in the organization
678
+ @@allow('create', owner == auth() && org.members?[this == auth()])
679
+ // only the owner can update it and is not allowed to change the owner
680
+ @@allow('update', owner == auth() && org.members?[this == auth()] && future().owner == owner)
681
+ // allow owner to read
682
+ @@allow('read', owner == auth())
683
+ // allow shared group members to read it
684
+ @@allow('read', groups?[users?[this == auth()]])
685
+ // allow organization to access if public
686
+ @@allow('read', isPublic && org.members?[this == auth()])
687
+ // can not be read if deleted
688
+ @@deny('all', isDeleted == true)
689
+ }
690
+
691
+ model Post extends organizationBaseEntity {
692
+ title String
693
+ content String
694
+ comments Comment[]
695
+ }
696
+
697
+ model Comment extends organizationBaseEntity {
698
+ content String
699
+ post Post @relation(fields: [postId], references: [id])
700
+ postId String
701
+ }
702
+
703
+ model Group {
704
+ id String @id @default(uuid())
705
+ name String
706
+ users User[]
707
+ posts Post[]
708
+ comments Comment[]
709
+ org Organization @relation(fields: [orgId], references: [id])
710
+ orgId String
711
+
712
+ // group is shared by organization
713
+ @@allow('all', org.members?[auth() == this])
714
+ }
715
+ `
716
+ ) ;
717
+
718
+ const userData = [
719
+ {
720
+ id : 'robin@prisma.io' ,
721
+ name : 'Robin' ,
722
+ email : 'robin@prisma.io' ,
723
+ orgs : {
724
+ create : [
725
+ {
726
+ id : 'prisma' ,
727
+ name : 'prisma' ,
728
+ } ,
729
+ ] ,
730
+ } ,
731
+ groups : {
732
+ create : [
733
+ {
734
+ id : 'community' ,
735
+ name : 'community' ,
736
+ orgId : 'prisma' ,
737
+ } ,
738
+ ] ,
739
+ } ,
740
+ posts : {
741
+ create : [
742
+ {
743
+ id : 'slack' ,
744
+ title : 'Join the Prisma Slack' ,
745
+ content : 'https://slack.prisma.io' ,
746
+ orgId : 'prisma' ,
747
+ comments : {
748
+ create : [
749
+ {
750
+ id : 'comment-1' ,
751
+ content : 'This is the first comment' ,
752
+ orgId : 'prisma' ,
753
+ ownerId : 'robin@prisma.io' ,
754
+ } ,
755
+ ] ,
756
+ } ,
757
+ } ,
758
+ ] ,
759
+ } ,
760
+ } ,
761
+ {
762
+ id : 'bryan@prisma.io' ,
763
+ name : 'Bryan' ,
764
+ email : 'bryan@prisma.io' ,
765
+ orgs : {
766
+ connect : {
767
+ id : 'prisma' ,
768
+ } ,
769
+ } ,
770
+ posts : {
771
+ create : [
772
+ {
773
+ id : 'discord' ,
774
+ title : 'Join the Prisma Discord' ,
775
+ content : 'https://discord.gg/jS3XY7vp46' ,
776
+ orgId : 'prisma' ,
777
+ groups : {
778
+ connect : {
779
+ id : 'community' ,
780
+ } ,
781
+ } ,
782
+ } ,
783
+ ] ,
784
+ } ,
785
+ } ,
786
+ ] ;
787
+
788
+ for ( const u of userData ) {
789
+ const user = await prisma . user . create ( {
790
+ data : u ,
791
+ } ) ;
792
+ console . log ( `Created user with id: ${ user . id } ` ) ;
793
+ }
794
+
795
+ const db = withPolicy ( { id : 'robin@prisma.io' } ) ;
796
+ await expect (
797
+ db . comment . findMany ( {
798
+ where : {
799
+ owner : {
800
+ name : 'Bryan' ,
801
+ } ,
802
+ } ,
803
+ select : {
804
+ id : true ,
805
+ content : true ,
806
+ owner : {
807
+ select : {
808
+ id : true ,
809
+ name : true ,
810
+ } ,
811
+ } ,
812
+ } ,
813
+ } )
814
+ ) . resolves . toHaveLength ( 0 ) ;
815
+
816
+ await expect (
817
+ db . comment . findMany ( {
818
+ where : {
819
+ owner : {
820
+ name : 'Robin' ,
821
+ } ,
822
+ } ,
823
+ select : {
824
+ id : true ,
825
+ content : true ,
826
+ owner : {
827
+ select : {
828
+ id : true ,
829
+ name : true ,
830
+ } ,
831
+ } ,
832
+ } ,
833
+ } )
834
+ ) . resolves . toHaveLength ( 1 ) ;
835
+ } ) ;
630
836
} ) ;
0 commit comments