changeset 2668:f0851f37d6be beta

Implementes #509 require SSL flag now works for both git and mercurial. - check is done at earlies possible stage - if detected protocol is not https and flag require is there RhodeCode will return HTTP Error 406: Not Acceptable, before even checking credentials - removed push_ssl flag from mercurial UI objects since that would duplicate logic
author Marcin Kuzminski <marcin@python-works.com>
date Thu, 26 Jul 2012 23:03:26 +0200
parents 129beb0062c2
children 64bb1c46c861
files rhodecode/lib/base.py rhodecode/lib/middleware/https_fixup.py rhodecode/lib/middleware/simplegit.py rhodecode/lib/middleware/simplehg.py rhodecode/lib/utils.py rhodecode/model/db.py rhodecode/templates/admin/settings/settings.html
diffstat 7 files changed, 40 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/rhodecode/lib/base.py	Thu Jul 26 22:22:31 2012 +0200
+++ b/rhodecode/lib/base.py	Thu Jul 26 23:03:26 2012 +0200
@@ -23,7 +23,7 @@
 from rhodecode.lib.utils import get_repo_slug, invalidate_cache
 from rhodecode.model import meta
 
-from rhodecode.model.db import Repository
+from rhodecode.model.db import Repository, RhodeCodeUi
 from rhodecode.model.notification import NotificationModel
 from rhodecode.model.scm import ScmModel
 
@@ -145,6 +145,21 @@
     def _get_ip_addr(self, environ):
         return _get_ip_addr(environ)
 
+    def _check_ssl(self, environ, start_response):
+        """
+        Checks the SSL check flag and returns False if SSL is not present
+        and required True otherwise
+        """
+        org_proto = environ['wsgi._org_proto']
+        #check if we have SSL required  ! if not it's a bad request !
+        require_ssl = str2bool(RhodeCodeUi.get_by_key('push_ssl')\
+                               .scalar().ui_value)
+        if require_ssl and org_proto == 'http':
+            log.debug('proto is %s and SSL is required BAD REQUEST !'
+                      % org_proto)
+            return False
+        return True 
+
     def __call__(self, environ, start_response):
         start = time.time()
         try:
--- a/rhodecode/lib/middleware/https_fixup.py	Thu Jul 26 22:22:31 2012 +0200
+++ b/rhodecode/lib/middleware/https_fixup.py	Thu Jul 26 23:03:26 2012 +0200
@@ -42,21 +42,20 @@
         middleware you should set this header inside your
         proxy ie. nginx, apache etc.
         """
+        # DETECT PROTOCOL !
+        if 'HTTP_X_URL_SCHEME' in environ:
+            proto = environ.get('HTTP_X_URL_SCHEME')
+        elif 'HTTP_X_FORWARDED_SCHEME' in environ:
+            proto = environ.get('HTTP_X_FORWARDED_SCHEME')
+        elif 'HTTP_X_FORWARDED_PROTO' in environ:
+            proto = environ.get('HTTP_X_FORWARDED_PROTO')
+        else:
+            proto = 'http'
+        org_proto = proto
 
+        # if we have force, just override
         if str2bool(self.config.get('force_https')):
             proto = 'https'
-        else:
-            if 'HTTP_X_URL_SCHEME' in environ:
-                proto = environ.get('HTTP_X_URL_SCHEME')
-            elif 'HTTP_X_FORWARDED_SCHEME' in environ:
-                proto = environ.get('HTTP_X_FORWARDED_SCHEME')
-            elif 'HTTP_X_FORWARDED_PROTO' in environ:
-                proto = environ.get('HTTP_X_FORWARDED_PROTO')
-            else:
-                proto = 'http'
-        if proto == 'https':
-            environ['wsgi.url_scheme'] = proto
-        else:
-            environ['wsgi.url_scheme'] = 'http'
 
-        return None
+        environ['wsgi.url_scheme'] = proto
+        environ['wsgi._org_proto'] = org_proto
--- a/rhodecode/lib/middleware/simplegit.py	Thu Jul 26 22:22:31 2012 +0200
+++ b/rhodecode/lib/middleware/simplegit.py	Thu Jul 26 23:03:26 2012 +0200
@@ -74,6 +74,8 @@
 #from dulwich.web import make_wsgi_chain
 
 from paste.httpheaders import REMOTE_USER, AUTH_TYPE
+from webob.exc import HTTPNotFound, HTTPForbidden, HTTPInternalServerError, \
+    HTTPBadRequest, HTTPNotAcceptable
 
 from rhodecode.lib.utils2 import safe_str
 from rhodecode.lib.base import BaseVCSController
@@ -81,8 +83,6 @@
 from rhodecode.lib.utils import is_valid_repo, make_ui
 from rhodecode.model.db import User, RhodeCodeUi
 
-from webob.exc import HTTPNotFound, HTTPForbidden, HTTPInternalServerError
-
 log = logging.getLogger(__name__)
 
 
@@ -104,7 +104,8 @@
 
         if not is_git(environ):
             return self.application(environ, start_response)
-
+        if not self._check_ssl(environ, start_response):
+            return HTTPNotAcceptable('SSL REQUIRED !')(environ, start_response)
         ipaddr = self._get_ip_addr(environ)
         username = None
         self._git_first_op = False
--- a/rhodecode/lib/middleware/simplehg.py	Thu Jul 26 22:22:31 2012 +0200
+++ b/rhodecode/lib/middleware/simplehg.py	Thu Jul 26 23:03:26 2012 +0200
@@ -33,6 +33,8 @@
 from mercurial.hgweb import hgweb_mod
 
 from paste.httpheaders import REMOTE_USER, AUTH_TYPE
+from webob.exc import HTTPNotFound, HTTPForbidden, HTTPInternalServerError, \
+    HTTPBadRequest, HTTPNotAcceptable
 
 from rhodecode.lib.utils2 import safe_str
 from rhodecode.lib.base import BaseVCSController
@@ -40,7 +42,6 @@
 from rhodecode.lib.utils import make_ui, is_valid_repo, ui_sections
 from rhodecode.model.db import User
 
-from webob.exc import HTTPNotFound, HTTPForbidden, HTTPInternalServerError
 
 log = logging.getLogger(__name__)
 
@@ -68,6 +69,8 @@
     def _handle_request(self, environ, start_response):
         if not is_mercurial(environ):
             return self.application(environ, start_response)
+        if not self._check_ssl(environ, start_response):
+            return HTTPNotAcceptable('SSL REQUIRED !')(environ, start_response)
 
         ipaddr = self._get_ip_addr(environ)
         username = None 
--- a/rhodecode/lib/utils.py	Thu Jul 26 22:22:31 2012 +0200
+++ b/rhodecode/lib/utils.py	Thu Jul 26 23:03:26 2012 +0200
@@ -312,7 +312,7 @@
 
         hg_ui = ret
         for ui_ in hg_ui:
-            if ui_.ui_active:
+            if ui_.ui_active and ui_.ui_key != 'push_ssl':
                 log.debug('settings ui from db[%s]%s:%s', ui_.ui_section,
                           ui_.ui_key, ui_.ui_value)
                 baseui.setconfig(ui_.ui_section, ui_.ui_key, ui_.ui_value)
--- a/rhodecode/model/db.py	Thu Jul 26 22:22:31 2012 +0200
+++ b/rhodecode/model/db.py	Thu Jul 26 23:03:26 2012 +0200
@@ -728,7 +728,7 @@
 
         hg_ui = ret
         for ui_ in hg_ui:
-            if ui_.ui_active:
+            if ui_.ui_active and ui_.ui_key != 'push_ssl':
                 log.debug('settings ui from db[%s]%s:%s', ui_.ui_section,
                           ui_.ui_key, ui_.ui_value)
                 baseui.setconfig(ui_.ui_section, ui_.ui_key, ui_.ui_value)
--- a/rhodecode/templates/admin/settings/settings.html	Thu Jul 26 22:22:31 2012 +0200
+++ b/rhodecode/templates/admin/settings/settings.html	Thu Jul 26 23:03:26 2012 +0200
@@ -129,7 +129,7 @@
                 <div class="checkboxes">
 					<div class="checkbox">
 						${h.checkbox('web_push_ssl','true')}
-						<label for="web_push_ssl">${_('require ssl for pushing')}</label>
+						<label for="web_push_ssl">${_('require ssl for vcs operations')}</label>
 					</div>
 				</div>
              </div>