Changeset - 3790279d2538
[Not reviewed]
beta
0 1 0
Marcin Kuzminski - 15 years ago 2011-02-09 18:54:20
marcin@python-works.com
#56 added propagation of permission from group
1 file changed with 43 insertions and 17 deletions:
0 comments (0 inline, 0 general)
rhodecode/lib/auth.py
Show inline comments
 
@@ -38,17 +38,24 @@ from rhodecode.lib.exceptions import Lda
 
from rhodecode.lib.utils import get_repo_slug
 
from rhodecode.lib.auth_ldap import AuthLdap
 

	
 
from rhodecode.model import meta
 
from rhodecode.model.user import UserModel
 
from rhodecode.model.db import User, RepoToPerm, Repository, Permission, \
 
    UserToPerm
 
    UserToPerm, UsersGroupToPerm, UsersGroupMember
 

	
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
PERM_WEIGHTS = {'repository.none':0,
 
                'repository.read':1,
 
                'repository.write':3,
 
                'repository.admin':3}
 

	
 

	
 
class PasswordGenerator(object):
 
    """This is a simple class for generating password from
 
        different sets of characters
 
        usage:
 
        passwd_gen = PasswordGenerator()
 
        #print 8-letter password containing only big and small letters of alphabet
 
@@ -70,32 +77,31 @@ class PasswordGenerator(object):
 
    def gen_password(self, len, type):
 
        self.passwd = ''.join([random.choice(type) for _ in xrange(len)])
 
        return self.passwd
 

	
 

	
 
def get_crypt_password(password):
 
    """Cryptographic function used for password hashing based on sha1
 
    """Cryptographic function used for password hashing based on pybcrypt
 
    
 
    :param password: password to hash
 
    """
 
    return bcrypt.hashpw(password, bcrypt.gensalt(10))
 

	
 
def check_password(password, hashed):
 
    return bcrypt.hashpw(password, hashed) == hashed
 

	
 
def authfunc(environ, username, password):
 
    """
 
    Dummy authentication function used in Mercurial/Git/ and access control,
 
    """Dummy authentication function used in Mercurial/Git/ and access control,
 
    
 
    :param environ: needed only for using in Basic auth
 
    """
 
    return authenticate(username, password)
 

	
 

	
 
def authenticate(username, password):
 
    """
 
    Authentication function used for access control,
 
    """Authentication function used for access control,
 
    firstly checks for db authentication then if ldap is enabled for ldap
 
    authentication, also creates ldap user if not in database
 
    
 
    :param username: username
 
    :param password: password
 
    """
 
@@ -127,13 +133,13 @@ def authenticate(username, password):
 
            return False
 

	
 
        from rhodecode.model.settings import SettingsModel
 
        ldap_settings = SettingsModel().get_ldap_settings()
 

	
 
        #======================================================================
 
        # FALLBACK TO LDAP AUTH IN ENABLE                
 
        # FALLBACK TO LDAP AUTH IF ENABLE                
 
        #======================================================================
 
        if ldap_settings.get('ldap_active', False):
 
            log.debug("Authenticating user using ldap")
 
            kwargs = {
 
                  'server':ldap_settings.get('ldap_host', ''),
 
                  'base_dn':ldap_settings.get('ldap_base_dn', ''),
 
@@ -157,26 +163,26 @@ def authenticate(username, password):
 
                    'name'     : ldap_attrs[ldap_settings.get('ldap_attr_firstname')][0],
 
                    'lastname' : ldap_attrs[ldap_settings.get('ldap_attr_lastname')][0],
 
                    'email'    : ldap_attrs[ldap_settings.get('ldap_attr_email')][0],
 
                    }
 

	
 
                if user_model.create_ldap(username, password, user_dn, user_attrs):
 
                    log.info('created new ldap user')
 
                    log.info('created new ldap user %s', username)
 

	
 
                return True
 
            except (LdapUsernameError, LdapPasswordError,):
 
                pass
 
            except (Exception,):
 
                log.error(traceback.format_exc())
 
                pass
 
    return False
 

	
 
class  AuthUser(object):
 
    """A simple object that handles a mercurial username for authentication
 
    """
 
    A simple object that handles a mercurial username for authentication
 
    """
 

	
 
    def __init__(self):
 
        self.username = 'None'
 
        self.name = ''
 
        self.lastname = ''
 
        self.email = ''
 
        self.user_id = None
 
@@ -186,13 +192,13 @@ class  AuthUser(object):
 

	
 
    def __repr__(self):
 
        return "<AuthUser('id:%s:%s')>" % (self.user_id, self.username)
 

	
 
def set_available_permissions(config):
 
    """This function will propagate pylons globals with all available defined
 
    permission given in db. We don't wannt to check each time from db for new 
 
    permission given in db. We don't want to check each time from db for new 
 
    permissions since adding a new permission also requires application restart
 
    ie. to decorate new views with the newly created permission
 
    
 
    :param config: current pylons config instance
 
    
 
    """
 
@@ -210,15 +216,16 @@ def set_available_permissions(config):
 
def set_base_path(config):
 
    config['base_path'] = config['pylons.app_globals'].base_path
 

	
 

	
 
def fill_perms(user):
 
    """Fills user permission attribute with permissions taken from database
 
    works for permissions given for repositories, and for permissions that
 
    as part of beeing group member
 
    
 
    :param user:
 
    
 
    :param user: user instance to fill his perms
 
    """
 

	
 
    sa = meta.Session()
 
    user.permissions['repositories'] = {}
 
    user.permissions['global'] = set()
 

	
 
@@ -252,13 +259,13 @@ def fill_perms(user):
 
            .filter(UserToPerm.user == sa.query(User)\
 
                   .filter(User.username == 'default').one())
 

	
 
        for perm in default_global_perms:
 
            user.permissions['global'].add(perm.permission.permission_name)
 

	
 
        #default repositories
 
        #default for repositories
 
        for perm in default_perms:
 
            if perm.Repository.private and not perm.Repository.user_id == user.user_id:
 
                #disable defaults for private repos,
 
                p = 'repository.none'
 
            elif perm.Repository.user_id == user.user_id:
 
                #set admin if owner
 
@@ -266,31 +273,50 @@ def fill_perms(user):
 
            else:
 
                p = perm.Permission.permission_name
 

	
 
            user.permissions['repositories'][perm.RepoToPerm.repository.repo_name] = p
 

	
 
        #=======================================================================
 
        # #overwrite default with user permissions if any
 
        # overwrite default with user permissions if any
 
        #=======================================================================
 
        user_perms = sa.query(RepoToPerm, Permission, Repository)\
 
            .join((Repository, RepoToPerm.repository_id == Repository.repo_id))\
 
            .join((Permission, RepoToPerm.permission_id == Permission.permission_id))\
 
            .filter(RepoToPerm.user_id == user.user_id).all()
 

	
 
        for perm in user_perms:
 
            if perm.Repository.user_id == user.user_id:#set admin if owner
 
                p = 'repository.admin'
 
            else:
 
                p = perm.Permission.permission_name
 
            user.permissions['repositories'][perm.RepoToPerm.repository.repo_name] = p
 

	
 

	
 
        #=======================================================================
 
        # check if user is part of groups for this repository and fill in 
 
        # (or replace with higher) permissions
 
        #=======================================================================
 
        user_perms_from_users_groups = sa.query(UsersGroupToPerm, Permission, Repository,)\
 
            .join((Repository, UsersGroupToPerm.repository_id == Repository.repo_id))\
 
            .join((Permission, UsersGroupToPerm.permission_id == Permission.permission_id))\
 
            .join((UsersGroupMember, UsersGroupToPerm.users_group_id == UsersGroupMember.users_group_id))\
 
            .filter(UsersGroupMember.user_id == user.user_id).all()
 

	
 
        for perm in user_perms_from_users_groups:
 
            p = perm.Permission.permission_name
 
            cur_perm = user.permissions['repositories'][perm.UsersGroupToPerm.repository.repo_name]
 
            #overwrite permission only if it's greater than permission given from other sources
 
            if PERM_WEIGHTS[p] > PERM_WEIGHTS[cur_perm]:
 
                user.permissions['repositories'][perm.UsersGroupToPerm.repository.repo_name] = p
 

	
 
    meta.Session.remove()
 
    return user
 

	
 
def get_user(session):
 
    """
 
    Gets user from session, and wraps permissions into user
 
    """Gets user from session, and wraps permissions into user
 
    
 
    :param session:
 
    """
 
    user = session.get('rhodecode_user', AuthUser())
 
    #if the user is not logged in we check for anonymous access
 
    #if user is logged and it's a default user check if we still have anonymous
 
    #access enabled
0 comments (0 inline, 0 general)