99namespace OCA \Tables \Controller ;
1010
1111use OCA \Tables \AppInfo \Application ;
12+ use OCA \Tables \Db \Row2Mapper ;
1213use OCA \Tables \Errors \BadRequestError ;
1314use OCA \Tables \Errors \InternalError ;
1415use OCA \Tables \Errors \NotFoundError ;
1516use OCA \Tables \Errors \PermissionError ;
1617use OCA \Tables \Helper \ConversionHelper ;
1718use OCA \Tables \Middleware \Attribute \AssertShareAccessIsAccessible ;
19+ use OCA \Tables \Model \RowDataInput ;
1820use OCA \Tables \ResponseDefinitions ;
1921use OCA \Tables \Service \RowService ;
2022use OCA \Tables \Service \ShareService ;
@@ -37,11 +39,13 @@ class PublicRowOCSController extends AOCSController {
3739 public function __construct (
3840 protected ShareService $ shareService ,
3941 protected RowService $ rowService ,
42+ protected Row2Mapper $ row2Mapper ,
4043 IRequest $ request ,
4144 LoggerInterface $ logger ,
4245 IL10N $ l ,
4346 ) {
4447 parent ::__construct ($ request , $ logger , $ l , '' );
48+ $ this ->rowService ->setPublicContext ();
4549 }
4650
4751 /**
@@ -68,6 +72,10 @@ public function getRows(string $token, ?int $limit, ?int $offset): DataResponse
6872 $ shareToken = new ShareToken ($ token );
6973 $ share = $ this ->shareService ->findByToken ($ shareToken );
7074
75+ if (!$ share ->getPermissionRead ()) {
76+ return $ this ->handlePermissionError (new PermissionError ('No read permission on this share ' ));
77+ }
78+
7179 $ limit = $ limit !== null ? max (0 , min (500 , $ limit )) : null ;
7280 $ offset = $ offset !== null ? max (0 , $ offset ) : null ;
7381
@@ -90,4 +98,153 @@ public function getRows(string $token, ?int $limit, ?int $offset): DataResponse
9098 return $ this ->handleBadRequestError ($ e );
9199 }
92100 }
101+
102+ /**
103+ * [api v2] Create a row in a link share
104+ *
105+ * @param string $token The share token
106+ * @param string|array<string, mixed> $data An array containing the column identifiers and their values
107+ * @return DataResponse<Http::STATUS_OK, TablesPublicRow, array{}>|DataResponse<Http::STATUS_FORBIDDEN|Http::STATUS_BAD_REQUEST|Http::STATUS_NOT_FOUND|Http::STATUS_INTERNAL_SERVER_ERROR, array{message: string}, array{}>
108+ *
109+ * 200: Row created
110+ * 400: Invalid request parameters
111+ * 403: No permissions
112+ * 404: Not found
113+ * 500: Internal error
114+ */
115+ #[PublicPage]
116+ #[AssertShareAccessIsAccessible]
117+ #[ApiRoute(verb: 'POST ' , url: '/api/2/public/{token}/rows ' , requirements: ['token ' => '[a-zA-Z0-9]{16} ' ])]
118+ #[OpenAPI]
119+ #[AnonRateLimit(limit: 20 , period: 30 )]
120+ public function createRow (string $ token , mixed $ data ): DataResponse {
121+ try {
122+ $ shareToken = new ShareToken ($ token );
123+ $ share = $ this ->shareService ->findByToken ($ shareToken );
124+ $ this ->row2Mapper ->setUserId ('public- ' . $ token );
125+
126+ if (!$ share ->getPermissionCreate ()) {
127+ return $ this ->handlePermissionError (new PermissionError ('No create permission on this share ' ));
128+ }
129+
130+ if (is_string ($ data )) {
131+ $ data = json_decode ($ data , true );
132+ }
133+ if (!is_array ($ data )) {
134+ return $ this ->handleBadRequestError (new BadRequestError ('Invalid data input ' ));
135+ }
136+
137+ $ newRowData = new RowDataInput ();
138+ foreach ($ data as $ key => $ value ) {
139+ $ newRowData ->add ((int )$ key , $ value );
140+ }
141+
142+ $ tableId = $ share ->getNodeType () === 'table ' ? $ share ->getNodeId () : null ;
143+ $ viewId = $ share ->getNodeType () === 'view ' ? $ share ->getNodeId () : null ;
144+
145+ $ row = $ this ->rowService ->create ($ tableId , $ viewId , $ newRowData );
146+ return new DataResponse ($ this ->rowService ->formatRowsForPublicShare ([$ row ])[0 ]);
147+ } catch (PermissionError $ e ) {
148+ return $ this ->handlePermissionError ($ e );
149+ } catch (NotFoundError $ e ) {
150+ return $ this ->handleNotFoundError ($ e );
151+ } catch (BadRequestError $ e ) {
152+ return $ this ->handleBadRequestError ($ e );
153+ } catch (InternalError |\Exception $ e ) {
154+ return $ this ->handleError ($ e );
155+ }
156+ }
157+
158+ /**
159+ * [api v2] Update a row in a link share
160+ *
161+ * @param string $token The share token
162+ * @param int $rowId The row identifier
163+ * @param string|array<string, mixed> $data An array containing the column identifiers and their values
164+ * @return DataResponse<Http::STATUS_OK, TablesPublicRow, array{}>|DataResponse<Http::STATUS_FORBIDDEN|Http::STATUS_BAD_REQUEST|Http::STATUS_NOT_FOUND|Http::STATUS_INTERNAL_SERVER_ERROR, array{message: string}, array{}>
165+ *
166+ * 200: Row updated
167+ * 400: Invalid request parameters
168+ * 403: No permissions
169+ * 404: Not found
170+ * 500: Internal error
171+ */
172+ #[PublicPage]
173+ #[AssertShareAccessIsAccessible]
174+ #[ApiRoute(verb: 'PUT ' , url: '/api/2/public/{token}/rows/{rowId} ' , requirements: ['token ' => '[a-zA-Z0-9]{16} ' , 'rowId ' => '\d+ ' ])]
175+ #[OpenAPI]
176+ #[AnonRateLimit(limit: 20 , period: 30 )]
177+ public function updateRow (string $ token , int $ rowId , mixed $ data ): DataResponse {
178+ try {
179+ $ shareToken = new ShareToken ($ token );
180+ $ share = $ this ->shareService ->findByToken ($ shareToken );
181+ $ this ->row2Mapper ->setUserId ('public- ' . $ token );
182+
183+ if (!$ share ->getPermissionUpdate ()) {
184+ return $ this ->handlePermissionError (new PermissionError ('No update permission on this share ' ));
185+ }
186+
187+ if (is_string ($ data )) {
188+ $ data = json_decode ($ data , true );
189+ }
190+ if (!is_array ($ data )) {
191+ return $ this ->handleBadRequestError (new BadRequestError ('Invalid data input ' ));
192+ }
193+
194+ $ viewId = $ share ->getNodeType () === 'view ' ? $ share ->getNodeId () : null ;
195+ $ tableId = $ share ->getNodeType () === 'table ' ? $ share ->getNodeId () : null ;
196+
197+ $ row = $ this ->rowService ->updateSet ($ rowId , $ viewId , $ data , '' , $ tableId );
198+ return new DataResponse ($ this ->rowService ->formatRowsForPublicShare ([$ row ])[0 ]);
199+ } catch (PermissionError $ e ) {
200+ return $ this ->handlePermissionError ($ e );
201+ } catch (NotFoundError $ e ) {
202+ return $ this ->handleNotFoundError ($ e );
203+ } catch (BadRequestError $ e ) {
204+ return $ this ->handleBadRequestError ($ e );
205+ } catch (InternalError |\Exception $ e ) {
206+ return $ this ->handleError ($ e );
207+ }
208+ }
209+
210+ /**
211+ * [api v2] Delete a row in a link share
212+ *
213+ * @param string $token The share token
214+ * @param int $rowId The row identifier
215+ * @return DataResponse<Http::STATUS_OK, TablesPublicRow, array{}>|DataResponse<Http::STATUS_FORBIDDEN|Http::STATUS_NOT_FOUND|Http::STATUS_INTERNAL_SERVER_ERROR, array{message: string}, array{}>
216+ *
217+ * 200: Row deleted
218+ * 403: No permissions
219+ * 404: Not found
220+ * 500: Internal error
221+ */
222+ #[PublicPage]
223+ #[AssertShareAccessIsAccessible]
224+ #[ApiRoute(verb: 'DELETE ' , url: '/api/2/public/{token}/rows/{rowId} ' , requirements: ['token ' => '[a-zA-Z0-9]{16} ' , 'rowId ' => '\d+ ' ])]
225+ #[OpenAPI]
226+ #[AnonRateLimit(limit: 20 , period: 30 )]
227+ public function deleteRow (string $ token , int $ rowId ): DataResponse {
228+ try {
229+ $ shareToken = new ShareToken ($ token );
230+ $ share = $ this ->shareService ->findByToken ($ shareToken );
231+ $ this ->row2Mapper ->setUserId ('public- ' . $ token );
232+
233+ if (!$ share ->getPermissionDelete ()) {
234+ return $ this ->handlePermissionError (new PermissionError ('No delete permission on this share ' ));
235+ }
236+
237+ $ viewId = $ share ->getNodeType () === 'view ' ? $ share ->getNodeId () : null ;
238+ $ tableId = $ share ->getNodeType () === 'table ' ? $ share ->getNodeId () : null ;
239+
240+ $ row = $ this ->rowService ->delete ($ rowId , $ viewId , '' , $ tableId );
241+ return new DataResponse ($ this ->rowService ->formatRowsForPublicShare ([$ row ])[0 ]);
242+ } catch (PermissionError $ e ) {
243+ return $ this ->handlePermissionError ($ e );
244+ } catch (NotFoundError $ e ) {
245+ return $ this ->handleNotFoundError ($ e );
246+ } catch (InternalError |\Exception $ e ) {
247+ return $ this ->handleError ($ e );
248+ }
249+ }
93250}
0 commit comments