Fossil SCM

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.

stephan 2011-09-16 23:06 UTC json
Commit b0885e864c3a4f9242a11cb139ef4642499b4cd2
1 file changed +86 -41
+86 -41
--- src/json.c
+++ src/json.c
@@ -53,15 +53,18 @@
5353
FSL_JSON_E_ASSERT = FSL_JSON_E_GENERIC + 6,
5454
FSL_JSON_E_ALLOC = FSL_JSON_E_GENERIC + 7,
5555
FSL_JSON_E_NYI = FSL_JSON_E_GENERIC + 8,
5656
5757
FSL_JSON_E_AUTH = 2000,
58
-FSL_JSON_E_LOGIN_FAILED = FSL_JSON_E_AUTH + 1,
5958
FSL_JSON_E_MISSING_AUTH = FSL_JSON_E_AUTH + 2,
6059
FSL_JSON_E_DENIED = FSL_JSON_E_AUTH + 3,
6160
FSL_JSON_E_WRONG_MODE = FSL_JSON_E_AUTH + 4,
6261
62
+FSL_JSON_E_LOGIN_FAILED = FSL_JSON_E_AUTH + 100,
63
+FSL_JSON_E_LOGIN_FAILED_NONAME = FSL_JSON_E_LOGIN_FAILED + 1,
64
+FSL_JSON_E_LOGIN_FAILED_NOPW = FSL_JSON_E_LOGIN_FAILED + 2,
65
+FSL_JSON_E_LOGIN_FAILED_NOTFOUND = FSL_JSON_E_LOGIN_FAILED + 3,
6366
6467
FSL_JSON_E_USAGE = 3000,
6568
FSL_JSON_E_INVALID_ARGS = FSL_JSON_E_USAGE + 1,
6669
FSL_JSON_E_MISSING_ARGS = FSL_JSON_E_USAGE + 2,
6770
@@ -103,10 +106,13 @@
103106
C(ASSERT,"Assertion failed");
104107
C(ALLOC,"Resource allocation failed");
105108
C(NYI,"Not yet implemented.");
106109
C(AUTH,"Authentication error");
107110
C(LOGIN_FAILED,"Login failed");
111
+ C(LOGIN_FAILED_NONAME,"Login failed - name not supplied");
112
+ C(LOGIN_FAILED_NOPW,"Login failed - password not supplied");
113
+ C(LOGIN_FAILED_NOTFOUND,"Login failed - no match found");
108114
C(MISSING_AUTH,"Authentication info missing from request");
109115
C(DENIED,"Access denied");
110116
C(WRONG_MODE,"Request not allowed (wrong operation mode)");
111117
112118
C(USAGE,"Usage error");
@@ -499,10 +505,16 @@
499505
if( modulo ) code = code - (code % modulo);
500506
return code;
501507
}
502508
}
503509
510
+#if 0
511
+static unsigned int json_timestamp(){
512
+
513
+}
514
+#endif
515
+
504516
/*
505517
** Creates a new Fossil/REST response envelope skeleton. It is owned
506518
** by the caller, who must eventually free it using cson_value_free(),
507519
** or add it to a cson container to transfer ownership. Returns NULL
508520
** on error.
@@ -664,16 +676,25 @@
664676
cson_object_set( jobj, "releaseVersionNumber",
665677
cson_value_new_integer(RELEASE_VERSION_NUMBER) );
666678
return jval;
667679
}
668680
681
+#if 0
682
+/* we have a disconnect here between fossil's server-mode QUERY_STRING
683
+ handling and cson_cgi's.
684
+*/
669685
static cson_value * json_getenv( char const *zWhichEnv, char const * zKey ){
670686
return cson_cgi_getenv(&g.json.cgiCx, zWhichEnv, zKey);
671687
}
672688
static char const * json_getenv_cstr( char const *zWhichEnv, char const * zKey ){
673
- return cson_value_get_cstr( json_getenv(zWhichEnv, zKey) );
689
+ char const * rc = cson_value_get_cstr( json_getenv(zWhichEnv, zKey) );
690
+ if( !rc && zWhichEnv && (NULL!=strstr(zWhichEnv,"g")) ){
691
+ rc = PD(zKey,NULL);
692
+ }
693
+ return rc;
674694
}
695
+#endif
675696
676697
/*
677698
** Implementation for /json/cap
678699
**
679700
** Returned object contains details about the "capabilities" of the
@@ -738,55 +759,79 @@
738759
** TODOs:
739760
**
740761
** - anonymous user login (requires separate handling
741762
** due to random password).
742763
**
743
-** - more testing
764
+** - more testing with ONLY the JSON-specified authToken
765
+** (no cookie). In theory that works but we don't yet have
766
+** a non-browser client to play with.
767
+**
744768
*/
745769
cson_value * json_page_login(void){
746
- char const * name = cson_value_get_cstr(json_payload_property("name"));
747
- char const * pw;
748
- cson_value * payload = NULL;
749
- /*cson_object * pObj;*/
750
- int uid = 0;
751
- /*return cson_cgi_env_get_val(&g.json.cgiCx,'g',0);*/
752
-
753
- if( !name ){
754
- name = json_getenv_cstr( "g", "name" )
755
- /* When i use P("n") i'm not getting the result i expect! */
756
- ;
757
- if( !name ){
758
- name = json_getenv_cstr( "g", "n" );
759
- }
760
- }
761
- if( !name ){
762
- g.json.resultCode = FSL_JSON_E_LOGIN_FAILED;
763
- return NULL;
770
+ /*
771
+ FIXME: we want to check the GET/POST args in this order:
772
+
773
+ - GET: name, n, password, p
774
+ - POST: name, password
775
+
776
+ but a bug in cgi_parameter() is breaking that, causing PD() to
777
+ return the last element of the PATH_INFO instead.
778
+
779
+ Summary: If we check for P("name") first, then P("n"),
780
+ then ONLY a GET param of "name" will match ("n"
781
+ is not recognized). If we reverse the order of the
782
+ checks then both forms work. Strangely enough, the
783
+ "p"/"password" check is not affected by this.
784
+ */
785
+ char const * name = cson_value_get_cstr(json_payload_property("name"));
786
+ char const * pw = NULL;
787
+ if( !name ){
788
+ name = PD("n",NULL);
789
+ if( !name ){
790
+ name = PD("name",NULL);
791
+ if( !name ){
792
+ g.json.resultCode = FSL_JSON_E_LOGIN_FAILED_NONAME;
793
+ return NULL;
794
+ }
795
+ }
764796
}
765797
766798
pw = cson_value_get_cstr(json_payload_property("password"));
767799
if( !pw ){
768
- pw = json_getenv_cstr( "g", "password" );
769
- if( !pw ){
770
- pw = json_getenv_cstr( "g", "p" );
771
- }
772
- }
773
-
774
- if(!pw){
775
- g.json.resultCode = FSL_JSON_E_LOGIN_FAILED;
776
- }else{
777
- uid = login_search_uid( name, pw );
778
- }
779
- if( !uid ){
780
- g.json.resultCode = FSL_JSON_E_LOGIN_FAILED;
781
- }else{
782
- char * cookie = NULL;
783
- login_set_user_cookie(name, uid, &cookie);
784
- payload = cson_value_new_string( cookie, strlen(cookie) );
785
- free(cookie);
786
- }
787
- return payload;
800
+ pw = PD("p",NULL);
801
+ if( !pw ){
802
+ pw = PD("password",NULL);
803
+ }
804
+ }
805
+ if(!pw){
806
+ g.json.resultCode = FSL_JSON_E_LOGIN_FAILED_NOPW;
807
+ return NULL;
808
+ }else{
809
+ cson_value * payload = NULL;
810
+ int uid = 0;
811
+#if 0
812
+ /* only for debugging the PD()-incorrect-result problem */
813
+ cson_object * o = NULL;
814
+ uid = login_search_uid( name, pw );
815
+ payload = cson_value_new_object();
816
+ o = cson_value_get_object(payload);
817
+ cson_object_set( o, "n", cson_value_new_string(name,strlen(name)));
818
+ cson_object_set( o, "p", cson_value_new_string(pw,strlen(pw)));
819
+ return payload;
820
+#else
821
+ uid = login_search_uid( name, pw );
822
+ if( !uid ){
823
+ g.json.resultCode = FSL_JSON_E_LOGIN_FAILED_NOTFOUND;
824
+ }else{
825
+ char * cookie = NULL;
826
+ login_set_user_cookie(name, uid, &cookie);
827
+ payload = cson_value_new_string( cookie, strlen(cookie) );
828
+ free(cookie);
829
+ }
830
+ return payload;
831
+#endif
832
+ }
788833
}
789834
790835
/*
791836
** Impl of /json/logout.
792837
**
793838
--- src/json.c
+++ src/json.c
@@ -53,15 +53,18 @@
53 FSL_JSON_E_ASSERT = FSL_JSON_E_GENERIC + 6,
54 FSL_JSON_E_ALLOC = FSL_JSON_E_GENERIC + 7,
55 FSL_JSON_E_NYI = FSL_JSON_E_GENERIC + 8,
56
57 FSL_JSON_E_AUTH = 2000,
58 FSL_JSON_E_LOGIN_FAILED = FSL_JSON_E_AUTH + 1,
59 FSL_JSON_E_MISSING_AUTH = FSL_JSON_E_AUTH + 2,
60 FSL_JSON_E_DENIED = FSL_JSON_E_AUTH + 3,
61 FSL_JSON_E_WRONG_MODE = FSL_JSON_E_AUTH + 4,
62
 
 
 
 
63
64 FSL_JSON_E_USAGE = 3000,
65 FSL_JSON_E_INVALID_ARGS = FSL_JSON_E_USAGE + 1,
66 FSL_JSON_E_MISSING_ARGS = FSL_JSON_E_USAGE + 2,
67
@@ -103,10 +106,13 @@
103 C(ASSERT,"Assertion failed");
104 C(ALLOC,"Resource allocation failed");
105 C(NYI,"Not yet implemented.");
106 C(AUTH,"Authentication error");
107 C(LOGIN_FAILED,"Login failed");
 
 
 
108 C(MISSING_AUTH,"Authentication info missing from request");
109 C(DENIED,"Access denied");
110 C(WRONG_MODE,"Request not allowed (wrong operation mode)");
111
112 C(USAGE,"Usage error");
@@ -499,10 +505,16 @@
499 if( modulo ) code = code - (code % modulo);
500 return code;
501 }
502 }
503
 
 
 
 
 
 
504 /*
505 ** Creates a new Fossil/REST response envelope skeleton. It is owned
506 ** by the caller, who must eventually free it using cson_value_free(),
507 ** or add it to a cson container to transfer ownership. Returns NULL
508 ** on error.
@@ -664,16 +676,25 @@
664 cson_object_set( jobj, "releaseVersionNumber",
665 cson_value_new_integer(RELEASE_VERSION_NUMBER) );
666 return jval;
667 }
668
 
 
 
 
669 static cson_value * json_getenv( char const *zWhichEnv, char const * zKey ){
670 return cson_cgi_getenv(&g.json.cgiCx, zWhichEnv, zKey);
671 }
672 static char const * json_getenv_cstr( char const *zWhichEnv, char const * zKey ){
673 return cson_value_get_cstr( json_getenv(zWhichEnv, zKey) );
 
 
 
 
674 }
 
675
676 /*
677 ** Implementation for /json/cap
678 **
679 ** Returned object contains details about the "capabilities" of the
@@ -738,55 +759,79 @@
738 ** TODOs:
739 **
740 ** - anonymous user login (requires separate handling
741 ** due to random password).
742 **
743 ** - more testing
 
 
 
744 */
745 cson_value * json_page_login(void){
746 char const * name = cson_value_get_cstr(json_payload_property("name"));
747 char const * pw;
748 cson_value * payload = NULL;
749 /*cson_object * pObj;*/
750 int uid = 0;
751 /*return cson_cgi_env_get_val(&g.json.cgiCx,'g',0);*/
752
753 if( !name ){
754 name = json_getenv_cstr( "g", "name" )
755 /* When i use P("n") i'm not getting the result i expect! */
756 ;
757 if( !name ){
758 name = json_getenv_cstr( "g", "n" );
759 }
760 }
761 if( !name ){
762 g.json.resultCode = FSL_JSON_E_LOGIN_FAILED;
763 return NULL;
 
 
 
 
 
 
 
 
764 }
765
766 pw = cson_value_get_cstr(json_payload_property("password"));
767 if( !pw ){
768 pw = json_getenv_cstr( "g", "password" );
769 if( !pw ){
770 pw = json_getenv_cstr( "g", "p" );
771 }
772 }
773
774 if(!pw){
775 g.json.resultCode = FSL_JSON_E_LOGIN_FAILED;
776 }else{
777 uid = login_search_uid( name, pw );
778 }
779 if( !uid ){
780 g.json.resultCode = FSL_JSON_E_LOGIN_FAILED;
781 }else{
782 char * cookie = NULL;
783 login_set_user_cookie(name, uid, &cookie);
784 payload = cson_value_new_string( cookie, strlen(cookie) );
785 free(cookie);
786 }
787 return payload;
 
 
 
 
 
 
 
 
 
 
 
 
 
788 }
789
790 /*
791 ** Impl of /json/logout.
792 **
793
--- src/json.c
+++ src/json.c
@@ -53,15 +53,18 @@
53 FSL_JSON_E_ASSERT = FSL_JSON_E_GENERIC + 6,
54 FSL_JSON_E_ALLOC = FSL_JSON_E_GENERIC + 7,
55 FSL_JSON_E_NYI = FSL_JSON_E_GENERIC + 8,
56
57 FSL_JSON_E_AUTH = 2000,
 
58 FSL_JSON_E_MISSING_AUTH = FSL_JSON_E_AUTH + 2,
59 FSL_JSON_E_DENIED = FSL_JSON_E_AUTH + 3,
60 FSL_JSON_E_WRONG_MODE = FSL_JSON_E_AUTH + 4,
61
62 FSL_JSON_E_LOGIN_FAILED = FSL_JSON_E_AUTH + 100,
63 FSL_JSON_E_LOGIN_FAILED_NONAME = FSL_JSON_E_LOGIN_FAILED + 1,
64 FSL_JSON_E_LOGIN_FAILED_NOPW = FSL_JSON_E_LOGIN_FAILED + 2,
65 FSL_JSON_E_LOGIN_FAILED_NOTFOUND = FSL_JSON_E_LOGIN_FAILED + 3,
66
67 FSL_JSON_E_USAGE = 3000,
68 FSL_JSON_E_INVALID_ARGS = FSL_JSON_E_USAGE + 1,
69 FSL_JSON_E_MISSING_ARGS = FSL_JSON_E_USAGE + 2,
70
@@ -103,10 +106,13 @@
106 C(ASSERT,"Assertion failed");
107 C(ALLOC,"Resource allocation failed");
108 C(NYI,"Not yet implemented.");
109 C(AUTH,"Authentication error");
110 C(LOGIN_FAILED,"Login failed");
111 C(LOGIN_FAILED_NONAME,"Login failed - name not supplied");
112 C(LOGIN_FAILED_NOPW,"Login failed - password not supplied");
113 C(LOGIN_FAILED_NOTFOUND,"Login failed - no match found");
114 C(MISSING_AUTH,"Authentication info missing from request");
115 C(DENIED,"Access denied");
116 C(WRONG_MODE,"Request not allowed (wrong operation mode)");
117
118 C(USAGE,"Usage error");
@@ -499,10 +505,16 @@
505 if( modulo ) code = code - (code % modulo);
506 return code;
507 }
508 }
509
510 #if 0
511 static unsigned int json_timestamp(){
512
513 }
514 #endif
515
516 /*
517 ** Creates a new Fossil/REST response envelope skeleton. It is owned
518 ** by the caller, who must eventually free it using cson_value_free(),
519 ** or add it to a cson container to transfer ownership. Returns NULL
520 ** on error.
@@ -664,16 +676,25 @@
676 cson_object_set( jobj, "releaseVersionNumber",
677 cson_value_new_integer(RELEASE_VERSION_NUMBER) );
678 return jval;
679 }
680
681 #if 0
682 /* we have a disconnect here between fossil's server-mode QUERY_STRING
683 handling and cson_cgi's.
684 */
685 static cson_value * json_getenv( char const *zWhichEnv, char const * zKey ){
686 return cson_cgi_getenv(&g.json.cgiCx, zWhichEnv, zKey);
687 }
688 static char const * json_getenv_cstr( char const *zWhichEnv, char const * zKey ){
689 char const * rc = cson_value_get_cstr( json_getenv(zWhichEnv, zKey) );
690 if( !rc && zWhichEnv && (NULL!=strstr(zWhichEnv,"g")) ){
691 rc = PD(zKey,NULL);
692 }
693 return rc;
694 }
695 #endif
696
697 /*
698 ** Implementation for /json/cap
699 **
700 ** Returned object contains details about the "capabilities" of the
@@ -738,55 +759,79 @@
759 ** TODOs:
760 **
761 ** - anonymous user login (requires separate handling
762 ** due to random password).
763 **
764 ** - more testing with ONLY the JSON-specified authToken
765 ** (no cookie). In theory that works but we don't yet have
766 ** a non-browser client to play with.
767 **
768 */
769 cson_value * json_page_login(void){
770 /*
771 FIXME: we want to check the GET/POST args in this order:
772
773 - GET: name, n, password, p
774 - POST: name, password
775
776 but a bug in cgi_parameter() is breaking that, causing PD() to
777 return the last element of the PATH_INFO instead.
778
779 Summary: If we check for P("name") first, then P("n"),
780 then ONLY a GET param of "name" will match ("n"
781 is not recognized). If we reverse the order of the
782 checks then both forms work. Strangely enough, the
783 "p"/"password" check is not affected by this.
784 */
785 char const * name = cson_value_get_cstr(json_payload_property("name"));
786 char const * pw = NULL;
787 if( !name ){
788 name = PD("n",NULL);
789 if( !name ){
790 name = PD("name",NULL);
791 if( !name ){
792 g.json.resultCode = FSL_JSON_E_LOGIN_FAILED_NONAME;
793 return NULL;
794 }
795 }
796 }
797
798 pw = cson_value_get_cstr(json_payload_property("password"));
799 if( !pw ){
800 pw = PD("p",NULL);
801 if( !pw ){
802 pw = PD("password",NULL);
803 }
804 }
805 if(!pw){
806 g.json.resultCode = FSL_JSON_E_LOGIN_FAILED_NOPW;
807 return NULL;
808 }else{
809 cson_value * payload = NULL;
810 int uid = 0;
811 #if 0
812 /* only for debugging the PD()-incorrect-result problem */
813 cson_object * o = NULL;
814 uid = login_search_uid( name, pw );
815 payload = cson_value_new_object();
816 o = cson_value_get_object(payload);
817 cson_object_set( o, "n", cson_value_new_string(name,strlen(name)));
818 cson_object_set( o, "p", cson_value_new_string(pw,strlen(pw)));
819 return payload;
820 #else
821 uid = login_search_uid( name, pw );
822 if( !uid ){
823 g.json.resultCode = FSL_JSON_E_LOGIN_FAILED_NOTFOUND;
824 }else{
825 char * cookie = NULL;
826 login_set_user_cookie(name, uid, &cookie);
827 payload = cson_value_new_string( cookie, strlen(cookie) );
828 free(cookie);
829 }
830 return payload;
831 #endif
832 }
833 }
834
835 /*
836 ** Impl of /json/logout.
837 **
838

Keyboard Shortcuts

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