Fossil

Check-in [13cc3b82]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Added userName to /json/stat output for the nobody user (it was previously not set in that case). Renamed captcha to password in /json/anonymousPassword. Added NYI (not yet implemented) placeholders for several planned request types.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | json
Files: files | file ages | folders
SHA1: 13cc3b823ffbb0d244bfacff022afda4fee3a547
User & Date: stephan 2011-09-18 10:25:56
Context
2011-09-18
10:40
Removed some no-longer valid comments after confirming that JSON mode works without cookies. Dumbed-down the various login errors by default (again). check-in: 52229655 user: stephan tags: json
10:25
Added userName to /json/stat output for the nobody user (it was previously not set in that case). Renamed captcha to password in /json/anonymousPassword. Added NYI (not yet implemented) placeholders for several planned request types. check-in: 13cc3b82 user: stephan tags: json
08:11
Implemented anonymous user login over JSON. Requires 2 requests (captcha-fetch and then login). check-in: cebf9919 user: stephan tags: json
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/json.c.

843
844
845
846
847
848
849
850






851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
....
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
....
1183
1184
1185
1186
1187
1188
1189










1190
1191
1192
1193
1194
1195
1196
1197

1198
1199
1200
1201
1202



1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
....
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
....
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251

1252
1253
1254
1255
1256
1257

1258

1259
1260
1261
1262
1263
1264
1265
1266
1267
*/
cson_value * json_page_cap(void){
  cson_value * payload = cson_value_new_object();
  cson_value * sub = cson_value_new_object();
  char * zCap;
  Stmt q;
  cson_object * obj = cson_value_get_object(payload);
  if( g.zLogin ){






    cson_object_set( obj, "userName",
                     cson_value_new_string(g.zLogin,strlen(g.zLogin)) );
  }
  db_prepare(&q, "SELECT cap FROM user WHERE uid=%d", g.userUid);
  if( db_step(&q)==SQLITE_ROW ){
    char const * zCap = (char const *)sqlite3_column_text(q.pStmt,0);
    if( zCap ){
      cson_object_set( obj, "capabilities",
                       cson_value_new_string(zCap,strlen(zCap)) );
    }
  }
  db_finalize(&q);
  cson_object_set( obj, "permissionFlags", sub );
  obj = cson_value_get_object(sub);

#define ADD(X) cson_object_set(obj, #X, cson_value_new_bool(g.perm.X))
................................................................................
  cson_value * v = cson_value_new_object();
  cson_object * o = cson_value_get_object(v);
  unsigned const int seed = captcha_seed();
  char const * zCaptcha = captcha_decode(seed);
  cson_object_set(o, "seed",
                  cson_value_new_integer( (cson_int_t)seed )
                  );
  cson_object_set(o, "captcha",
                  cson_value_new_string( zCaptcha, strlen(zCaptcha) )
                  );
  return v;
}


/*
................................................................................
  db_finalize(&q);
  assert( NULL != jlist );
  rows = cson_object_take( cson_value_get_object(jlist), "rows" );
  assert( NULL != rows );
  cson_value_free( jlist );
  return rows;
}











/*
** Mapping of names to JSON pages/commands.  Each name is a subpath of
** /json (in CGI mode) or a subcommand of the json command in CLI mode
*/
static const JsonPageDef JsonPageDefs[] = {
/* please keep alphabetically sorted (case-insensitive) for maintenance reasons. */
{"anonymousPassword", json_page_anon_password, 1},

{"cap", json_page_cap, 0},
{"HAI",json_page_version,0},
{"login",json_page_login,1/*should be >0. Only 0 for dev/testing purposes.*/},
{"logout",json_page_logout,1/*should be >0. Only 0 for dev/testing purposes.*/},
{"stat",json_page_stat,0},



{"version",json_page_version,0},
{"wiki",json_page_wiki,0},
/* Last entry MUST have a NULL name. */
{NULL,NULL}
};

/*
** WEBPAGE: json
**
** Pages under /json/... must be entered into JsonPageDefs.
*/
................................................................................
  cson_value * root = NULL;
  JsonPageDef const * pageDef = NULL;
  json_mode_bootstrap();
  cmd = json_command_arg(1);
  /*cgi_printf("{\"cmd\":\"%s\"}\n",cmd); return;*/
  pageDef = json_handler_for_name(cmd,&JsonPageDefs[0]);
  if( ! pageDef ){
    json_err( FSL_JSON_E_UNKNOWN_COMMAND, cmd, 0 );
    return;
  }else if( pageDef->runMode < 0 /*CLI only*/){
    rc = FSL_JSON_E_WRONG_MODE;
  }else{
    rc = 0;
    payload = (*pageDef->func)();
  }
................................................................................
    cgi_set_content(&buf)/*takes ownership of the buf memory*/;
  }
}

/*
** COMMAND: json
**
** Usage: %fossil json subcommand
**
** The commands include:
**

**   stat
**   version (alias: HAI)
**
**
** TODOs:
**

**   wiki

**   timeline
**   tickets
**   ...
**
*/
void json_cmd_top(void){
  char const * cmd = NULL;
  int rc = 1002;
  cson_value * payload = NULL;







|
>
>
>
>
>
>
|
|
|
<
<
|
|

|







 







|







 







>
>
>
>
>
>
>
>
>
>







|
>


|
|

>
>
>



|







 







|







 







|



>






>
|
>

|







843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859


860
861
862
863
864
865
866
867
868
869
870
....
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
....
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
....
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
....
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
*/
cson_value * json_page_cap(void){
  cson_value * payload = cson_value_new_object();
  cson_value * sub = cson_value_new_object();
  char * zCap;
  Stmt q;
  cson_object * obj = cson_value_get_object(payload);
  db_prepare(&q, "SELECT login, cap FROM user WHERE uid=%d", g.userUid);
  if( db_step(&q)==SQLITE_ROW ){
    /* reminder: we don't use g.zLogin because it's 0 for the guest
       user and the HTML UI appears to currently allow the name to be
       changed (but doing so would break other code). */
    char const * str = (char const *)sqlite3_column_text(q.pStmt,0);
    if( str ){
      cson_object_set( obj, "userName",
                       cson_value_new_string(str,strlen(str)) );
    }


    str = (char const *)sqlite3_column_text(q.pStmt,1);
    if( str ){
      cson_object_set( obj, "capabilities",
                       cson_value_new_string(str,strlen(str)) );
    }
  }
  db_finalize(&q);
  cson_object_set( obj, "permissionFlags", sub );
  obj = cson_value_get_object(sub);

#define ADD(X) cson_object_set(obj, #X, cson_value_new_bool(g.perm.X))
................................................................................
  cson_value * v = cson_value_new_object();
  cson_object * o = cson_value_get_object(v);
  unsigned const int seed = captcha_seed();
  char const * zCaptcha = captcha_decode(seed);
  cson_object_set(o, "seed",
                  cson_value_new_integer( (cson_int_t)seed )
                  );
  cson_object_set(o, "password",
                  cson_value_new_string( zCaptcha, strlen(zCaptcha) )
                  );
  return v;
}


/*
................................................................................
  db_finalize(&q);
  assert( NULL != jlist );
  rows = cson_object_take( cson_value_get_object(jlist), "rows" );
  assert( NULL != rows );
  cson_value_free( jlist );
  return rows;
}

/*
** Placeholder /json/XXX page impl for NYI (Not Yet Implemented)
** (but planned) pages/commands.
*/
static cson_value * json_page_nyi(void){
  g.json.resultCode = FSL_JSON_E_NYI;
  return NULL;
}


/*
** Mapping of names to JSON pages/commands.  Each name is a subpath of
** /json (in CGI mode) or a subcommand of the json command in CLI mode
*/
static const JsonPageDef JsonPageDefs[] = {
/* please keep alphabetically sorted (case-insensitive) for maintenance reasons. */
{"anonymousPassword",json_page_anon_password, 1},
{"branch", json_page_nyi,0},
{"cap", json_page_cap, 0},
{"HAI",json_page_version,0},
{"login",json_page_login,1},
{"logout",json_page_logout,1},
{"stat",json_page_stat,0},
{"tag", json_page_nyi,0},
{"ticket", json_page_nyi,0},
{"user", json_page_nyi,0},
{"version",json_page_version,0},
{"wiki",json_page_wiki,0},
/* Last entry MUST have a NULL name. */
{NULL,NULL,0}
};

/*
** WEBPAGE: json
**
** Pages under /json/... must be entered into JsonPageDefs.
*/
................................................................................
  cson_value * root = NULL;
  JsonPageDef const * pageDef = NULL;
  json_mode_bootstrap();
  cmd = json_command_arg(1);
  /*cgi_printf("{\"cmd\":\"%s\"}\n",cmd); return;*/
  pageDef = json_handler_for_name(cmd,&JsonPageDefs[0]);
  if( ! pageDef ){
    json_err( FSL_JSON_E_UNKNOWN_COMMAND, NULL, 0 );
    return;
  }else if( pageDef->runMode < 0 /*CLI only*/){
    rc = FSL_JSON_E_WRONG_MODE;
  }else{
    rc = 0;
    payload = (*pageDef->func)();
  }
................................................................................
    cgi_set_content(&buf)/*takes ownership of the buf memory*/;
  }
}

/*
** COMMAND: json
**
** Usage: %fossil json SUBCOMMAND
**
** The commands include:
**
**   cap
**   stat
**   version (alias: HAI)
**
**
** TODOs:
**
**   branch
**   tag
**   ticket
**   timeline
**   wiki
**   ...
**
*/
void json_cmd_top(void){
  char const * cmd = NULL;
  int rc = 1002;
  cson_value * payload = NULL;