##// END OF EJS Templates
Extended API...
Extended API - updated docs - created two new methods for creating users and creating users groups - changed user attribute generated from api_key to apiuser for better name compatibility with functoin parameters

File last commit:

r1417:5875955d beta
r1500:256e729a beta
Show More
user.py
387 lines | 15.0 KiB | text/x-python | PythonLexer
ldap auth rewrite, moved split authfunc into two functions,...
r761 # -*- coding: utf-8 -*-
"""
started working on issue #56
r956 rhodecode.model.user
~~~~~~~~~~~~~~~~~~~~
ldap auth rewrite, moved split authfunc into two functions,...
r761
users model for RhodeCode
source code cleanup: remove trailing white space, normalize file endings
r1203
ldap auth rewrite, moved split authfunc into two functions,...
r761 :created_on: Apr 9, 2010
:author: marcink
source code cleanup: remove trailing white space, normalize file endings
r1203 :copyright: (C) 2009-2011 Marcin Kuzminski <marcin@python-works.com>
ldap auth rewrite, moved split authfunc into two functions,...
r761 :license: GPLv3, see COPYING for more details.
"""
fixed license issue #149
r1206 # 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.
source code cleanup: remove trailing white space, normalize file endings
r1203 #
Code refactoring,models renames...
r629 # 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.
source code cleanup: remove trailing white space, normalize file endings
r1203 #
Code refactoring,models renames...
r629 # You should have received a copy of the GNU General Public License
fixed license issue #149
r1206 # along with this program. If not, see <http://www.gnu.org/licenses/>.
fixed security issue when saving ldap user saved plaintext password
r750
Code refactoring,models renames...
r629 import logging
import traceback
ldap auth rewrite, moved split authfunc into two functions,...
r761 from pylons.i18n.translation import _
from rhodecode.model import BaseModel
from rhodecode.model.caching_query import FromCache
Major rewrite of auth objects. Moved parts of filling user data into user model....
r1117 from rhodecode.model.db import User, RepoToPerm, Repository, Permission, \
tries to fix issue #177 by fallback to user.user_id instead of fetching from db, user.user_id...
r1269 UserToPerm, UsersGroupRepoToPerm, UsersGroupToPerm, UsersGroupMember
from rhodecode.lib.exceptions import DefaultUserException, \
UserOwnsReposException
fixed #72 show warning on removal when user still is owner of existing repositories...
r713
ldap auth rewrite, moved split authfunc into two functions,...
r761 from sqlalchemy.exc import DatabaseError
Added api_key into user, api key get's generated again after password change...
r1116 from rhodecode.lib import generate_api_key
tries to fix issue #177 by fallback to user.user_id instead of fetching from db, user.user_id...
r1269 from sqlalchemy.orm import joinedload
ldap auth rewrite, moved split authfunc into two functions,...
r761
log = logging.getLogger(__name__)
Code refactoring,models renames...
r629
tries to fix issue #177 by fallback to user.user_id instead of fetching from db, user.user_id...
r1269 PERM_WEIGHTS = {'repository.none': 0,
'repository.read': 1,
'repository.write': 3,
'repository.admin': 3}
Major rewrite of auth objects. Moved parts of filling user data into user model....
r1117
user defined permission will update the global permissions, and overwrite default settings.
r1267
fixed Example celery config to ampq,...
r752 class UserModel(BaseModel):
Code refactoring,models renames...
r629
def get(self, user_id, cache=False):
user = self.sa.query(User)
if cache:
user = user.options(FromCache("sql_cache_short",
"get_user_%s" % user_id))
return user.get(user_id)
#78, fixed more reliable case insensitive searches
r742 def get_by_username(self, username, cache=False, case_insensitive=False):
fixed security issue when saving ldap user saved plaintext password
r750
#78, fixed more reliable case insensitive searches
r742 if case_insensitive:
user = self.sa.query(User).filter(User.username.ilike(username))
else:
user = self.sa.query(User)\
.filter(User.username == username)
Code refactoring,models renames...
r629 if cache:
user = user.options(FromCache("sql_cache_short",
"get_user_%s" % username))
return user.scalar()
Major rewrite of auth objects. Moved parts of filling user data into user model....
r1117 def get_by_api_key(self, api_key, cache=False):
user = self.sa.query(User)\
.filter(User.api_key == api_key)
if cache:
user = user.options(FromCache("sql_cache_short",
"get_user_%s" % api_key))
return user.scalar()
Code refactoring,models renames...
r629 def create(self, form_data):
try:
new_user = User()
for k, v in form_data.items():
setattr(new_user, k, v)
Added api_key into user, api key get's generated again after password change...
r1116 new_user.api_key = generate_api_key(form_data['username'])
Code refactoring,models renames...
r629 self.sa.add(new_user)
self.sa.commit()
except:
log.error(traceback.format_exc())
self.sa.rollback()
raise
Thayne Harbaugh
Improve LDAP authentication...
r991 def create_ldap(self, username, password, user_dn, attrs):
implements #60, ldap configuration and authentication....
r705 """
Checks if user is in database, if not creates this user marked
as ldap user
:param username:
:param password:
Thayne Harbaugh
Improve LDAP authentication...
r991 :param user_dn:
:param attrs:
implements #60, ldap configuration and authentication....
r705 """
fixed security issue when saving ldap user saved plaintext password
r750 from rhodecode.lib.auth import get_crypt_password
ldap auth rewrite, moved split authfunc into two functions,...
r761 log.debug('Checking for such ldap account in RhodeCode database')
if self.get_by_username(username, case_insensitive=True) is None:
implements #60, ldap configuration and authentication....
r705 try:
new_user = User()
tries to fix issue #177 by fallback to user.user_id instead of fetching from db, user.user_id...
r1269 # add ldap account always lowercase
new_user.username = username.lower()
fixed security issue when saving ldap user saved plaintext password
r750 new_user.password = get_crypt_password(password)
Added api_key into user, api key get's generated again after password change...
r1116 new_user.api_key = generate_api_key(username)
Thayne Harbaugh
Improve LDAP authentication...
r991 new_user.email = attrs['email']
implements #60, ldap configuration and authentication....
r705 new_user.active = True
Thayne Harbaugh
Improve LDAP authentication...
r991 new_user.ldap_dn = user_dn
new_user.name = attrs['name']
new_user.lastname = attrs['lastname']
implements #60, ldap configuration and authentication....
r705
self.sa.add(new_user)
self.sa.commit()
return True
ldap auth rewrite, moved split authfunc into two functions,...
r761 except (DatabaseError,):
implements #60, ldap configuration and authentication....
r705 log.error(traceback.format_exc())
self.sa.rollback()
raise
ldap auth rewrite, moved split authfunc into two functions,...
r761 log.debug('this %s user exists skipping creation of ldap account',
username)
implements #60, ldap configuration and authentication....
r705 return False
Code refactoring,models renames...
r629 def create_registration(self, form_data):
fixes #59, notifications for user registrations + some changes to mailer
r689 from rhodecode.lib.celerylib import tasks, run_task
Code refactoring,models renames...
r629 try:
new_user = User()
for k, v in form_data.items():
if k != 'admin':
setattr(new_user, k, v)
self.sa.add(new_user)
self.sa.commit()
fixes #59, notifications for user registrations + some changes to mailer
r689 body = ('New user registration\n'
'username: %s\n'
'email: %s\n')
body = body % (form_data['username'], form_data['email'])
run_task(tasks.send_email, None,
_('[RhodeCode] New User registration'),
body)
Code refactoring,models renames...
r629 except:
log.error(traceback.format_exc())
self.sa.rollback()
raise
def update(self, user_id, form_data):
try:
Added api_key into user, api key get's generated again after password change...
r1116 user = self.get(user_id, cache=False)
if user.username == 'default':
Code refactoring,models renames...
r629 raise DefaultUserException(
_("You can't Edit this user since it's"
" crucial for entire application"))
fixed #72 show warning on removal when user still is owner of existing repositories...
r713
Code refactoring,models renames...
r629 for k, v in form_data.items():
if k == 'new_password' and v != '':
Added api_key into user, api key get's generated again after password change...
r1116 user.password = v
user.api_key = generate_api_key(user.username)
Code refactoring,models renames...
r629 else:
Added api_key into user, api key get's generated again after password change...
r1116 setattr(user, k, v)
Code refactoring,models renames...
r629
Added api_key into user, api key get's generated again after password change...
r1116 self.sa.add(user)
Code refactoring,models renames...
r629 self.sa.commit()
except:
log.error(traceback.format_exc())
self.sa.rollback()
raise
def update_my_account(self, user_id, form_data):
try:
Added api_key into user, api key get's generated again after password change...
r1116 user = self.get(user_id, cache=False)
if user.username == 'default':
Code refactoring,models renames...
r629 raise DefaultUserException(
_("You can't Edit this user since it's"
" crucial for entire application"))
for k, v in form_data.items():
if k == 'new_password' and v != '':
Added api_key into user, api key get's generated again after password change...
r1116 user.password = v
user.api_key = generate_api_key(user.username)
Code refactoring,models renames...
r629 else:
if k not in ['admin', 'active']:
Added api_key into user, api key get's generated again after password change...
r1116 setattr(user, k, v)
Code refactoring,models renames...
r629
Added api_key into user, api key get's generated again after password change...
r1116 self.sa.add(user)
Code refactoring,models renames...
r629 self.sa.commit()
except:
log.error(traceback.format_exc())
self.sa.rollback()
raise
def delete(self, user_id):
try:
user = self.get(user_id, cache=False)
if user.username == 'default':
raise DefaultUserException(
_("You can't remove this user since it's"
" crucial for entire application"))
fixed #72 show warning on removal when user still is owner of existing repositories...
r713 if user.repositories:
raise UserOwnsReposException(_('This user still owns %s '
'repositories and cannot be '
'removed. Switch owners or '
'remove those repositories') \
% user.repositories)
Code refactoring,models renames...
r629 self.sa.delete(user)
self.sa.commit()
except:
log.error(traceback.format_exc())
self.sa.rollback()
raise
fixes #223 improve password reset form
r1417 def reset_password_link(self, data):
from rhodecode.lib.celerylib import tasks, run_task
run_task(tasks.send_password_link, data['email'])
Code refactoring,models renames...
r629 def reset_password(self, data):
from rhodecode.lib.celerylib import tasks, run_task
run_task(tasks.reset_user_password, data['email'])
#49 Enabled anonymous access for web interface controllable from permissions pannel
r673
Major rewrite of auth objects. Moved parts of filling user data into user model....
r1117 def fill_data(self, auth_user, user_id=None, api_key=None):
#49 Enabled anonymous access for web interface controllable from permissions pannel
r673 """
Major rewrite of auth objects. Moved parts of filling user data into user model....
r1117 Fetches auth_user by user_id,or api_key if present.
Fills auth_user attributes with those taken from database.
source code cleanup: remove trailing white space, normalize file endings
r1203 Additionally set's is_authenitated if lookup fails
#49 Enabled anonymous access for web interface controllable from permissions pannel
r673 present in database
source code cleanup: remove trailing white space, normalize file endings
r1203
Major rewrite of auth objects. Moved parts of filling user data into user model....
r1117 :param auth_user: instance of user to set attributes
:param user_id: user id to fetch by
:param api_key: api key to fetch by
#49 Enabled anonymous access for web interface controllable from permissions pannel
r673 """
fixed some bugs in api key auth, added access by api key into rss/atom feeds in global journal...
r1120 if user_id is None and api_key is None:
Major rewrite of auth objects. Moved parts of filling user data into user model....
r1117 raise Exception('You need to pass user_id or api_key')
fixed anonymous access bug.
r686
Major rewrite of auth objects. Moved parts of filling user data into user model....
r1117 try:
if api_key:
dbuser = self.get_by_api_key(api_key)
else:
dbuser = self.get(user_id)
fixed some bugs in api key auth, added access by api key into rss/atom feeds in global journal...
r1120 if dbuser is not None:
log.debug('filling %s data', dbuser)
for k, v in dbuser.get_dict().items():
setattr(auth_user, k, v)
Major rewrite of auth objects. Moved parts of filling user data into user model....
r1117
except:
log.error(traceback.format_exc())
auth_user.is_authenticated = False
return auth_user
fixed anonymous access bug.
r686
Major rewrite of auth objects. Moved parts of filling user data into user model....
r1117 def fill_perms(self, user):
tries to fix issue #177 by fallback to user.user_id instead of fetching from db, user.user_id...
r1269 """
Fills user permission attribute with permissions taken from database
Major rewrite of auth objects. Moved parts of filling user data into user model....
r1117 works for permissions given for repositories, and for permissions that
tries to fix issue #177 by fallback to user.user_id instead of fetching from db, user.user_id...
r1269 are granted to groups
source code cleanup: remove trailing white space, normalize file endings
r1203
Major rewrite of auth objects. Moved parts of filling user data into user model....
r1117 :param user: user instance to fill his perms
"""
user.permissions['repositories'] = {}
user.permissions['global'] = set()
user defined permission will update the global permissions, and overwrite default settings.
r1267 #======================================================================
Major rewrite of auth objects. Moved parts of filling user data into user model....
r1117 # fetch default permissions
user defined permission will update the global permissions, and overwrite default settings.
r1267 #======================================================================
Major rewrite of auth objects. Moved parts of filling user data into user model....
r1117 default_user = self.get_by_username('default', cache=True)
default_perms = self.sa.query(RepoToPerm, Repository, Permission)\
tries to fix issue #177 by fallback to user.user_id instead of fetching from db, user.user_id...
r1269 .join((Repository, RepoToPerm.repository_id ==
Repository.repo_id))\
.join((Permission, RepoToPerm.permission_id ==
Permission.permission_id))\
Major rewrite of auth objects. Moved parts of filling user data into user model....
r1117 .filter(RepoToPerm.user == default_user).all()
if user.is_admin:
user defined permission will update the global permissions, and overwrite default settings.
r1267 #==================================================================
source code cleanup: remove trailing white space, normalize file endings
r1203 # #admin have all default rights set to admin
user defined permission will update the global permissions, and overwrite default settings.
r1267 #==================================================================
Major rewrite of auth objects. Moved parts of filling user data into user model....
r1117 user.permissions['global'].add('hg.admin')
for perm in default_perms:
p = 'repository.admin'
tries to fix issue #177 by fallback to user.user_id instead of fetching from db, user.user_id...
r1269 user.permissions['repositories'][perm.RepoToPerm.
repository.repo_name] = p
Major rewrite of auth objects. Moved parts of filling user data into user model....
r1117
else:
user defined permission will update the global permissions, and overwrite default settings.
r1267 #==================================================================
Major rewrite of auth objects. Moved parts of filling user data into user model....
r1117 # set default permissions
user defined permission will update the global permissions, and overwrite default settings.
r1267 #==================================================================
tries to fix issue #177 by fallback to user.user_id instead of fetching from db, user.user_id...
r1269 uid = user.user_id
Major rewrite of auth objects. Moved parts of filling user data into user model....
r1117
#default global
default_global_perms = self.sa.query(UserToPerm)\
removed extra query for default user
r1270 .filter(UserToPerm.user == default_user)
Major rewrite of auth objects. Moved parts of filling user data into user model....
r1117
for perm in default_global_perms:
user.permissions['global'].add(perm.permission.permission_name)
#default for repositories
for perm in default_perms:
tries to fix issue #177 by fallback to user.user_id instead of fetching from db, user.user_id...
r1269 if perm.Repository.private and not (perm.Repository.user_id ==
uid):
Major rewrite of auth objects. Moved parts of filling user data into user model....
r1117 #diself.sable defaults for private repos,
p = 'repository.none'
tries to fix issue #177 by fallback to user.user_id instead of fetching from db, user.user_id...
r1269 elif perm.Repository.user_id == uid:
Major rewrite of auth objects. Moved parts of filling user data into user model....
r1117 #set admin if owner
p = 'repository.admin'
else:
p = perm.Permission.permission_name
tries to fix issue #177 by fallback to user.user_id instead of fetching from db, user.user_id...
r1269 user.permissions['repositories'][perm.RepoToPerm.
repository.repo_name] = p
Major rewrite of auth objects. Moved parts of filling user data into user model....
r1117
user defined permission will update the global permissions, and overwrite default settings.
r1267 #==================================================================
Major rewrite of auth objects. Moved parts of filling user data into user model....
r1117 # overwrite default with user permissions if any
user defined permission will update the global permissions, and overwrite default settings.
r1267 #==================================================================
tries to fix issue #177 by fallback to user.user_id instead of fetching from db, user.user_id...
r1269 #user global
user defined permission will update the global permissions, and overwrite default settings.
r1267 user_perms = self.sa.query(UserToPerm)\
tries to fix issue #177 by fallback to user.user_id instead of fetching from db, user.user_id...
r1269 .options(joinedload(UserToPerm.permission))\
.filter(UserToPerm.user_id == uid).all()
user defined permission will update the global permissions, and overwrite default settings.
r1267
for perm in user_perms:
tries to fix issue #177 by fallback to user.user_id instead of fetching from db, user.user_id...
r1269 user.permissions['global'].add(perm.permission.
permission_name)
user defined permission will update the global permissions, and overwrite default settings.
r1267
tries to fix issue #177 by fallback to user.user_id instead of fetching from db, user.user_id...
r1269 #user repositories
user_repo_perms = self.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 == uid).all()
Major rewrite of auth objects. Moved parts of filling user data into user model....
r1117
user defined permission will update the global permissions, and overwrite default settings.
r1267 for perm in user_repo_perms:
tries to fix issue #177 by fallback to user.user_id instead of fetching from db, user.user_id...
r1269 # set admin if owner
if perm.Repository.user_id == uid:
Major rewrite of auth objects. Moved parts of filling user data into user model....
r1117 p = 'repository.admin'
else:
p = perm.Permission.permission_name
tries to fix issue #177 by fallback to user.user_id instead of fetching from db, user.user_id...
r1269 user.permissions['repositories'][perm.RepoToPerm.
repository.repo_name] = p
Major rewrite of auth objects. Moved parts of filling user data into user model....
r1117
tries to fix issue #177 by fallback to user.user_id instead of fetching from db, user.user_id...
r1269 #==================================================================
source code cleanup: remove trailing white space, normalize file endings
r1203 # check if user is part of groups for this repository and fill in
Major rewrite of auth objects. Moved parts of filling user data into user model....
r1117 # (or replace with higher) permissions
tries to fix issue #177 by fallback to user.user_id instead of fetching from db, user.user_id...
r1269 #==================================================================
#users group global
user_perms_from_users_groups = self.sa.query(UsersGroupToPerm)\
.options(joinedload(UsersGroupToPerm.permission))\
.join((UsersGroupMember, UsersGroupToPerm.users_group_id ==
UsersGroupMember.users_group_id))\
.filter(UsersGroupMember.user_id == uid).all()
Major rewrite of auth objects. Moved parts of filling user data into user model....
r1117
for perm in user_perms_from_users_groups:
tries to fix issue #177 by fallback to user.user_id instead of fetching from db, user.user_id...
r1269 user.permissions['global'].add(perm.permission.permission_name)
#users group repositories
user_repo_perms_from_users_groups = self.sa.query(
UsersGroupRepoToPerm,
Permission, Repository,)\
.join((Repository, UsersGroupRepoToPerm.repository_id ==
Repository.repo_id))\
.join((Permission, UsersGroupRepoToPerm.permission_id ==
Permission.permission_id))\
.join((UsersGroupMember, UsersGroupRepoToPerm.users_group_id ==
UsersGroupMember.users_group_id))\
.filter(UsersGroupMember.user_id == uid).all()
for perm in user_repo_perms_from_users_groups:
Major rewrite of auth objects. Moved parts of filling user data into user model....
r1117 p = perm.Permission.permission_name
tries to fix issue #177 by fallback to user.user_id instead of fetching from db, user.user_id...
r1269 cur_perm = user.permissions['repositories'][perm.
UsersGroupRepoToPerm.
repository.repo_name]
#overwrite permission only if it's greater than permission
# given from other sources
Major rewrite of auth objects. Moved parts of filling user data into user model....
r1117 if PERM_WEIGHTS[p] > PERM_WEIGHTS[cur_perm]:
tries to fix issue #177 by fallback to user.user_id instead of fetching from db, user.user_id...
r1269 user.permissions['repositories'][perm.UsersGroupRepoToPerm.
repository.repo_name] = p
#49 Enabled anonymous access for web interface controllable from permissions pannel
r673
return user