diff rhodecode/lib/base.py @ 4116:ffd45b185016 rhodecode-2.2.5-gpl

Imported some of the GPLv3'd changes from RhodeCode v2.2.5. This imports changes between changesets 21af6c4eab3d and 6177597791c2 in RhodeCode's original repository, including only changes to Python files and HTML. RhodeCode clearly licensed its changes to these files under GPLv3 in their /LICENSE file, which states the following: The Python code and integrated HTML are licensed under the GPLv3 license. (See: https://code.rhodecode.com/rhodecode/files/v2.2.5/LICENSE or http://web.archive.org/web/20140512193334/https://code.rhodecode.com/rhodecode/files/f3b123159901f15426d18e3dc395e8369f70ebe0/LICENSE for an online copy of that LICENSE file) Conservancy reviewed these changes and confirmed that they can be licensed as a whole to the Kallithea project under GPLv3-only. While some of the contents committed herein are clearly licensed GPLv3-or-later, on the whole we must assume the are GPLv3-only, since the statement above from RhodeCode indicates that they intend GPLv3-only as their license, per GPLv3ยง14 and other relevant sections of GPLv3.
author Bradley M. Kuhn <bkuhn@sfconservancy.org>
date Wed, 02 Jul 2014 19:03:13 -0400
parents a5888ca796b5
children 7e5f8c12a3fc
line wrap: on
line diff
--- a/rhodecode/lib/base.py	Wed Jul 02 19:03:10 2014 -0400
+++ b/rhodecode/lib/base.py	Wed Jul 02 19:03:13 2014 -0400
@@ -1,7 +1,31 @@
-"""The base Controller API
+# -*- coding: utf-8 -*-
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-Provides the BaseController class for subclassing.
 """
+rhodecode.lib.base
+~~~~~~~~~~~~~~~~~~
+
+The base Controller API
+Provides the BaseController class for subclassing. And usage in different
+controllers
+
+:created_on: Oct 06, 2010
+:author: marcink
+:copyright: (c) 2013 RhodeCode GmbH.
+:license: GPLv3, see LICENSE for more details.
+"""
+
 import logging
 import time
 import traceback
@@ -13,14 +37,14 @@
 from pylons import config, tmpl_context as c, request, session, url
 from pylons.controllers import WSGIController
 from pylons.controllers.util import redirect
-from pylons.templating import render_mako as render
+from pylons.templating import render_mako as render  # don't remove this import
 
 from rhodecode import __version__, BACKENDS
 
 from rhodecode.lib.utils2 import str2bool, safe_unicode, AttributeDict,\
     safe_str, safe_int
-from rhodecode.lib.auth import AuthUser, get_container_username, authfunc,\
-    HasPermissionAnyMiddleware, CookieStoreWrapper
+from rhodecode.lib import auth_modules
+from rhodecode.lib.auth import AuthUser, HasPermissionAnyMiddleware, CookieStoreWrapper
 from rhodecode.lib.utils import get_repo_slug
 from rhodecode.lib.exceptions import UserCreationError
 from rhodecode.model import meta
@@ -100,7 +124,7 @@
         _parts = auth.split(':', 1)
         if len(_parts) == 2:
             username, password = _parts
-            if self.authfunc(environ, username, password):
+            if self.authfunc(username, password, environ):
                 return username
         return self.build_authentication()
 
@@ -114,8 +138,8 @@
         self.config = config
         # base path of repo locations
         self.basepath = self.config['base_path']
-        #authenticate this mercurial request using authfunc
-        self.authenticate = BasicAuth('', authfunc,
+        #authenticate this VCS request using authfunc
+        self.authenticate = BasicAuth('', auth_modules.authenticate,
                                       config.get('auth_ret_code'))
         self.ip_addr = '0.0.0.0'
 
@@ -129,18 +153,13 @@
 
         :param repo_name:
         """
-        try:
-            data = repo_name.split('/')
-            if len(data) >= 2:
-                by_id = data[1].split('_')
-                if len(by_id) == 2 and by_id[1].isdigit():
-                    _repo_name = Repository.get(by_id[1]).repo_name
-                    data[1] = _repo_name
-        except Exception:
-            log.debug('Failed to extract repo_name from id %s' % (
-                      traceback.format_exc()
-                      )
-            )
+
+        data = repo_name.split('/')
+        if len(data) >= 2:
+            from rhodecode.lib.utils import get_repo_by_id
+            by_id_match = get_repo_by_id(repo_name)
+            if by_id_match:
+                data[1] = by_id_match
 
         return '/'.join(data)
 
@@ -161,12 +180,15 @@
         :param user: user instance
         :param repo_name: repository name
         """
-        #check IP
-        authuser = AuthUser(user_id=user.user_id, ip_addr=ip_addr)
-        if not authuser.ip_allowed:
+        # check IP
+        inherit = user.inherit_default_permissions
+        ip_allowed = AuthUser.check_ip_allowed(user.user_id, ip_addr,
+                                               inherit_from_default=inherit)
+        if ip_allowed:
+            log.info('Access for IP:%s allowed' % (ip_addr,))
+        else:
             return False
-        else:
-            log.info('Access for IP:%s allowed' % (ip_addr))
+
         if action == 'push':
             if not HasPermissionAnyMiddleware('repository.write',
                                               'repository.admin')(user,
@@ -261,31 +283,40 @@
         __before__ is called before controller methods and after __call__
         """
         c.rhodecode_version = __version__
-        c.rhodecode_instanceid = config.get('instance_id')
-        c.rhodecode_name = config.get('rhodecode_title')
-        c.rhodecode_bugtracker = config.get('bugtracker', 'http://bitbucket.org/marcinkuzminski/rhodecode/issues')
-        c.use_gravatar = str2bool(config.get('use_gravatar'))
-        c.ga_code = config.get('rhodecode_ga_code')
+        rc_config = RhodeCodeSetting.get_app_settings()
+
         # Visual options
         c.visual = AttributeDict({})
-        rc_config = RhodeCodeSetting.get_app_settings()
+
         ## DB stored
         c.visual.show_public_icon = str2bool(rc_config.get('rhodecode_show_public_icon'))
         c.visual.show_private_icon = str2bool(rc_config.get('rhodecode_show_private_icon'))
         c.visual.stylify_metatags = str2bool(rc_config.get('rhodecode_stylify_metatags'))
         c.visual.dashboard_items = safe_int(rc_config.get('rhodecode_dashboard_items', 100))
+        c.visual.admin_grid_items = safe_int(rc_config.get('rhodecode_admin_grid_items', 100))
         c.visual.repository_fields = str2bool(rc_config.get('rhodecode_repository_fields'))
         c.visual.show_version = str2bool(rc_config.get('rhodecode_show_version'))
+        c.visual.use_gravatar = str2bool(rc_config.get('rhodecode_use_gravatar'))
+        c.visual.gravatar_url = rc_config.get('rhodecode_gravatar_url')
+
+        c.ga_code = rc_config.get('rhodecode_ga_code')
+        c.rhodecode_name = rc_config.get('rhodecode_title')
+        c.clone_uri_tmpl = rc_config.get('rhodecode_clone_uri_tmpl')
 
         ## INI stored
-        self.cut_off_limit = int(config.get('cut_off_limit'))
         c.visual.allow_repo_location_change = str2bool(config.get('allow_repo_location_change', True))
         c.visual.allow_custom_hooks_settings = str2bool(config.get('allow_custom_hooks_settings', True))
 
+        c.rhodecode_instanceid = config.get('instance_id')
+        c.rhodecode_bugtracker = config.get('bugtracker', url('rc_issue_tracker'))
+        # END CONFIG VARS
+
         c.repo_name = get_repo_slug(request)  # can be empty
         c.backends = BACKENDS.keys()
         c.unread_notifications = NotificationModel()\
                         .get_unread_cnt_for_user(c.rhodecode_user.user_id)
+
+        self.cut_off_limit = safe_int(config.get('cut_off_limit'))
         self.sa = meta.Session
         self.scm_model = ScmModel(self.sa)
 
@@ -298,27 +329,33 @@
             self.ip_addr = _get_ip_addr(environ)
             # make sure that we update permissions each time we call controller
             api_key = request.GET.get('api_key')
-            cookie_store = CookieStoreWrapper(session.get('rhodecode_user'))
-            user_id = cookie_store.get('user_id', None)
-            username = get_container_username(environ, config)
-            try:
-                auth_user = AuthUser(user_id, api_key, username, self.ip_addr)
-            except UserCreationError, e:
-                from rhodecode.lib import helpers as h
-                h.flash(e, 'error')
-                # container auth or other auth functions that create users on
-                # the fly can throw this exception signaling that there's issue
-                # with user creation, explanation should be provided in
-                # Exception itself
-                auth_user = AuthUser(ip_addr=self.ip_addr)
 
+            if api_key:
+                # when using API_KEY we are sure user exists.
+                auth_user = AuthUser(api_key=api_key, ip_addr=self.ip_addr)
+                authenticated = False
+            else:
+                cookie_store = CookieStoreWrapper(session.get('rhodecode_user'))
+                try:
+                    auth_user = AuthUser(user_id=cookie_store.get('user_id', None),
+                                         ip_addr=self.ip_addr)
+                except UserCreationError, e:
+                    from rhodecode.lib import helpers as h
+                    h.flash(e, 'error')
+                    # container auth or other auth functions that create users on
+                    # the fly can throw this exception signaling that there's issue
+                    # with user creation, explanation should be provided in
+                    # Exception itself
+                    auth_user = AuthUser(ip_addr=self.ip_addr)
+
+                authenticated = cookie_store.get('is_authenticated')
+
+            if not auth_user.is_authenticated and auth_user.user_id is not None:
+                # user is not authenticated and not empty
+                auth_user.set_authenticated(authenticated)
             request.user = auth_user
+            #set globals for auth user
             self.rhodecode_user = c.rhodecode_user = auth_user
-            if not self.rhodecode_user.is_authenticated and \
-                       self.rhodecode_user.user_id is not None:
-                self.rhodecode_user.set_authenticated(
-                    cookie_store.get('is_authenticated')
-                )
             log.info('IP: %s User: %s accessed %s' % (
                self.ip_addr, auth_user, safe_unicode(_get_access_path(environ)))
             )
@@ -341,21 +378,39 @@
 
     def __before__(self):
         super(BaseRepoController, self).__before__()
-        if c.repo_name:
+        if c.repo_name:  # extracted from routes
+            _dbr = Repository.get_by_repo_name(c.repo_name)
+            if not _dbr:
+                return
+
+            log.debug('Found repository in database %s with state `%s`'
+                      % (safe_unicode(_dbr), safe_unicode(_dbr.repo_state)))
+            route = getattr(request.environ.get('routes.route'), 'name', '')
 
-            dbr = c.rhodecode_db_repo = Repository.get_by_repo_name(c.repo_name)
+            # allow to delete repos that are somehow damages in filesystem
+            if route in ['delete_repo']:
+                return
+
+            if _dbr.repo_state in [Repository.STATE_PENDING]:
+                if route in ['repo_creating_home']:
+                    return
+                check_url = url('repo_creating_home', repo_name=c.repo_name)
+                return redirect(check_url)
+
+            dbr = c.rhodecode_db_repo = _dbr
             c.rhodecode_repo = c.rhodecode_db_repo.scm_instance
-            # update last change according to VCS data
-            dbr.update_changeset_cache(dbr.get_changeset())
             if c.rhodecode_repo is None:
                 log.error('%s this repository is present in database but it '
                           'cannot be created as an scm instance', c.repo_name)
 
                 redirect(url('home'))
 
+            # update last change according to VCS data
+            dbr.update_changeset_cache(dbr.get_changeset())
+
             # some globals counter for menu
             c.repository_followers = self.scm_model.get_followers(dbr)
             c.repository_forks = self.scm_model.get_forks(dbr)
             c.repository_pull_requests = self.scm_model.get_pull_requests(dbr)
-            c.repository_following = self.scm_model.is_following_repo(c.repo_name,
-                                                self.rhodecode_user.user_id)
+            c.repository_following = self.scm_model.is_following_repo(
+                                    c.repo_name, self.rhodecode_user.user_id)