Fossil

Check-in [b0885e86]
Login

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

Overview
Comment: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.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | json
Files: files | file ages | folders
SHA1: b0885e864c3a4f9242a11cb139ef4642499b4cd2
User & Date: stephan 2011-09-16 23:06:42.951
Context
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)
21:39
restructured /json/cap output. ... (check-in: 7e3902d1 user: stephan tags: json)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/json.c.
51
52
53
54
55
56
57
58
59
60
61
62




63
64
65
66
67
68
69
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_LOGIN_FAILED = FSL_JSON_E_AUTH + 1,
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_USAGE = 3000,
FSL_JSON_E_INVALID_ARGS = FSL_JSON_E_USAGE + 1,
FSL_JSON_E_MISSING_ARGS = FSL_JSON_E_USAGE + 2,

FSL_JSON_E_DB = 4000,
FSL_JSON_E_STMT_PREP = FSL_JSON_E_DB + 1,







<




>
>
>
>







51
52
53
54
55
56
57

58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
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,
FSL_JSON_E_LOGIN_FAILED_NONAME = FSL_JSON_E_LOGIN_FAILED + 1,
FSL_JSON_E_LOGIN_FAILED_NOPW = FSL_JSON_E_LOGIN_FAILED + 2,
FSL_JSON_E_LOGIN_FAILED_NOTFOUND = FSL_JSON_E_LOGIN_FAILED + 3,

FSL_JSON_E_USAGE = 3000,
FSL_JSON_E_INVALID_ARGS = FSL_JSON_E_USAGE + 1,
FSL_JSON_E_MISSING_ARGS = FSL_JSON_E_USAGE + 2,

FSL_JSON_E_DB = 4000,
FSL_JSON_E_STMT_PREP = FSL_JSON_E_DB + 1,
101
102
103
104
105
106
107



108
109
110
111
112
113
114
    C(RESOURCE_NOT_FOUND,"Resource not found");
    C(TIMEOUT,"Timeout reached");
    C(ASSERT,"Assertion failed");
    C(ALLOC,"Resource allocation failed");
    C(NYI,"Not yet implemented.");
    C(AUTH,"Authentication error");
    C(LOGIN_FAILED,"Login failed");



    C(MISSING_AUTH,"Authentication info missing from request");
    C(DENIED,"Access denied");
    C(WRONG_MODE,"Request not allowed (wrong operation mode)");

    C(USAGE,"Usage error");
    C(INVALID_ARGS,"Invalid arguments");
    C(MISSING_ARGS,"Missing arguments");







>
>
>







104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
    C(RESOURCE_NOT_FOUND,"Resource not found");
    C(TIMEOUT,"Timeout reached");
    C(ASSERT,"Assertion failed");
    C(ALLOC,"Resource allocation failed");
    C(NYI,"Not yet implemented.");
    C(AUTH,"Authentication error");
    C(LOGIN_FAILED,"Login failed");
    C(LOGIN_FAILED_NONAME,"Login failed - name not supplied");
    C(LOGIN_FAILED_NOPW,"Login failed - password not supplied");
    C(LOGIN_FAILED_NOTFOUND,"Login failed - no match found");
    C(MISSING_AUTH,"Authentication info missing from request");
    C(DENIED,"Access denied");
    C(WRONG_MODE,"Request not allowed (wrong operation mode)");

    C(USAGE,"Usage error");
    C(INVALID_ARGS,"Invalid arguments");
    C(MISSING_ARGS,"Missing arguments");
497
498
499
500
501
502
503






504
505
506
507
508
509
510
      default: break;
    }
    if( modulo ) code = code - (code % modulo);
    return code;
  }
}







/*
** Creates a new Fossil/REST response envelope skeleton.  It is owned
** by the caller, who must eventually free it using cson_value_free(),
** or add it to a cson container to transfer ownership. Returns NULL
** on error.
**
** If payload is not NULL and resultCode is 0 then it is set as the







>
>
>
>
>
>







503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
      default: break;
    }
    if( modulo ) code = code - (code % modulo);
    return code;
  }
}

#if 0
static unsigned int json_timestamp(){

}
#endif

/*
** Creates a new Fossil/REST response envelope skeleton.  It is owned
** by the caller, who must eventually free it using cson_value_free(),
** or add it to a cson container to transfer ownership. Returns NULL
** on error.
**
** If payload is not NULL and resultCode is 0 then it is set as the
662
663
664
665
666
667
668




669
670
671
672
673


674



675
676
677
678
679
680
681
  FSET(RELEASE_VERSION,"releaseVersion");
#undef FSET
  cson_object_set( jobj, "releaseVersionNumber",
                   cson_value_new_integer(RELEASE_VERSION_NUMBER) );
  return jval;
}





static cson_value * json_getenv( char const *zWhichEnv, char const * zKey ){
  return cson_cgi_getenv(&g.json.cgiCx, zWhichEnv, zKey);
}
static char const * json_getenv_cstr( char const *zWhichEnv, char const * zKey ){
  return cson_value_get_cstr( json_getenv(zWhichEnv, zKey) );


}




/*
** Implementation for /json/cap
**
** Returned object contains details about the "capabilities" of the
** current user (what he may/may not do).
**







>
>
>
>




|
>
>
|
>
>
>







674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
  FSET(RELEASE_VERSION,"releaseVersion");
#undef FSET
  cson_object_set( jobj, "releaseVersionNumber",
                   cson_value_new_integer(RELEASE_VERSION_NUMBER) );
  return jval;
}

#if 0
/* we have a disconnect here between fossil's server-mode QUERY_STRING
   handling and cson_cgi's.
*/
static cson_value * json_getenv( char const *zWhichEnv, char const * zKey ){
  return cson_cgi_getenv(&g.json.cgiCx, zWhichEnv, zKey);
}
static char const * json_getenv_cstr( char const *zWhichEnv, char const * zKey ){
  char const * rc = cson_value_get_cstr( json_getenv(zWhichEnv, zKey) );
  if( !rc && zWhichEnv && (NULL!=strstr(zWhichEnv,"g")) ){
    rc = PD(zKey,NULL);
  }
  return rc;
}
#endif

/*
** Implementation for /json/cap
**
** Returned object contains details about the "capabilities" of the
** current user (what he may/may not do).
**
736
737
738
739
740
741
742
743



744
745


746
747
748
749
750

751
752








753
754
755
756
757
758
759
760
761
762
763


764
765
766
767
768
769
770
771
772
773
774
775

776





777
778







779
780
781
782
783
784
785
786
787


788
789
790
791
792
793
794
**
** NOT YET FINSIHED!
** TODOs:
**
** - anonymous user login (requires separate handling
** due to random password).
**
** - more testing



*/
cson_value * json_page_login(void){


  char const * name = cson_value_get_cstr(json_payload_property("name"));
  char const * pw;
  cson_value * payload = NULL;
  /*cson_object * pObj;*/
  int uid = 0;

  /*return cson_cgi_env_get_val(&g.json.cgiCx,'g',0);*/
  








  if( !name ){
    name = json_getenv_cstr( "g", "name" )
      /* When i use P("n") i'm not getting the result i expect! */
      ;
    if( !name ){
      name = json_getenv_cstr( "g", "n" );
    }
  }
  if( !name ){
    g.json.resultCode = FSL_JSON_E_LOGIN_FAILED;
    return NULL;


  }

  pw = cson_value_get_cstr(json_payload_property("password"));
  if( !pw ){
    pw = json_getenv_cstr( "g", "password" );
    if( !pw ){
      pw = json_getenv_cstr( "g", "p" );
    }
  }

  if(!pw){
    g.json.resultCode = FSL_JSON_E_LOGIN_FAILED;

  }else{





    uid = login_search_uid( name, pw );
  }







  if( !uid ){
    g.json.resultCode = 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;


}

/*
** Impl of /json/logout.
**
** Shortcomings: this never reports failure, as we don't go through
** the trouble of actually checking whether the user is logged in or







|
>
>
>


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

|
<
<

|
<
<
|
|
|
>
>




|

|


<

|
>

>
>
>
>
>

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







757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775

776
777
778
779
780
781
782
783
784
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
831
832
833
834
835
836
837
838
839
**
** NOT YET FINSIHED!
** TODOs:
**
** - anonymous user login (requires separate handling
** due to random password).
**
** - 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
    return the last element of the PATH_INFO instead.

    Summary: If we check for P("name") first, then P("n"),
    then ONLY a GET param of "name" will match ("n"
    is not recognized). If we reverse the order of the
    checks then both forms work. Strangely enough, the
    "p"/"password" check is not affected by this.
   */
  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;
#endif
  }
}

/*
** Impl of /json/logout.
**
** Shortcomings: this never reports failure, as we don't go through
** the trouble of actually checking whether the user is logged in or