77 "net/http"
88 "strings"
99
10+ "github.com/Thanus-Kumaar/controller_microservice_v2/middleware"
1011 "github.com/Thanus-Kumaar/controller_microservice_v2/modules"
1112 "github.com/Thanus-Kumaar/controller_microservice_v2/pkg"
1213 "github.com/Thanus-Kumaar/controller_microservice_v2/pkg/models"
@@ -42,17 +43,17 @@ var validOutputTypes = map[string]struct{}{
4243
4344// CellController holds the dependencies for the cell handlers.
4445type CellController struct {
45- Module * modules.CellModule
46- Logger zerolog.Logger
46+ Module * modules.CellModule
47+ Logger zerolog.Logger
48+ NotebookModule * modules.NotebookModule // Added NotebookModule
4749}
4850
49-
50-
5151// NewCellController creates and returns a new CellController.
52- func NewCellController (module * modules.CellModule , logger zerolog.Logger ) * CellController {
52+ func NewCellController (module * modules.CellModule , logger zerolog.Logger , notebookModule * modules. NotebookModule ) * CellController {
5353 return & CellController {
54- Module : module ,
55- Logger : logger ,
54+ Module : module ,
55+ Logger : logger ,
56+ NotebookModule : notebookModule ,
5657 }
5758}
5859
@@ -61,14 +62,29 @@ func (c *CellController) UpdateCellsHandler(w http.ResponseWriter, r *http.Reque
6162 notebookID , err := uuid .Parse (notebookIDStr )
6263 if err != nil {
6364 pkg .WriteJSONResponseWithLogger (
64- w ,
65- http .StatusBadRequest ,
66- map [string ]string {"error" : "Invalid notebook ID" },
65+ w ,
66+ http .StatusBadRequest ,
67+ map [string ]string {"error" : "Invalid notebook ID" },
6768 & c .Logger ,
6869 )
6970 return
7071 }
7172
73+ user , ok := r .Context ().Value (middleware .UserContextKey ).(* middleware.User )
74+ if ! ok || user .ID == "" {
75+ c .Logger .Error ().Msg ("user not found in context for cell update" )
76+ http .Error (w , "User not found in context" , http .StatusUnauthorized )
77+ return
78+ }
79+
80+ // Verify ownership of the notebook
81+ _ , err = c .NotebookModule .GetNotebookByID (r .Context (), notebookIDStr , user .ID )
82+ if err != nil {
83+ c .Logger .Error ().Err (err ).Str ("notebook_id" , notebookIDStr ).Msg ("Notebook not found or not owned by user for cell update" )
84+ http .Error (w , "Notebook not found or not owned by user" , http .StatusNotFound )
85+ return
86+ }
87+
7288 body , err := io .ReadAll (r .Body )
7389 if err != nil {
7490 c .Logger .Error ().Err (err ).Msg ("Failed to read request body" )
@@ -86,37 +102,52 @@ func (c *CellController) UpdateCellsHandler(w http.ResponseWriter, r *http.Reque
86102 if err := json .Unmarshal (body , & req ); err != nil {
87103 c .Logger .Error ().Err (err ).Msg ("Failed to decode request body" )
88104 pkg .WriteJSONResponseWithLogger (
89- w ,
90- http .StatusBadRequest ,
91- map [string ]string {"error" : "Invalid request body" },
105+ w ,
106+ http .StatusBadRequest ,
107+ map [string ]string {"error" : "Invalid request body" },
92108 & c .Logger ,
93109 )
94110 return
95111 }
96112
97113 c .Logger .Info ().Interface ("decoded_request" , req ).Msg ("Decoded request body" )
98114
99- if err := c .Module .UpdateCells (r .Context (), notebookID , & req ); err != nil {
115+ if err := c .Module .UpdateCells (r .Context (), notebookID , & req , user . ID ); err != nil { // Pass userID to module
100116 c .Logger .Error ().Err (err ).Msg ("Failed to update cells" )
101117 pkg .WriteJSONResponseWithLogger (
102- w ,
103- http .StatusInternalServerError ,
104- map [string ]string {"error" : "Failed to update cells" },
118+ w ,
119+ http .StatusInternalServerError ,
120+ map [string ]string {"error" : "Failed to update cells" },
105121 & c .Logger ,
106122 )
107123 return
108124 }
109125
110126 pkg .WriteJSONResponseWithLogger (w , http .StatusOK , map [string ]string {"status" : "success" }, & c .Logger )
111127}
112-
113128func (c * CellController ) CreateCellHandler (w http.ResponseWriter , r * http.Request ) {
129+ user , ok := r .Context ().Value (middleware .UserContextKey ).(* middleware.User )
130+ if ! ok || user .ID == "" {
131+ c .Logger .Error ().Msg ("user not found in context for cell creation" )
132+ http .Error (w , "User not found in context" , http .StatusUnauthorized )
133+ return
134+ }
135+
114136 var req models.CreateCellRequest
115137 if err := json .NewDecoder (r .Body ).Decode (& req ); err != nil {
116138 pkg .WriteJSONResponseWithLogger (w , http .StatusBadRequest , map [string ]string {"error" : "Invalid request body" }, & c .Logger )
117139 return
118140 }
119141
142+ // Verify ownership of the parent notebook
143+ notebookIDStr := req .NotebookID .String ()
144+ _ , err := c .NotebookModule .GetNotebookByID (r .Context (), notebookIDStr , user .ID )
145+ if err != nil {
146+ c .Logger .Error ().Err (err ).Str ("notebook_id" , notebookIDStr ).Msg ("Notebook not found or not owned by user for cell creation" )
147+ http .Error (w , "Notebook not found or not owned by user" , http .StatusNotFound )
148+ return
149+ }
150+
120151 if _ , ok := validCellTypes [req .CellType ]; ! ok {
121152 allowedTypes := make ([]string , 0 , len (validCellTypes ))
122153 for k := range validCellTypes {
@@ -127,7 +158,7 @@ func (c *CellController) CreateCellHandler(w http.ResponseWriter, r *http.Reques
127158 return
128159 }
129160
130- cell , err := c .Module .CreateCell (r .Context (), & req )
161+ cell , err := c .Module .CreateCell (r .Context (), & req , user . ID ) // Pass userID to module
131162 if err != nil {
132163 c .Logger .Error ().Err (err ).Msg ("Failed to create cell" )
133164 pkg .WriteJSONResponseWithLogger (w , http .StatusInternalServerError , map [string ]string {"error" : "Failed to create cell" }, & c .Logger )
@@ -145,7 +176,22 @@ func (c *CellController) GetCellsByNotebookIDHandler(w http.ResponseWriter, r *h
145176 return
146177 }
147178
148- cells , err := c .Module .GetCellsByNotebookID (r .Context (), notebookID )
179+ user , ok := r .Context ().Value (middleware .UserContextKey ).(* middleware.User )
180+ if ! ok || user .ID == "" {
181+ c .Logger .Error ().Msg ("user not found in context for getting cells by notebook ID" )
182+ http .Error (w , "User not found in context" , http .StatusUnauthorized )
183+ return
184+ }
185+
186+ // Verify ownership of the parent notebook
187+ _ , err = c .NotebookModule .GetNotebookByID (r .Context (), notebookIDStr , user .ID )
188+ if err != nil {
189+ c .Logger .Error ().Err (err ).Str ("notebook_id" , notebookIDStr ).Msg ("Notebook not found or not owned by user for getting cells" )
190+ http .Error (w , "Notebook not found or not owned by user" , http .StatusNotFound )
191+ return
192+ }
193+
194+ cells , err := c .Module .GetCellsByNotebookID (r .Context (), notebookID , user .ID )
149195 if err != nil {
150196 c .Logger .Error ().Err (err ).Msg ("Failed to get cells" )
151197 pkg .WriteJSONResponseWithLogger (w , http .StatusInternalServerError , map [string ]string {"error" : "Failed to get cells" }, & c .Logger )
@@ -163,10 +209,17 @@ func (c *CellController) GetCellByIDHandler(w http.ResponseWriter, r *http.Reque
163209 return
164210 }
165211
166- cell , err := c .Module .GetCellByID (r .Context (), cellID )
212+ user , ok := r .Context ().Value (middleware .UserContextKey ).(* middleware.User )
213+ if ! ok || user .ID == "" {
214+ c .Logger .Error ().Msg ("user not found in context for getting cell by ID" )
215+ http .Error (w , "User not found in context" , http .StatusUnauthorized )
216+ return
217+ }
218+
219+ cell , err := c .Module .GetCellByID (r .Context (), cellID , user .ID ) // Pass userID to module
167220 if err != nil {
168221 c .Logger .Error ().Err (err ).Msg ("Failed to get cell" )
169- pkg .WriteJSONResponseWithLogger (w , http .StatusNotFound , map [string ]string {"error" : "Cell not found" }, & c .Logger )
222+ pkg .WriteJSONResponseWithLogger (w , http .StatusNotFound , map [string ]string {"error" : "Cell not found or not owned by user " }, & c .Logger )
170223 return
171224 }
172225
@@ -181,6 +234,21 @@ func (c *CellController) UpdateCellHandler(w http.ResponseWriter, r *http.Reques
181234 return
182235 }
183236
237+ user , ok := r .Context ().Value (middleware .UserContextKey ).(* middleware.User )
238+ if ! ok || user .ID == "" {
239+ c .Logger .Error ().Msg ("user not found in context for updating cell" )
240+ http .Error (w , "User not found in context" , http .StatusUnauthorized )
241+ return
242+ }
243+
244+ // Retrieve the cell to get its notebook ID and implicitly check ownership via module call
245+ _ , err = c .Module .GetCellByID (r .Context (), cellID , user .ID )
246+ if err != nil {
247+ c .Logger .Error ().Err (err ).Str ("cell_id" , cellIDStr ).Msg ("Failed to retrieve existing cell for update or not owned by user" )
248+ pkg .WriteJSONResponseWithLogger (w , http .StatusNotFound , map [string ]string {"error" : "Cell not found or not owned by user" }, & c .Logger )
249+ return
250+ }
251+
184252 var req models.UpdateCellRequest
185253 if err := json .NewDecoder (r .Body ).Decode (& req ); err != nil {
186254 pkg .WriteJSONResponseWithLogger (w , http .StatusBadRequest , map [string ]string {"error" : "Invalid request body" }, & c .Logger )
@@ -199,7 +267,7 @@ func (c *CellController) UpdateCellHandler(w http.ResponseWriter, r *http.Reques
199267 }
200268 }
201269
202- cell , err := c .Module .UpdateCell (r .Context (), cellID , & req )
270+ cell , err := c .Module .UpdateCell (r .Context (), cellID , & req , user . ID ) // Pass userID to module
203271 if err != nil {
204272 c .Logger .Error ().Err (err ).Msg ("Failed to update cell" )
205273 pkg .WriteJSONResponseWithLogger (w , http .StatusInternalServerError , map [string ]string {"error" : "Failed to update cell" }, & c .Logger )
@@ -217,7 +285,22 @@ func (c *CellController) DeleteCellHandler(w http.ResponseWriter, r *http.Reques
217285 return
218286 }
219287
220- if err := c .Module .DeleteCell (r .Context (), cellID ); err != nil {
288+ user , ok := r .Context ().Value (middleware .UserContextKey ).(* middleware.User )
289+ if ! ok || user .ID == "" {
290+ c .Logger .Error ().Msg ("user not found in context for deleting cell" )
291+ http .Error (w , "User not found in context" , http .StatusUnauthorized )
292+ return
293+ }
294+
295+ // Verify ownership before deleting
296+ _ , err = c .Module .GetCellByID (r .Context (), cellID , user .ID )
297+ if err != nil {
298+ c .Logger .Error ().Err (err ).Str ("cell_id" , cellIDStr ).Msg ("Failed to retrieve existing cell for delete or not owned by user" )
299+ pkg .WriteJSONResponseWithLogger (w , http .StatusNotFound , map [string ]string {"error" : "Cell not found or not owned by user" }, & c .Logger )
300+ return
301+ }
302+
303+ if err := c .Module .DeleteCell (r .Context (), cellID , user .ID ); err != nil {
221304 c .Logger .Error ().Err (err ).Msg ("Failed to delete cell" )
222305 pkg .WriteJSONResponseWithLogger (w , http .StatusInternalServerError , map [string ]string {"error" : "Failed to delete cell" }, & c .Logger )
223306 return
@@ -227,6 +310,13 @@ func (c *CellController) DeleteCellHandler(w http.ResponseWriter, r *http.Reques
227310}
228311
229312func (c * CellController ) CreateCellOutputHandler (w http.ResponseWriter , r * http.Request ) {
313+ user , ok := r .Context ().Value (middleware .UserContextKey ).(* middleware.User )
314+ if ! ok || user .ID == "" {
315+ c .Logger .Error ().Msg ("user not found in context for creating cell output" )
316+ http .Error (w , "User not found in context" , http .StatusUnauthorized )
317+ return
318+ }
319+
230320 var req models.CreateCellOutputRequest
231321 if err := json .NewDecoder (r .Body ).Decode (& req ); err != nil {
232322 c .Logger .Error ().Err (err ).Msg ("CreateCellOutputHandler: Invalid request body" )
@@ -235,6 +325,14 @@ func (c *CellController) CreateCellOutputHandler(w http.ResponseWriter, r *http.
235325 }
236326 c .Logger .Debug ().Interface ("request_body" , req ).Msg ("CreateCellOutputHandler: Decoded request body" )
237327
328+ // Verify ownership of the cell before creating an output for it
329+ _ , err := c .Module .GetCellByID (r .Context (), req .CellID .ToUUID (), user .ID )
330+ if err != nil {
331+ c .Logger .Error ().Err (err ).Str ("cell_id" , req .CellID .ToUUID ().String ()).Msg ("Cell not found or not owned by user for creating output" )
332+ http .Error (w , "Cell not found or not owned by user" , http .StatusNotFound )
333+ return
334+ }
335+
238336 if _ , ok := validOutputTypes [req .Type ]; ! ok {
239337 allowedTypes := make ([]string , 0 , len (validOutputTypes ))
240338 for k := range validOutputTypes {
@@ -246,7 +344,7 @@ func (c *CellController) CreateCellOutputHandler(w http.ResponseWriter, r *http.
246344 return
247345 }
248346 c .Logger .Debug ().Str ("cell_id" , req .CellID .ToUUID ().String ()).Msg ("CreateCellOutputHandler: Calling module to create cell output" )
249- output , err := c .Module .CreateCellOutput (r .Context (), & req )
347+ output , err := c .Module .CreateCellOutput (r .Context (), & req ) // Ownership already checked
250348 if err != nil {
251349 c .Logger .Error ().Err (err ).Msg ("CreateCellOutputHandler: Failed to create cell output" )
252350 pkg .WriteJSONResponseWithLogger (w , http .StatusInternalServerError , map [string ]string {"error" : "Failed to create cell output" }, & c .Logger )
@@ -264,7 +362,22 @@ func (c *CellController) GetCellOutputsByCellIDHandler(w http.ResponseWriter, r
264362 return
265363 }
266364
267- outputs , err := c .Module .GetCellOutputsByCellID (r .Context (), cellID )
365+ user , ok := r .Context ().Value (middleware .UserContextKey ).(* middleware.User )
366+ if ! ok || user .ID == "" {
367+ c .Logger .Error ().Msg ("user not found in context for getting cell outputs" )
368+ http .Error (w , "User not found in context" , http .StatusUnauthorized )
369+ return
370+ }
371+
372+ // Verify ownership of the cell before getting outputs
373+ _ , err = c .Module .GetCellByID (r .Context (), cellID , user .ID )
374+ if err != nil {
375+ c .Logger .Error ().Err (err ).Str ("cell_id" , cellID .String ()).Msg ("Cell not found or not owned by user for getting outputs" )
376+ http .Error (w , "Cell not found or not owned by user" , http .StatusNotFound )
377+ return
378+ }
379+
380+ outputs , err := c .Module .GetCellOutputsByCellID (r .Context (), cellID , user .ID )
268381 if err != nil {
269382 c .Logger .Error ().Err (err ).Msg ("Failed to get cell outputs" )
270383 pkg .WriteJSONResponseWithLogger (w , http .StatusInternalServerError , map [string ]string {"error" : "Failed to get cell outputs" }, & c .Logger )
@@ -282,7 +395,23 @@ func (c *CellController) DeleteCellOutputHandler(w http.ResponseWriter, r *http.
282395 return
283396 }
284397
285- if err := c .Module .DeleteCellOutput (r .Context (), outputID ); err != nil {
398+ user , ok := r .Context ().Value (middleware .UserContextKey ).(* middleware.User )
399+ if ! ok || user .ID == "" {
400+ c .Logger .Error ().Msg ("user not found in context for deleting cell output" )
401+ http .Error (w , "User not found in context" , http .StatusUnauthorized )
402+ return
403+ }
404+
405+ // To verify ownership, we must check if the user owns the notebook associated with this output.
406+ // This requires getting the output, then its cell, then its notebook.
407+ _ , err = c .Module .GetCellOutputByID (r .Context (), outputID , user .ID )
408+ if err != nil {
409+ c .Logger .Error ().Err (err ).Str ("output_id" , outputIDStr ).Msg ("Output not found or not owned by user" )
410+ pkg .WriteJSONResponseWithLogger (w , http .StatusNotFound , map [string ]string {"error" : "Output not found or not owned by user" }, & c .Logger )
411+ return
412+ }
413+
414+ if err := c .Module .DeleteCellOutput (r .Context (), outputID , user .ID ); err != nil {
286415 c .Logger .Error ().Err (err ).Msg ("Failed to delete cell output" )
287416 pkg .WriteJSONResponseWithLogger (w , http .StatusInternalServerError , map [string ]string {"error" : "Failed to delete cell output" }, & c .Logger )
288417 return
0 commit comments