Fossil SCM
Fix enforcement of access restrictions on reports. Do not allow reports to show the content of fields whose names begin with "private_" unless the "e" permission is enabled.
Commit
21326fb6f7d3e2d175a80c3a603095c1f5b92f1b
Parent
b7588eb2f7ede91…
4 files changed
+1
-1
+22
-7
+1
-1
+10
-4
+1
-1
| --- src/main.c | ||
| +++ src/main.c | ||
| @@ -116,11 +116,11 @@ | ||
| 116 | 116 | int okRdTkt; /* r: view tickets via web */ |
| 117 | 117 | int okNewTkt; /* n: create new tickets */ |
| 118 | 118 | int okApndTkt; /* c: append to tickets via the web */ |
| 119 | 119 | int okWrTkt; /* w: make changes to tickets via web */ |
| 120 | 120 | int okTktFmt; /* t: create new ticket report formats */ |
| 121 | - int okRdAddr; /* e: read email addresses on tickets */ | |
| 121 | + int okRdAddr; /* e: read email addresses or other private data */ | |
| 122 | 122 | |
| 123 | 123 | FILE *fDebug; /* Write debug information here, if the file exists */ |
| 124 | 124 | |
| 125 | 125 | /* Storage for the aux() and/or option() SQL function arguments */ |
| 126 | 126 | int nAux; /* Number of distinct aux() or option() values */ |
| 127 | 127 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -116,11 +116,11 @@ | |
| 116 | int okRdTkt; /* r: view tickets via web */ |
| 117 | int okNewTkt; /* n: create new tickets */ |
| 118 | int okApndTkt; /* c: append to tickets via the web */ |
| 119 | int okWrTkt; /* w: make changes to tickets via web */ |
| 120 | int okTktFmt; /* t: create new ticket report formats */ |
| 121 | int okRdAddr; /* e: read email addresses on tickets */ |
| 122 | |
| 123 | FILE *fDebug; /* Write debug information here, if the file exists */ |
| 124 | |
| 125 | /* Storage for the aux() and/or option() SQL function arguments */ |
| 126 | int nAux; /* Number of distinct aux() or option() values */ |
| 127 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -116,11 +116,11 @@ | |
| 116 | int okRdTkt; /* r: view tickets via web */ |
| 117 | int okNewTkt; /* n: create new tickets */ |
| 118 | int okApndTkt; /* c: append to tickets via the web */ |
| 119 | int okWrTkt; /* w: make changes to tickets via web */ |
| 120 | int okTktFmt; /* t: create new ticket report formats */ |
| 121 | int okRdAddr; /* e: read email addresses or other private data */ |
| 122 | |
| 123 | FILE *fDebug; /* Write debug information here, if the file exists */ |
| 124 | |
| 125 | /* Storage for the aux() and/or option() SQL function arguments */ |
| 126 | int nAux; /* Number of distinct aux() or option() values */ |
| 127 |
+22
-7
| --- src/report.c | ||
| +++ src/report.c | ||
| @@ -154,12 +154,12 @@ | ||
| 154 | 154 | const char *zArg1, |
| 155 | 155 | const char *zArg2, |
| 156 | 156 | const char *zArg3, |
| 157 | 157 | const char *zArg4 |
| 158 | 158 | ){ |
| 159 | - char *zError = *(char**)pError; | |
| 160 | - if( zError ){ | |
| 159 | + int rc = SQLITE_OK; | |
| 160 | + if( *(char**)pError ){ | |
| 161 | 161 | /* We've already seen an error. No need to continue. */ |
| 162 | 162 | return SQLITE_OK; |
| 163 | 163 | } |
| 164 | 164 | switch( code ){ |
| 165 | 165 | case SQLITE_SELECT: |
| @@ -180,20 +180,24 @@ | ||
| 180 | 180 | int i; |
| 181 | 181 | for(i=0; i<sizeof(azAllowed)/sizeof(azAllowed[0]); i++){ |
| 182 | 182 | if( strcasecmp(zArg1, azAllowed[i])==0 ) break; |
| 183 | 183 | } |
| 184 | 184 | if( i>=sizeof(azAllowed)/sizeof(azAllowed[0]) ){ |
| 185 | - zError = mprintf("cannot access table %s", zArg1); | |
| 185 | + *(char**)pError = mprintf("access to table \"%s\" is restricted",zArg1); | |
| 186 | + rc = SQLITE_DENY; | |
| 187 | + }else if( !g.okRdAddr && strncmp(zArg2, "private_", 8)==0 ){ | |
| 188 | + rc = SQLITE_IGNORE; | |
| 186 | 189 | } |
| 187 | 190 | break; |
| 188 | 191 | } |
| 189 | 192 | default: { |
| 190 | - zError = mprintf("only SELECT statements are allowed"); | |
| 193 | + *(char**)pError = mprintf("only SELECT statements are allowed"); | |
| 194 | + rc = SQLITE_DENY; | |
| 191 | 195 | break; |
| 192 | 196 | } |
| 193 | 197 | } |
| 194 | - return SQLITE_OK; | |
| 198 | + return rc; | |
| 195 | 199 | } |
| 196 | 200 | |
| 197 | 201 | |
| 198 | 202 | /* |
| 199 | 203 | ** Check the given SQL to see if is a valid query that does not |
| @@ -875,10 +879,12 @@ | ||
| 875 | 879 | char *zTitle; |
| 876 | 880 | char *zOwner; |
| 877 | 881 | char *zClrKey; |
| 878 | 882 | int tabs; |
| 879 | 883 | Stmt q; |
| 884 | + char *zErr1 = 0; | |
| 885 | + char *zErr2 = 0; | |
| 880 | 886 | |
| 881 | 887 | login_check_credentials(); |
| 882 | 888 | if( !g.okRead ){ login_needed(); return; } |
| 883 | 889 | rn = atoi(PD("rn","0")); |
| 884 | 890 | if( rn==0 ){ |
| @@ -932,13 +938,22 @@ | ||
| 932 | 938 | output_color_key(zClrKey, 1, |
| 933 | 939 | "border=0 cellpadding=3 cellspacing=0 class=\"report\""); |
| 934 | 940 | @ <table border=1 cellpadding=2 cellspacing=0 class="report"> |
| 935 | 941 | sState.rn = rn; |
| 936 | 942 | sState.nCount = 0; |
| 937 | - sqlite3_exec(g.db, zSql, generate_html, &sState, 0); | |
| 943 | + sqlite3_set_authorizer(g.db, report_query_authorizer, (void*)&zErr1); | |
| 944 | + sqlite3_exec(g.db, zSql, generate_html, &sState, &zErr2); | |
| 945 | + sqlite3_set_authorizer(g.db, 0, 0); | |
| 938 | 946 | @ </table> |
| 947 | + if( zErr1 ){ | |
| 948 | + @ <p><font color="red"><b>Error: %h(zErr1)</b></font></p> | |
| 949 | + }else if( zErr2 ){ | |
| 950 | + @ <p><font color="red"><b>Error: %h(zErr2)</b></font></p> | |
| 951 | + } | |
| 939 | 952 | style_footer(); |
| 940 | 953 | }else{ |
| 941 | - sqlite3_exec(g.db, zSql, output_tab_separated, &count, 0); | |
| 954 | + sqlite3_set_authorizer(g.db, report_query_authorizer, (void*)&zErr1); | |
| 955 | + sqlite3_exec(g.db, zSql, output_tab_separated, &count, &zErr2); | |
| 956 | + sqlite3_set_authorizer(g.db, 0, 0); | |
| 942 | 957 | cgi_set_content_type("text/plain"); |
| 943 | 958 | } |
| 944 | 959 | } |
| 945 | 960 |
| --- src/report.c | |
| +++ src/report.c | |
| @@ -154,12 +154,12 @@ | |
| 154 | const char *zArg1, |
| 155 | const char *zArg2, |
| 156 | const char *zArg3, |
| 157 | const char *zArg4 |
| 158 | ){ |
| 159 | char *zError = *(char**)pError; |
| 160 | if( zError ){ |
| 161 | /* We've already seen an error. No need to continue. */ |
| 162 | return SQLITE_OK; |
| 163 | } |
| 164 | switch( code ){ |
| 165 | case SQLITE_SELECT: |
| @@ -180,20 +180,24 @@ | |
| 180 | int i; |
| 181 | for(i=0; i<sizeof(azAllowed)/sizeof(azAllowed[0]); i++){ |
| 182 | if( strcasecmp(zArg1, azAllowed[i])==0 ) break; |
| 183 | } |
| 184 | if( i>=sizeof(azAllowed)/sizeof(azAllowed[0]) ){ |
| 185 | zError = mprintf("cannot access table %s", zArg1); |
| 186 | } |
| 187 | break; |
| 188 | } |
| 189 | default: { |
| 190 | zError = mprintf("only SELECT statements are allowed"); |
| 191 | break; |
| 192 | } |
| 193 | } |
| 194 | return SQLITE_OK; |
| 195 | } |
| 196 | |
| 197 | |
| 198 | /* |
| 199 | ** Check the given SQL to see if is a valid query that does not |
| @@ -875,10 +879,12 @@ | |
| 875 | char *zTitle; |
| 876 | char *zOwner; |
| 877 | char *zClrKey; |
| 878 | int tabs; |
| 879 | Stmt q; |
| 880 | |
| 881 | login_check_credentials(); |
| 882 | if( !g.okRead ){ login_needed(); return; } |
| 883 | rn = atoi(PD("rn","0")); |
| 884 | if( rn==0 ){ |
| @@ -932,13 +938,22 @@ | |
| 932 | output_color_key(zClrKey, 1, |
| 933 | "border=0 cellpadding=3 cellspacing=0 class=\"report\""); |
| 934 | @ <table border=1 cellpadding=2 cellspacing=0 class="report"> |
| 935 | sState.rn = rn; |
| 936 | sState.nCount = 0; |
| 937 | sqlite3_exec(g.db, zSql, generate_html, &sState, 0); |
| 938 | @ </table> |
| 939 | style_footer(); |
| 940 | }else{ |
| 941 | sqlite3_exec(g.db, zSql, output_tab_separated, &count, 0); |
| 942 | cgi_set_content_type("text/plain"); |
| 943 | } |
| 944 | } |
| 945 |
| --- src/report.c | |
| +++ src/report.c | |
| @@ -154,12 +154,12 @@ | |
| 154 | const char *zArg1, |
| 155 | const char *zArg2, |
| 156 | const char *zArg3, |
| 157 | const char *zArg4 |
| 158 | ){ |
| 159 | int rc = SQLITE_OK; |
| 160 | if( *(char**)pError ){ |
| 161 | /* We've already seen an error. No need to continue. */ |
| 162 | return SQLITE_OK; |
| 163 | } |
| 164 | switch( code ){ |
| 165 | case SQLITE_SELECT: |
| @@ -180,20 +180,24 @@ | |
| 180 | int i; |
| 181 | for(i=0; i<sizeof(azAllowed)/sizeof(azAllowed[0]); i++){ |
| 182 | if( strcasecmp(zArg1, azAllowed[i])==0 ) break; |
| 183 | } |
| 184 | if( i>=sizeof(azAllowed)/sizeof(azAllowed[0]) ){ |
| 185 | *(char**)pError = mprintf("access to table \"%s\" is restricted",zArg1); |
| 186 | rc = SQLITE_DENY; |
| 187 | }else if( !g.okRdAddr && strncmp(zArg2, "private_", 8)==0 ){ |
| 188 | rc = SQLITE_IGNORE; |
| 189 | } |
| 190 | break; |
| 191 | } |
| 192 | default: { |
| 193 | *(char**)pError = mprintf("only SELECT statements are allowed"); |
| 194 | rc = SQLITE_DENY; |
| 195 | break; |
| 196 | } |
| 197 | } |
| 198 | return rc; |
| 199 | } |
| 200 | |
| 201 | |
| 202 | /* |
| 203 | ** Check the given SQL to see if is a valid query that does not |
| @@ -875,10 +879,12 @@ | |
| 879 | char *zTitle; |
| 880 | char *zOwner; |
| 881 | char *zClrKey; |
| 882 | int tabs; |
| 883 | Stmt q; |
| 884 | char *zErr1 = 0; |
| 885 | char *zErr2 = 0; |
| 886 | |
| 887 | login_check_credentials(); |
| 888 | if( !g.okRead ){ login_needed(); return; } |
| 889 | rn = atoi(PD("rn","0")); |
| 890 | if( rn==0 ){ |
| @@ -932,13 +938,22 @@ | |
| 938 | output_color_key(zClrKey, 1, |
| 939 | "border=0 cellpadding=3 cellspacing=0 class=\"report\""); |
| 940 | @ <table border=1 cellpadding=2 cellspacing=0 class="report"> |
| 941 | sState.rn = rn; |
| 942 | sState.nCount = 0; |
| 943 | sqlite3_set_authorizer(g.db, report_query_authorizer, (void*)&zErr1); |
| 944 | sqlite3_exec(g.db, zSql, generate_html, &sState, &zErr2); |
| 945 | sqlite3_set_authorizer(g.db, 0, 0); |
| 946 | @ </table> |
| 947 | if( zErr1 ){ |
| 948 | @ <p><font color="red"><b>Error: %h(zErr1)</b></font></p> |
| 949 | }else if( zErr2 ){ |
| 950 | @ <p><font color="red"><b>Error: %h(zErr2)</b></font></p> |
| 951 | } |
| 952 | style_footer(); |
| 953 | }else{ |
| 954 | sqlite3_set_authorizer(g.db, report_query_authorizer, (void*)&zErr1); |
| 955 | sqlite3_exec(g.db, zSql, output_tab_separated, &count, &zErr2); |
| 956 | sqlite3_set_authorizer(g.db, 0, 0); |
| 957 | cgi_set_content_type("text/plain"); |
| 958 | } |
| 959 | } |
| 960 |
+1
-1
| --- src/setup.c | ||
| +++ src/setup.c | ||
| @@ -136,11 +136,11 @@ | ||
| 136 | 136 | @ <li><p>The permission flags are as follows:</p> |
| 137 | 137 | @ <ol type="a"> |
| 138 | 138 | @ <li value="1"><b>Admin</b>: Create and delete users</li> |
| 139 | 139 | @ <li value="3"><b>Append-Tkt</b>: Append to tickets</li> |
| 140 | 140 | @ <li value="4"><b>Delete</b>: Delete wiki and tickets</li> |
| 141 | - @ <li value="5"><b>Email</b>: View EMail addresses on tickets</li> | |
| 141 | + @ <li value="5"><b>Email</b>: View sensitive data such as EMail addresses</li> | |
| 142 | 142 | @ <li value="6"><b>New-Wiki</b>: Create new wiki pages</li> |
| 143 | 143 | @ <li value="7"><b>Clone</b>: Clone the repository</li> |
| 144 | 144 | @ <li value="8"><b>History</b>: View detail repository history</li> |
| 145 | 145 | @ <li value="9"><b>Check-In</b>: Commit new versions in the repository</li> |
| 146 | 146 | @ <li value="10"><b>Read-Wiki</b>: View wiki pages</li> |
| 147 | 147 |
| --- src/setup.c | |
| +++ src/setup.c | |
| @@ -136,11 +136,11 @@ | |
| 136 | @ <li><p>The permission flags are as follows:</p> |
| 137 | @ <ol type="a"> |
| 138 | @ <li value="1"><b>Admin</b>: Create and delete users</li> |
| 139 | @ <li value="3"><b>Append-Tkt</b>: Append to tickets</li> |
| 140 | @ <li value="4"><b>Delete</b>: Delete wiki and tickets</li> |
| 141 | @ <li value="5"><b>Email</b>: View EMail addresses on tickets</li> |
| 142 | @ <li value="6"><b>New-Wiki</b>: Create new wiki pages</li> |
| 143 | @ <li value="7"><b>Clone</b>: Clone the repository</li> |
| 144 | @ <li value="8"><b>History</b>: View detail repository history</li> |
| 145 | @ <li value="9"><b>Check-In</b>: Commit new versions in the repository</li> |
| 146 | @ <li value="10"><b>Read-Wiki</b>: View wiki pages</li> |
| 147 |
| --- src/setup.c | |
| +++ src/setup.c | |
| @@ -136,11 +136,11 @@ | |
| 136 | @ <li><p>The permission flags are as follows:</p> |
| 137 | @ <ol type="a"> |
| 138 | @ <li value="1"><b>Admin</b>: Create and delete users</li> |
| 139 | @ <li value="3"><b>Append-Tkt</b>: Append to tickets</li> |
| 140 | @ <li value="4"><b>Delete</b>: Delete wiki and tickets</li> |
| 141 | @ <li value="5"><b>Email</b>: View sensitive data such as EMail addresses</li> |
| 142 | @ <li value="6"><b>New-Wiki</b>: Create new wiki pages</li> |
| 143 | @ <li value="7"><b>Clone</b>: Clone the repository</li> |
| 144 | @ <li value="8"><b>History</b>: View detail repository history</li> |
| 145 | @ <li value="9"><b>Check-In</b>: Commit new versions in the repository</li> |
| 146 | @ <li value="10"><b>Read-Wiki</b>: View wiki pages</li> |
| 147 |
+10
-4
| --- src/tktsetup.c | ||
| +++ src/tktsetup.c | ||
| @@ -56,10 +56,14 @@ | ||
| 56 | 56 | "The default color key for reports."); |
| 57 | 57 | @ </table> |
| 58 | 58 | style_footer(); |
| 59 | 59 | } |
| 60 | 60 | |
| 61 | +/* | |
| 62 | +** NOTE: When changing the table definition below, also change the | |
| 63 | +** equivalent definition found in schema.c. | |
| 64 | +*/ | |
| 61 | 65 | /* @-comment: ** */ |
| 62 | 66 | static const char zDefaultTicketTable[] = |
| 63 | 67 | @ CREATE TABLE ticket( |
| 64 | 68 | @ -- Do not change any column that begins with tkt_ |
| 65 | 69 | @ tkt_id INTEGER PRIMARY KEY, |
| @@ -70,11 +74,11 @@ | ||
| 70 | 74 | @ status TEXT, |
| 71 | 75 | @ subsystem TEXT, |
| 72 | 76 | @ priority TEXT, |
| 73 | 77 | @ severity TEXT, |
| 74 | 78 | @ foundin TEXT, |
| 75 | -@ contact TEXT, | |
| 79 | +@ private_contact TEXT, | |
| 76 | 80 | @ resolution TEXT, |
| 77 | 81 | @ title TEXT, |
| 78 | 82 | @ comment TEXT, |
| 79 | 83 | @ -- Do not alter this UNIQUE clause: |
| 80 | 84 | @ UNIQUE(tkt_uuid, tkt_mtime) |
| @@ -125,10 +129,11 @@ | ||
| 125 | 129 | if( xText && (zErr = xText(z))!=0 ){ |
| 126 | 130 | @ <p><font color="red"><b>ERROR: %h(zErr)</b></font></p> |
| 127 | 131 | }else{ |
| 128 | 132 | db_set(zDbField, z, 0); |
| 129 | 133 | if( xRebuild ) xRebuild(); |
| 134 | + cgi_redirect("tktsetup"); | |
| 130 | 135 | } |
| 131 | 136 | } |
| 132 | 137 | @ <form action="%s(g.zBaseURL)/%s(g.zPath)" method="POST"> |
| 133 | 138 | @ <p>%s(zDesc)</p> |
| 134 | 139 | @ <textarea name="x" rows="%d(height)" cols="80">%h(z)</textarea> |
| @@ -276,11 +281,11 @@ | ||
| 276 | 281 | @ effect the operation of the product?</td> |
| 277 | 282 | @ </tr> |
| 278 | 283 | @ |
| 279 | 284 | @ <tr> |
| 280 | 285 | @ <td align="right">EMail: |
| 281 | -@ <input type="text" name="contact" value="$<contact>" size="30"> | |
| 286 | +@ <input type="text" name="private_contact" value="$<private_contact>" size="30"> | |
| 282 | 287 | @ </td> |
| 283 | 288 | @ <td><u>Not publicly visible</u>. Used by developers to contact you with |
| 284 | 289 | @ questions.</td> |
| 285 | 290 | @ </tr> |
| 286 | 291 | @ |
| @@ -377,11 +382,11 @@ | ||
| 377 | 382 | @ <tr><td align="right">Last Modified:</td><td bgcolor="#d0d0d0"> |
| 378 | 383 | @ $<tkt_datetime> |
| 379 | 384 | @ </td> |
| 380 | 385 | @ <th1>enable_output [hascap e]</th1> |
| 381 | 386 | @ <td align="right">Contact:</td><td bgcolor="#d0d0d0"> |
| 382 | -@ $<contact> | |
| 387 | +@ $<private_contact> | |
| 383 | 388 | @ </td> |
| 384 | 389 | @ <th1>enable_output 1</th1> |
| 385 | 390 | @ </tr> |
| 386 | 391 | @ <tr><td align="right">Version Found In:</td> |
| 387 | 392 | @ <td colspan="3" valign="top" bgcolor="#d0d0d0"> |
| @@ -461,11 +466,12 @@ | ||
| 461 | 466 | @ <tr><td align="right">Subsystem:</td><td> |
| 462 | 467 | @ <th1>combobox subsystem $subsystem_choices 1</th1> |
| 463 | 468 | @ </td></tr> |
| 464 | 469 | @ <th1>enable_output [hascap e]</th1> |
| 465 | 470 | @ <tr><td align="right">Contact:</td><td> |
| 466 | -@ <input type="text" name="contact" size="40" value="$<contact>"> | |
| 471 | +@ <input type="text" name="private_contact" size="40" | |
| 472 | +@ value="$<private_contact>"> | |
| 467 | 473 | @ </td></tr> |
| 468 | 474 | @ <th1>enable_output 1</th1> |
| 469 | 475 | @ <tr><td align="right">Version Found In:</td><td> |
| 470 | 476 | @ <input type="text" name="foundin" size="50" value="$<foundin>"> |
| 471 | 477 | @ </td></tr> |
| 472 | 478 |
| --- src/tktsetup.c | |
| +++ src/tktsetup.c | |
| @@ -56,10 +56,14 @@ | |
| 56 | "The default color key for reports."); |
| 57 | @ </table> |
| 58 | style_footer(); |
| 59 | } |
| 60 | |
| 61 | /* @-comment: ** */ |
| 62 | static const char zDefaultTicketTable[] = |
| 63 | @ CREATE TABLE ticket( |
| 64 | @ -- Do not change any column that begins with tkt_ |
| 65 | @ tkt_id INTEGER PRIMARY KEY, |
| @@ -70,11 +74,11 @@ | |
| 70 | @ status TEXT, |
| 71 | @ subsystem TEXT, |
| 72 | @ priority TEXT, |
| 73 | @ severity TEXT, |
| 74 | @ foundin TEXT, |
| 75 | @ contact TEXT, |
| 76 | @ resolution TEXT, |
| 77 | @ title TEXT, |
| 78 | @ comment TEXT, |
| 79 | @ -- Do not alter this UNIQUE clause: |
| 80 | @ UNIQUE(tkt_uuid, tkt_mtime) |
| @@ -125,10 +129,11 @@ | |
| 125 | if( xText && (zErr = xText(z))!=0 ){ |
| 126 | @ <p><font color="red"><b>ERROR: %h(zErr)</b></font></p> |
| 127 | }else{ |
| 128 | db_set(zDbField, z, 0); |
| 129 | if( xRebuild ) xRebuild(); |
| 130 | } |
| 131 | } |
| 132 | @ <form action="%s(g.zBaseURL)/%s(g.zPath)" method="POST"> |
| 133 | @ <p>%s(zDesc)</p> |
| 134 | @ <textarea name="x" rows="%d(height)" cols="80">%h(z)</textarea> |
| @@ -276,11 +281,11 @@ | |
| 276 | @ effect the operation of the product?</td> |
| 277 | @ </tr> |
| 278 | @ |
| 279 | @ <tr> |
| 280 | @ <td align="right">EMail: |
| 281 | @ <input type="text" name="contact" value="$<contact>" size="30"> |
| 282 | @ </td> |
| 283 | @ <td><u>Not publicly visible</u>. Used by developers to contact you with |
| 284 | @ questions.</td> |
| 285 | @ </tr> |
| 286 | @ |
| @@ -377,11 +382,11 @@ | |
| 377 | @ <tr><td align="right">Last Modified:</td><td bgcolor="#d0d0d0"> |
| 378 | @ $<tkt_datetime> |
| 379 | @ </td> |
| 380 | @ <th1>enable_output [hascap e]</th1> |
| 381 | @ <td align="right">Contact:</td><td bgcolor="#d0d0d0"> |
| 382 | @ $<contact> |
| 383 | @ </td> |
| 384 | @ <th1>enable_output 1</th1> |
| 385 | @ </tr> |
| 386 | @ <tr><td align="right">Version Found In:</td> |
| 387 | @ <td colspan="3" valign="top" bgcolor="#d0d0d0"> |
| @@ -461,11 +466,12 @@ | |
| 461 | @ <tr><td align="right">Subsystem:</td><td> |
| 462 | @ <th1>combobox subsystem $subsystem_choices 1</th1> |
| 463 | @ </td></tr> |
| 464 | @ <th1>enable_output [hascap e]</th1> |
| 465 | @ <tr><td align="right">Contact:</td><td> |
| 466 | @ <input type="text" name="contact" size="40" value="$<contact>"> |
| 467 | @ </td></tr> |
| 468 | @ <th1>enable_output 1</th1> |
| 469 | @ <tr><td align="right">Version Found In:</td><td> |
| 470 | @ <input type="text" name="foundin" size="50" value="$<foundin>"> |
| 471 | @ </td></tr> |
| 472 |
| --- src/tktsetup.c | |
| +++ src/tktsetup.c | |
| @@ -56,10 +56,14 @@ | |
| 56 | "The default color key for reports."); |
| 57 | @ </table> |
| 58 | style_footer(); |
| 59 | } |
| 60 | |
| 61 | /* |
| 62 | ** NOTE: When changing the table definition below, also change the |
| 63 | ** equivalent definition found in schema.c. |
| 64 | */ |
| 65 | /* @-comment: ** */ |
| 66 | static const char zDefaultTicketTable[] = |
| 67 | @ CREATE TABLE ticket( |
| 68 | @ -- Do not change any column that begins with tkt_ |
| 69 | @ tkt_id INTEGER PRIMARY KEY, |
| @@ -70,11 +74,11 @@ | |
| 74 | @ status TEXT, |
| 75 | @ subsystem TEXT, |
| 76 | @ priority TEXT, |
| 77 | @ severity TEXT, |
| 78 | @ foundin TEXT, |
| 79 | @ private_contact TEXT, |
| 80 | @ resolution TEXT, |
| 81 | @ title TEXT, |
| 82 | @ comment TEXT, |
| 83 | @ -- Do not alter this UNIQUE clause: |
| 84 | @ UNIQUE(tkt_uuid, tkt_mtime) |
| @@ -125,10 +129,11 @@ | |
| 129 | if( xText && (zErr = xText(z))!=0 ){ |
| 130 | @ <p><font color="red"><b>ERROR: %h(zErr)</b></font></p> |
| 131 | }else{ |
| 132 | db_set(zDbField, z, 0); |
| 133 | if( xRebuild ) xRebuild(); |
| 134 | cgi_redirect("tktsetup"); |
| 135 | } |
| 136 | } |
| 137 | @ <form action="%s(g.zBaseURL)/%s(g.zPath)" method="POST"> |
| 138 | @ <p>%s(zDesc)</p> |
| 139 | @ <textarea name="x" rows="%d(height)" cols="80">%h(z)</textarea> |
| @@ -276,11 +281,11 @@ | |
| 281 | @ effect the operation of the product?</td> |
| 282 | @ </tr> |
| 283 | @ |
| 284 | @ <tr> |
| 285 | @ <td align="right">EMail: |
| 286 | @ <input type="text" name="private_contact" value="$<private_contact>" size="30"> |
| 287 | @ </td> |
| 288 | @ <td><u>Not publicly visible</u>. Used by developers to contact you with |
| 289 | @ questions.</td> |
| 290 | @ </tr> |
| 291 | @ |
| @@ -377,11 +382,11 @@ | |
| 382 | @ <tr><td align="right">Last Modified:</td><td bgcolor="#d0d0d0"> |
| 383 | @ $<tkt_datetime> |
| 384 | @ </td> |
| 385 | @ <th1>enable_output [hascap e]</th1> |
| 386 | @ <td align="right">Contact:</td><td bgcolor="#d0d0d0"> |
| 387 | @ $<private_contact> |
| 388 | @ </td> |
| 389 | @ <th1>enable_output 1</th1> |
| 390 | @ </tr> |
| 391 | @ <tr><td align="right">Version Found In:</td> |
| 392 | @ <td colspan="3" valign="top" bgcolor="#d0d0d0"> |
| @@ -461,11 +466,12 @@ | |
| 466 | @ <tr><td align="right">Subsystem:</td><td> |
| 467 | @ <th1>combobox subsystem $subsystem_choices 1</th1> |
| 468 | @ </td></tr> |
| 469 | @ <th1>enable_output [hascap e]</th1> |
| 470 | @ <tr><td align="right">Contact:</td><td> |
| 471 | @ <input type="text" name="private_contact" size="40" |
| 472 | @ value="$<private_contact>"> |
| 473 | @ </td></tr> |
| 474 | @ <th1>enable_output 1</th1> |
| 475 | @ <tr><td align="right">Version Found In:</td><td> |
| 476 | @ <input type="text" name="foundin" size="50" value="$<foundin>"> |
| 477 | @ </td></tr> |
| 478 |