##// END OF EJS Templates
Add flag for permission check in _update_permissions function
Add flag for permission check in _update_permissions function

File last commit:

r3809:647fb653 beta
r3827:ff57547c beta
Show More
api.py
1066 lines | 35.6 KiB | text/x-python | PythonLexer
2012 copyrights
r1824 # -*- coding: utf-8 -*-
"""
rhodecode.controllers.api
~~~~~~~~~~~~~~~~~~~~~~~~~
API controller for RhodeCode
:created_on: Aug 20, 2011
:author: marcink
:copyright: (C) 2011-2012 Marcin Kuzminski <marcin@python-works.com>
:license: GPLv3, see COPYING for more details.
"""
# 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; version 2
# of the License or (at your opinion) any later version of the license.
#
# 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, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
locking API returns objects instead of string messages....
r3808 import time
Extended API...
r1500 import traceback
import logging
Beginning of API implementation for rhodecode
r1445 from rhodecode.controllers.api import JSONRPCController, JSONRPCError
Implemented API calls for non-admin users for locking/unlocking repositories
r3161 from rhodecode.lib.auth import PasswordGenerator, AuthUser, \
HasPermissionAllDecorator, HasPermissionAnyDecorator, \
HasPermissionAnyApi, HasRepoPermissionAnyApi
API: Added option to rescann repositories via api call
r2697 from rhodecode.lib.utils import map_groups, repo2db_mapper
get_locks API function draft
r3502 from rhodecode.lib.utils2 import str2bool, time_to_datetime, safe_int
calling lock function without lock attribute, will return lock state
r3457 from rhodecode.lib import helpers as h
another major refactoring with session management
r1734 from rhodecode.model.meta import Session
Beginning of API implementation for rhodecode
r1445 from rhodecode.model.scm import ScmModel
Nicolas VINOT
Improve API with user/group/repo CRUD methods
r1584 from rhodecode.model.repo import RepoModel
Nicolas VINOT
Add API for repositories and groups (creation, permission)
r1586 from rhodecode.model.user import UserModel
Mads Kiilerich
further cleanup of UsersGroup...
r3417 from rhodecode.model.users_group import UserGroupModel
make the permission update function idempotent
r3730 from rhodecode.model.db import Repository, RhodeCodeSetting, UserIpMap,\
hide listing of default user...
r3799 Permission, User
get_locks API function draft
r3502 from rhodecode.lib.compat import json
hide listing of default user...
r3799 from rhodecode.lib.exceptions import DefaultUserException
another major refactoring with session management
r1734
Nicolas VINOT
Correct code style
r1593 log = logging.getLogger(__name__)
Extended API...
r1500
Beginning of API implementation for rhodecode
r1445
Implemented API calls for non-admin users for locking/unlocking repositories
r3161 class OptionalAttr(object):
"""
Special Optional Option that defines other attribute
"""
def __init__(self, attr_name):
self.attr_name = attr_name
def __repr__(self):
return '<OptionalAttr:%s>' % self.attr_name
def __call__(self):
return self
#alias
OAttr = OptionalAttr
Refactored API...
r2526 class Optional(object):
"""
Defines an optional parameter::
param = param.getval() if isinstance(param, Optional) else param
param = param() if isinstance(param, Optional) else param
is equivalent of::
param = Optional.extract(param)
"""
def __init__(self, type_):
self.type_ = type_
def __repr__(self):
return '<Optional:%s>' % self.type_.__repr__()
def __call__(self):
return self.getval()
def getval(self):
"""
returns value from this Optional instance
"""
return self.type_
@classmethod
def extract(cls, val):
if isinstance(val, cls):
return val.getval()
return val
def get_user_or_error(userid):
"""
Get user by id or name or return JsonRPCError if not found
:param userid:
"""
user = UserModel().get_user(userid)
if user is None:
raise JSONRPCError("user `%s` does not exist" % userid)
return user
def get_repo_or_error(repoid):
"""
Get repo by id or name or return JsonRPCError if not found
:param userid:
"""
repo = RepoModel().get_repo(repoid)
if repo is None:
raise JSONRPCError('repository `%s` does not exist' % (repoid))
return repo
def get_users_group_or_error(usersgroupid):
"""
Mads Kiilerich
"Users groups" is grammatically incorrect English - rename to "user groups"...
r3410 Get user group by id or name or return JsonRPCError if not found
Refactored API...
r2526
:param userid:
"""
Mads Kiilerich
further cleanup of UsersGroup...
r3417 users_group = UserGroupModel().get_group(usersgroupid)
Refactored API...
r2526 if users_group is None:
Mads Kiilerich
"Users groups" is grammatically incorrect English - rename to "user groups"...
r3410 raise JSONRPCError('user group `%s` does not exist' % usersgroupid)
Refactored API...
r2526 return users_group
def get_perm_or_error(permid):
"""
Get permission by id or name or return JsonRPCError if not found
:param userid:
"""
make the permission update function idempotent
r3730 perm = Permission.get_by_key(permid)
Refactored API...
r2526 if perm is None:
raise JSONRPCError('permission `%s` does not exist' % (permid))
return perm
Nicolas VINOT
Correct code style
r1593 class ApiController(JSONRPCController):
Beginning of API implementation for rhodecode
r1445 """
API Controller
Nicolas VINOT
Improve API with user/group/repo CRUD methods
r1584
Beginning of API implementation for rhodecode
r1445 Each method needs to have USER as argument this is then based on given
API_KEY propagated as instance of user object
Nicolas VINOT
Improve API with user/group/repo CRUD methods
r1584
Beginning of API implementation for rhodecode
r1445 Preferably this should be first argument also
Nicolas VINOT
Improve API with user/group/repo CRUD methods
r1584
Each function should also **raise** JSONRPCError for any
Beginning of API implementation for rhodecode
r1445 errors that happens
Nicolas VINOT
Improve API with user/group/repo CRUD methods
r1584
Beginning of API implementation for rhodecode
r1445 """
Nicolas VINOT
Correct code style
r1593 @HasPermissionAllDecorator('hg.admin')
Refactored API...
r2526 def pull(self, apiuser, repoid):
Beginning of API implementation for rhodecode
r1445 """
Dispatch pull action on given repo
Nicolas VINOT
Improve API with user/group/repo CRUD methods
r1584
Refactored API...
r2526 :param apiuser:
:param repoid:
Beginning of API implementation for rhodecode
r1445 """
Refactored API...
r2526 repo = get_repo_or_error(repoid)
Nicolas VINOT
Implement all CRUD API operation for repo
r1587
Beginning of API implementation for rhodecode
r1445 try:
Refactored API...
r2526 ScmModel().pull_changes(repo.repo_name,
self.rhodecode_user.username)
return 'Pulled from `%s`' % repo.repo_name
Beginning of API implementation for rhodecode
r1445 except Exception:
Refactored API...
r2526 log.error(traceback.format_exc())
raise JSONRPCError(
'Unable to pull changes from `%s`' % repo.repo_name
)
Beginning of API implementation for rhodecode
r1445
Nicolas VINOT
Correct code style
r1593 @HasPermissionAllDecorator('hg.admin')
API: Added option to rescann repositories via api call
r2697 def rescan_repos(self, apiuser, remove_obsolete=Optional(False)):
"""
Dispatch rescan repositories action. If remove_obsolete is set
than also delete repos that are in database but not in the filesystem.
aka "clean zombies"
:param apiuser:
:param remove_obsolete:
"""
try:
rm_obsolete = Optional.extract(remove_obsolete)
added, removed = repo2db_mapper(ScmModel().repo_scan(),
remove_obsolete=rm_obsolete)
return {'added': added, 'removed': removed}
except Exception:
log.error(traceback.format_exc())
raise JSONRPCError(
added API call for locking/unlocking repositories
r2737 'Error occurred during rescan repositories action'
)
API invalidate_cache function ref #733
r3235 def invalidate_cache(self, apiuser, repoid):
"""
Dispatch cache invalidation action on given repo
:param apiuser:
:param repoid:
"""
repo = get_repo_or_error(repoid)
if HasPermissionAnyApi('hg.admin')(user=apiuser) is False:
# check if we have admin permission for this repo !
if HasRepoPermissionAnyApi('repository.admin',
'repository.write')(user=apiuser,
repo_name=repo.repo_name) is False:
raise JSONRPCError('repository `%s` does not exist' % (repoid))
try:
Mads Kiilerich
api: don't report invalidated cache_keys after invalidating a repo...
r3759 ScmModel().mark_for_invalidation(repo.repo_name)
return ('Caches of repository `%s` was invalidated' % repoid)
API invalidate_cache function ref #733
r3235 except Exception:
log.error(traceback.format_exc())
raise JSONRPCError(
'Error occurred during cache invalidation action'
)
calling lock function without lock attribute, will return lock state
r3457 def lock(self, apiuser, repoid, locked=Optional(None),
userid=Optional(OAttr('apiuser'))):
added API call for locking/unlocking repositories
r2737 """
Implemented API calls for non-admin users for locking/unlocking repositories
r3161 Set locking state on particular repository by given user, if
this command is runned by non-admin account userid is set to user
who is calling this method
added API call for locking/unlocking repositories
r2737
:param apiuser:
:param repoid:
:param userid:
:param locked:
"""
repo = get_repo_or_error(repoid)
Implemented API calls for non-admin users for locking/unlocking repositories
r3161 if HasPermissionAnyApi('hg.admin')(user=apiuser):
pass
elif HasRepoPermissionAnyApi('repository.admin',
'repository.write')(user=apiuser,
repo_name=repo.repo_name):
whitespace cleanup
r3168 #make sure normal user does not pass someone else userid,
API methods create_repo, fork_repo, delete_repo, get_repo, get_repos...
r3163 #he is not allowed to do that
if not isinstance(userid, Optional) and userid != apiuser.user_id:
Implemented API calls for non-admin users for locking/unlocking repositories
r3161 raise JSONRPCError(
API methods create_repo, fork_repo, delete_repo, get_repo, get_repos...
r3163 'userid is not the same as your user'
Implemented API calls for non-admin users for locking/unlocking repositories
r3161 )
else:
API methods create_repo, fork_repo, delete_repo, get_repo, get_repos...
r3163 raise JSONRPCError('repository `%s` does not exist' % (repoid))
Implemented API calls for non-admin users for locking/unlocking repositories
r3161 if isinstance(userid, Optional):
userid = apiuser.user_id
calling lock function without lock attribute, will return lock state
r3457
added API call for locking/unlocking repositories
r2737 user = get_user_or_error(userid)
calling lock function without lock attribute, will return lock state
r3457
if isinstance(locked, Optional):
lockobj = Repository.getlock(repo)
if lockobj[0] is None:
locking API returns objects instead of string messages....
r3808 _d = {
'repo': repo.repo_name,
'locked': False,
'locked_since': None,
'locked_by': None,
'msg': 'Repo `%s` not locked.' % repo.repo_name
}
return _d
added API call for locking/unlocking repositories
r2737 else:
calling lock function without lock attribute, will return lock state
r3457 userid, time_ = lockobj
locking API returns objects instead of string messages....
r3808 lock_user = get_user_or_error(userid)
_d = {
'repo': repo.repo_name,
'locked': True,
'locked_since': time_,
'locked_by': lock_user.username,
'msg': ('Repo `%s` locked by `%s`. '
% (repo.repo_name,
json.dumps(time_to_datetime(time_))))
}
return _d
added API call for locking/unlocking repositories
r2737
locking API returns objects instead of string messages....
r3808 # force locked state through a flag
calling lock function without lock attribute, will return lock state
r3457 else:
locked = str2bool(locked)
try:
if locked:
locking API returns objects instead of string messages....
r3808 lock_time = time.time()
Repository.lock(repo, user.user_id, lock_time)
calling lock function without lock attribute, will return lock state
r3457 else:
locking API returns objects instead of string messages....
r3808 lock_time = None
calling lock function without lock attribute, will return lock state
r3457 Repository.unlock(repo)
locking API returns objects instead of string messages....
r3808 _d = {
'repo': repo.repo_name,
'locked': locked,
'locked_since': lock_time,
'locked_by': user.username,
'msg': ('User `%s` set lock state for repo `%s` to `%s`'
% (user.username, repo.repo_name, locked))
}
return _d
calling lock function without lock attribute, will return lock state
r3457 except Exception:
log.error(traceback.format_exc())
raise JSONRPCError(
'Error occurred locking repository `%s`' % repo.repo_name
)
API: Added option to rescann repositories via api call
r2697
get_locks API function draft
r3502 def get_locks(self, apiuser, userid=Optional(OAttr('apiuser'))):
"""
Get all locks for given userid, if
this command is runned by non-admin account userid is set to user
who is calling this method, thus returning locks for himself
:param apiuser:
:param userid:
"""
if HasPermissionAnyApi('hg.admin')(user=apiuser):
pass
else:
#make sure normal user does not pass someone else userid,
#he is not allowed to do that
if not isinstance(userid, Optional) and userid != apiuser.user_id:
raise JSONRPCError(
'userid is not the same as your user'
)
ret = []
if isinstance(userid, Optional):
user = None
else:
user = get_user_or_error(userid)
#show all locks
for r in Repository.getAll():
userid, time_ = r.locked
if time_:
_api_data = r.get_api_data()
# if we use userfilter just show the locks for this user
if user:
if safe_int(userid) == user.user_id:
ret.append(_api_data)
else:
ret.append(_api_data)
return ret
API: Added option to rescann repositories via api call
r2697 @HasPermissionAllDecorator('hg.admin')
added API method for checking IP
r3126 def show_ip(self, apiuser, userid):
"""
Shows IP address as seen from RhodeCode server, together with all
defined IP addresses for given user
:param apiuser:
:param userid:
"""
user = get_user_or_error(userid)
ips = UserIpMap.query().filter(UserIpMap.user == user).all()
return dict(
ip_addr_server=self.ip_addr,
user_ips=ips
)
API method get_user can be executed by non-admin users ref #539
r3162 def get_user(self, apiuser, userid=Optional(OAttr('apiuser'))):
Nicolas VINOT
Implement all CRUD API operation for repo
r1587 """"
API method get_user can be executed by non-admin users ref #539
r3162 Get a user by username, or userid, if userid is given
Nicolas VINOT
Implement all CRUD API operation for repo
r1587
implements #329...
r1793 :param apiuser:
Refactored API...
r2526 :param userid:
Nicolas VINOT
Implement all CRUD API operation for repo
r1587 """
API methods create_repo, fork_repo, delete_repo, get_repo, get_repos...
r3163 if HasPermissionAnyApi('hg.admin')(user=apiuser) is False:
whitespace cleanup
r3168 #make sure normal user does not pass someone else userid,
API methods create_repo, fork_repo, delete_repo, get_repo, get_repos...
r3163 #he is not allowed to do that
if not isinstance(userid, Optional) and userid != apiuser.user_id:
API method get_user can be executed by non-admin users ref #539
r3162 raise JSONRPCError(
API methods create_repo, fork_repo, delete_repo, get_repo, get_repos...
r3163 'userid is not the same as your user'
API method get_user can be executed by non-admin users ref #539
r3162 )
API methods create_repo, fork_repo, delete_repo, get_repo, get_repos...
r3163
if isinstance(userid, Optional):
API method get_user can be executed by non-admin users ref #539
r3162 userid = apiuser.user_id
Beginning of API implementation for rhodecode
r1445
Refactored API...
r2526 user = get_user_or_error(userid)
data = user.get_api_data()
data['permissions'] = AuthUser(user_id=user.user_id).permissions
return data
implements #329...
r1793
@HasPermissionAllDecorator('hg.admin')
def get_users(self, apiuser):
""""
Get all users
:param apiuser:
"""
result = []
hide listing of default user...
r3799 users_list = User.query().order_by(User.username)\
.filter(User.username != User.DEFAULT_USER)\
.all()
for user in users_list:
Refactored API...
r2526 result.append(user.get_api_data())
Nicolas VINOT
Add API for repositories and groups (creation, permission)
r1586 return result
Nicolas VINOT
Correct code style
r1593 @HasPermissionAllDecorator('hg.admin')
make the password optional in API calls
r3809 def create_user(self, apiuser, username, email, password=Optional(None),
Refactored API...
r2526 firstname=Optional(None), lastname=Optional(None),
active=Optional(True), admin=Optional(False),
ldap_dn=Optional(None)):
Extended API...
r1500 """
API added explicit method for updating user account
r2002 Create new user
Nicolas VINOT
Improve API with user/group/repo CRUD methods
r1584
Extended API...
r1500 :param apiuser:
:param username:
Refactored API...
r2526 :param email:
Extended API...
r1500 :param password:
Refactored API...
r2526 :param firstname:
Extended API...
r1500 :param lastname:
Nicolas VINOT
Improve API with user/group/repo CRUD methods
r1584 :param active:
:param admin:
:param ldap_dn:
Extended API...
r1500 """
Nicolas VINOT
[API] Create groups needed when creating repo
r1589
Refactored API...
r2526 if UserModel().get_by_username(username):
raise JSONRPCError("user `%s` already exist" % username)
if UserModel().get_by_email(email, case_insensitive=True):
raise JSONRPCError("email `%s` already exist" % email)
API: allowed password field to be null when used with ldap_dn ref #362...
r2008
fixed passing password via API create_user
r2758 if Optional.extract(ldap_dn):
API: allowed password field to be null when used with ldap_dn ref #362...
r2008 # generate temporary password if ldap_dn
password = PasswordGenerator().gen_password(length=8)
Extended API...
r1500 try:
API, added delete_user method....
r2365 user = UserModel().create_or_update(
Refactored API...
r2526 username=Optional.extract(username),
password=Optional.extract(password),
email=Optional.extract(email),
firstname=Optional.extract(firstname),
lastname=Optional.extract(lastname),
active=Optional.extract(active),
admin=Optional.extract(admin),
ldap_dn=Optional.extract(ldap_dn)
api review...
r1843 )
Refactored API...
r2526 Session().commit()
api review...
r1843 return dict(
Refactored API...
r2526 msg='created new user `%s`' % username,
user=user.get_api_data()
api review...
r1843 )
Extended API...
r1500 except Exception:
Nicolas VINOT
Correct code style
r1593 log.error(traceback.format_exc())
Refactored API...
r2526 raise JSONRPCError('failed to create user `%s`' % username)
Nicolas VINOT
Implement all CRUD API operation for repo
r1587
Nicolas VINOT
Correct code style
r1593 @HasPermissionAllDecorator('hg.admin')
Refactored API...
r2526 def update_user(self, apiuser, userid, username=Optional(None),
email=Optional(None), firstname=Optional(None),
lastname=Optional(None), active=Optional(None),
admin=Optional(None), ldap_dn=Optional(None),
password=Optional(None)):
API added explicit method for updating user account
r2002 """
Updates given user
:param apiuser:
Refactored API...
r2526 :param userid:
API added explicit method for updating user account
r2002 :param username:
:param email:
Refactored API...
r2526 :param firstname:
API added explicit method for updating user account
r2002 :param lastname:
:param active:
:param admin:
:param ldap_dn:
Refactored API...
r2526 :param password:
API added explicit method for updating user account
r2002 """
Refactored API...
r2526
user = get_user_or_error(userid)
fixed api issue with changing username during update_user
r2657 # call function and store only updated arguments
updates = {}
def store_update(attr, name):
if not isinstance(attr, Optional):
updates[name] = attr
API added explicit method for updating user account
r2002
try:
Refactored API...
r2526
fixed api issue with changing username during update_user
r2657 store_update(username, 'username')
store_update(password, 'password')
store_update(email, 'email')
store_update(firstname, 'name')
store_update(lastname, 'lastname')
store_update(active, 'active')
store_update(admin, 'admin')
store_update(ldap_dn, 'ldap_dn')
user = UserModel().update_user(user, **updates)
Refactored API...
r2526 Session().commit()
API added explicit method for updating user account
r2002 return dict(
API: update_user returns new updated user data
r2507 msg='updated user ID:%s %s' % (user.user_id, user.username),
Refactored API...
r2526 user=user.get_api_data()
API added explicit method for updating user account
r2002 )
hide listing of default user...
r3799 except DefaultUserException:
log.error(traceback.format_exc())
raise JSONRPCError('editing default user is forbidden')
API added explicit method for updating user account
r2002 except Exception:
log.error(traceback.format_exc())
Refactored API...
r2526 raise JSONRPCError('failed to update user `%s`' % userid)
API, added delete_user method....
r2365
@HasPermissionAllDecorator('hg.admin')
def delete_user(self, apiuser, userid):
""""
Deletes an user
:param apiuser:
Refactored API...
r2526 :param userid:
API, added delete_user method....
r2365 """
Refactored API...
r2526 user = get_user_or_error(userid)
API, added delete_user method....
r2365
try:
UserModel().delete(userid)
Refactored API...
r2526 Session().commit()
API, added delete_user method....
r2365 return dict(
Refactored API...
r2526 msg='deleted user ID:%s %s' % (user.user_id, user.username),
user=None
API, added delete_user method....
r2365 )
except Exception:
log.error(traceback.format_exc())
Refactored API...
r2526 raise JSONRPCError('failed to delete ID:%s %s' % (user.user_id,
user.username))
API added explicit method for updating user account
r2002
@HasPermissionAllDecorator('hg.admin')
Refactored API...
r2526 def get_users_group(self, apiuser, usersgroupid):
Nicolas VINOT
Implement all CRUD API operation for repo
r1587 """"
Mads Kiilerich
"Users groups" is grammatically incorrect English - rename to "user groups"...
r3410 Get user group by name or id
Nicolas VINOT
Implement all CRUD API operation for repo
r1587
implements #329...
r1793 :param apiuser:
Refactored API...
r2526 :param usersgroupid:
Nicolas VINOT
Implement all CRUD API operation for repo
r1587 """
Refactored API...
r2526 users_group = get_users_group_or_error(usersgroupid)
Nicolas VINOT
Implement all CRUD API operation for repo
r1587
Refactored API...
r2526 data = users_group.get_api_data()
Beginning of API implementation for rhodecode
r1445
Nicolas VINOT
Implement all CRUD API operation for repo
r1587 members = []
for user in users_group.members:
user = user.user
Refactored API...
r2526 members.append(user.get_api_data())
data['members'] = members
return data
Nicolas VINOT
Implement all CRUD API operation for repo
r1587
Nicolas VINOT
Correct code style
r1593 @HasPermissionAllDecorator('hg.admin')
def get_users_groups(self, apiuser):
Nicolas VINOT
Improve API with user/group/repo CRUD methods
r1584 """"
Mads Kiilerich
"Users groups" is grammatically incorrect English - rename to "user groups"...
r3410 Get all user groups
Nicolas VINOT
Improve API with user/group/repo CRUD methods
r1584
implements #329...
r1793 :param apiuser:
Nicolas VINOT
Improve API with user/group/repo CRUD methods
r1584 """
Nicolas VINOT
Add API for repositories and groups (creation, permission)
r1586
Nicolas VINOT
Improve API with user/group/repo CRUD methods
r1584 result = []
Mads Kiilerich
further cleanup of UsersGroup...
r3417 for users_group in UserGroupModel().get_all():
Refactored API...
r2526 result.append(users_group.get_api_data())
Nicolas VINOT
Improve API with user/group/repo CRUD methods
r1584 return result
Nicolas VINOT
Correct code style
r1593 @HasPermissionAllDecorator('hg.admin')
- Manage User’s Groups: create, delete, rename, add/remove users inside....
r3714 def create_users_group(self, apiuser, group_name,
owner=Optional(OAttr('apiuser')),
active=Optional(True)):
Extended API...
r1500 """
Creates an new usergroup
Nicolas VINOT
Improve API with user/group/repo CRUD methods
r1584
Refactored API...
r2526 :param apiuser:
api review...
r1843 :param group_name:
- Manage User’s Groups: create, delete, rename, add/remove users inside....
r3714 :param owner:
Extended API...
r1500 :param active:
"""
Nicolas VINOT
Add API for repositories and groups (creation, permission)
r1586
Mads Kiilerich
further cleanup of UsersGroup...
r3417 if UserGroupModel().get_by_name(group_name):
Mads Kiilerich
"Users groups" is grammatically incorrect English - rename to "user groups"...
r3410 raise JSONRPCError("user group `%s` already exist" % group_name)
Nicolas VINOT
[API] Create groups needed when creating repo
r1589
Extended API...
r1500 try:
- Manage User’s Groups: create, delete, rename, add/remove users inside....
r3714 if isinstance(owner, Optional):
owner = apiuser.user_id
owner = get_user_or_error(owner)
Refactored API...
r2526 active = Optional.extract(active)
- Manage User’s Groups: create, delete, rename, add/remove users inside....
r3714 ug = UserGroupModel().create(name=group_name,
owner=owner,
active=active)
Refactored API...
r2526 Session().commit()
return dict(
Mads Kiilerich
"Users groups" is grammatically incorrect English - rename to "user groups"...
r3410 msg='created new user group `%s`' % group_name,
Refactored API...
r2526 users_group=ug.get_api_data()
)
Extended API...
r1500 except Exception:
Nicolas VINOT
Correct code style
r1593 log.error(traceback.format_exc())
Refactored API...
r2526 raise JSONRPCError('failed to create group `%s`' % group_name)
Nicolas VINOT
Improve API with user/group/repo CRUD methods
r1584
Nicolas VINOT
Correct code style
r1593 @HasPermissionAllDecorator('hg.admin')
Refactored API...
r2526 def add_user_to_users_group(self, apiuser, usersgroupid, userid):
Nicolas VINOT
Improve API with user/group/repo CRUD methods
r1584 """"
Mads Kiilerich
"Users groups" is grammatically incorrect English - rename to "user groups"...
r3410 Add a user to a user group
Nicolas VINOT
Improve API with user/group/repo CRUD methods
r1584
implements #329...
r1793 :param apiuser:
Refactored API...
r2526 :param usersgroupid:
:param userid:
Nicolas VINOT
Improve API with user/group/repo CRUD methods
r1584 """
Refactored API...
r2526 user = get_user_or_error(userid)
users_group = get_users_group_or_error(usersgroupid)
Nicolas VINOT
Improve API with user/group/repo CRUD methods
r1584
Nicolas VINOT
Add API for repositories and groups (creation, permission)
r1586 try:
Mads Kiilerich
further cleanup of UsersGroup...
r3417 ugm = UserGroupModel().add_user_to_group(users_group, user)
API changes...
r1989 success = True if ugm != True else False
Mads Kiilerich
"Users groups" is grammatically incorrect English - rename to "user groups"...
r3410 msg = 'added member `%s` to user group `%s`' % (
Refactored API...
r2526 user.username, users_group.users_group_name
)
API changes...
r1989 msg = msg if success else 'User is already in that group'
Refactored API...
r2526 Session().commit()
API changes...
r1989
return dict(
success=success,
msg=msg
)
Nicolas VINOT
Implement all CRUD API operation for repo
r1587 except Exception:
Nicolas VINOT
Correct code style
r1593 log.error(traceback.format_exc())
Refactored API...
r2526 raise JSONRPCError(
Mads Kiilerich
"Users groups" is grammatically incorrect English - rename to "user groups"...
r3410 'failed to add member to user group `%s`' % (
Refactored API...
r2526 users_group.users_group_name
)
)
API changes...
r1989
@HasPermissionAllDecorator('hg.admin')
Refactored API...
r2526 def remove_user_from_users_group(self, apiuser, usersgroupid, userid):
API changes...
r1989 """
Remove user from a group
Refactored API...
r2526 :param apiuser:
:param usersgroupid:
:param userid:
API changes...
r1989 """
Refactored API...
r2526 user = get_user_or_error(userid)
users_group = get_users_group_or_error(usersgroupid)
API changes...
r1989
try:
Mads Kiilerich
further cleanup of UsersGroup...
r3417 success = UserGroupModel().remove_user_from_group(users_group,
Refactored API...
r2526 user)
Mads Kiilerich
"Users groups" is grammatically incorrect English - rename to "user groups"...
r3410 msg = 'removed member `%s` from user group `%s`' % (
Refactored API...
r2526 user.username, users_group.users_group_name
)
API changes...
r1989 msg = msg if success else "User wasn't in group"
Refactored API...
r2526 Session().commit()
API changes...
r1989 return dict(success=success, msg=msg)
except Exception:
log.error(traceback.format_exc())
Refactored API...
r2526 raise JSONRPCError(
Mads Kiilerich
"Users groups" is grammatically incorrect English - rename to "user groups"...
r3410 'failed to remove member from user group `%s`' % (
Refactored API...
r2526 users_group.users_group_name
)
)
Nicolas VINOT
Implement all CRUD API operation for repo
r1587
API get_user and get_repo methods can fetch by id or names
r2010 def get_repo(self, apiuser, repoid):
Nicolas VINOT
Implement all CRUD API operation for repo
r1587 """"
Get repository by name
implements #329...
r1793 :param apiuser:
Refactored API...
r2526 :param repoid:
Nicolas VINOT
Implement all CRUD API operation for repo
r1587 """
Refactored API...
r2526 repo = get_repo_or_error(repoid)
Nicolas VINOT
Improve API with user/group/repo CRUD methods
r1584
API methods create_repo, fork_repo, delete_repo, get_repo, get_repos...
r3163 if HasPermissionAnyApi('hg.admin')(user=apiuser) is False:
# check if we have admin permission for this repo !
if HasRepoPermissionAnyApi('repository.admin')(user=apiuser,
repo_name=repo.repo_name) is False:
raise JSONRPCError('repository `%s` does not exist' % (repoid))
Nicolas VINOT
Implement all CRUD API operation for repo
r1587 members = []
aparkar
Added repository followers to the get_repo api function result.
r3195 followers = []
Nicolas VINOT
Implement all CRUD API operation for repo
r1587 for user in repo.repo_to_perm:
perm = user.permission.permission_name
user = user.user
Refactored API...
r2526 user_data = user.get_api_data()
user_data['type'] = "user"
user_data['permission'] = perm
members.append(user_data)
Nicolas VINOT
Implement all CRUD API operation for repo
r1587 for users_group in repo.users_group_to_perm:
perm = users_group.permission.permission_name
users_group = users_group.users_group
Refactored API...
r2526 users_group_data = users_group.get_api_data()
users_group_data['type'] = "users_group"
users_group_data['permission'] = perm
members.append(users_group_data)
Nicolas VINOT
Improve API with user/group/repo CRUD methods
r1584
aparkar
Added repository followers to the get_repo api function result.
r3195 for user in repo.followers:
followers.append(user.user.get_api_data())
Refactored API...
r2526 data = repo.get_api_data()
data['members'] = members
aparkar
Added repository followers to the get_repo api function result.
r3195 data['followers'] = followers
Refactored API...
r2526 return data
Nicolas VINOT
Implement all CRUD API operation for repo
r1587
Nicolas VINOT
Correct code style
r1593 def get_repos(self, apiuser):
Nicolas VINOT
Add API for repositories and groups (creation, permission)
r1586 """"
Nicolas VINOT
Implement all CRUD API operation for repo
r1587 Get all repositories
Nicolas VINOT
Add API for repositories and groups (creation, permission)
r1586
implements #329...
r1793 :param apiuser:
Nicolas VINOT
Add API for repositories and groups (creation, permission)
r1586 """
API methods create_repo, fork_repo, delete_repo, get_repo, get_repos...
r3163 result = []
if HasPermissionAnyApi('hg.admin')(user=apiuser) is False:
repos = RepoModel().get_all_user_repos(user=apiuser)
else:
repos = RepoModel().get_all()
Nicolas VINOT
Implement all CRUD API operation for repo
r1587
API methods create_repo, fork_repo, delete_repo, get_repo, get_repos...
r3163 for repo in repos:
Refactored API...
r2526 result.append(repo.get_api_data())
Nicolas VINOT
Add API for repositories and groups (creation, permission)
r1586 return result
Implemented API calls for non-admin users for locking/unlocking repositories
r3161 @HasPermissionAllDecorator('hg.admin')
Refactored API...
r2526 def get_repo_nodes(self, apiuser, repoid, revision, root_path,
implements #330 api method for listing nodes at particular revision...
r1810 ret_type='all'):
"""
returns a list of nodes and it's children
for a given path at given revision. It's possible to specify ret_type
to show only files or dirs
:param apiuser:
Refactored API...
r2526 :param repoid: name or id of repository
implements #330 api method for listing nodes at particular revision...
r1810 :param revision: revision for which listing should be done
:param root_path: path from which start displaying
:param ret_type: return type 'all|files|dirs' nodes
"""
Refactored API...
r2526 repo = get_repo_or_error(repoid)
implements #330 api method for listing nodes at particular revision...
r1810 try:
Refactored API...
r2526 _d, _f = ScmModel().get_nodes(repo, revision, root_path,
implements #330 api method for listing nodes at particular revision...
r1810 flat=False)
_map = {
'all': _d + _f,
'files': _f,
'dirs': _d,
}
return _map[ret_type]
except KeyError:
raise JSONRPCError('ret_type must be one of %s' % _map.keys())
Refactored API...
r2526 except Exception:
log.error(traceback.format_exc())
raise JSONRPCError(
'failed to get repo: `%s` nodes' % repo.repo_name
)
implements #330 api method for listing nodes at particular revision...
r1810
Nicolas VINOT
Correct code style
r1593 @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
API methods create_repo, fork_repo, delete_repo, get_repo, get_repos...
r3163 def create_repo(self, apiuser, repo_name, owner=Optional(OAttr('apiuser')),
repo_type=Optional('hg'),
Refactored API...
r2526 description=Optional(''), private=Optional(False),
Default parameters are now also used for creating repos using API calls, and initial repo scanner...
r3115 clone_uri=Optional(None), landing_rev=Optional('tip'),
enable_statistics=Optional(False),
enable_locking=Optional(False),
enable_downloads=Optional(False)):
Nicolas VINOT
Improve API with user/group/repo CRUD methods
r1584 """
added clone_uri to API method for creating users
r2006 Create repository, if clone_url is given it makes a remote clone
API methods create_repo, fork_repo, delete_repo, get_repo, get_repos...
r3163 if repo_name is within a group name the groups will be created
Refactored API...
r2526 automatically if they aren't present
Nicolas VINOT
Improve API with user/group/repo CRUD methods
r1584
implements #329...
r1793 :param apiuser:
api review...
r1843 :param repo_name:
Refactored API...
r2526 :param onwer:
:param repo_type:
implements #329...
r1793 :param description:
:param private:
added clone_uri to API method for creating users
r2006 :param clone_uri:
Refactored API...
r2526 :param landing_rev:
Nicolas VINOT
Improve API with user/group/repo CRUD methods
r1584 """
API methods create_repo, fork_repo, delete_repo, get_repo, get_repos...
r3163 if HasPermissionAnyApi('hg.admin')(user=apiuser) is False:
if not isinstance(owner, Optional):
#forbid setting owner for non-admins
raise JSONRPCError(
'Only RhodeCode admin can specify `owner` param'
)
if isinstance(owner, Optional):
owner = apiuser.user_id
Refactored API...
r2526 owner = get_user_or_error(owner)
if RepoModel().get_by_repo_name(repo_name):
raise JSONRPCError("repo `%s` already exist" % repo_name)
Default parameters are now also used for creating repos using API calls, and initial repo scanner...
r3115 defs = RhodeCodeSetting.get_default_repo_settings(strip_prefix=True)
if isinstance(private, Optional):
private = defs.get('repo_private') or Optional.extract(private)
if isinstance(repo_type, Optional):
repo_type = defs.get('repo_type')
if isinstance(enable_statistics, Optional):
enable_statistics = defs.get('repo_enable_statistics')
if isinstance(enable_locking, Optional):
enable_locking = defs.get('repo_enable_locking')
if isinstance(enable_downloads, Optional):
enable_downloads = defs.get('repo_enable_downloads')
Refactored API...
r2526 clone_uri = Optional.extract(clone_uri)
description = Optional.extract(description)
landing_rev = Optional.extract(landing_rev)
Nicolas VINOT
Improve API with user/group/repo CRUD methods
r1584
Nicolas VINOT
Add API for repositories and groups (creation, permission)
r1586 try:
Refactored API...
r2526 # create structure of groups and return the last group
Resolve error occurring during recursive group creation in API create-repo function
r2120 group = map_groups(repo_name)
Nicolas VINOT
[API] Create groups needed when creating repo
r1589
Refactored API...
r2526 repo = RepoModel().create_repo(
repo_name=repo_name,
repo_type=repo_type,
description=description,
owner=owner,
private=private,
clone_uri=clone_uri,
repos_group=group,
landing_rev=landing_rev,
Default parameters are now also used for creating repos using API calls, and initial repo scanner...
r3115 enable_statistics=enable_statistics,
enable_downloads=enable_downloads,
enable_locking=enable_locking
implements #329...
r1793 )
Refactored API...
r2526
Session().commit()
api review...
r1843 return dict(
Refactored API...
r2526 msg="Created new repository `%s`" % (repo.repo_name),
repo=repo.get_api_data()
api review...
r1843 )
Nicolas VINOT
Improve API with user/group/repo CRUD methods
r1584 except Exception:
Nicolas VINOT
Correct code style
r1593 log.error(traceback.format_exc())
Refactored API...
r2526 raise JSONRPCError('failed to create repository `%s`' % repo_name)
API methods create_repo, fork_repo, delete_repo, get_repo, get_repos...
r3163 @HasPermissionAnyDecorator('hg.admin', 'hg.fork.repository')
def fork_repo(self, apiuser, repoid, fork_name, owner=Optional(OAttr('apiuser')),
Implemented #354 added forking option to API
r2653 description=Optional(''), copy_permissions=Optional(False),
private=Optional(False), landing_rev=Optional('tip')):
repo = get_repo_or_error(repoid)
repo_name = repo.repo_name
_repo = RepoModel().get_by_repo_name(fork_name)
if _repo:
type_ = 'fork' if _repo.fork else 'repo'
raise JSONRPCError("%s `%s` already exist" % (type_, fork_name))
API methods create_repo, fork_repo, delete_repo, get_repo, get_repos...
r3163 if HasPermissionAnyApi('hg.admin')(user=apiuser):
pass
elif HasRepoPermissionAnyApi('repository.admin',
'repository.write',
'repository.read')(user=apiuser,
repo_name=repo.repo_name):
if not isinstance(owner, Optional):
#forbid setting owner for non-admins
raise JSONRPCError(
'Only RhodeCode admin can specify `owner` param'
)
else:
raise JSONRPCError('repository `%s` does not exist' % (repoid))
if isinstance(owner, Optional):
owner = apiuser.user_id
owner = get_user_or_error(owner)
Implemented #354 added forking option to API
r2653 try:
# create structure of groups and return the last group
group = map_groups(fork_name)
form_data = dict(
repo_name=fork_name,
repo_name_full=fork_name,
repo_group=group,
repo_type=repo.repo_type,
description=Optional.extract(description),
private=Optional.extract(private),
copy_permissions=Optional.extract(copy_permissions),
landing_rev=Optional.extract(landing_rev),
update_after_clone=False,
fork_parent_id=repo.repo_id,
)
RepoModel().create_fork(form_data, cur_user=owner)
return dict(
msg='Created fork of `%s` as `%s`' % (repo.repo_name,
fork_name),
success=True # cannot return the repo data here since fork
# cann be done async
)
except Exception:
log.error(traceback.format_exc())
raise JSONRPCError(
'failed to fork repository `%s` as `%s`' % (repo_name,
fork_name)
)
Nicolas VINOT
Improve API with user/group/repo CRUD methods
r1584
recursive forks detach...
r3641 def delete_repo(self, apiuser, repoid, forks=Optional(None)):
implements #361 API method for deleting repositories
r2003 """
Deletes a given repository
Refactored API...
r2526 :param apiuser:
:param repoid:
recursive forks detach...
r3641 :param forks: detach or delete, what do do with attached forks for repo
implements #361 API method for deleting repositories
r2003 """
Refactored API...
r2526 repo = get_repo_or_error(repoid)
API methods create_repo, fork_repo, delete_repo, get_repo, get_repos...
r3163 if HasPermissionAnyApi('hg.admin')(user=apiuser) is False:
# check if we have admin permission for this repo !
if HasRepoPermissionAnyApi('repository.admin')(user=apiuser,
repo_name=repo.repo_name) is False:
recursive forks detach...
r3641 raise JSONRPCError('repository `%s` does not exist' % (repoid))
API methods create_repo, fork_repo, delete_repo, get_repo, get_repos...
r3163
implements #361 API method for deleting repositories
r2003 try:
recursive forks detach...
r3641 handle_forks = Optional.extract(forks)
_forks_msg = ''
_forks = [f for f in repo.forks]
if handle_forks == 'detach':
_forks_msg = ' ' + _('Detached %s forks') % len(_forks)
elif handle_forks == 'delete':
_forks_msg = ' ' + _('Deleted %s forks') % len(_forks)
elif _forks:
raise JSONRPCError(
'Cannot delete `%s` it still contains attached forks'
% repo.repo_name
)
RepoModel().delete(repo, forks=forks)
Refactored API...
r2526 Session().commit()
implements #361 API method for deleting repositories
r2003 return dict(
recursive forks detach...
r3641 msg='Deleted repository `%s`%s' % (repo.repo_name, _forks_msg),
Refactored API...
r2526 success=True
implements #361 API method for deleting repositories
r2003 )
except Exception:
log.error(traceback.format_exc())
Refactored API...
r2526 raise JSONRPCError(
'failed to delete repository `%s`' % repo.repo_name
)
implements #361 API method for deleting repositories
r2003
Implemented API calls for non-admin users for locking/unlocking repositories
r3161 @HasPermissionAllDecorator('hg.admin')
Refactored API...
r2526 def grant_user_permission(self, apiuser, repoid, userid, perm):
Nicolas VINOT
Add API for repositories and groups (creation, permission)
r1586 """
#227 Initial version of repository groups permissions system...
r1982 Grant permission for user on given repository, or update existing one
if found
Nicolas VINOT
Improve API with user/group/repo CRUD methods
r1584
Refactored API...
r2526 :param repoid:
:param userid:
implements #329...
r1793 :param perm:
Nicolas VINOT
Add API for repositories and groups (creation, permission)
r1586 """
Refactored API...
r2526 repo = get_repo_or_error(repoid)
user = get_user_or_error(userid)
perm = get_perm_or_error(perm)
Nicolas VINOT
Add API for repositories and groups (creation, permission)
r1586
try:
#227 Initial version of repository groups permissions system...
r1982 RepoModel().grant_user_permission(repo=repo, user=user, perm=perm)
Refactored API...
r2526 Session().commit()
implements #329...
r1793 return dict(
Refactored API...
r2526 msg='Granted perm: `%s` for user: `%s` in repo: `%s`' % (
perm.permission_name, user.username, repo.repo_name
),
success=True
implements #329...
r1793 )
Nicolas VINOT
Add API for repositories and groups (creation, permission)
r1586 except Exception:
Nicolas VINOT
Correct code style
r1593 log.error(traceback.format_exc())
implements #329...
r1793 raise JSONRPCError(
Refactored API...
r2526 'failed to edit permission for user: `%s` in repo: `%s`' % (
userid, repoid
implements #329...
r1793 )
)
Implemented API calls for non-admin users for locking/unlocking repositories
r3161 @HasPermissionAllDecorator('hg.admin')
Refactored API...
r2526 def revoke_user_permission(self, apiuser, repoid, userid):
#227 Initial version of repository groups permissions system...
r1982 """
Revoke permission for user on given repository
Refactored API...
r2526 :param apiuser:
:param repoid:
:param userid:
implements #329...
r1793 """
#227 Initial version of repository groups permissions system...
r1982
Refactored API...
r2526 repo = get_repo_or_error(repoid)
user = get_user_or_error(userid)
#227 Initial version of repository groups permissions system...
r1982 try:
Refactored API...
r2526
RepoModel().revoke_user_permission(repo=repo, user=user)
#227 Initial version of repository groups permissions system...
r1982
Refactored API...
r2526 Session().commit()
#227 Initial version of repository groups permissions system...
r1982 return dict(
Refactored API...
r2526 msg='Revoked perm for user: `%s` in repo: `%s`' % (
user.username, repo.repo_name
),
success=True
#227 Initial version of repository groups permissions system...
r1982 )
except Exception:
log.error(traceback.format_exc())
raise JSONRPCError(
Refactored API...
r2526 'failed to edit permission for user: `%s` in repo: `%s`' % (
userid, repoid
#227 Initial version of repository groups permissions system...
r1982 )
)
Implemented API calls for non-admin users for locking/unlocking repositories
r3161 @HasPermissionAllDecorator('hg.admin')
Refactored API...
r2526 def grant_users_group_permission(self, apiuser, repoid, usersgroupid,
perm):
#227 Initial version of repository groups permissions system...
r1982 """
Mads Kiilerich
"Users groups" is grammatically incorrect English - rename to "user groups"...
r3410 Grant permission for user group on given repository, or update
#227 Initial version of repository groups permissions system...
r1982 existing one if found
Refactored API...
r2526 :param apiuser:
:param repoid:
:param usersgroupid:
implements #329...
r1793 :param perm:
"""
Refactored API...
r2526 repo = get_repo_or_error(repoid)
perm = get_perm_or_error(perm)
users_group = get_users_group_or_error(usersgroupid)
implements #329...
r1793
try:
Refactored API...
r2526 RepoModel().grant_users_group_permission(repo=repo,
group_name=users_group,
#227 Initial version of repository groups permissions system...
r1982 perm=perm)
Refactored API...
r2526 Session().commit()
implements #329...
r1793 return dict(
Mads Kiilerich
"Users groups" is grammatically incorrect English - rename to "user groups"...
r3410 msg='Granted perm: `%s` for user group: `%s` in '
Refactored API...
r2526 'repo: `%s`' % (
perm.permission_name, users_group.users_group_name,
repo.repo_name
),
success=True
)
except Exception:
log.error(traceback.format_exc())
raise JSONRPCError(
Mads Kiilerich
"Users groups" is grammatically incorrect English - rename to "user groups"...
r3410 'failed to edit permission for user group: `%s` in '
Refactored API...
r2526 'repo: `%s`' % (
usersgroupid, repo.repo_name
implements #329...
r1793 )
)
Refactored API...
r2526
Implemented API calls for non-admin users for locking/unlocking repositories
r3161 @HasPermissionAllDecorator('hg.admin')
Refactored API...
r2526 def revoke_users_group_permission(self, apiuser, repoid, usersgroupid):
"""
Mads Kiilerich
"Users groups" is grammatically incorrect English - rename to "user groups"...
r3410 Revoke permission for user group on given repository
Refactored API...
r2526
:param apiuser:
:param repoid:
:param usersgroupid:
"""
repo = get_repo_or_error(repoid)
users_group = get_users_group_or_error(usersgroupid)
try:
RepoModel().revoke_users_group_permission(repo=repo,
group_name=users_group)
Session().commit()
return dict(
Mads Kiilerich
"Users groups" is grammatically incorrect English - rename to "user groups"...
r3410 msg='Revoked perm for user group: `%s` in repo: `%s`' % (
Refactored API...
r2526 users_group.users_group_name, repo.repo_name
),
success=True
)
implements #329...
r1793 except Exception:
log.error(traceback.format_exc())
raise JSONRPCError(
Mads Kiilerich
"Users groups" is grammatically incorrect English - rename to "user groups"...
r3410 'failed to edit permission for user group: `%s` in '
Refactored API...
r2526 'repo: `%s`' % (
users_group.users_group_name, repo.repo_name
implements #329...
r1793 )
)