generated from datumforge/go-template
-
Notifications
You must be signed in to change notification settings - Fork 5
/
user_owned_mixin.go
148 lines (126 loc) · 3.92 KB
/
user_owned_mixin.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
package schema
import (
"context"
"errors"
"entgo.io/contrib/entgql"
"entgo.io/contrib/entoas"
"entgo.io/ent"
"entgo.io/ent/dialect/entsql"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/schema/edge"
"entgo.io/ent/schema/field"
"entgo.io/ent/schema/index"
"entgo.io/ent/schema/mixin"
"github.com/datumforge/datum/internal/ent/generated/intercept"
"github.com/datumforge/datum/internal/ent/interceptors"
"github.com/datumforge/datum/pkg/auth"
)
type UserOwnedMixin struct {
mixin.Schema
// Ref table for the id
Ref string
// Optional makes the owner id field not required
Optional bool
// AllowUpdate allows the owner id field to be updated
AllowUpdate bool
// SkipOASGeneration skips open api spec generation for the field
SkipOASGeneration bool
// SoftDeleteIndex creates a unique index on the owner id field where deleted_at is null
SoftDeleteIndex bool
// AllowWhere includes the owner_id field in gql generated fields
AllowWhere bool
// SkipInterceptor skips the interceptor for that schema for all queries, or specific types,
// this is useful for tokens, etc
SkipInterceptor interceptors.SkipMode
}
// Fields of the UserOwnedMixin
func (userOwned UserOwnedMixin) Fields() []ent.Field {
ownerIDField := field.String("owner_id").Annotations(
entgql.Skip(), entoas.Skip(true),
)
if userOwned.Optional {
ownerIDField.Optional()
}
return []ent.Field{
ownerIDField,
}
}
// Edges of the UserOwnedMixin
func (userOwned UserOwnedMixin) Edges() []ent.Edge {
if userOwned.Ref == "" {
panic(errors.New("ref must be non-empty string")) // nolint: goerr113
}
ownerEdge := edge.
From("owner", User.Type).
Field("owner_id").
Ref(userOwned.Ref).
Annotations(entoas.Skip(true)).
Unique()
if !userOwned.Optional {
ownerEdge.Required()
}
if !userOwned.AllowUpdate {
ownerEdge.Annotations(
entgql.Skip(entgql.SkipMutationUpdateInput),
entoas.UpdateOperation(entoas.OperationPolicy(entoas.PolicyExclude)),
)
}
if userOwned.SkipOASGeneration {
ownerEdge.Annotations(
entoas.Skip(true),
entoas.CreateOperation(entoas.OperationPolicy(entoas.PolicyExclude)),
entoas.ReadOperation(entoas.OperationPolicy(entoas.PolicyExclude)),
entoas.UpdateOperation(entoas.OperationPolicy(entoas.PolicyExclude)),
entoas.DeleteOperation(entoas.OperationPolicy(entoas.PolicyExclude)),
entoas.ListOperation(entoas.OperationPolicy(entoas.PolicyExclude)),
)
}
return []ent.Edge{
ownerEdge,
}
}
// Indexes of the UserOwnedMixin
func (userOwned UserOwnedMixin) Indexes() []ent.Index {
if !userOwned.SoftDeleteIndex {
return []ent.Index{}
}
return []ent.Index{
index.Fields("owner_id").
Unique().Annotations(entsql.IndexWhere("deleted_at is NULL")),
}
}
func (userOwned UserOwnedMixin) Interceptors() []ent.Interceptor {
if userOwned.Optional {
// do not add interceptors if the field is optional
return []ent.Interceptor{}
} else {
return []ent.Interceptor{
intercept.TraverseFunc(func(ctx context.Context, q intercept.Query) error {
// Skip the interceptor for all queries if BypassInterceptor flag is set
// This is needed for schemas that are never authorized users such as email verification tokens
if userOwned.SkipInterceptor == interceptors.SkipAll {
return nil
}
userID, err := auth.GetUserIDFromContext(ctx)
if err != nil {
ctxQuery := ent.QueryFromContext(ctx)
// Skip the interceptor if the query is for a single entity
// and the BypassInterceptor flag is set for Only queries
if userOwned.SkipInterceptor == interceptors.SkipOnlyQuery && ctxQuery.Op == "Only" {
return nil
}
return err
}
// sets the owner id on the query for the current organization
userOwned.P(q, userID)
return nil
}),
}
}
}
// P adds a storage-level predicate to the queries and mutations.
func (userOwned UserOwnedMixin) P(w interface{ WhereP(...func(*sql.Selector)) }, userID string) {
w.WhereP(
sql.FieldEQ(ownerFieldName, userID),
)
}