Fossil SCM
Moved /fileedit permissions check below the ajax dispatching check, as ajax bootstrapping performs that check itself, along with a CSRF check for write-mode requests, and emits a JSON-format response (as opposed to HTML) if it fails.
Commit
13e26db40393a52fae89c30ee6b4669e85d93a8b89b71746529a5b65f9d5fb0c
Parent
a80861de0319234…
1 file changed
+25
-20
+25
-20
| --- src/fileedit.c | ||
| +++ src/fileedit.c | ||
| @@ -1766,19 +1766,40 @@ | ||
| 1766 | 1766 | combined into a single JS |
| 1767 | 1767 | function call, thus each |
| 1768 | 1768 | entry must end with a |
| 1769 | 1769 | semicolon. */ |
| 1770 | 1770 | const char *zAjax = P("name"); |
| 1771 | + | |
| 1772 | + /* Dispatch AJAX methods based tail of the request URI. | |
| 1773 | + ** The ajax parts do their own permissions/CSRF check and | |
| 1774 | + ** fail with a JSON-format response if needed. | |
| 1775 | + */ | |
| 1776 | + if( 0!=zAjax ){ | |
| 1777 | + if(0==strcmp("content",zAjax)){ | |
| 1778 | + fileedit_ajax_content(); | |
| 1779 | + }else if(0==strcmp("preview",zAjax)){ | |
| 1780 | + fileedit_ajax_preview(); | |
| 1781 | + }else if(0==strcmp("filelist",zAjax)){ | |
| 1782 | + fileedit_ajax_filelist(); | |
| 1783 | + }else if(0==strcmp("diff",zAjax)){ | |
| 1784 | + fileedit_ajax_diff(); | |
| 1785 | + }else if(0==strcmp("commit",zAjax)){ | |
| 1786 | + fileedit_ajax_commit(); | |
| 1787 | + }else{ | |
| 1788 | + fileedit_ajax_error(500, "Unhandled ajax route name."); | |
| 1789 | + } | |
| 1790 | + return; | |
| 1791 | + } | |
| 1771 | 1792 | |
| 1772 | 1793 | /* Allow no access to this page without check-in privilege */ |
| 1773 | 1794 | login_check_credentials(); |
| 1774 | 1795 | if( !g.perm.Write ){ |
| 1775 | 1796 | login_needed(g.anon.Write); |
| 1776 | 1797 | return; |
| 1777 | 1798 | } |
| 1778 | 1799 | |
| 1779 | - /* No access to anything on this page if the fileedit_glob is empty */ | |
| 1800 | + /* No access to anything on this page if the fileedit-glob is empty */ | |
| 1780 | 1801 | if( fileedit_glob()==0 ){ |
| 1781 | 1802 | style_header("File Editor (disabled)"); |
| 1782 | 1803 | CX("<h1>Online File Editing Is Disabled</h1>\n"); |
| 1783 | 1804 | if( g.perm.Admin ){ |
| 1784 | 1805 | CX("<p>To enable online editing, the " |
| @@ -1792,33 +1813,17 @@ | ||
| 1792 | 1813 | } |
| 1793 | 1814 | style_footer(); |
| 1794 | 1815 | return; |
| 1795 | 1816 | } |
| 1796 | 1817 | |
| 1797 | - /* Dispatch AJAX methods based tail of the request URI */ | |
| 1798 | - if( 0!=zAjax ){ | |
| 1799 | - if(0==strcmp("content",zAjax)){ | |
| 1800 | - fileedit_ajax_content(); | |
| 1801 | - }else if(0==strcmp("preview",zAjax)){ | |
| 1802 | - fileedit_ajax_preview(); | |
| 1803 | - }else if(0==strcmp("filelist",zAjax)){ | |
| 1804 | - fileedit_ajax_filelist(); | |
| 1805 | - }else if(0==strcmp("diff",zAjax)){ | |
| 1806 | - fileedit_ajax_diff(); | |
| 1807 | - }else if(0==strcmp("commit",zAjax)){ | |
| 1808 | - fileedit_ajax_commit(); | |
| 1809 | - }else{ | |
| 1810 | - fileedit_ajax_error(500, "Unhandled ajax route name."); | |
| 1811 | - } | |
| 1812 | - return; | |
| 1813 | - } | |
| 1814 | 1818 | db_begin_transaction(); |
| 1815 | 1819 | CheckinMiniInfo_init(&cimi); |
| 1816 | 1820 | style_header("File Editor"); |
| 1817 | 1821 | /* As of this point, don't use return or fossil_fatal(). Write any |
| 1818 | 1822 | ** error in (&err) and goto end_footer instead so that we can be |
| 1819 | - ** sure to do any cleanup and end the transaction cleanly. | |
| 1823 | + ** sure to emit the error message, do any cleanup, and end the | |
| 1824 | + ** transaction cleanly. | |
| 1820 | 1825 | */ |
| 1821 | 1826 | { |
| 1822 | 1827 | int isMissingArg = 0; |
| 1823 | 1828 | if(fileedit_setup_cimi_from_p(&cimi, &err, &isMissingArg)==0){ |
| 1824 | 1829 | zFilename = cimi.zFilename; |
| @@ -1826,11 +1831,11 @@ | ||
| 1826 | 1831 | assert(zRev); |
| 1827 | 1832 | assert(zFilename); |
| 1828 | 1833 | zFileMime = mimetype_from_name(cimi.zFilename); |
| 1829 | 1834 | }else if(isMissingArg!=0){ |
| 1830 | 1835 | /* Squelch these startup warnings - they're non-fatal now but |
| 1831 | - ** used to be. */ | |
| 1836 | + ** used to be fatal. */ | |
| 1832 | 1837 | blob_reset(&err); |
| 1833 | 1838 | } |
| 1834 | 1839 | } |
| 1835 | 1840 | |
| 1836 | 1841 | /******************************************************************** |
| 1837 | 1842 |
| --- src/fileedit.c | |
| +++ src/fileedit.c | |
| @@ -1766,19 +1766,40 @@ | |
| 1766 | combined into a single JS |
| 1767 | function call, thus each |
| 1768 | entry must end with a |
| 1769 | semicolon. */ |
| 1770 | const char *zAjax = P("name"); |
| 1771 | |
| 1772 | /* Allow no access to this page without check-in privilege */ |
| 1773 | login_check_credentials(); |
| 1774 | if( !g.perm.Write ){ |
| 1775 | login_needed(g.anon.Write); |
| 1776 | return; |
| 1777 | } |
| 1778 | |
| 1779 | /* No access to anything on this page if the fileedit_glob is empty */ |
| 1780 | if( fileedit_glob()==0 ){ |
| 1781 | style_header("File Editor (disabled)"); |
| 1782 | CX("<h1>Online File Editing Is Disabled</h1>\n"); |
| 1783 | if( g.perm.Admin ){ |
| 1784 | CX("<p>To enable online editing, the " |
| @@ -1792,33 +1813,17 @@ | |
| 1792 | } |
| 1793 | style_footer(); |
| 1794 | return; |
| 1795 | } |
| 1796 | |
| 1797 | /* Dispatch AJAX methods based tail of the request URI */ |
| 1798 | if( 0!=zAjax ){ |
| 1799 | if(0==strcmp("content",zAjax)){ |
| 1800 | fileedit_ajax_content(); |
| 1801 | }else if(0==strcmp("preview",zAjax)){ |
| 1802 | fileedit_ajax_preview(); |
| 1803 | }else if(0==strcmp("filelist",zAjax)){ |
| 1804 | fileedit_ajax_filelist(); |
| 1805 | }else if(0==strcmp("diff",zAjax)){ |
| 1806 | fileedit_ajax_diff(); |
| 1807 | }else if(0==strcmp("commit",zAjax)){ |
| 1808 | fileedit_ajax_commit(); |
| 1809 | }else{ |
| 1810 | fileedit_ajax_error(500, "Unhandled ajax route name."); |
| 1811 | } |
| 1812 | return; |
| 1813 | } |
| 1814 | db_begin_transaction(); |
| 1815 | CheckinMiniInfo_init(&cimi); |
| 1816 | style_header("File Editor"); |
| 1817 | /* As of this point, don't use return or fossil_fatal(). Write any |
| 1818 | ** error in (&err) and goto end_footer instead so that we can be |
| 1819 | ** sure to do any cleanup and end the transaction cleanly. |
| 1820 | */ |
| 1821 | { |
| 1822 | int isMissingArg = 0; |
| 1823 | if(fileedit_setup_cimi_from_p(&cimi, &err, &isMissingArg)==0){ |
| 1824 | zFilename = cimi.zFilename; |
| @@ -1826,11 +1831,11 @@ | |
| 1826 | assert(zRev); |
| 1827 | assert(zFilename); |
| 1828 | zFileMime = mimetype_from_name(cimi.zFilename); |
| 1829 | }else if(isMissingArg!=0){ |
| 1830 | /* Squelch these startup warnings - they're non-fatal now but |
| 1831 | ** used to be. */ |
| 1832 | blob_reset(&err); |
| 1833 | } |
| 1834 | } |
| 1835 | |
| 1836 | /******************************************************************** |
| 1837 |
| --- src/fileedit.c | |
| +++ src/fileedit.c | |
| @@ -1766,19 +1766,40 @@ | |
| 1766 | combined into a single JS |
| 1767 | function call, thus each |
| 1768 | entry must end with a |
| 1769 | semicolon. */ |
| 1770 | const char *zAjax = P("name"); |
| 1771 | |
| 1772 | /* Dispatch AJAX methods based tail of the request URI. |
| 1773 | ** The ajax parts do their own permissions/CSRF check and |
| 1774 | ** fail with a JSON-format response if needed. |
| 1775 | */ |
| 1776 | if( 0!=zAjax ){ |
| 1777 | if(0==strcmp("content",zAjax)){ |
| 1778 | fileedit_ajax_content(); |
| 1779 | }else if(0==strcmp("preview",zAjax)){ |
| 1780 | fileedit_ajax_preview(); |
| 1781 | }else if(0==strcmp("filelist",zAjax)){ |
| 1782 | fileedit_ajax_filelist(); |
| 1783 | }else if(0==strcmp("diff",zAjax)){ |
| 1784 | fileedit_ajax_diff(); |
| 1785 | }else if(0==strcmp("commit",zAjax)){ |
| 1786 | fileedit_ajax_commit(); |
| 1787 | }else{ |
| 1788 | fileedit_ajax_error(500, "Unhandled ajax route name."); |
| 1789 | } |
| 1790 | return; |
| 1791 | } |
| 1792 | |
| 1793 | /* Allow no access to this page without check-in privilege */ |
| 1794 | login_check_credentials(); |
| 1795 | if( !g.perm.Write ){ |
| 1796 | login_needed(g.anon.Write); |
| 1797 | return; |
| 1798 | } |
| 1799 | |
| 1800 | /* No access to anything on this page if the fileedit-glob is empty */ |
| 1801 | if( fileedit_glob()==0 ){ |
| 1802 | style_header("File Editor (disabled)"); |
| 1803 | CX("<h1>Online File Editing Is Disabled</h1>\n"); |
| 1804 | if( g.perm.Admin ){ |
| 1805 | CX("<p>To enable online editing, the " |
| @@ -1792,33 +1813,17 @@ | |
| 1813 | } |
| 1814 | style_footer(); |
| 1815 | return; |
| 1816 | } |
| 1817 | |
| 1818 | db_begin_transaction(); |
| 1819 | CheckinMiniInfo_init(&cimi); |
| 1820 | style_header("File Editor"); |
| 1821 | /* As of this point, don't use return or fossil_fatal(). Write any |
| 1822 | ** error in (&err) and goto end_footer instead so that we can be |
| 1823 | ** sure to emit the error message, do any cleanup, and end the |
| 1824 | ** transaction cleanly. |
| 1825 | */ |
| 1826 | { |
| 1827 | int isMissingArg = 0; |
| 1828 | if(fileedit_setup_cimi_from_p(&cimi, &err, &isMissingArg)==0){ |
| 1829 | zFilename = cimi.zFilename; |
| @@ -1826,11 +1831,11 @@ | |
| 1831 | assert(zRev); |
| 1832 | assert(zFilename); |
| 1833 | zFileMime = mimetype_from_name(cimi.zFilename); |
| 1834 | }else if(isMissingArg!=0){ |
| 1835 | /* Squelch these startup warnings - they're non-fatal now but |
| 1836 | ** used to be fatal. */ |
| 1837 | blob_reset(&err); |
| 1838 | } |
| 1839 | } |
| 1840 | |
| 1841 | /******************************************************************** |
| 1842 |