1
1
/*
2
- * To change this license header, choose License Headers in Project Properties.
3
- * To change this template file, choose Tools | Templates
4
- * and open the template in the editor.
2
+ * Copyright (c) 2019 Parallax Inc.
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
5
+ * and associated documentation files (the “Software”), to deal in the Software without
6
+ * restriction, including without limitation the rights to use, copy, modify, merge, publish,
7
+ * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
8
+ * Software is furnished to do so, subject to the following conditions:
9
+ *
10
+ * The above copyright notice and this permission notice shall be included in all copies or
11
+ * substantial portions of the Software.
12
+ *
13
+ * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ * SOFTWARE.
5
20
*/
21
+
6
22
package com .parallax .server .blocklyprop .rest ;
7
23
8
24
import com .cuubez .visualizer .annotation .Detail ;
16
32
import com .google .inject .Inject ;
17
33
import com .parallax .server .blocklyprop .TableOrder ;
18
34
import com .parallax .server .blocklyprop .TableSort ;
35
+ import com .parallax .server .blocklyprop .utils .RestProjectUtils ;
19
36
import com .parallax .server .blocklyprop .converter .ProjectConverter ;
20
37
import com .parallax .server .blocklyprop .db .enums .ProjectType ;
21
38
import com .parallax .server .blocklyprop .db .generated .tables .records .ProjectRecord ;
31
48
import javax .ws .rs .QueryParam ;
32
49
import javax .ws .rs .core .Response ;
33
50
import org .apache .shiro .authz .AuthorizationException ;
51
+ import org .jetbrains .annotations .NotNull ;
34
52
import org .slf4j .Logger ;
35
53
import org .slf4j .LoggerFactory ;
36
54
45
63
@ Group (name = "/project" , title = "Project management" )
46
64
@ HttpCode ("500>Internal Server Error,200>Success Response" )
47
65
public class RestProject {
48
- // Get a logger instance
66
+
67
+ /**
68
+ * Get a logger instance
69
+ */
49
70
private static final Logger LOG = LoggerFactory .getLogger (RestProject .class );
50
71
51
- // Connector to project services object
72
+
73
+ /**
74
+ * Connector to project services object
75
+ */
52
76
private ProjectService projectService ;
53
77
54
- // Connector to project converter object
78
+
79
+ /**
80
+ * Connector to project converter object
81
+ */
55
82
private ProjectConverter projectConverter ;
56
83
57
84
85
+ /**
86
+ * Limit the number of records that can be returned in list functions
87
+ */
88
+ final int REQUEST_LIMIT = 100 ;
89
+
90
+
58
91
/**
59
92
* Connect to the project service object
60
- * @param projectService
93
+ *
94
+ * @param projectService
95
+ * An instance of the ProjectService object
61
96
*/
62
97
@ Inject
63
98
public void setProjectService (ProjectService projectService ) {
@@ -67,7 +102,9 @@ public void setProjectService(ProjectService projectService) {
67
102
68
103
/**
69
104
* Connect to the project converter object
70
- * @param projectConverter
105
+ *
106
+ * @param projectConverter
107
+ * An instance of the ProjectConverter object
71
108
*/
72
109
@ Inject
73
110
public void setProjectConverter (ProjectConverter projectConverter ) {
@@ -77,13 +114,22 @@ public void setProjectConverter(ProjectConverter projectConverter) {
77
114
78
115
/**
79
116
* Return a list of projects owned by the currently authenticated user.
80
- *
117
+ *
81
118
* @param sort
119
+ * The project field used to evaluate the sort
120
+ *
82
121
* @param order
122
+ * Specify the sort order - ascending or descending
123
+ *
83
124
* @param limit
125
+ * Specify the maximum number of rows to return
126
+ *
84
127
* @param offset
85
- *
86
- * @return JSON formatted list of project details
128
+ * Specify the beginning row to return
129
+ *
130
+ * @return
131
+ * Return a response object that contains either the data requested
132
+ * or a JSON string containing the error details
87
133
*/
88
134
@ GET
89
135
@ Path ("/list" )
@@ -95,49 +141,62 @@ public Response get(
95
141
@ QueryParam ("order" ) @ ParameterDetail ("Sort order" ) @ M () TableOrder order ,
96
142
@ QueryParam ("limit" ) @ ParameterDetail ("Number of rows to return" ) @ M () Integer limit ,
97
143
@ QueryParam ("offset" ) @ ParameterDetail ("Offset to next row returned" ) @ M () Integer offset ) {
98
-
99
- LOG .info ("REST:/rest/project/list/ Get request received" );
100
-
144
+
145
+ String endPoint = "REST:/rest/project/list/" ;
146
+
147
+ LOG .info ("{} Get request received" , endPoint );
148
+ RestProjectUtils restProjectUtils = new RestProjectUtils ();
149
+
101
150
try {
102
151
// Get the logged in user id for the current session
103
152
Long idUser = BlocklyPropSecurityUtils .getCurrentUserId ();
104
-
153
+
154
+ // Return FORBIDDEN if we cannot identify the current user. This could
155
+ // mean that the user is not logged in or that some underlying issue
156
+ // is causing the authentication system to fail.
105
157
if (idUser == 0 ) {
106
158
// Current session is not logged in.
107
- return Response .status (Response .Status .NOT_FOUND ).build ();
159
+ return Response .status (Response .Status .FORBIDDEN ).build ();
108
160
}
109
161
110
162
//Sanity checks - is the request reasonable
111
- if (sort == null )
112
- sort = TableSort .modified ;
113
-
114
- if (order == null )
115
- order = TableOrder .asc ;
116
-
117
- if (limit == null )
118
- limit = 20 ;
119
-
120
- if (offset == null )
121
- offset = 0 ;
122
163
123
- List <ProjectRecord > userProjects =
124
- projectService .getUserProjects (idUser , sort , order , limit , offset );
125
-
126
- int projectCount = projectService .countUserProjects (idUser );
164
+ // Sort flag evaluation
165
+ if (!restProjectUtils .ValidateSortType (sort )) {
166
+ LOG .warn ("{} Sort parameter failed" , endPoint );
167
+ return Response .status (Response .Status .NOT_ACCEPTABLE ).build ();
168
+ }
169
+
170
+ // Sort order evaluation
171
+ if (!restProjectUtils .ValidateSortOrder (order )) {
172
+ LOG .warn ("{} Sort order parameter failed" , endPoint );
173
+ return Response .status (Response .Status .NOT_ACCEPTABLE ).build ();
174
+ }
127
175
128
- JsonObject result = new JsonObject ();
129
- JsonArray jsonProjects = new JsonArray ();
176
+ // Limit result set value
177
+ if ( (limit == null ) || (limit > REQUEST_LIMIT )) {
178
+ LOG .info ("{} Limit throttle to {} entries" , endPoint , REQUEST_LIMIT );
179
+ limit = REQUEST_LIMIT ;
180
+ }
130
181
131
- // Loop through user projects and build a Json array
132
- for ( ProjectRecord project : userProjects ) {
133
- jsonProjects . add ( projectConverter . toListJson ( project )) ;
182
+ // Check ofset from the beginning of the record set
183
+ if (( offset == null ) || ( offset < 0 ) ) {
184
+ offset = 0 ;
134
185
}
135
186
136
- // Add payload details
137
- result .add ("rows" , jsonProjects );
138
- result .addProperty ("total" , projectCount );
187
+ // Obtain a list of the user's projects
188
+ List <ProjectRecord > userProjects = projectService .getUserProjects (idUser , sort , order , limit , offset );
139
189
140
- return Response .ok (result .toString ()).build ();
190
+ // Tell the caller that there is nothing to see here
191
+ if (userProjects == null ) {
192
+ return Response .status (Response .Status .NOT_FOUND ).build ();
193
+ }
194
+
195
+ return Response .ok (
196
+ returnProjectsJson (
197
+ userProjects ,
198
+ projectService .countUserProjects (idUser )))
199
+ .build ();
141
200
}
142
201
143
202
catch (Exception ex ) {
@@ -152,7 +211,11 @@ public Response get(
152
211
* Retreive a project based on the supplied project ID
153
212
*
154
213
* @param idProject
214
+ * The project key ID
215
+ *
155
216
* @return
217
+ * Return a string representation of the project in Json format if successful, otherwise
218
+ * return a Json string containing an error status message
156
219
*/
157
220
@ GET
158
221
@ Path ("/get/{id}" )
@@ -197,7 +260,10 @@ public Response get(@PathParam("id") @ParameterDetail("Project identifier") Long
197
260
*
198
261
* @param idProject
199
262
* @param code
200
- * @return
263
+ * @return
264
+ * Returns a Json string containing the project details if the update was successful
265
+ * or an error message upon failure
266
+ *
201
267
*/
202
268
@ POST
203
269
@ Path ("/code" )
@@ -211,12 +277,19 @@ public Response saveProjectCode(
211
277
LOG .info ("REST:/rest/project/code/ POST request received for project '{}'" , idProject );
212
278
213
279
try {
280
+
281
+ /* WARNING:
282
+ * =================================================================================
283
+ * This call can create a new project record under specific circumstances and does
284
+ * not appear to provide any notification that this has occurred.
285
+ * =================================================================================
286
+ */
214
287
ProjectRecord savedProject = projectService .saveProjectCode (idProject , code );
288
+
215
289
LOG .debug ("Code for project {} has been saved" , idProject );
216
290
217
291
JsonObject result = projectConverter .toJson (savedProject ,false );
218
292
219
- LOG .debug ("Returning JSON: {}" , result );
220
293
221
294
result .addProperty ("success" , true );
222
295
@@ -332,4 +405,32 @@ public Response saveProject(
332
405
return Response .status (Response .Status .INTERNAL_SERVER_ERROR ).build ();
333
406
}
334
407
}
408
+
409
+ /**
410
+ * Iterate a list of projects into an array of Json objects
411
+ *
412
+ * @param projects
413
+ * A List of ProjectRecord objects
414
+ *
415
+ * @param projectCount
416
+ * The number of projects available. This may not be the same value as
417
+ * the number of records contained in the passed list of ProjectRecords.
418
+ *
419
+ * @return
420
+ * A String containing the array of the converted Json objects
421
+ */
422
+ private String returnProjectsJson (@ NotNull List <ProjectRecord > projects , int projectCount ) {
423
+ JsonObject result = new JsonObject ();
424
+ JsonArray jsonProjects = new JsonArray ();
425
+
426
+ for (ProjectRecord project : projects ) {
427
+ jsonProjects .add (projectConverter .toListJson (project ));
428
+ }
429
+
430
+ result .add ("rows" , jsonProjects );
431
+ result .addProperty ("total" , projectCount );
432
+
433
+ return result .toString ();
434
+ }
435
+
335
436
}
0 commit comments