Fossil SCM

Started adding /json/artifact tickets support, but grokking tkt.c is more than i am up for tonight. Changed how permissions checks are done under /json/artifact (previous approach is just plain silly without C++ templates)

stephan 2011-10-04 20:02 UTC json-multitag-test
Commit cee8bc672779570879a9c616de420a6354ff384b
1 file changed +51 -28
--- src/json_artifact.c
+++ src/json_artifact.c
@@ -45,18 +45,10 @@
4545
/**
4646
JSON construction callback. Creates the contents for the
4747
payload.artifact property of /json/artifact responses.
4848
*/
4949
artifact_f func;
50
-
51
- /**
52
- Must return true if g.perm has the proper permissions to fetch
53
- this info, else false. If it returns false, func() is skipped
54
- (producing no extra payload output) and an access error is
55
- generated.
56
- */
57
- char (*permCheck)();
5850
} ArtifactDispatchEntry;
5951
6052
6153
/*
6254
** Generates an artifact Object for the given rid/zUuid. rid
@@ -160,16 +152,50 @@
160152
#undef SET
161153
}
162154
db_finalize(&q);
163155
return v;
164156
}
157
+
158
+cson_value * json_artifact_ticket( int rid ){
159
+ cson_value * payV = NULL;
160
+ cson_object * pay = NULL;
161
+ Manifest *pTktChng = NULL;
162
+ static cson_value * eventTypeLabel = NULL;
163
+ if(! g.perm.RdTkt ){
164
+ g.json.resultCode = FSL_JSON_E_DENIED;
165
+ return NULL;
166
+ }
167
+ if(!eventTypeLabel){
168
+ eventTypeLabel = json_new_string("ticket");
169
+ json_gc_add("$EVENT_TYPE_LABEL(ticket)", eventTypeLabel, 1);
170
+ }
171
+
172
+ pTktChng = manifest_get(rid, CFTYPE_TICKET);
173
+ if( pTktChng==0 ){
174
+ g.json.resultCode = FSL_JSON_E_UNKNOWN;
175
+ return NULL;
176
+ }
177
+ payV = cson_value_new_object();
178
+ pay = cson_value_get_object(payV);
179
+ cson_object_set(pay, "eventType", eventTypeLabel );
180
+ cson_object_set(pay, "uuid", json_new_string(pTktChng->zTicketUuid));
181
+ cson_object_set(pay, "user", json_new_string(pTktChng->zUser));
182
+ cson_object_set(pay, "timestamp", json_julian_to_timestamp(pTktChng->rDate));
183
+ manifest_destroy(pTktChng);
184
+ return payV;
185
+}
165186
166187
/*
167188
** Sub-impl of /json/artifact for checkins.
168189
*/
169190
static cson_value * json_artifact_ci( int rid ){
170
- return json_artifact_for_ci(rid, 1);
191
+ if(! g.perm.Read ){
192
+ g.json.resultCode = FSL_JSON_E_DENIED;
193
+ return NULL;
194
+ }else{
195
+ return json_artifact_for_ci(rid, 1);
196
+ }
171197
}
172198
173199
/*
174200
** Permissions callback func for ArtifactDispatchEntry.
175201
*/
@@ -176,15 +202,16 @@
176202
static char perms_can_read(){
177203
return g.perm.Read ? 1 : 0;
178204
}
179205
180206
static ArtifactDispatchEntry ArtifactDispatchList[] = {
181
-{"checkin", json_artifact_ci, perms_can_read},
182
-{"tag", NULL, perms_can_read},
183
-{"ticket", NULL, perms_can_read},
184
-{"wiki", NULL, perms_can_read},
185
-{NULL,NULL,NULL}
207
+{"checkin", json_artifact_ci},
208
+{"tag", NULL},
209
+{"ticket", json_artifact_ticket},
210
+{"wiki", NULL},
211
+/* Final entry MUST have a NULL name. */
212
+{NULL,NULL}
186213
};
187214
188215
/*
189216
** Impl of /json/artifact. This basically just determines the type of
190217
** an artifact and forwards the real work to another function.
@@ -193,13 +220,14 @@
193220
cson_value * payV = NULL;
194221
cson_object * pay = NULL;
195222
char const * zName = NULL;
196223
char const * zType = NULL;
197224
char const * zUuid = NULL;
225
+ cson_value * entry = NULL;
198226
Blob uuid = empty_blob;
199227
int rc;
200
- int rid;
228
+ int rid = 0;
201229
ArtifactDispatchEntry const * dispatcher = &ArtifactDispatchList[0];
202230
zName = g.isHTTP
203231
? json_getenv_cstr("uuid")
204232
: find_option("uuid","u",1);
205233
if(!zName||!*zName){
@@ -261,34 +289,29 @@
261289
assert( (NULL != zType) && "Internal dispatching error." );
262290
for( ; dispatcher->name; ++dispatcher ){
263291
if(0!=strcmp(dispatcher->name, zType)){
264292
continue;
265293
}else{
266
- if( ! (*dispatcher->permCheck)() ){
267
- g.json.resultCode = FSL_JSON_E_DENIED;
268
- }
294
+ entry = (*dispatcher->func)(rid);
269295
break;
270296
}
271297
}
272298
if(!g.json.resultCode){
299
+ assert( NULL != entry );
300
+ assert( NULL != zType );
273301
payV = cson_value_new_object();
274302
pay = cson_value_get_object(payV);
275
- assert( NULL != zType );
276303
cson_object_set( pay, "type", json_new_string(zType) );
277304
/*cson_object_set( pay, "uuid", json_new_string(zUuid) );*/
278305
cson_object_set( pay, "name", json_new_string(zName ? zName : zUuid) );
279306
cson_object_set( pay, "rid", cson_value_new_integer(rid) );
280
- if( !dispatcher->name ){
281
- cson_object_set(pay,"artifact",
282
- json_new_string("TODO: handle this artifact type!"));
283
- }else {
284
- cson_value * entry = (*dispatcher->func)(rid);
285
- if(entry){
286
- cson_object_set(pay, "artifact", entry);
287
- }
288
- }
307
+ if(entry){
308
+ cson_object_set(pay, "artifact", entry);
309
+ }
310
+ }else{
311
+ assert((NULL == entry) && "Internal misuse - callback must return NULL on error.");
289312
}
290313
veryend:
291314
blob_reset(&uuid);
292315
return payV;
293316
}
294317
295318
--- src/json_artifact.c
+++ src/json_artifact.c
@@ -45,18 +45,10 @@
45 /**
46 JSON construction callback. Creates the contents for the
47 payload.artifact property of /json/artifact responses.
48 */
49 artifact_f func;
50
51 /**
52 Must return true if g.perm has the proper permissions to fetch
53 this info, else false. If it returns false, func() is skipped
54 (producing no extra payload output) and an access error is
55 generated.
56 */
57 char (*permCheck)();
58 } ArtifactDispatchEntry;
59
60
61 /*
62 ** Generates an artifact Object for the given rid/zUuid. rid
@@ -160,16 +152,50 @@
160 #undef SET
161 }
162 db_finalize(&q);
163 return v;
164 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
165
166 /*
167 ** Sub-impl of /json/artifact for checkins.
168 */
169 static cson_value * json_artifact_ci( int rid ){
170 return json_artifact_for_ci(rid, 1);
 
 
 
 
 
171 }
172
173 /*
174 ** Permissions callback func for ArtifactDispatchEntry.
175 */
@@ -176,15 +202,16 @@
176 static char perms_can_read(){
177 return g.perm.Read ? 1 : 0;
178 }
179
180 static ArtifactDispatchEntry ArtifactDispatchList[] = {
181 {"checkin", json_artifact_ci, perms_can_read},
182 {"tag", NULL, perms_can_read},
183 {"ticket", NULL, perms_can_read},
184 {"wiki", NULL, perms_can_read},
185 {NULL,NULL,NULL}
 
186 };
187
188 /*
189 ** Impl of /json/artifact. This basically just determines the type of
190 ** an artifact and forwards the real work to another function.
@@ -193,13 +220,14 @@
193 cson_value * payV = NULL;
194 cson_object * pay = NULL;
195 char const * zName = NULL;
196 char const * zType = NULL;
197 char const * zUuid = NULL;
 
198 Blob uuid = empty_blob;
199 int rc;
200 int rid;
201 ArtifactDispatchEntry const * dispatcher = &ArtifactDispatchList[0];
202 zName = g.isHTTP
203 ? json_getenv_cstr("uuid")
204 : find_option("uuid","u",1);
205 if(!zName||!*zName){
@@ -261,34 +289,29 @@
261 assert( (NULL != zType) && "Internal dispatching error." );
262 for( ; dispatcher->name; ++dispatcher ){
263 if(0!=strcmp(dispatcher->name, zType)){
264 continue;
265 }else{
266 if( ! (*dispatcher->permCheck)() ){
267 g.json.resultCode = FSL_JSON_E_DENIED;
268 }
269 break;
270 }
271 }
272 if(!g.json.resultCode){
 
 
273 payV = cson_value_new_object();
274 pay = cson_value_get_object(payV);
275 assert( NULL != zType );
276 cson_object_set( pay, "type", json_new_string(zType) );
277 /*cson_object_set( pay, "uuid", json_new_string(zUuid) );*/
278 cson_object_set( pay, "name", json_new_string(zName ? zName : zUuid) );
279 cson_object_set( pay, "rid", cson_value_new_integer(rid) );
280 if( !dispatcher->name ){
281 cson_object_set(pay,"artifact",
282 json_new_string("TODO: handle this artifact type!"));
283 }else {
284 cson_value * entry = (*dispatcher->func)(rid);
285 if(entry){
286 cson_object_set(pay, "artifact", entry);
287 }
288 }
289 }
290 veryend:
291 blob_reset(&uuid);
292 return payV;
293 }
294
295
--- src/json_artifact.c
+++ src/json_artifact.c
@@ -45,18 +45,10 @@
45 /**
46 JSON construction callback. Creates the contents for the
47 payload.artifact property of /json/artifact responses.
48 */
49 artifact_f func;
 
 
 
 
 
 
 
 
50 } ArtifactDispatchEntry;
51
52
53 /*
54 ** Generates an artifact Object for the given rid/zUuid. rid
@@ -160,16 +152,50 @@
152 #undef SET
153 }
154 db_finalize(&q);
155 return v;
156 }
157
158 cson_value * json_artifact_ticket( int rid ){
159 cson_value * payV = NULL;
160 cson_object * pay = NULL;
161 Manifest *pTktChng = NULL;
162 static cson_value * eventTypeLabel = NULL;
163 if(! g.perm.RdTkt ){
164 g.json.resultCode = FSL_JSON_E_DENIED;
165 return NULL;
166 }
167 if(!eventTypeLabel){
168 eventTypeLabel = json_new_string("ticket");
169 json_gc_add("$EVENT_TYPE_LABEL(ticket)", eventTypeLabel, 1);
170 }
171
172 pTktChng = manifest_get(rid, CFTYPE_TICKET);
173 if( pTktChng==0 ){
174 g.json.resultCode = FSL_JSON_E_UNKNOWN;
175 return NULL;
176 }
177 payV = cson_value_new_object();
178 pay = cson_value_get_object(payV);
179 cson_object_set(pay, "eventType", eventTypeLabel );
180 cson_object_set(pay, "uuid", json_new_string(pTktChng->zTicketUuid));
181 cson_object_set(pay, "user", json_new_string(pTktChng->zUser));
182 cson_object_set(pay, "timestamp", json_julian_to_timestamp(pTktChng->rDate));
183 manifest_destroy(pTktChng);
184 return payV;
185 }
186
187 /*
188 ** Sub-impl of /json/artifact for checkins.
189 */
190 static cson_value * json_artifact_ci( int rid ){
191 if(! g.perm.Read ){
192 g.json.resultCode = FSL_JSON_E_DENIED;
193 return NULL;
194 }else{
195 return json_artifact_for_ci(rid, 1);
196 }
197 }
198
199 /*
200 ** Permissions callback func for ArtifactDispatchEntry.
201 */
@@ -176,15 +202,16 @@
202 static char perms_can_read(){
203 return g.perm.Read ? 1 : 0;
204 }
205
206 static ArtifactDispatchEntry ArtifactDispatchList[] = {
207 {"checkin", json_artifact_ci},
208 {"tag", NULL},
209 {"ticket", json_artifact_ticket},
210 {"wiki", NULL},
211 /* Final entry MUST have a NULL name. */
212 {NULL,NULL}
213 };
214
215 /*
216 ** Impl of /json/artifact. This basically just determines the type of
217 ** an artifact and forwards the real work to another function.
@@ -193,13 +220,14 @@
220 cson_value * payV = NULL;
221 cson_object * pay = NULL;
222 char const * zName = NULL;
223 char const * zType = NULL;
224 char const * zUuid = NULL;
225 cson_value * entry = NULL;
226 Blob uuid = empty_blob;
227 int rc;
228 int rid = 0;
229 ArtifactDispatchEntry const * dispatcher = &ArtifactDispatchList[0];
230 zName = g.isHTTP
231 ? json_getenv_cstr("uuid")
232 : find_option("uuid","u",1);
233 if(!zName||!*zName){
@@ -261,34 +289,29 @@
289 assert( (NULL != zType) && "Internal dispatching error." );
290 for( ; dispatcher->name; ++dispatcher ){
291 if(0!=strcmp(dispatcher->name, zType)){
292 continue;
293 }else{
294 entry = (*dispatcher->func)(rid);
 
 
295 break;
296 }
297 }
298 if(!g.json.resultCode){
299 assert( NULL != entry );
300 assert( NULL != zType );
301 payV = cson_value_new_object();
302 pay = cson_value_get_object(payV);
 
303 cson_object_set( pay, "type", json_new_string(zType) );
304 /*cson_object_set( pay, "uuid", json_new_string(zUuid) );*/
305 cson_object_set( pay, "name", json_new_string(zName ? zName : zUuid) );
306 cson_object_set( pay, "rid", cson_value_new_integer(rid) );
307 if(entry){
308 cson_object_set(pay, "artifact", entry);
309 }
310 }else{
311 assert((NULL == entry) && "Internal misuse - callback must return NULL on error.");
 
 
 
 
312 }
313 veryend:
314 blob_reset(&uuid);
315 return payV;
316 }
317
318

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button