Fossil SCM

Extend /json/settings/get with a version=X flag indicating the check-in version to check for versionable flags in before falling back to either the checkout or repository. List sensitive properties for all users but elide their values for non-setup users (previously they were elided altogether for non-setup users).

stephan 2023-01-19 02:39 json-settings-command
Commit fd405e956359226215494ed2cde070eaebcf6198c2850ce6c8fab8fa18b6be5c
1 file changed +52 -20
+52 -20
--- src/json_config.c
+++ src/json_config.c
@@ -208,19 +208,40 @@
208208
209209
/*
210210
** Impl of /json/settings/get.
211211
*/
212212
static cson_value * json_settings_get(void){
213
- cson_array * pay = cson_new_array();
214
- int nSetting, i;
213
+ cson_array * pay = cson_new_array(); /* output payload */
214
+ int nSetting, i; /* setting count and loop var */
215215
const Setting *aSetting = setting_info(&nSetting);
216
- Stmt q = empty_Stmt;
216
+ const char * zRevision = 0; /* revision to look for
217
+ versioned settings in */
218
+ char * zUuid = 0; /* Resolved UUID of zRevision */
219
+ Stmt q = empty_Stmt; /* Config-search query */
220
+ Stmt qFoci = empty_Stmt; /* foci query */
217221
218222
if( !g.perm.Read ){
219223
json_set_err( FSL_JSON_E_DENIED, "Fetching settings requires 'o' access." );
220224
return NULL;
221225
}
226
+ zRevision = json_find_option_cstr("version",NULL,NULL);
227
+ if( 0!=zRevision ){
228
+ int rid = name_to_uuid2(zRevision, "ci", &zUuid);
229
+ if(rid<=0){
230
+ json_set_err(FSL_JSON_E_RESOURCE_NOT_FOUND,
231
+ "Cannot find the given version.");
232
+ return NULL;
233
+ }
234
+ db_multi_exec("CREATE VIRTUAL TABLE IF NOT EXISTS "
235
+ "temp.foci USING files_of_checkin;");
236
+ db_prepare(&qFoci,
237
+ "SELECT uuid FROM temp.foci WHERE "
238
+ "checkinID=%d AND filename='.fossil-settings/' || :name",
239
+ rid);
240
+ }
241
+ zRevision = 0;
242
+
222243
if( g.localOpen ){
223244
db_prepare(&q,
224245
"SELECT 'checkout', value FROM vvar WHERE name=:name"
225246
" UNION ALL "
226247
"SELECT 'repo', value FROM config WHERE name=:name"
@@ -232,27 +253,44 @@
232253
}
233254
for(i=0; i<nSetting; ++i){
234255
const Setting *pSet = &aSetting[i];
235256
cson_object * jSet;
236257
cson_value * pVal = 0, * pSrc = 0;
237
- if( pSet->sensitive && !g.perm.Setup ){
238
- continue;
239
- }
240258
jSet = cson_new_object();
241259
cson_array_append(pay, cson_object_value(jSet));
242260
cson_object_set(jSet, "name", json_new_string(pSet->name));
243261
cson_object_set(jSet, "versionable", cson_value_new_bool(pSet->versionable));
244262
cson_object_set(jSet, "sensitive", cson_value_new_bool(pSet->sensitive));
245263
cson_object_set(jSet, "defaultValue", (pSet->def && pSet->def[0])
246264
? json_new_string(pSet->def)
247265
: cson_value_null());
266
+ if( pSet->sensitive && !g.perm.Setup ){
267
+ /* Should we also allow non-Setup admins to see these? */
268
+ continue;
269
+ }
248270
if( pSet->versionable ){
249271
/* Check to see if this is overridden by a versionable settings file */
250
- if( g.localOpen ){
272
+ Blob versionedPathname;
273
+ blob_zero(&versionedPathname);
274
+ if( 0!=zUuid ){
275
+ /* Attempt to find a versioned setting stored in the given
276
+ ** check-in version. */
277
+ db_bind_text(&qFoci, ":name", pSet->name);
278
+ if( SQLITE_ROW==db_step(&qFoci) ){
279
+ int frid = fast_uuid_to_rid(db_column_text(&qFoci, 0));
280
+ Blob content;
281
+ blob_zero(&content);
282
+ if( 0!=content_get(frid, &content) ){
283
+ pSrc = json_new_string("versioned");
284
+ pVal = json_new_string(blob_str(&content));
285
+ }
286
+ blob_reset(&content);
287
+ }
288
+ db_reset(&qFoci);
289
+ }
290
+ if( 0==pSrc && g.localOpen ){
251291
/* Pull value from a local .fossil-settings/X file, if one exists. */
252
- Blob versionedPathname;
253
- blob_zero(&versionedPathname);
254292
blob_appendf(&versionedPathname, "%s.fossil-settings/%s",
255293
g.zLocalRoot, pSet->name);
256294
if( file_size(blob_str(&versionedPathname), ExtFILE)>=0 ){
257295
Blob content;
258296
blob_zero(&content);
@@ -261,32 +299,26 @@
261299
pVal = json_new_string(blob_str(&content));
262300
blob_reset(&content);
263301
}
264302
blob_reset(&versionedPathname);
265303
}
266
- if( 0==pSrc ){
267
- /*
268
- ** TODO? No checkout-local versioned setting found. We could
269
- ** fish the file out of the repository but we'd need to make
270
- ** an assumption about which branch to pull it from or require
271
- ** the user to pass in a version.
272
- */
273
- }
274304
}
275305
if( 0==pSrc ){
276
- /* We had no checkout-local value, so use the value from
277
- ** repo.config. */
306
+ /* We had no versioned value, so use the value from
307
+ ** localdb.vvar or repository.config (in that order). */
278308
db_bind_text(&q, ":name", pSet->name);
279309
if( SQLITE_ROW==db_step(&q) ){
280310
pSrc = json_new_string(db_column_text(&q, 0));
281311
pVal = json_new_string(db_column_text(&q, 1));
282312
}
283313
db_reset(&q);
284314
}
285315
cson_object_set(jSet, "valueSource", pSrc ? pSrc : cson_value_null());
286316
cson_object_set(jSet, "value", pVal ? pVal : cson_value_null());
287
- }
317
+ }/*aSetting loop*/
288318
db_finalize(&q);
319
+ db_finalize(&qFoci);
320
+ fossil_free(zUuid);
289321
return cson_array_value(pay);
290322
}
291323
292324
#endif /* FOSSIL_ENABLE_JSON */
293325
--- src/json_config.c
+++ src/json_config.c
@@ -208,19 +208,40 @@
208
209 /*
210 ** Impl of /json/settings/get.
211 */
212 static cson_value * json_settings_get(void){
213 cson_array * pay = cson_new_array();
214 int nSetting, i;
215 const Setting *aSetting = setting_info(&nSetting);
216 Stmt q = empty_Stmt;
 
 
 
 
217
218 if( !g.perm.Read ){
219 json_set_err( FSL_JSON_E_DENIED, "Fetching settings requires 'o' access." );
220 return NULL;
221 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
222 if( g.localOpen ){
223 db_prepare(&q,
224 "SELECT 'checkout', value FROM vvar WHERE name=:name"
225 " UNION ALL "
226 "SELECT 'repo', value FROM config WHERE name=:name"
@@ -232,27 +253,44 @@
232 }
233 for(i=0; i<nSetting; ++i){
234 const Setting *pSet = &aSetting[i];
235 cson_object * jSet;
236 cson_value * pVal = 0, * pSrc = 0;
237 if( pSet->sensitive && !g.perm.Setup ){
238 continue;
239 }
240 jSet = cson_new_object();
241 cson_array_append(pay, cson_object_value(jSet));
242 cson_object_set(jSet, "name", json_new_string(pSet->name));
243 cson_object_set(jSet, "versionable", cson_value_new_bool(pSet->versionable));
244 cson_object_set(jSet, "sensitive", cson_value_new_bool(pSet->sensitive));
245 cson_object_set(jSet, "defaultValue", (pSet->def && pSet->def[0])
246 ? json_new_string(pSet->def)
247 : cson_value_null());
 
 
 
 
248 if( pSet->versionable ){
249 /* Check to see if this is overridden by a versionable settings file */
250 if( g.localOpen ){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
251 /* Pull value from a local .fossil-settings/X file, if one exists. */
252 Blob versionedPathname;
253 blob_zero(&versionedPathname);
254 blob_appendf(&versionedPathname, "%s.fossil-settings/%s",
255 g.zLocalRoot, pSet->name);
256 if( file_size(blob_str(&versionedPathname), ExtFILE)>=0 ){
257 Blob content;
258 blob_zero(&content);
@@ -261,32 +299,26 @@
261 pVal = json_new_string(blob_str(&content));
262 blob_reset(&content);
263 }
264 blob_reset(&versionedPathname);
265 }
266 if( 0==pSrc ){
267 /*
268 ** TODO? No checkout-local versioned setting found. We could
269 ** fish the file out of the repository but we'd need to make
270 ** an assumption about which branch to pull it from or require
271 ** the user to pass in a version.
272 */
273 }
274 }
275 if( 0==pSrc ){
276 /* We had no checkout-local value, so use the value from
277 ** repo.config. */
278 db_bind_text(&q, ":name", pSet->name);
279 if( SQLITE_ROW==db_step(&q) ){
280 pSrc = json_new_string(db_column_text(&q, 0));
281 pVal = json_new_string(db_column_text(&q, 1));
282 }
283 db_reset(&q);
284 }
285 cson_object_set(jSet, "valueSource", pSrc ? pSrc : cson_value_null());
286 cson_object_set(jSet, "value", pVal ? pVal : cson_value_null());
287 }
288 db_finalize(&q);
 
 
289 return cson_array_value(pay);
290 }
291
292 #endif /* FOSSIL_ENABLE_JSON */
293
--- src/json_config.c
+++ src/json_config.c
@@ -208,19 +208,40 @@
208
209 /*
210 ** Impl of /json/settings/get.
211 */
212 static cson_value * json_settings_get(void){
213 cson_array * pay = cson_new_array(); /* output payload */
214 int nSetting, i; /* setting count and loop var */
215 const Setting *aSetting = setting_info(&nSetting);
216 const char * zRevision = 0; /* revision to look for
217 versioned settings in */
218 char * zUuid = 0; /* Resolved UUID of zRevision */
219 Stmt q = empty_Stmt; /* Config-search query */
220 Stmt qFoci = empty_Stmt; /* foci query */
221
222 if( !g.perm.Read ){
223 json_set_err( FSL_JSON_E_DENIED, "Fetching settings requires 'o' access." );
224 return NULL;
225 }
226 zRevision = json_find_option_cstr("version",NULL,NULL);
227 if( 0!=zRevision ){
228 int rid = name_to_uuid2(zRevision, "ci", &zUuid);
229 if(rid<=0){
230 json_set_err(FSL_JSON_E_RESOURCE_NOT_FOUND,
231 "Cannot find the given version.");
232 return NULL;
233 }
234 db_multi_exec("CREATE VIRTUAL TABLE IF NOT EXISTS "
235 "temp.foci USING files_of_checkin;");
236 db_prepare(&qFoci,
237 "SELECT uuid FROM temp.foci WHERE "
238 "checkinID=%d AND filename='.fossil-settings/' || :name",
239 rid);
240 }
241 zRevision = 0;
242
243 if( g.localOpen ){
244 db_prepare(&q,
245 "SELECT 'checkout', value FROM vvar WHERE name=:name"
246 " UNION ALL "
247 "SELECT 'repo', value FROM config WHERE name=:name"
@@ -232,27 +253,44 @@
253 }
254 for(i=0; i<nSetting; ++i){
255 const Setting *pSet = &aSetting[i];
256 cson_object * jSet;
257 cson_value * pVal = 0, * pSrc = 0;
 
 
 
258 jSet = cson_new_object();
259 cson_array_append(pay, cson_object_value(jSet));
260 cson_object_set(jSet, "name", json_new_string(pSet->name));
261 cson_object_set(jSet, "versionable", cson_value_new_bool(pSet->versionable));
262 cson_object_set(jSet, "sensitive", cson_value_new_bool(pSet->sensitive));
263 cson_object_set(jSet, "defaultValue", (pSet->def && pSet->def[0])
264 ? json_new_string(pSet->def)
265 : cson_value_null());
266 if( pSet->sensitive && !g.perm.Setup ){
267 /* Should we also allow non-Setup admins to see these? */
268 continue;
269 }
270 if( pSet->versionable ){
271 /* Check to see if this is overridden by a versionable settings file */
272 Blob versionedPathname;
273 blob_zero(&versionedPathname);
274 if( 0!=zUuid ){
275 /* Attempt to find a versioned setting stored in the given
276 ** check-in version. */
277 db_bind_text(&qFoci, ":name", pSet->name);
278 if( SQLITE_ROW==db_step(&qFoci) ){
279 int frid = fast_uuid_to_rid(db_column_text(&qFoci, 0));
280 Blob content;
281 blob_zero(&content);
282 if( 0!=content_get(frid, &content) ){
283 pSrc = json_new_string("versioned");
284 pVal = json_new_string(blob_str(&content));
285 }
286 blob_reset(&content);
287 }
288 db_reset(&qFoci);
289 }
290 if( 0==pSrc && g.localOpen ){
291 /* Pull value from a local .fossil-settings/X file, if one exists. */
 
 
292 blob_appendf(&versionedPathname, "%s.fossil-settings/%s",
293 g.zLocalRoot, pSet->name);
294 if( file_size(blob_str(&versionedPathname), ExtFILE)>=0 ){
295 Blob content;
296 blob_zero(&content);
@@ -261,32 +299,26 @@
299 pVal = json_new_string(blob_str(&content));
300 blob_reset(&content);
301 }
302 blob_reset(&versionedPathname);
303 }
 
 
 
 
 
 
 
 
304 }
305 if( 0==pSrc ){
306 /* We had no versioned value, so use the value from
307 ** localdb.vvar or repository.config (in that order). */
308 db_bind_text(&q, ":name", pSet->name);
309 if( SQLITE_ROW==db_step(&q) ){
310 pSrc = json_new_string(db_column_text(&q, 0));
311 pVal = json_new_string(db_column_text(&q, 1));
312 }
313 db_reset(&q);
314 }
315 cson_object_set(jSet, "valueSource", pSrc ? pSrc : cson_value_null());
316 cson_object_set(jSet, "value", pVal ? pVal : cson_value_null());
317 }/*aSetting loop*/
318 db_finalize(&q);
319 db_finalize(&qFoci);
320 fossil_free(zUuid);
321 return cson_array_value(pay);
322 }
323
324 #endif /* FOSSIL_ENABLE_JSON */
325

Keyboard Shortcuts

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