Fossil

Check-in [388c9888]
Login

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

Overview
Comment:Added some code for dumbing-down only the different login errors (missing name, missing pw, or no match found). Defaults to dumbed-down mode.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | json
Files: files | file ages | folders
SHA1: 388c9888afe93db29790f65580d6b1e0a2e6835a
User & Date: stephan 2011-09-16 23:29:13.601
Context
2011-09-17
01:25
dropped back to a simpler timestamp generation mechanism. Thanks to Ge Weijers for the input. ... (check-in: 147f4bfb user: stephan tags: json)
2011-09-16
23:29
Added some code for dumbing-down only the different login errors (missing name, missing pw, or no match found). Defaults to dumbed-down mode. ... (check-in: 388c9888 user: stephan tags: json)
23:06
worked around a weird cgi_parameter() bug. We are now not processing the name/password params with the precedence i would like, but it works now in server/cgi modes with GET and POST. ... (check-in: b0885e86 user: stephan tags: json)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/json.c.
41
42
43
44
45
46
47

48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
** and error codes for a given category have their
** high bits set to the category value.
**
*/
enum FossilJsonCodes {

FSL_JSON_E_GENERIC = 1000,

FSL_JSON_E_INVALID_REQUEST = FSL_JSON_E_GENERIC + 1,
FSL_JSON_E_UNKNOWN_COMMAND = FSL_JSON_E_GENERIC + 2,
FSL_JSON_E_UNKNOWN = FSL_JSON_E_GENERIC + 3,
FSL_JSON_E_RESOURCE_NOT_FOUND = FSL_JSON_E_GENERIC + 4,
FSL_JSON_E_TIMEOUT = FSL_JSON_E_GENERIC + 5,
FSL_JSON_E_ASSERT = FSL_JSON_E_GENERIC + 6,
FSL_JSON_E_ALLOC = FSL_JSON_E_GENERIC + 7,
FSL_JSON_E_NYI = FSL_JSON_E_GENERIC + 8,

FSL_JSON_E_AUTH = 2000,
FSL_JSON_E_MISSING_AUTH = FSL_JSON_E_AUTH + 2,
FSL_JSON_E_DENIED = FSL_JSON_E_AUTH + 3,
FSL_JSON_E_WRONG_MODE = FSL_JSON_E_AUTH + 4,

FSL_JSON_E_LOGIN_FAILED = FSL_JSON_E_AUTH + 100,







>
|
|
|
|
|
|
|
|







41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
** and error codes for a given category have their
** high bits set to the category value.
**
*/
enum FossilJsonCodes {

FSL_JSON_E_GENERIC = 1000,
FSL_JSON_E_GENERIC_SUB1 = FSL_JSON_E_GENERIC + 100,
FSL_JSON_E_INVALID_REQUEST = FSL_JSON_E_GENERIC_SUB1 + 1,
FSL_JSON_E_UNKNOWN_COMMAND = FSL_JSON_E_GENERIC_SUB1 + 2,
FSL_JSON_E_UNKNOWN = FSL_JSON_E_GENERIC_SUB1 + 3,
FSL_JSON_E_RESOURCE_NOT_FOUND = FSL_JSON_E_GENERIC_SUB1 + 4,
FSL_JSON_E_TIMEOUT = FSL_JSON_E_GENERIC_SUB1 + 5,
FSL_JSON_E_ASSERT = FSL_JSON_E_GENERIC_SUB1 + 6,
FSL_JSON_E_ALLOC = FSL_JSON_E_GENERIC_SUB1 + 7,
FSL_JSON_E_NYI = FSL_JSON_E_GENERIC_SUB1 + 8,

FSL_JSON_E_AUTH = 2000,
FSL_JSON_E_MISSING_AUTH = FSL_JSON_E_AUTH + 2,
FSL_JSON_E_DENIED = FSL_JSON_E_AUTH + 3,
FSL_JSON_E_WRONG_MODE = FSL_JSON_E_AUTH + 4,

FSL_JSON_E_LOGIN_FAILED = FSL_JSON_E_AUTH + 100,
555
556
557
558
559
560
561



562
563
564
565
566
567
568

  tmp = cson_value_new_string(MANIFEST_UUID,strlen(MANIFEST_UUID));
  SET("fossil");
 
  {/* "timestamp" */
    cson_int_t jsTime;
#if 1



    time_t const t = (time_t)time(0);
    struct tm gt = *gmtime(&t);
    gt.tm_isdst = -1;
    jsTime = (cson_int_t)mktime(&gt);
#else
    /* i'm not 100% sure that the above actually does what i expect,
       but we can't use the following because this function can be







>
>
>







556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572

  tmp = cson_value_new_string(MANIFEST_UUID,strlen(MANIFEST_UUID));
  SET("fossil");
 
  {/* "timestamp" */
    cson_int_t jsTime;
#if 1
    /* Ge Weijers has pointed out that time(0) commonly returns
       GMT, but is not required to by the standard.
    */
    time_t const t = (time_t)time(0);
    struct tm gt = *gmtime(&t);
    gt.tm_isdst = -1;
    jsTime = (cson_int_t)mktime(&gt);
#else
    /* i'm not 100% sure that the above actually does what i expect,
       but we can't use the following because this function can be
763
764
765
766
767
768
769







770
771
772
773
774
775
776
**
** - more testing with ONLY the JSON-specified authToken
** (no cookie). In theory that works but we don't yet have
** a non-browser client to play with.
**
*/
cson_value * json_page_login(void){







  /*
    FIXME: we want to check the GET/POST args in this order:

    - GET: name, n, password, p
    - POST: name, password

    but a bug in cgi_parameter() is breaking that, causing PD() to







>
>
>
>
>
>
>







767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
**
** - more testing with ONLY the JSON-specified authToken
** (no cookie). In theory that works but we don't yet have
** a non-browser client to play with.
**
*/
cson_value * json_page_login(void){
  static char preciseErrors =
#if 0
    g.json.errorDetailParanoia ? 0 : 1
#else
    0
#endif
    ;
  /*
    FIXME: we want to check the GET/POST args in this order:

    - GET: name, n, password, p
    - POST: name, password

    but a bug in cgi_parameter() is breaking that, causing PD() to
785
786
787
788
789
790
791

792

793
794
795
796
797
798
799
800
801
802
803
804
805

806

807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822

823

824
825
826
827
828
829
830
  char const * name = cson_value_get_cstr(json_payload_property("name"));
  char const * pw = NULL;
  if( !name ){
    name = PD("n",NULL);
    if( !name ){
      name = PD("name",NULL);
      if( !name ){

        g.json.resultCode = FSL_JSON_E_LOGIN_FAILED_NONAME;

        return NULL;
      }
    }
  }

  pw = cson_value_get_cstr(json_payload_property("password"));
  if( !pw ){
    pw = PD("p",NULL);
    if( !pw ){
      pw = PD("password",NULL);
    }
  }
  if(!pw){

    g.json.resultCode = FSL_JSON_E_LOGIN_FAILED_NOPW;

    return NULL;
  }else{
    cson_value * payload = NULL;
    int uid = 0;
#if 0
    /* only for debugging the PD()-incorrect-result problem */
    cson_object * o = NULL;
    uid = login_search_uid( name, pw );
    payload = cson_value_new_object();
    o = cson_value_get_object(payload);
    cson_object_set( o, "n", cson_value_new_string(name,strlen(name)));
    cson_object_set( o, "p", cson_value_new_string(pw,strlen(pw)));
    return payload;
#else
    uid = login_search_uid( name, pw );
    if( !uid ){

      g.json.resultCode = FSL_JSON_E_LOGIN_FAILED_NOTFOUND;

    }else{
      char * cookie = NULL;
      login_set_user_cookie(name, uid, &cookie);
      payload = cson_value_new_string( cookie, strlen(cookie) );
      free(cookie);
    }
    return payload;







>
|
>













>
|
>
















>
|
>







796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
  char const * name = cson_value_get_cstr(json_payload_property("name"));
  char const * pw = NULL;
  if( !name ){
    name = PD("n",NULL);
    if( !name ){
      name = PD("name",NULL);
      if( !name ){
        g.json.resultCode = preciseErrors
          ? FSL_JSON_E_LOGIN_FAILED_NONAME
          : FSL_JSON_E_LOGIN_FAILED;
        return NULL;
      }
    }
  }

  pw = cson_value_get_cstr(json_payload_property("password"));
  if( !pw ){
    pw = PD("p",NULL);
    if( !pw ){
      pw = PD("password",NULL);
    }
  }
  if(!pw){
    g.json.resultCode = preciseErrors
      ? FSL_JSON_E_LOGIN_FAILED_NOPW
      : FSL_JSON_E_LOGIN_FAILED;
    return NULL;
  }else{
    cson_value * payload = NULL;
    int uid = 0;
#if 0
    /* only for debugging the PD()-incorrect-result problem */
    cson_object * o = NULL;
    uid = login_search_uid( name, pw );
    payload = cson_value_new_object();
    o = cson_value_get_object(payload);
    cson_object_set( o, "n", cson_value_new_string(name,strlen(name)));
    cson_object_set( o, "p", cson_value_new_string(pw,strlen(pw)));
    return payload;
#else
    uid = login_search_uid( name, pw );
    if( !uid ){
      g.json.resultCode = preciseErrors
        ? FSL_JSON_E_LOGIN_FAILED_NOTFOUND
        : FSL_JSON_E_LOGIN_FAILED;
    }else{
      char * cookie = NULL;
      login_set_user_cookie(name, uid, &cookie);
      payload = cson_value_new_string( cookie, strlen(cookie) );
      free(cookie);
    }
    return payload;
Changes to src/main.c.
277
278
279
280
281
282
283






284

285
286
287
288
289
290
291
  int i;

  sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0);
  memset(&g, 0, sizeof(g));
  g.now = time(0);
  g.argc = argc;
  g.argv = argv;






  g.json.errorDetailParanoia = 0 /* FIXME: make configurable */;

  g.json.cgiCx = cson_cgi_cx_empty;
  g.json.outOpt = cson_output_opt_empty;
  g.json.outOpt.addNewline = 1;
  g.json.outOpt.indentation = 1 /* FIXME: make configurable */;
  for(i=0; i<argc; i++) g.argv[i] = fossil_mbcs_to_utf8(argv[i]);
  if( getenv("GATEWAY_INTERFACE")!=0 && !find_option("nocgi", 0, 0)){
    zCmdName = "cgi";







>
>
>
>
>
>
|
>







277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
  int i;

  sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0);
  memset(&g, 0, sizeof(g));
  g.now = time(0);
  g.argc = argc;
  g.argv = argv;
#if defined(NDEBUG)
  g.json.errorDetailParanoia = 2 /* FIXME: make configurable
                                    One problem we have here is that this
                                    code is needed before the db is opened,
                                    so we can't sql for it.*/;
#else
  g.json.errorDetailParanoia = 0;
#endif
  g.json.cgiCx = cson_cgi_cx_empty;
  g.json.outOpt = cson_output_opt_empty;
  g.json.outOpt.addNewline = 1;
  g.json.outOpt.indentation = 1 /* FIXME: make configurable */;
  for(i=0; i<argc; i++) g.argv[i] = fossil_mbcs_to_utf8(argv[i]);
  if( getenv("GATEWAY_INTERFACE")!=0 && !find_option("nocgi", 0, 0)){
    zCmdName = "cgi";