@@ -2,10 +2,14 @@ package v1beta1connect
2
2
3
3
import (
4
4
"context"
5
+ "errors"
5
6
6
7
"connectrpc.com/connect"
8
+ "github.com/raystack/frontier/core/audit"
7
9
"github.com/raystack/frontier/core/resource"
10
+ "github.com/raystack/frontier/core/user"
8
11
"github.com/raystack/frontier/internal/bootstrap/schema"
12
+ "github.com/raystack/frontier/pkg/metadata"
9
13
frontierv1beta1 "github.com/raystack/frontier/proto/v1beta1"
10
14
"google.golang.org/protobuf/types/known/structpb"
11
15
"google.golang.org/protobuf/types/known/timestamppb"
@@ -36,6 +40,205 @@ func (h *ConnectHandler) ListResources(ctx context.Context, request *connect.Req
36
40
}), nil
37
41
}
38
42
43
+ func (h * ConnectHandler ) ListProjectResources (ctx context.Context , request * connect.Request [frontierv1beta1.ListProjectResourcesRequest ]) (* connect.Response [frontierv1beta1.ListProjectResourcesResponse ], error ) {
44
+ var resources []* frontierv1beta1.Resource
45
+ namespaceID := schema .ParseNamespaceAliasIfRequired (request .Msg .GetNamespace ())
46
+ filters := resource.Filter {
47
+ NamespaceID : namespaceID ,
48
+ ProjectID : request .Msg .GetProjectId (),
49
+ }
50
+ resourcesList , err := h .resourceService .List (ctx , filters )
51
+ if err != nil {
52
+ return nil , connect .NewError (connect .CodeInternal , ErrInternalServerError )
53
+ }
54
+ for _ , r := range resourcesList {
55
+ resourcePB , err := transformResourceToPB (r )
56
+ if err != nil {
57
+ return nil , connect .NewError (connect .CodeInternal , ErrInternalServerError )
58
+ }
59
+ resources = append (resources , resourcePB )
60
+ }
61
+ return connect .NewResponse (& frontierv1beta1.ListProjectResourcesResponse {
62
+ Resources : resources ,
63
+ }), nil
64
+ }
65
+
66
+ func (h * ConnectHandler ) CreateProjectResource (ctx context.Context , request * connect.Request [frontierv1beta1.CreateProjectResourceRequest ]) (* connect.Response [frontierv1beta1.CreateProjectResourceResponse ], error ) {
67
+ if request .Msg .GetBody () == nil {
68
+ return nil , connect .NewError (connect .CodeInvalidArgument , ErrBadRequest )
69
+ }
70
+
71
+ var metaDataMap metadata.Metadata
72
+ var err error
73
+ if request .Msg .GetBody ().GetMetadata () != nil {
74
+ metaDataMap = metadata .Build (request .Msg .GetBody ().GetMetadata ().AsMap ())
75
+ }
76
+
77
+ parentProject , err := h .projectService .Get (ctx , request .Msg .GetProjectId ())
78
+ if err != nil {
79
+ return nil , connect .NewError (connect .CodeInternal , ErrInternalServerError )
80
+ }
81
+
82
+ principalType := schema .UserPrincipal
83
+ principalID := request .Msg .GetBody ().GetPrincipal ()
84
+ if ns , id , err := schema .SplitNamespaceAndResourceID (request .Msg .GetBody ().GetPrincipal ()); err == nil {
85
+ principalType = ns
86
+ principalID = id
87
+ }
88
+ namespaceID := schema .ParseNamespaceAliasIfRequired (request .Msg .GetBody ().GetNamespace ())
89
+ newResource , err := h .resourceService .Create (ctx , resource.Resource {
90
+ ID : request .Msg .GetId (),
91
+ Name : request .Msg .GetBody ().GetName (),
92
+ Title : request .Msg .GetBody ().GetTitle (),
93
+ ProjectID : parentProject .ID ,
94
+ NamespaceID : namespaceID ,
95
+ PrincipalID : principalID ,
96
+ PrincipalType : principalType ,
97
+ Metadata : metaDataMap ,
98
+ })
99
+ if err != nil {
100
+ switch {
101
+ case errors .Is (err , user .ErrInvalidEmail ):
102
+ return nil , connect .NewError (connect .CodeUnauthenticated , ErrUnauthenticated )
103
+ case errors .Is (err , resource .ErrInvalidUUID ),
104
+ errors .Is (err , resource .ErrInvalidDetail ):
105
+ return nil , connect .NewError (connect .CodeInvalidArgument , ErrBadRequest )
106
+ case errors .Is (err , resource .ErrConflict ):
107
+ return nil , connect .NewError (connect .CodeAlreadyExists , ErrConflictRequest )
108
+ default :
109
+ return nil , connect .NewError (connect .CodeInternal , ErrInternalServerError )
110
+ }
111
+ }
112
+
113
+ resourcePB , err := transformResourceToPB (newResource )
114
+ if err != nil {
115
+ return nil , connect .NewError (connect .CodeInternal , ErrInternalServerError )
116
+ }
117
+
118
+ audit .GetAuditor (ctx , parentProject .Organization .ID ).Log (audit .ResourceCreatedEvent , audit.Target {
119
+ ID : newResource .ID ,
120
+ Type : newResource .NamespaceID ,
121
+ })
122
+ return connect .NewResponse (& frontierv1beta1.CreateProjectResourceResponse {
123
+ Resource : resourcePB ,
124
+ }), nil
125
+ }
126
+
127
+ func (h * ConnectHandler ) GetProjectResource (ctx context.Context , request * connect.Request [frontierv1beta1.GetProjectResourceRequest ]) (* connect.Response [frontierv1beta1.GetProjectResourceResponse ], error ) {
128
+ fetchedResource , err := h .resourceService .Get (ctx , request .Msg .GetId ())
129
+ if err != nil {
130
+ switch {
131
+ case errors .Is (err , resource .ErrNotExist ),
132
+ errors .Is (err , resource .ErrInvalidUUID ),
133
+ errors .Is (err , resource .ErrInvalidID ):
134
+ return nil , connect .NewError (connect .CodeNotFound , ErrResourceNotFound )
135
+ default :
136
+ return nil , connect .NewError (connect .CodeInternal , ErrInternalServerError )
137
+ }
138
+ }
139
+
140
+ resourcePB , err := transformResourceToPB (fetchedResource )
141
+ if err != nil {
142
+ return nil , connect .NewError (connect .CodeInternal , ErrInternalServerError )
143
+ }
144
+
145
+ return connect .NewResponse (& frontierv1beta1.GetProjectResourceResponse {
146
+ Resource : resourcePB ,
147
+ }), nil
148
+ }
149
+
150
+ func (h * ConnectHandler ) UpdateProjectResource (ctx context.Context , request * connect.Request [frontierv1beta1.UpdateProjectResourceRequest ]) (* connect.Response [frontierv1beta1.UpdateProjectResourceResponse ], error ) {
151
+ if request .Msg .GetBody () == nil {
152
+ return nil , connect .NewError (connect .CodeInvalidArgument , ErrBadRequest )
153
+ }
154
+
155
+ var metaDataMap metadata.Metadata
156
+ var err error
157
+ if request .Msg .GetBody ().GetMetadata () != nil {
158
+ metaDataMap = metadata .Build (request .Msg .GetBody ().GetMetadata ().AsMap ())
159
+ }
160
+
161
+ parentProject , err := h .projectService .Get (ctx , request .Msg .GetProjectId ())
162
+ if err != nil {
163
+ return nil , connect .NewError (connect .CodeInternal , ErrInternalServerError )
164
+ }
165
+
166
+ principalType := schema .UserPrincipal
167
+ principalID := request .Msg .GetBody ().GetPrincipal ()
168
+ if ns , id , err := schema .SplitNamespaceAndResourceID (request .Msg .GetBody ().GetPrincipal ()); err == nil {
169
+ principalType = ns
170
+ principalID = id
171
+ }
172
+ namespaceID := schema .ParseNamespaceAliasIfRequired (request .Msg .GetBody ().GetNamespace ())
173
+ updatedResource , err := h .resourceService .Update (ctx , resource.Resource {
174
+ ID : request .Msg .GetId (),
175
+ ProjectID : parentProject .ID ,
176
+ NamespaceID : namespaceID ,
177
+ Name : request .Msg .GetBody ().GetName (),
178
+ PrincipalID : principalID ,
179
+ PrincipalType : principalType ,
180
+ Metadata : metaDataMap ,
181
+ })
182
+ if err != nil {
183
+ switch {
184
+ case errors .Is (err , resource .ErrNotExist ),
185
+ errors .Is (err , resource .ErrInvalidUUID ),
186
+ errors .Is (err , resource .ErrInvalidID ):
187
+ return nil , connect .NewError (connect .CodeNotFound , ErrResourceNotFound )
188
+ case errors .Is (err , resource .ErrInvalidDetail ),
189
+ errors .Is (err , resource .ErrInvalidURN ):
190
+ return nil , connect .NewError (connect .CodeInvalidArgument , ErrBadRequest )
191
+ case errors .Is (err , resource .ErrConflict ):
192
+ return nil , connect .NewError (connect .CodeAlreadyExists , ErrConflictRequest )
193
+ default :
194
+ return nil , connect .NewError (connect .CodeInternal , ErrInternalServerError )
195
+ }
196
+ }
197
+
198
+ resourcePB , err := transformResourceToPB (updatedResource )
199
+ if err != nil {
200
+ return nil , connect .NewError (connect .CodeInternal , ErrInternalServerError )
201
+ }
202
+
203
+ audit .GetAuditor (ctx , parentProject .Organization .ID ).Log (audit .ResourceUpdatedEvent , audit.Target {
204
+ ID : updatedResource .ID ,
205
+ Type : updatedResource .NamespaceID ,
206
+ })
207
+ return connect .NewResponse (& frontierv1beta1.UpdateProjectResourceResponse {
208
+ Resource : resourcePB ,
209
+ }), nil
210
+ }
211
+
212
+ func (h * ConnectHandler ) DeleteProjectResource (ctx context.Context , request * connect.Request [frontierv1beta1.DeleteProjectResourceRequest ]) (* connect.Response [frontierv1beta1.DeleteProjectResourceResponse ], error ) {
213
+ resourceToDel , err := h .resourceService .Get (ctx , request .Msg .GetId ())
214
+ if err != nil {
215
+ switch {
216
+ case errors .Is (err , resource .ErrNotExist ),
217
+ errors .Is (err , resource .ErrInvalidID ),
218
+ errors .Is (err , resource .ErrInvalidUUID ):
219
+ return nil , connect .NewError (connect .CodeNotFound , ErrResourceNotFound )
220
+ default :
221
+ return nil , connect .NewError (connect .CodeInternal , ErrInternalServerError )
222
+ }
223
+ }
224
+
225
+ parentProject , err := h .projectService .Get (ctx , resourceToDel .ProjectID )
226
+ if err != nil {
227
+ return nil , connect .NewError (connect .CodeInternal , ErrInternalServerError )
228
+ }
229
+
230
+ err = h .resourceService .Delete (ctx , resourceToDel .NamespaceID , resourceToDel .ID )
231
+ if err != nil {
232
+ return nil , connect .NewError (connect .CodeInternal , ErrInternalServerError )
233
+ }
234
+
235
+ audit .GetAuditor (ctx , parentProject .Organization .ID ).Log (audit .ResourceDeletedEvent , audit.Target {
236
+ ID : request .Msg .GetId (),
237
+ Type : resourceToDel .NamespaceID ,
238
+ })
239
+ return connect .NewResponse (& frontierv1beta1.DeleteProjectResourceResponse {}), nil
240
+ }
241
+
39
242
func transformResourceToPB (from resource.Resource ) (* frontierv1beta1.Resource , error ) {
40
243
var metadata * structpb.Struct
41
244
var err error
0 commit comments