##// END OF EJS Templates
Implemented #354 added forking option to API
marcink -
r2653:8be70a4d beta
parent child Browse files
Show More
@@ -1,739 +1,761 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.controllers.api
3 rhodecode.controllers.api
4 ~~~~~~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~~~~~~
5
5
6 API controller for RhodeCode
6 API controller for RhodeCode
7
7
8 :created_on: Aug 20, 2011
8 :created_on: Aug 20, 2011
9 :author: marcink
9 :author: marcink
10 :copyright: (C) 2011-2012 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2011-2012 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
11 :license: GPLv3, see COPYING for more details.
12 """
12 """
13 # This program is free software; you can redistribute it and/or
13 # This program is free software; you can redistribute it and/or
14 # modify it under the terms of the GNU General Public License
14 # modify it under the terms of the GNU General Public License
15 # as published by the Free Software Foundation; version 2
15 # as published by the Free Software Foundation; version 2
16 # of the License or (at your opinion) any later version of the license.
16 # of the License or (at your opinion) any later version of the license.
17 #
17 #
18 # This program is distributed in the hope that it will be useful,
18 # This program is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
21 # GNU General Public License for more details.
22 #
22 #
23 # You should have received a copy of the GNU General Public License
23 # You should have received a copy of the GNU General Public License
24 # along with this program; if not, write to the Free Software
24 # along with this program; if not, write to the Free Software
25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
26 # MA 02110-1301, USA.
26 # MA 02110-1301, USA.
27
27
28 import traceback
28 import traceback
29 import logging
29 import logging
30
30
31 from rhodecode.controllers.api import JSONRPCController, JSONRPCError
31 from rhodecode.controllers.api import JSONRPCController, JSONRPCError
32 from rhodecode.lib.auth import HasPermissionAllDecorator, \
32 from rhodecode.lib.auth import HasPermissionAllDecorator, \
33 HasPermissionAnyDecorator, PasswordGenerator, AuthUser
33 HasPermissionAnyDecorator, PasswordGenerator, AuthUser
34 from rhodecode.lib.utils import map_groups
34 from rhodecode.lib.utils import map_groups
35 from rhodecode.model.meta import Session
35 from rhodecode.model.meta import Session
36 from rhodecode.model.scm import ScmModel
36 from rhodecode.model.scm import ScmModel
37 from rhodecode.model.repo import RepoModel
37 from rhodecode.model.repo import RepoModel
38 from rhodecode.model.user import UserModel
38 from rhodecode.model.user import UserModel
39 from rhodecode.model.users_group import UsersGroupModel
39 from rhodecode.model.users_group import UsersGroupModel
40 from rhodecode.model.permission import PermissionModel
40 from rhodecode.model.permission import PermissionModel
41
41
42 log = logging.getLogger(__name__)
42 log = logging.getLogger(__name__)
43
43
44
44
45 class Optional(object):
45 class Optional(object):
46 """
46 """
47 Defines an optional parameter::
47 Defines an optional parameter::
48
48
49 param = param.getval() if isinstance(param, Optional) else param
49 param = param.getval() if isinstance(param, Optional) else param
50 param = param() if isinstance(param, Optional) else param
50 param = param() if isinstance(param, Optional) else param
51
51
52 is equivalent of::
52 is equivalent of::
53
53
54 param = Optional.extract(param)
54 param = Optional.extract(param)
55
55
56 """
56 """
57 def __init__(self, type_):
57 def __init__(self, type_):
58 self.type_ = type_
58 self.type_ = type_
59
59
60 def __repr__(self):
60 def __repr__(self):
61 return '<Optional:%s>' % self.type_.__repr__()
61 return '<Optional:%s>' % self.type_.__repr__()
62
62
63 def __call__(self):
63 def __call__(self):
64 return self.getval()
64 return self.getval()
65
65
66 def getval(self):
66 def getval(self):
67 """
67 """
68 returns value from this Optional instance
68 returns value from this Optional instance
69 """
69 """
70 return self.type_
70 return self.type_
71
71
72 @classmethod
72 @classmethod
73 def extract(cls, val):
73 def extract(cls, val):
74 if isinstance(val, cls):
74 if isinstance(val, cls):
75 return val.getval()
75 return val.getval()
76 return val
76 return val
77
77
78
78
79 def get_user_or_error(userid):
79 def get_user_or_error(userid):
80 """
80 """
81 Get user by id or name or return JsonRPCError if not found
81 Get user by id or name or return JsonRPCError if not found
82
82
83 :param userid:
83 :param userid:
84 """
84 """
85 user = UserModel().get_user(userid)
85 user = UserModel().get_user(userid)
86 if user is None:
86 if user is None:
87 raise JSONRPCError("user `%s` does not exist" % userid)
87 raise JSONRPCError("user `%s` does not exist" % userid)
88 return user
88 return user
89
89
90
90
91 def get_repo_or_error(repoid):
91 def get_repo_or_error(repoid):
92 """
92 """
93 Get repo by id or name or return JsonRPCError if not found
93 Get repo by id or name or return JsonRPCError if not found
94
94
95 :param userid:
95 :param userid:
96 """
96 """
97 repo = RepoModel().get_repo(repoid)
97 repo = RepoModel().get_repo(repoid)
98 if repo is None:
98 if repo is None:
99 raise JSONRPCError('repository `%s` does not exist' % (repoid))
99 raise JSONRPCError('repository `%s` does not exist' % (repoid))
100 return repo
100 return repo
101
101
102
102
103 def get_users_group_or_error(usersgroupid):
103 def get_users_group_or_error(usersgroupid):
104 """
104 """
105 Get users group by id or name or return JsonRPCError if not found
105 Get users group by id or name or return JsonRPCError if not found
106
106
107 :param userid:
107 :param userid:
108 """
108 """
109 users_group = UsersGroupModel().get_group(usersgroupid)
109 users_group = UsersGroupModel().get_group(usersgroupid)
110 if users_group is None:
110 if users_group is None:
111 raise JSONRPCError('users group `%s` does not exist' % usersgroupid)
111 raise JSONRPCError('users group `%s` does not exist' % usersgroupid)
112 return users_group
112 return users_group
113
113
114
114
115 def get_perm_or_error(permid):
115 def get_perm_or_error(permid):
116 """
116 """
117 Get permission by id or name or return JsonRPCError if not found
117 Get permission by id or name or return JsonRPCError if not found
118
118
119 :param userid:
119 :param userid:
120 """
120 """
121 perm = PermissionModel().get_permission_by_name(permid)
121 perm = PermissionModel().get_permission_by_name(permid)
122 if perm is None:
122 if perm is None:
123 raise JSONRPCError('permission `%s` does not exist' % (permid))
123 raise JSONRPCError('permission `%s` does not exist' % (permid))
124 return perm
124 return perm
125
125
126
126
127 class ApiController(JSONRPCController):
127 class ApiController(JSONRPCController):
128 """
128 """
129 API Controller
129 API Controller
130
130
131
131
132 Each method needs to have USER as argument this is then based on given
132 Each method needs to have USER as argument this is then based on given
133 API_KEY propagated as instance of user object
133 API_KEY propagated as instance of user object
134
134
135 Preferably this should be first argument also
135 Preferably this should be first argument also
136
136
137
137
138 Each function should also **raise** JSONRPCError for any
138 Each function should also **raise** JSONRPCError for any
139 errors that happens
139 errors that happens
140
140
141 """
141 """
142
142
143 @HasPermissionAllDecorator('hg.admin')
143 @HasPermissionAllDecorator('hg.admin')
144 def pull(self, apiuser, repoid):
144 def pull(self, apiuser, repoid):
145 """
145 """
146 Dispatch pull action on given repo
146 Dispatch pull action on given repo
147
147
148 :param apiuser:
148 :param apiuser:
149 :param repoid:
149 :param repoid:
150 """
150 """
151
151
152 repo = get_repo_or_error(repoid)
152 repo = get_repo_or_error(repoid)
153
153
154 try:
154 try:
155 ScmModel().pull_changes(repo.repo_name,
155 ScmModel().pull_changes(repo.repo_name,
156 self.rhodecode_user.username)
156 self.rhodecode_user.username)
157 return 'Pulled from `%s`' % repo.repo_name
157 return 'Pulled from `%s`' % repo.repo_name
158 except Exception:
158 except Exception:
159 log.error(traceback.format_exc())
159 log.error(traceback.format_exc())
160 raise JSONRPCError(
160 raise JSONRPCError(
161 'Unable to pull changes from `%s`' % repo.repo_name
161 'Unable to pull changes from `%s`' % repo.repo_name
162 )
162 )
163
163
164 @HasPermissionAllDecorator('hg.admin')
164 @HasPermissionAllDecorator('hg.admin')
165 def get_user(self, apiuser, userid):
165 def get_user(self, apiuser, userid):
166 """"
166 """"
167 Get a user by username
167 Get a user by username
168
168
169 :param apiuser:
169 :param apiuser:
170 :param userid:
170 :param userid:
171 """
171 """
172
172
173 user = get_user_or_error(userid)
173 user = get_user_or_error(userid)
174 data = user.get_api_data()
174 data = user.get_api_data()
175 data['permissions'] = AuthUser(user_id=user.user_id).permissions
175 data['permissions'] = AuthUser(user_id=user.user_id).permissions
176 return data
176 return data
177
177
178 @HasPermissionAllDecorator('hg.admin')
178 @HasPermissionAllDecorator('hg.admin')
179 def get_users(self, apiuser):
179 def get_users(self, apiuser):
180 """"
180 """"
181 Get all users
181 Get all users
182
182
183 :param apiuser:
183 :param apiuser:
184 """
184 """
185
185
186 result = []
186 result = []
187 for user in UserModel().get_all():
187 for user in UserModel().get_all():
188 result.append(user.get_api_data())
188 result.append(user.get_api_data())
189 return result
189 return result
190
190
191 @HasPermissionAllDecorator('hg.admin')
191 @HasPermissionAllDecorator('hg.admin')
192 def create_user(self, apiuser, username, email, password,
192 def create_user(self, apiuser, username, email, password,
193 firstname=Optional(None), lastname=Optional(None),
193 firstname=Optional(None), lastname=Optional(None),
194 active=Optional(True), admin=Optional(False),
194 active=Optional(True), admin=Optional(False),
195 ldap_dn=Optional(None)):
195 ldap_dn=Optional(None)):
196 """
196 """
197 Create new user
197 Create new user
198
198
199 :param apiuser:
199 :param apiuser:
200 :param username:
200 :param username:
201 :param email:
201 :param email:
202 :param password:
202 :param password:
203 :param firstname:
203 :param firstname:
204 :param lastname:
204 :param lastname:
205 :param active:
205 :param active:
206 :param admin:
206 :param admin:
207 :param ldap_dn:
207 :param ldap_dn:
208 """
208 """
209
209
210 if UserModel().get_by_username(username):
210 if UserModel().get_by_username(username):
211 raise JSONRPCError("user `%s` already exist" % username)
211 raise JSONRPCError("user `%s` already exist" % username)
212
212
213 if UserModel().get_by_email(email, case_insensitive=True):
213 if UserModel().get_by_email(email, case_insensitive=True):
214 raise JSONRPCError("email `%s` already exist" % email)
214 raise JSONRPCError("email `%s` already exist" % email)
215
215
216 if ldap_dn:
216 if ldap_dn:
217 # generate temporary password if ldap_dn
217 # generate temporary password if ldap_dn
218 password = PasswordGenerator().gen_password(length=8)
218 password = PasswordGenerator().gen_password(length=8)
219
219
220 try:
220 try:
221 user = UserModel().create_or_update(
221 user = UserModel().create_or_update(
222 username=Optional.extract(username),
222 username=Optional.extract(username),
223 password=Optional.extract(password),
223 password=Optional.extract(password),
224 email=Optional.extract(email),
224 email=Optional.extract(email),
225 firstname=Optional.extract(firstname),
225 firstname=Optional.extract(firstname),
226 lastname=Optional.extract(lastname),
226 lastname=Optional.extract(lastname),
227 active=Optional.extract(active),
227 active=Optional.extract(active),
228 admin=Optional.extract(admin),
228 admin=Optional.extract(admin),
229 ldap_dn=Optional.extract(ldap_dn)
229 ldap_dn=Optional.extract(ldap_dn)
230 )
230 )
231 Session().commit()
231 Session().commit()
232 return dict(
232 return dict(
233 msg='created new user `%s`' % username,
233 msg='created new user `%s`' % username,
234 user=user.get_api_data()
234 user=user.get_api_data()
235 )
235 )
236 except Exception:
236 except Exception:
237 log.error(traceback.format_exc())
237 log.error(traceback.format_exc())
238 raise JSONRPCError('failed to create user `%s`' % username)
238 raise JSONRPCError('failed to create user `%s`' % username)
239
239
240 @HasPermissionAllDecorator('hg.admin')
240 @HasPermissionAllDecorator('hg.admin')
241 def update_user(self, apiuser, userid, username=Optional(None),
241 def update_user(self, apiuser, userid, username=Optional(None),
242 email=Optional(None), firstname=Optional(None),
242 email=Optional(None), firstname=Optional(None),
243 lastname=Optional(None), active=Optional(None),
243 lastname=Optional(None), active=Optional(None),
244 admin=Optional(None), ldap_dn=Optional(None),
244 admin=Optional(None), ldap_dn=Optional(None),
245 password=Optional(None)):
245 password=Optional(None)):
246 """
246 """
247 Updates given user
247 Updates given user
248
248
249 :param apiuser:
249 :param apiuser:
250 :param userid:
250 :param userid:
251 :param username:
251 :param username:
252 :param email:
252 :param email:
253 :param firstname:
253 :param firstname:
254 :param lastname:
254 :param lastname:
255 :param active:
255 :param active:
256 :param admin:
256 :param admin:
257 :param ldap_dn:
257 :param ldap_dn:
258 :param password:
258 :param password:
259 """
259 """
260
260
261 user = get_user_or_error(userid)
261 user = get_user_or_error(userid)
262
262
263 #return old attribute if Optional is passed. We don't change parameter
263 #return old attribute if Optional is passed. We don't change parameter
264 # so user doesn't get updated parameters
264 # so user doesn't get updated parameters
265 get = lambda attr, name: (
265 get = lambda attr, name: (
266 getattr(user, name) if isinstance(attr, Optional) else attr
266 getattr(user, name) if isinstance(attr, Optional) else attr
267 )
267 )
268
268
269 try:
269 try:
270
270
271 user = UserModel().create_or_update(
271 user = UserModel().create_or_update(
272 username=get(username, 'username'),
272 username=get(username, 'username'),
273 password=get(password, 'password'),
273 password=get(password, 'password'),
274 email=get(email, 'email'),
274 email=get(email, 'email'),
275 firstname=get(firstname, 'name'),
275 firstname=get(firstname, 'name'),
276 lastname=get(lastname, 'lastname'),
276 lastname=get(lastname, 'lastname'),
277 active=get(active, 'active'),
277 active=get(active, 'active'),
278 admin=get(admin, 'admin'),
278 admin=get(admin, 'admin'),
279 ldap_dn=get(ldap_dn, 'ldap_dn')
279 ldap_dn=get(ldap_dn, 'ldap_dn')
280 )
280 )
281 Session().commit()
281 Session().commit()
282 return dict(
282 return dict(
283 msg='updated user ID:%s %s' % (user.user_id, user.username),
283 msg='updated user ID:%s %s' % (user.user_id, user.username),
284 user=user.get_api_data()
284 user=user.get_api_data()
285 )
285 )
286 except Exception:
286 except Exception:
287 log.error(traceback.format_exc())
287 log.error(traceback.format_exc())
288 raise JSONRPCError('failed to update user `%s`' % userid)
288 raise JSONRPCError('failed to update user `%s`' % userid)
289
289
290 @HasPermissionAllDecorator('hg.admin')
290 @HasPermissionAllDecorator('hg.admin')
291 def delete_user(self, apiuser, userid):
291 def delete_user(self, apiuser, userid):
292 """"
292 """"
293 Deletes an user
293 Deletes an user
294
294
295 :param apiuser:
295 :param apiuser:
296 :param userid:
296 :param userid:
297 """
297 """
298 user = get_user_or_error(userid)
298 user = get_user_or_error(userid)
299
299
300 try:
300 try:
301 UserModel().delete(userid)
301 UserModel().delete(userid)
302 Session().commit()
302 Session().commit()
303 return dict(
303 return dict(
304 msg='deleted user ID:%s %s' % (user.user_id, user.username),
304 msg='deleted user ID:%s %s' % (user.user_id, user.username),
305 user=None
305 user=None
306 )
306 )
307 except Exception:
307 except Exception:
308 log.error(traceback.format_exc())
308 log.error(traceback.format_exc())
309 raise JSONRPCError('failed to delete ID:%s %s' % (user.user_id,
309 raise JSONRPCError('failed to delete ID:%s %s' % (user.user_id,
310 user.username))
310 user.username))
311
311
312 @HasPermissionAllDecorator('hg.admin')
312 @HasPermissionAllDecorator('hg.admin')
313 def get_users_group(self, apiuser, usersgroupid):
313 def get_users_group(self, apiuser, usersgroupid):
314 """"
314 """"
315 Get users group by name or id
315 Get users group by name or id
316
316
317 :param apiuser:
317 :param apiuser:
318 :param usersgroupid:
318 :param usersgroupid:
319 """
319 """
320 users_group = get_users_group_or_error(usersgroupid)
320 users_group = get_users_group_or_error(usersgroupid)
321
321
322 data = users_group.get_api_data()
322 data = users_group.get_api_data()
323
323
324 members = []
324 members = []
325 for user in users_group.members:
325 for user in users_group.members:
326 user = user.user
326 user = user.user
327 members.append(user.get_api_data())
327 members.append(user.get_api_data())
328 data['members'] = members
328 data['members'] = members
329 return data
329 return data
330
330
331 @HasPermissionAllDecorator('hg.admin')
331 @HasPermissionAllDecorator('hg.admin')
332 def get_users_groups(self, apiuser):
332 def get_users_groups(self, apiuser):
333 """"
333 """"
334 Get all users groups
334 Get all users groups
335
335
336 :param apiuser:
336 :param apiuser:
337 """
337 """
338
338
339 result = []
339 result = []
340 for users_group in UsersGroupModel().get_all():
340 for users_group in UsersGroupModel().get_all():
341 result.append(users_group.get_api_data())
341 result.append(users_group.get_api_data())
342 return result
342 return result
343
343
344 @HasPermissionAllDecorator('hg.admin')
344 @HasPermissionAllDecorator('hg.admin')
345 def create_users_group(self, apiuser, group_name, active=Optional(True)):
345 def create_users_group(self, apiuser, group_name, active=Optional(True)):
346 """
346 """
347 Creates an new usergroup
347 Creates an new usergroup
348
348
349 :param apiuser:
349 :param apiuser:
350 :param group_name:
350 :param group_name:
351 :param active:
351 :param active:
352 """
352 """
353
353
354 if UsersGroupModel().get_by_name(group_name):
354 if UsersGroupModel().get_by_name(group_name):
355 raise JSONRPCError("users group `%s` already exist" % group_name)
355 raise JSONRPCError("users group `%s` already exist" % group_name)
356
356
357 try:
357 try:
358 active = Optional.extract(active)
358 active = Optional.extract(active)
359 ug = UsersGroupModel().create(name=group_name, active=active)
359 ug = UsersGroupModel().create(name=group_name, active=active)
360 Session().commit()
360 Session().commit()
361 return dict(
361 return dict(
362 msg='created new users group `%s`' % group_name,
362 msg='created new users group `%s`' % group_name,
363 users_group=ug.get_api_data()
363 users_group=ug.get_api_data()
364 )
364 )
365 except Exception:
365 except Exception:
366 log.error(traceback.format_exc())
366 log.error(traceback.format_exc())
367 raise JSONRPCError('failed to create group `%s`' % group_name)
367 raise JSONRPCError('failed to create group `%s`' % group_name)
368
368
369 @HasPermissionAllDecorator('hg.admin')
369 @HasPermissionAllDecorator('hg.admin')
370 def add_user_to_users_group(self, apiuser, usersgroupid, userid):
370 def add_user_to_users_group(self, apiuser, usersgroupid, userid):
371 """"
371 """"
372 Add a user to a users group
372 Add a user to a users group
373
373
374 :param apiuser:
374 :param apiuser:
375 :param usersgroupid:
375 :param usersgroupid:
376 :param userid:
376 :param userid:
377 """
377 """
378 user = get_user_or_error(userid)
378 user = get_user_or_error(userid)
379 users_group = get_users_group_or_error(usersgroupid)
379 users_group = get_users_group_or_error(usersgroupid)
380
380
381 try:
381 try:
382 ugm = UsersGroupModel().add_user_to_group(users_group, user)
382 ugm = UsersGroupModel().add_user_to_group(users_group, user)
383 success = True if ugm != True else False
383 success = True if ugm != True else False
384 msg = 'added member `%s` to users group `%s`' % (
384 msg = 'added member `%s` to users group `%s`' % (
385 user.username, users_group.users_group_name
385 user.username, users_group.users_group_name
386 )
386 )
387 msg = msg if success else 'User is already in that group'
387 msg = msg if success else 'User is already in that group'
388 Session().commit()
388 Session().commit()
389
389
390 return dict(
390 return dict(
391 success=success,
391 success=success,
392 msg=msg
392 msg=msg
393 )
393 )
394 except Exception:
394 except Exception:
395 log.error(traceback.format_exc())
395 log.error(traceback.format_exc())
396 raise JSONRPCError(
396 raise JSONRPCError(
397 'failed to add member to users group `%s`' % (
397 'failed to add member to users group `%s`' % (
398 users_group.users_group_name
398 users_group.users_group_name
399 )
399 )
400 )
400 )
401
401
402 @HasPermissionAllDecorator('hg.admin')
402 @HasPermissionAllDecorator('hg.admin')
403 def remove_user_from_users_group(self, apiuser, usersgroupid, userid):
403 def remove_user_from_users_group(self, apiuser, usersgroupid, userid):
404 """
404 """
405 Remove user from a group
405 Remove user from a group
406
406
407 :param apiuser:
407 :param apiuser:
408 :param usersgroupid:
408 :param usersgroupid:
409 :param userid:
409 :param userid:
410 """
410 """
411 user = get_user_or_error(userid)
411 user = get_user_or_error(userid)
412 users_group = get_users_group_or_error(usersgroupid)
412 users_group = get_users_group_or_error(usersgroupid)
413
413
414 try:
414 try:
415 success = UsersGroupModel().remove_user_from_group(users_group,
415 success = UsersGroupModel().remove_user_from_group(users_group,
416 user)
416 user)
417 msg = 'removed member `%s` from users group `%s`' % (
417 msg = 'removed member `%s` from users group `%s`' % (
418 user.username, users_group.users_group_name
418 user.username, users_group.users_group_name
419 )
419 )
420 msg = msg if success else "User wasn't in group"
420 msg = msg if success else "User wasn't in group"
421 Session().commit()
421 Session().commit()
422 return dict(success=success, msg=msg)
422 return dict(success=success, msg=msg)
423 except Exception:
423 except Exception:
424 log.error(traceback.format_exc())
424 log.error(traceback.format_exc())
425 raise JSONRPCError(
425 raise JSONRPCError(
426 'failed to remove member from users group `%s`' % (
426 'failed to remove member from users group `%s`' % (
427 users_group.users_group_name
427 users_group.users_group_name
428 )
428 )
429 )
429 )
430
430
431 @HasPermissionAnyDecorator('hg.admin')
431 @HasPermissionAnyDecorator('hg.admin')
432 def get_repo(self, apiuser, repoid):
432 def get_repo(self, apiuser, repoid):
433 """"
433 """"
434 Get repository by name
434 Get repository by name
435
435
436 :param apiuser:
436 :param apiuser:
437 :param repoid:
437 :param repoid:
438 """
438 """
439 repo = get_repo_or_error(repoid)
439 repo = get_repo_or_error(repoid)
440
440
441 members = []
441 members = []
442 for user in repo.repo_to_perm:
442 for user in repo.repo_to_perm:
443 perm = user.permission.permission_name
443 perm = user.permission.permission_name
444 user = user.user
444 user = user.user
445 user_data = user.get_api_data()
445 user_data = user.get_api_data()
446 user_data['type'] = "user"
446 user_data['type'] = "user"
447 user_data['permission'] = perm
447 user_data['permission'] = perm
448 members.append(user_data)
448 members.append(user_data)
449
449
450 for users_group in repo.users_group_to_perm:
450 for users_group in repo.users_group_to_perm:
451 perm = users_group.permission.permission_name
451 perm = users_group.permission.permission_name
452 users_group = users_group.users_group
452 users_group = users_group.users_group
453 users_group_data = users_group.get_api_data()
453 users_group_data = users_group.get_api_data()
454 users_group_data['type'] = "users_group"
454 users_group_data['type'] = "users_group"
455 users_group_data['permission'] = perm
455 users_group_data['permission'] = perm
456 members.append(users_group_data)
456 members.append(users_group_data)
457
457
458 data = repo.get_api_data()
458 data = repo.get_api_data()
459 data['members'] = members
459 data['members'] = members
460 return data
460 return data
461
461
462 @HasPermissionAnyDecorator('hg.admin')
462 @HasPermissionAnyDecorator('hg.admin')
463 def get_repos(self, apiuser):
463 def get_repos(self, apiuser):
464 """"
464 """"
465 Get all repositories
465 Get all repositories
466
466
467 :param apiuser:
467 :param apiuser:
468 """
468 """
469
469
470 result = []
470 result = []
471 for repo in RepoModel().get_all():
471 for repo in RepoModel().get_all():
472 result.append(repo.get_api_data())
472 result.append(repo.get_api_data())
473 return result
473 return result
474
474
475 @HasPermissionAnyDecorator('hg.admin')
475 @HasPermissionAnyDecorator('hg.admin')
476 def get_repo_nodes(self, apiuser, repoid, revision, root_path,
476 def get_repo_nodes(self, apiuser, repoid, revision, root_path,
477 ret_type='all'):
477 ret_type='all'):
478 """
478 """
479 returns a list of nodes and it's children
479 returns a list of nodes and it's children
480 for a given path at given revision. It's possible to specify ret_type
480 for a given path at given revision. It's possible to specify ret_type
481 to show only files or dirs
481 to show only files or dirs
482
482
483 :param apiuser:
483 :param apiuser:
484 :param repoid: name or id of repository
484 :param repoid: name or id of repository
485 :param revision: revision for which listing should be done
485 :param revision: revision for which listing should be done
486 :param root_path: path from which start displaying
486 :param root_path: path from which start displaying
487 :param ret_type: return type 'all|files|dirs' nodes
487 :param ret_type: return type 'all|files|dirs' nodes
488 """
488 """
489 repo = get_repo_or_error(repoid)
489 repo = get_repo_or_error(repoid)
490 try:
490 try:
491 _d, _f = ScmModel().get_nodes(repo, revision, root_path,
491 _d, _f = ScmModel().get_nodes(repo, revision, root_path,
492 flat=False)
492 flat=False)
493 _map = {
493 _map = {
494 'all': _d + _f,
494 'all': _d + _f,
495 'files': _f,
495 'files': _f,
496 'dirs': _d,
496 'dirs': _d,
497 }
497 }
498 return _map[ret_type]
498 return _map[ret_type]
499 except KeyError:
499 except KeyError:
500 raise JSONRPCError('ret_type must be one of %s' % _map.keys())
500 raise JSONRPCError('ret_type must be one of %s' % _map.keys())
501 except Exception:
501 except Exception:
502 log.error(traceback.format_exc())
502 log.error(traceback.format_exc())
503 raise JSONRPCError(
503 raise JSONRPCError(
504 'failed to get repo: `%s` nodes' % repo.repo_name
504 'failed to get repo: `%s` nodes' % repo.repo_name
505 )
505 )
506
506
507 @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
507 @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
508 def create_repo(self, apiuser, repo_name, owner, repo_type,
508 def create_repo(self, apiuser, repo_name, owner, repo_type,
509 description=Optional(''), private=Optional(False),
509 description=Optional(''), private=Optional(False),
510 clone_uri=Optional(None), landing_rev=Optional('tip')):
510 clone_uri=Optional(None), landing_rev=Optional('tip')):
511 """
511 """
512 Create repository, if clone_url is given it makes a remote clone
512 Create repository, if clone_url is given it makes a remote clone
513 if repo_name is withina group name the groups will be created
513 if repo_name is withina group name the groups will be created
514 automatically if they aren't present
514 automatically if they aren't present
515
515
516 :param apiuser:
516 :param apiuser:
517 :param repo_name:
517 :param repo_name:
518 :param onwer:
518 :param onwer:
519 :param repo_type:
519 :param repo_type:
520 :param description:
520 :param description:
521 :param private:
521 :param private:
522 :param clone_uri:
522 :param clone_uri:
523 :param landing_rev:
523 :param landing_rev:
524 """
524 """
525 owner = get_user_or_error(owner)
525 owner = get_user_or_error(owner)
526
526
527 if RepoModel().get_by_repo_name(repo_name):
527 if RepoModel().get_by_repo_name(repo_name):
528 raise JSONRPCError("repo `%s` already exist" % repo_name)
528 raise JSONRPCError("repo `%s` already exist" % repo_name)
529
529
530 private = Optional.extract(private)
530 private = Optional.extract(private)
531 clone_uri = Optional.extract(clone_uri)
531 clone_uri = Optional.extract(clone_uri)
532 description = Optional.extract(description)
532 description = Optional.extract(description)
533 landing_rev = Optional.extract(landing_rev)
533 landing_rev = Optional.extract(landing_rev)
534
534
535 try:
535 try:
536 # create structure of groups and return the last group
536 # create structure of groups and return the last group
537 group = map_groups(repo_name)
537 group = map_groups(repo_name)
538
538
539 repo = RepoModel().create_repo(
539 repo = RepoModel().create_repo(
540 repo_name=repo_name,
540 repo_name=repo_name,
541 repo_type=repo_type,
541 repo_type=repo_type,
542 description=description,
542 description=description,
543 owner=owner,
543 owner=owner,
544 private=private,
544 private=private,
545 clone_uri=clone_uri,
545 clone_uri=clone_uri,
546 repos_group=group,
546 repos_group=group,
547 landing_rev=landing_rev,
547 landing_rev=landing_rev,
548 )
548 )
549
549
550 Session().commit()
550 Session().commit()
551
551
552 return dict(
552 return dict(
553 msg="Created new repository `%s`" % (repo.repo_name),
553 msg="Created new repository `%s`" % (repo.repo_name),
554 repo=repo.get_api_data()
554 repo=repo.get_api_data()
555 )
555 )
556
556
557 except Exception:
557 except Exception:
558 log.error(traceback.format_exc())
558 log.error(traceback.format_exc())
559 raise JSONRPCError('failed to create repository `%s`' % repo_name)
559 raise JSONRPCError('failed to create repository `%s`' % repo_name)
560
560
561 # @HasPermissionAnyDecorator('hg.admin')
561 @HasPermissionAnyDecorator('hg.admin')
562 # def fork_repo(self, apiuser, repoid, fork_name):
562 def fork_repo(self, apiuser, repoid, fork_name, owner,
563 # repo = get_repo_or_error(repoid)
563 description=Optional(''), copy_permissions=Optional(False),
564 #
564 private=Optional(False), landing_rev=Optional('tip')):
565 # try:
565 repo = get_repo_or_error(repoid)
566 # form_data = dict(
566 repo_name = repo.repo_name
567 #
567 owner = get_user_or_error(owner)
568 # )
568
569 # RepoModel().create_fork(form_data, cur_user=apiuser)
569 _repo = RepoModel().get_by_repo_name(fork_name)
570 # return dict(
570 if _repo:
571 # msg='Created fork of `%s` as `%s`' % (repo.repo_name,
571 type_ = 'fork' if _repo.fork else 'repo'
572 # fork_name),
572 raise JSONRPCError("%s `%s` already exist" % (type_, fork_name))
573 # success=True
573
574 # )
574 try:
575 # except Exception:
575 # create structure of groups and return the last group
576 # log.error(traceback.format_exc())
576 group = map_groups(fork_name)
577 # raise JSONRPCError(
577
578 # 'failed to fork repository `%s` as `%s`' % (repo.repo_name,
578 form_data = dict(
579 # fork_name)
579 repo_name=fork_name,
580 # )
580 repo_name_full=fork_name,
581 repo_group=group,
582 repo_type=repo.repo_type,
583 description=Optional.extract(description),
584 private=Optional.extract(private),
585 copy_permissions=Optional.extract(copy_permissions),
586 landing_rev=Optional.extract(landing_rev),
587 update_after_clone=False,
588 fork_parent_id=repo.repo_id,
589 )
590 RepoModel().create_fork(form_data, cur_user=owner)
591 return dict(
592 msg='Created fork of `%s` as `%s`' % (repo.repo_name,
593 fork_name),
594 success=True # cannot return the repo data here since fork
595 # cann be done async
596 )
597 except Exception:
598 log.error(traceback.format_exc())
599 raise JSONRPCError(
600 'failed to fork repository `%s` as `%s`' % (repo_name,
601 fork_name)
602 )
581
603
582 @HasPermissionAnyDecorator('hg.admin')
604 @HasPermissionAnyDecorator('hg.admin')
583 def delete_repo(self, apiuser, repoid):
605 def delete_repo(self, apiuser, repoid):
584 """
606 """
585 Deletes a given repository
607 Deletes a given repository
586
608
587 :param apiuser:
609 :param apiuser:
588 :param repoid:
610 :param repoid:
589 """
611 """
590 repo = get_repo_or_error(repoid)
612 repo = get_repo_or_error(repoid)
591
613
592 try:
614 try:
593 RepoModel().delete(repo)
615 RepoModel().delete(repo)
594 Session().commit()
616 Session().commit()
595 return dict(
617 return dict(
596 msg='Deleted repository `%s`' % repo.repo_name,
618 msg='Deleted repository `%s`' % repo.repo_name,
597 success=True
619 success=True
598 )
620 )
599 except Exception:
621 except Exception:
600 log.error(traceback.format_exc())
622 log.error(traceback.format_exc())
601 raise JSONRPCError(
623 raise JSONRPCError(
602 'failed to delete repository `%s`' % repo.repo_name
624 'failed to delete repository `%s`' % repo.repo_name
603 )
625 )
604
626
605 @HasPermissionAnyDecorator('hg.admin')
627 @HasPermissionAnyDecorator('hg.admin')
606 def grant_user_permission(self, apiuser, repoid, userid, perm):
628 def grant_user_permission(self, apiuser, repoid, userid, perm):
607 """
629 """
608 Grant permission for user on given repository, or update existing one
630 Grant permission for user on given repository, or update existing one
609 if found
631 if found
610
632
611 :param repoid:
633 :param repoid:
612 :param userid:
634 :param userid:
613 :param perm:
635 :param perm:
614 """
636 """
615 repo = get_repo_or_error(repoid)
637 repo = get_repo_or_error(repoid)
616 user = get_user_or_error(userid)
638 user = get_user_or_error(userid)
617 perm = get_perm_or_error(perm)
639 perm = get_perm_or_error(perm)
618
640
619 try:
641 try:
620
642
621 RepoModel().grant_user_permission(repo=repo, user=user, perm=perm)
643 RepoModel().grant_user_permission(repo=repo, user=user, perm=perm)
622
644
623 Session().commit()
645 Session().commit()
624 return dict(
646 return dict(
625 msg='Granted perm: `%s` for user: `%s` in repo: `%s`' % (
647 msg='Granted perm: `%s` for user: `%s` in repo: `%s`' % (
626 perm.permission_name, user.username, repo.repo_name
648 perm.permission_name, user.username, repo.repo_name
627 ),
649 ),
628 success=True
650 success=True
629 )
651 )
630 except Exception:
652 except Exception:
631 log.error(traceback.format_exc())
653 log.error(traceback.format_exc())
632 raise JSONRPCError(
654 raise JSONRPCError(
633 'failed to edit permission for user: `%s` in repo: `%s`' % (
655 'failed to edit permission for user: `%s` in repo: `%s`' % (
634 userid, repoid
656 userid, repoid
635 )
657 )
636 )
658 )
637
659
638 @HasPermissionAnyDecorator('hg.admin')
660 @HasPermissionAnyDecorator('hg.admin')
639 def revoke_user_permission(self, apiuser, repoid, userid):
661 def revoke_user_permission(self, apiuser, repoid, userid):
640 """
662 """
641 Revoke permission for user on given repository
663 Revoke permission for user on given repository
642
664
643 :param apiuser:
665 :param apiuser:
644 :param repoid:
666 :param repoid:
645 :param userid:
667 :param userid:
646 """
668 """
647
669
648 repo = get_repo_or_error(repoid)
670 repo = get_repo_or_error(repoid)
649 user = get_user_or_error(userid)
671 user = get_user_or_error(userid)
650 try:
672 try:
651
673
652 RepoModel().revoke_user_permission(repo=repo, user=user)
674 RepoModel().revoke_user_permission(repo=repo, user=user)
653
675
654 Session().commit()
676 Session().commit()
655 return dict(
677 return dict(
656 msg='Revoked perm for user: `%s` in repo: `%s`' % (
678 msg='Revoked perm for user: `%s` in repo: `%s`' % (
657 user.username, repo.repo_name
679 user.username, repo.repo_name
658 ),
680 ),
659 success=True
681 success=True
660 )
682 )
661 except Exception:
683 except Exception:
662 log.error(traceback.format_exc())
684 log.error(traceback.format_exc())
663 raise JSONRPCError(
685 raise JSONRPCError(
664 'failed to edit permission for user: `%s` in repo: `%s`' % (
686 'failed to edit permission for user: `%s` in repo: `%s`' % (
665 userid, repoid
687 userid, repoid
666 )
688 )
667 )
689 )
668
690
669 @HasPermissionAnyDecorator('hg.admin')
691 @HasPermissionAnyDecorator('hg.admin')
670 def grant_users_group_permission(self, apiuser, repoid, usersgroupid,
692 def grant_users_group_permission(self, apiuser, repoid, usersgroupid,
671 perm):
693 perm):
672 """
694 """
673 Grant permission for users group on given repository, or update
695 Grant permission for users group on given repository, or update
674 existing one if found
696 existing one if found
675
697
676 :param apiuser:
698 :param apiuser:
677 :param repoid:
699 :param repoid:
678 :param usersgroupid:
700 :param usersgroupid:
679 :param perm:
701 :param perm:
680 """
702 """
681 repo = get_repo_or_error(repoid)
703 repo = get_repo_or_error(repoid)
682 perm = get_perm_or_error(perm)
704 perm = get_perm_or_error(perm)
683 users_group = get_users_group_or_error(usersgroupid)
705 users_group = get_users_group_or_error(usersgroupid)
684
706
685 try:
707 try:
686 RepoModel().grant_users_group_permission(repo=repo,
708 RepoModel().grant_users_group_permission(repo=repo,
687 group_name=users_group,
709 group_name=users_group,
688 perm=perm)
710 perm=perm)
689
711
690 Session().commit()
712 Session().commit()
691 return dict(
713 return dict(
692 msg='Granted perm: `%s` for users group: `%s` in '
714 msg='Granted perm: `%s` for users group: `%s` in '
693 'repo: `%s`' % (
715 'repo: `%s`' % (
694 perm.permission_name, users_group.users_group_name,
716 perm.permission_name, users_group.users_group_name,
695 repo.repo_name
717 repo.repo_name
696 ),
718 ),
697 success=True
719 success=True
698 )
720 )
699 except Exception:
721 except Exception:
700 print traceback.format_exc()
722 print traceback.format_exc()
701 log.error(traceback.format_exc())
723 log.error(traceback.format_exc())
702 raise JSONRPCError(
724 raise JSONRPCError(
703 'failed to edit permission for users group: `%s` in '
725 'failed to edit permission for users group: `%s` in '
704 'repo: `%s`' % (
726 'repo: `%s`' % (
705 usersgroupid, repo.repo_name
727 usersgroupid, repo.repo_name
706 )
728 )
707 )
729 )
708
730
709 @HasPermissionAnyDecorator('hg.admin')
731 @HasPermissionAnyDecorator('hg.admin')
710 def revoke_users_group_permission(self, apiuser, repoid, usersgroupid):
732 def revoke_users_group_permission(self, apiuser, repoid, usersgroupid):
711 """
733 """
712 Revoke permission for users group on given repository
734 Revoke permission for users group on given repository
713
735
714 :param apiuser:
736 :param apiuser:
715 :param repoid:
737 :param repoid:
716 :param usersgroupid:
738 :param usersgroupid:
717 """
739 """
718 repo = get_repo_or_error(repoid)
740 repo = get_repo_or_error(repoid)
719 users_group = get_users_group_or_error(usersgroupid)
741 users_group = get_users_group_or_error(usersgroupid)
720
742
721 try:
743 try:
722 RepoModel().revoke_users_group_permission(repo=repo,
744 RepoModel().revoke_users_group_permission(repo=repo,
723 group_name=users_group)
745 group_name=users_group)
724
746
725 Session().commit()
747 Session().commit()
726 return dict(
748 return dict(
727 msg='Revoked perm for users group: `%s` in repo: `%s`' % (
749 msg='Revoked perm for users group: `%s` in repo: `%s`' % (
728 users_group.users_group_name, repo.repo_name
750 users_group.users_group_name, repo.repo_name
729 ),
751 ),
730 success=True
752 success=True
731 )
753 )
732 except Exception:
754 except Exception:
733 log.error(traceback.format_exc())
755 log.error(traceback.format_exc())
734 raise JSONRPCError(
756 raise JSONRPCError(
735 'failed to edit permission for users group: `%s` in '
757 'failed to edit permission for users group: `%s` in '
736 'repo: `%s`' % (
758 'repo: `%s`' % (
737 users_group.users_group_name, repo.repo_name
759 users_group.users_group_name, repo.repo_name
738 )
760 )
739 )
761 )
@@ -1,902 +1,991 b''
1 from __future__ import with_statement
1 from __future__ import with_statement
2 import random
2 import random
3 import mock
3 import mock
4
4
5 from rhodecode.tests import *
5 from rhodecode.tests import *
6 from rhodecode.lib.compat import json
6 from rhodecode.lib.compat import json
7 from rhodecode.lib.auth import AuthUser
7 from rhodecode.lib.auth import AuthUser
8 from rhodecode.model.user import UserModel
8 from rhodecode.model.user import UserModel
9 from rhodecode.model.users_group import UsersGroupModel
9 from rhodecode.model.users_group import UsersGroupModel
10 from rhodecode.model.repo import RepoModel
10 from rhodecode.model.repo import RepoModel
11 from rhodecode.model.meta import Session
11 from rhodecode.model.meta import Session
12
12
13 API_URL = '/_admin/api'
13 API_URL = '/_admin/api'
14
14
15
15
16 def _build_data(apikey, method, **kw):
16 def _build_data(apikey, method, **kw):
17 """
17 """
18 Builds API data with given random ID
18 Builds API data with given random ID
19
19
20 :param random_id:
20 :param random_id:
21 :type random_id:
21 :type random_id:
22 """
22 """
23 random_id = random.randrange(1, 9999)
23 random_id = random.randrange(1, 9999)
24 return random_id, json.dumps({
24 return random_id, json.dumps({
25 "id": random_id,
25 "id": random_id,
26 "api_key": apikey,
26 "api_key": apikey,
27 "method": method,
27 "method": method,
28 "args": kw
28 "args": kw
29 })
29 })
30
30
31 jsonify = lambda obj: json.loads(json.dumps(obj))
31 jsonify = lambda obj: json.loads(json.dumps(obj))
32
32
33
33
34 def crash(*args, **kwargs):
34 def crash(*args, **kwargs):
35 raise Exception('Total Crash !')
35 raise Exception('Total Crash !')
36
36
37
37
38 TEST_USERS_GROUP = 'test_users_group'
38 TEST_USERS_GROUP = 'test_users_group'
39
39
40
40
41 def make_users_group(name=TEST_USERS_GROUP):
41 def make_users_group(name=TEST_USERS_GROUP):
42 gr = UsersGroupModel().create(name=name)
42 gr = UsersGroupModel().create(name=name)
43 UsersGroupModel().add_user_to_group(users_group=gr,
43 UsersGroupModel().add_user_to_group(users_group=gr,
44 user=TEST_USER_ADMIN_LOGIN)
44 user=TEST_USER_ADMIN_LOGIN)
45 Session().commit()
45 Session().commit()
46 return gr
46 return gr
47
47
48
48
49 def destroy_users_group(name=TEST_USERS_GROUP):
49 def destroy_users_group(name=TEST_USERS_GROUP):
50 UsersGroupModel().delete(users_group=name, force=True)
50 UsersGroupModel().delete(users_group=name, force=True)
51 Session().commit()
51 Session().commit()
52
52
53
53
54 def create_repo(repo_name, repo_type):
54 def create_repo(repo_name, repo_type):
55 # create new repo
55 # create new repo
56 form_data = dict(repo_name=repo_name,
56 form_data = dict(repo_name=repo_name,
57 repo_name_full=repo_name,
57 repo_name_full=repo_name,
58 fork_name=None,
58 fork_name=None,
59 description='description %s' % repo_name,
59 description='description %s' % repo_name,
60 repo_group=None,
60 repo_group=None,
61 private=False,
61 private=False,
62 repo_type=repo_type,
62 repo_type=repo_type,
63 clone_uri=None,
63 clone_uri=None,
64 landing_rev='tip')
64 landing_rev='tip')
65 cur_user = UserModel().get_by_username(TEST_USER_ADMIN_LOGIN)
65 cur_user = UserModel().get_by_username(TEST_USER_ADMIN_LOGIN)
66 r = RepoModel().create(form_data, cur_user)
66 r = RepoModel().create(form_data, cur_user)
67 Session().commit()
67 Session().commit()
68 return r
68 return r
69
69
70
70
71 def create_fork(fork_name, fork_type, fork_of):
72 fork = RepoModel(Session())._get_repo(fork_of)
73 r = create_repo(fork_name, fork_type)
74 r.fork = fork
75 Session().add(r)
76 Session().commit()
77 return r
78
79
71 def destroy_repo(repo_name):
80 def destroy_repo(repo_name):
72 RepoModel().delete(repo_name)
81 RepoModel().delete(repo_name)
73 Session().commit()
82 Session().commit()
74
83
75
84
76 class BaseTestApi(object):
85 class BaseTestApi(object):
77 REPO = None
86 REPO = None
78 REPO_TYPE = None
87 REPO_TYPE = None
79
88
80 @classmethod
89 @classmethod
81 def setUpClass(self):
90 def setUpClass(self):
82 self.usr = UserModel().get_by_username(TEST_USER_ADMIN_LOGIN)
91 self.usr = UserModel().get_by_username(TEST_USER_ADMIN_LOGIN)
83 self.apikey = self.usr.api_key
92 self.apikey = self.usr.api_key
84 self.TEST_USER = UserModel().create_or_update(
93 self.TEST_USER = UserModel().create_or_update(
85 username='test-api',
94 username='test-api',
86 password='test',
95 password='test',
87 email='test@api.rhodecode.org',
96 email='test@api.rhodecode.org',
88 firstname='first',
97 firstname='first',
89 lastname='last'
98 lastname='last'
90 )
99 )
91 Session().commit()
100 Session().commit()
92 self.TEST_USER_LOGIN = self.TEST_USER.username
101 self.TEST_USER_LOGIN = self.TEST_USER.username
93
102
94 @classmethod
103 @classmethod
95 def teardownClass(self):
104 def teardownClass(self):
96 pass
105 pass
97
106
98 def setUp(self):
107 def setUp(self):
99 self.maxDiff = None
108 self.maxDiff = None
100 make_users_group()
109 make_users_group()
101
110
102 def tearDown(self):
111 def tearDown(self):
103 destroy_users_group()
112 destroy_users_group()
104
113
105 def _compare_ok(self, id_, expected, given):
114 def _compare_ok(self, id_, expected, given):
106 expected = jsonify({
115 expected = jsonify({
107 'id': id_,
116 'id': id_,
108 'error': None,
117 'error': None,
109 'result': expected
118 'result': expected
110 })
119 })
111 given = json.loads(given)
120 given = json.loads(given)
112 self.assertEqual(expected, given)
121 self.assertEqual(expected, given)
113
122
114 def _compare_error(self, id_, expected, given):
123 def _compare_error(self, id_, expected, given):
115 expected = jsonify({
124 expected = jsonify({
116 'id': id_,
125 'id': id_,
117 'error': expected,
126 'error': expected,
118 'result': None
127 'result': None
119 })
128 })
120 given = json.loads(given)
129 given = json.loads(given)
121 self.assertEqual(expected, given)
130 self.assertEqual(expected, given)
122
131
123 # def test_Optional(self):
132 # def test_Optional(self):
124 # from rhodecode.controllers.api.api import Optional
133 # from rhodecode.controllers.api.api import Optional
125 # option1 = Optional(None)
134 # option1 = Optional(None)
126 # self.assertEqual('<Optional:%s>' % None, repr(option1))
135 # self.assertEqual('<Optional:%s>' % None, repr(option1))
127 #
136 #
128 # self.assertEqual(1, Optional.extract(Optional(1)))
137 # self.assertEqual(1, Optional.extract(Optional(1)))
129 # self.assertEqual('trololo', Optional.extract('trololo'))
138 # self.assertEqual('trololo', Optional.extract('trololo'))
130
139
131 def test_api_wrong_key(self):
140 def test_api_wrong_key(self):
132 id_, params = _build_data('trololo', 'get_user')
141 id_, params = _build_data('trololo', 'get_user')
133 response = self.app.post(API_URL, content_type='application/json',
142 response = self.app.post(API_URL, content_type='application/json',
134 params=params)
143 params=params)
135
144
136 expected = 'Invalid API KEY'
145 expected = 'Invalid API KEY'
137 self._compare_error(id_, expected, given=response.body)
146 self._compare_error(id_, expected, given=response.body)
138
147
139 def test_api_missing_non_optional_param(self):
148 def test_api_missing_non_optional_param(self):
140 id_, params = _build_data(self.apikey, 'get_user')
149 id_, params = _build_data(self.apikey, 'get_user')
141 response = self.app.post(API_URL, content_type='application/json',
150 response = self.app.post(API_URL, content_type='application/json',
142 params=params)
151 params=params)
143
152
144 expected = 'Missing non optional `userid` arg in JSON DATA'
153 expected = 'Missing non optional `userid` arg in JSON DATA'
145 self._compare_error(id_, expected, given=response.body)
154 self._compare_error(id_, expected, given=response.body)
146
155
147 def test_api_get_users(self):
156 def test_api_get_users(self):
148 id_, params = _build_data(self.apikey, 'get_users',)
157 id_, params = _build_data(self.apikey, 'get_users',)
149 response = self.app.post(API_URL, content_type='application/json',
158 response = self.app.post(API_URL, content_type='application/json',
150 params=params)
159 params=params)
151 ret_all = []
160 ret_all = []
152 for usr in UserModel().get_all():
161 for usr in UserModel().get_all():
153 ret = usr.get_api_data()
162 ret = usr.get_api_data()
154 ret_all.append(jsonify(ret))
163 ret_all.append(jsonify(ret))
155 expected = ret_all
164 expected = ret_all
156 self._compare_ok(id_, expected, given=response.body)
165 self._compare_ok(id_, expected, given=response.body)
157
166
158 def test_api_get_user(self):
167 def test_api_get_user(self):
159 id_, params = _build_data(self.apikey, 'get_user',
168 id_, params = _build_data(self.apikey, 'get_user',
160 userid=TEST_USER_ADMIN_LOGIN)
169 userid=TEST_USER_ADMIN_LOGIN)
161 response = self.app.post(API_URL, content_type='application/json',
170 response = self.app.post(API_URL, content_type='application/json',
162 params=params)
171 params=params)
163
172
164 usr = UserModel().get_by_username(TEST_USER_ADMIN_LOGIN)
173 usr = UserModel().get_by_username(TEST_USER_ADMIN_LOGIN)
165 ret = usr.get_api_data()
174 ret = usr.get_api_data()
166 ret['permissions'] = AuthUser(usr.user_id).permissions
175 ret['permissions'] = AuthUser(usr.user_id).permissions
167
176
168 expected = ret
177 expected = ret
169 self._compare_ok(id_, expected, given=response.body)
178 self._compare_ok(id_, expected, given=response.body)
170
179
171 def test_api_get_user_that_does_not_exist(self):
180 def test_api_get_user_that_does_not_exist(self):
172 id_, params = _build_data(self.apikey, 'get_user',
181 id_, params = _build_data(self.apikey, 'get_user',
173 userid='trololo')
182 userid='trololo')
174 response = self.app.post(API_URL, content_type='application/json',
183 response = self.app.post(API_URL, content_type='application/json',
175 params=params)
184 params=params)
176
185
177 expected = "user `%s` does not exist" % 'trololo'
186 expected = "user `%s` does not exist" % 'trololo'
178 self._compare_error(id_, expected, given=response.body)
187 self._compare_error(id_, expected, given=response.body)
179
188
180 def test_api_pull(self):
189 def test_api_pull(self):
181 #TODO: issues with rhodecode_extras here.. not sure why !
190 #TODO: issues with rhodecode_extras here.. not sure why !
182 pass
191 pass
183
192
184 # repo_name = 'test_pull'
193 # repo_name = 'test_pull'
185 # r = create_repo(repo_name, self.REPO_TYPE)
194 # r = create_repo(repo_name, self.REPO_TYPE)
186 # r.clone_uri = TEST_self.REPO
195 # r.clone_uri = TEST_self.REPO
187 # Session.add(r)
196 # Session.add(r)
188 # Session.commit()
197 # Session.commit()
189 #
198 #
190 # id_, params = _build_data(self.apikey, 'pull',
199 # id_, params = _build_data(self.apikey, 'pull',
191 # repoid=repo_name,)
200 # repoid=repo_name,)
192 # response = self.app.post(API_URL, content_type='application/json',
201 # response = self.app.post(API_URL, content_type='application/json',
193 # params=params)
202 # params=params)
194 #
203 #
195 # expected = 'Pulled from `%s`' % repo_name
204 # expected = 'Pulled from `%s`' % repo_name
196 # self._compare_ok(id_, expected, given=response.body)
205 # self._compare_ok(id_, expected, given=response.body)
197 #
206 #
198 # destroy_repo(repo_name)
207 # destroy_repo(repo_name)
199
208
200 def test_api_pull_error(self):
209 def test_api_pull_error(self):
201 id_, params = _build_data(self.apikey, 'pull',
210 id_, params = _build_data(self.apikey, 'pull',
202 repoid=self.REPO,)
211 repoid=self.REPO,)
203 response = self.app.post(API_URL, content_type='application/json',
212 response = self.app.post(API_URL, content_type='application/json',
204 params=params)
213 params=params)
205
214
206 expected = 'Unable to pull changes from `%s`' % self.REPO
215 expected = 'Unable to pull changes from `%s`' % self.REPO
207 self._compare_error(id_, expected, given=response.body)
216 self._compare_error(id_, expected, given=response.body)
208
217
209 def test_api_create_existing_user(self):
218 def test_api_create_existing_user(self):
210 id_, params = _build_data(self.apikey, 'create_user',
219 id_, params = _build_data(self.apikey, 'create_user',
211 username=TEST_USER_ADMIN_LOGIN,
220 username=TEST_USER_ADMIN_LOGIN,
212 email='test@foo.com',
221 email='test@foo.com',
213 password='trololo')
222 password='trololo')
214 response = self.app.post(API_URL, content_type='application/json',
223 response = self.app.post(API_URL, content_type='application/json',
215 params=params)
224 params=params)
216
225
217 expected = "user `%s` already exist" % TEST_USER_ADMIN_LOGIN
226 expected = "user `%s` already exist" % TEST_USER_ADMIN_LOGIN
218 self._compare_error(id_, expected, given=response.body)
227 self._compare_error(id_, expected, given=response.body)
219
228
220 def test_api_create_user_with_existing_email(self):
229 def test_api_create_user_with_existing_email(self):
221 id_, params = _build_data(self.apikey, 'create_user',
230 id_, params = _build_data(self.apikey, 'create_user',
222 username=TEST_USER_ADMIN_LOGIN + 'new',
231 username=TEST_USER_ADMIN_LOGIN + 'new',
223 email=TEST_USER_REGULAR_EMAIL,
232 email=TEST_USER_REGULAR_EMAIL,
224 password='trololo')
233 password='trololo')
225 response = self.app.post(API_URL, content_type='application/json',
234 response = self.app.post(API_URL, content_type='application/json',
226 params=params)
235 params=params)
227
236
228 expected = "email `%s` already exist" % TEST_USER_REGULAR_EMAIL
237 expected = "email `%s` already exist" % TEST_USER_REGULAR_EMAIL
229 self._compare_error(id_, expected, given=response.body)
238 self._compare_error(id_, expected, given=response.body)
230
239
231 def test_api_create_user(self):
240 def test_api_create_user(self):
232 username = 'test_new_api_user'
241 username = 'test_new_api_user'
233 email = username + "@foo.com"
242 email = username + "@foo.com"
234
243
235 id_, params = _build_data(self.apikey, 'create_user',
244 id_, params = _build_data(self.apikey, 'create_user',
236 username=username,
245 username=username,
237 email=email,
246 email=email,
238 password='trololo')
247 password='trololo')
239 response = self.app.post(API_URL, content_type='application/json',
248 response = self.app.post(API_URL, content_type='application/json',
240 params=params)
249 params=params)
241
250
242 usr = UserModel().get_by_username(username)
251 usr = UserModel().get_by_username(username)
243 ret = dict(
252 ret = dict(
244 msg='created new user `%s`' % username,
253 msg='created new user `%s`' % username,
245 user=jsonify(usr.get_api_data())
254 user=jsonify(usr.get_api_data())
246 )
255 )
247
256
248 expected = ret
257 expected = ret
249 self._compare_ok(id_, expected, given=response.body)
258 self._compare_ok(id_, expected, given=response.body)
250
259
251 UserModel().delete(usr.user_id)
260 UserModel().delete(usr.user_id)
252 self.Session().commit()
261 self.Session().commit()
253
262
254 @mock.patch.object(UserModel, 'create_or_update', crash)
263 @mock.patch.object(UserModel, 'create_or_update', crash)
255 def test_api_create_user_when_exception_happened(self):
264 def test_api_create_user_when_exception_happened(self):
256
265
257 username = 'test_new_api_user'
266 username = 'test_new_api_user'
258 email = username + "@foo.com"
267 email = username + "@foo.com"
259
268
260 id_, params = _build_data(self.apikey, 'create_user',
269 id_, params = _build_data(self.apikey, 'create_user',
261 username=username,
270 username=username,
262 email=email,
271 email=email,
263 password='trololo')
272 password='trololo')
264 response = self.app.post(API_URL, content_type='application/json',
273 response = self.app.post(API_URL, content_type='application/json',
265 params=params)
274 params=params)
266 expected = 'failed to create user `%s`' % username
275 expected = 'failed to create user `%s`' % username
267 self._compare_error(id_, expected, given=response.body)
276 self._compare_error(id_, expected, given=response.body)
268
277
269 def test_api_delete_user(self):
278 def test_api_delete_user(self):
270 usr = UserModel().create_or_update(username=u'test_user',
279 usr = UserModel().create_or_update(username=u'test_user',
271 password=u'qweqwe',
280 password=u'qweqwe',
272 email=u'u232@rhodecode.org',
281 email=u'u232@rhodecode.org',
273 firstname=u'u1', lastname=u'u1')
282 firstname=u'u1', lastname=u'u1')
274 self.Session().commit()
283 self.Session().commit()
275 username = usr.username
284 username = usr.username
276 email = usr.email
285 email = usr.email
277 usr_id = usr.user_id
286 usr_id = usr.user_id
278 ## DELETE THIS USER NOW
287 ## DELETE THIS USER NOW
279
288
280 id_, params = _build_data(self.apikey, 'delete_user',
289 id_, params = _build_data(self.apikey, 'delete_user',
281 userid=username,)
290 userid=username,)
282 response = self.app.post(API_URL, content_type='application/json',
291 response = self.app.post(API_URL, content_type='application/json',
283 params=params)
292 params=params)
284
293
285 ret = {'msg': 'deleted user ID:%s %s' % (usr_id, username),
294 ret = {'msg': 'deleted user ID:%s %s' % (usr_id, username),
286 'user': None}
295 'user': None}
287 expected = ret
296 expected = ret
288 self._compare_ok(id_, expected, given=response.body)
297 self._compare_ok(id_, expected, given=response.body)
289
298
290 @mock.patch.object(UserModel, 'delete', crash)
299 @mock.patch.object(UserModel, 'delete', crash)
291 def test_api_delete_user_when_exception_happened(self):
300 def test_api_delete_user_when_exception_happened(self):
292 usr = UserModel().create_or_update(username=u'test_user',
301 usr = UserModel().create_or_update(username=u'test_user',
293 password=u'qweqwe',
302 password=u'qweqwe',
294 email=u'u232@rhodecode.org',
303 email=u'u232@rhodecode.org',
295 firstname=u'u1', lastname=u'u1')
304 firstname=u'u1', lastname=u'u1')
296 self.Session().commit()
305 self.Session().commit()
297 username = usr.username
306 username = usr.username
298
307
299 id_, params = _build_data(self.apikey, 'delete_user',
308 id_, params = _build_data(self.apikey, 'delete_user',
300 userid=username,)
309 userid=username,)
301 response = self.app.post(API_URL, content_type='application/json',
310 response = self.app.post(API_URL, content_type='application/json',
302 params=params)
311 params=params)
303 ret = 'failed to delete ID:%s %s' % (usr.user_id,
312 ret = 'failed to delete ID:%s %s' % (usr.user_id,
304 usr.username)
313 usr.username)
305 expected = ret
314 expected = ret
306 self._compare_error(id_, expected, given=response.body)
315 self._compare_error(id_, expected, given=response.body)
307
316
308 @parameterized.expand([('firstname', 'new_username'),
317 @parameterized.expand([('firstname', 'new_username'),
309 ('lastname', 'new_username'),
318 ('lastname', 'new_username'),
310 ('email', 'new_username'),
319 ('email', 'new_username'),
311 ('admin', True),
320 ('admin', True),
312 ('admin', False),
321 ('admin', False),
313 ('ldap_dn', 'test'),
322 ('ldap_dn', 'test'),
314 ('ldap_dn', None),
323 ('ldap_dn', None),
315 ('active', False),
324 ('active', False),
316 ('active', True),
325 ('active', True),
317 ('password', 'newpass')
326 ('password', 'newpass')
318 ])
327 ])
319 def test_api_update_user(self, name, expected):
328 def test_api_update_user(self, name, expected):
320 usr = UserModel().get_by_username(self.TEST_USER_LOGIN)
329 usr = UserModel().get_by_username(self.TEST_USER_LOGIN)
321 kw = {name: expected,
330 kw = {name: expected,
322 'userid': usr.user_id}
331 'userid': usr.user_id}
323 id_, params = _build_data(self.apikey, 'update_user', **kw)
332 id_, params = _build_data(self.apikey, 'update_user', **kw)
324 response = self.app.post(API_URL, content_type='application/json',
333 response = self.app.post(API_URL, content_type='application/json',
325 params=params)
334 params=params)
326
335
327 ret = {
336 ret = {
328 'msg': 'updated user ID:%s %s' % (usr.user_id, self.TEST_USER_LOGIN),
337 'msg': 'updated user ID:%s %s' % (usr.user_id, self.TEST_USER_LOGIN),
329 'user': jsonify(UserModel()\
338 'user': jsonify(UserModel()\
330 .get_by_username(self.TEST_USER_LOGIN)\
339 .get_by_username(self.TEST_USER_LOGIN)\
331 .get_api_data())
340 .get_api_data())
332 }
341 }
333
342
334 expected = ret
343 expected = ret
335 self._compare_ok(id_, expected, given=response.body)
344 self._compare_ok(id_, expected, given=response.body)
336
345
337 def test_api_update_user_no_changed_params(self):
346 def test_api_update_user_no_changed_params(self):
338 usr = UserModel().get_by_username(TEST_USER_ADMIN_LOGIN)
347 usr = UserModel().get_by_username(TEST_USER_ADMIN_LOGIN)
339 ret = jsonify(usr.get_api_data())
348 ret = jsonify(usr.get_api_data())
340 id_, params = _build_data(self.apikey, 'update_user',
349 id_, params = _build_data(self.apikey, 'update_user',
341 userid=TEST_USER_ADMIN_LOGIN)
350 userid=TEST_USER_ADMIN_LOGIN)
342
351
343 response = self.app.post(API_URL, content_type='application/json',
352 response = self.app.post(API_URL, content_type='application/json',
344 params=params)
353 params=params)
345 ret = {
354 ret = {
346 'msg': 'updated user ID:%s %s' % (usr.user_id, TEST_USER_ADMIN_LOGIN),
355 'msg': 'updated user ID:%s %s' % (usr.user_id, TEST_USER_ADMIN_LOGIN),
347 'user': ret
356 'user': ret
348 }
357 }
349 expected = ret
358 expected = ret
350 self._compare_ok(id_, expected, given=response.body)
359 self._compare_ok(id_, expected, given=response.body)
351
360
352 def test_api_update_user_by_user_id(self):
361 def test_api_update_user_by_user_id(self):
353 usr = UserModel().get_by_username(TEST_USER_ADMIN_LOGIN)
362 usr = UserModel().get_by_username(TEST_USER_ADMIN_LOGIN)
354 ret = jsonify(usr.get_api_data())
363 ret = jsonify(usr.get_api_data())
355 id_, params = _build_data(self.apikey, 'update_user',
364 id_, params = _build_data(self.apikey, 'update_user',
356 userid=usr.user_id)
365 userid=usr.user_id)
357
366
358 response = self.app.post(API_URL, content_type='application/json',
367 response = self.app.post(API_URL, content_type='application/json',
359 params=params)
368 params=params)
360 ret = {
369 ret = {
361 'msg': 'updated user ID:%s %s' % (usr.user_id, TEST_USER_ADMIN_LOGIN),
370 'msg': 'updated user ID:%s %s' % (usr.user_id, TEST_USER_ADMIN_LOGIN),
362 'user': ret
371 'user': ret
363 }
372 }
364 expected = ret
373 expected = ret
365 self._compare_ok(id_, expected, given=response.body)
374 self._compare_ok(id_, expected, given=response.body)
366
375
367 @mock.patch.object(UserModel, 'create_or_update', crash)
376 @mock.patch.object(UserModel, 'create_or_update', crash)
368 def test_api_update_user_when_exception_happens(self):
377 def test_api_update_user_when_exception_happens(self):
369 usr = UserModel().get_by_username(TEST_USER_ADMIN_LOGIN)
378 usr = UserModel().get_by_username(TEST_USER_ADMIN_LOGIN)
370 ret = jsonify(usr.get_api_data())
379 ret = jsonify(usr.get_api_data())
371 id_, params = _build_data(self.apikey, 'update_user',
380 id_, params = _build_data(self.apikey, 'update_user',
372 userid=usr.user_id)
381 userid=usr.user_id)
373
382
374 response = self.app.post(API_URL, content_type='application/json',
383 response = self.app.post(API_URL, content_type='application/json',
375 params=params)
384 params=params)
376 ret = 'failed to update user `%s`' % usr.user_id
385 ret = 'failed to update user `%s`' % usr.user_id
377
386
378 expected = ret
387 expected = ret
379 self._compare_error(id_, expected, given=response.body)
388 self._compare_error(id_, expected, given=response.body)
380
389
381 def test_api_get_repo(self):
390 def test_api_get_repo(self):
382 new_group = 'some_new_group'
391 new_group = 'some_new_group'
383 make_users_group(new_group)
392 make_users_group(new_group)
384 RepoModel().grant_users_group_permission(repo=self.REPO,
393 RepoModel().grant_users_group_permission(repo=self.REPO,
385 group_name=new_group,
394 group_name=new_group,
386 perm='repository.read')
395 perm='repository.read')
387 self.Session().commit()
396 self.Session().commit()
388 id_, params = _build_data(self.apikey, 'get_repo',
397 id_, params = _build_data(self.apikey, 'get_repo',
389 repoid=self.REPO)
398 repoid=self.REPO)
390 response = self.app.post(API_URL, content_type='application/json',
399 response = self.app.post(API_URL, content_type='application/json',
391 params=params)
400 params=params)
392
401
393 repo = RepoModel().get_by_repo_name(self.REPO)
402 repo = RepoModel().get_by_repo_name(self.REPO)
394 ret = repo.get_api_data()
403 ret = repo.get_api_data()
395
404
396 members = []
405 members = []
397 for user in repo.repo_to_perm:
406 for user in repo.repo_to_perm:
398 perm = user.permission.permission_name
407 perm = user.permission.permission_name
399 user = user.user
408 user = user.user
400 user_data = user.get_api_data()
409 user_data = user.get_api_data()
401 user_data['type'] = "user"
410 user_data['type'] = "user"
402 user_data['permission'] = perm
411 user_data['permission'] = perm
403 members.append(user_data)
412 members.append(user_data)
404
413
405 for users_group in repo.users_group_to_perm:
414 for users_group in repo.users_group_to_perm:
406 perm = users_group.permission.permission_name
415 perm = users_group.permission.permission_name
407 users_group = users_group.users_group
416 users_group = users_group.users_group
408 users_group_data = users_group.get_api_data()
417 users_group_data = users_group.get_api_data()
409 users_group_data['type'] = "users_group"
418 users_group_data['type'] = "users_group"
410 users_group_data['permission'] = perm
419 users_group_data['permission'] = perm
411 members.append(users_group_data)
420 members.append(users_group_data)
412
421
413 ret['members'] = members
422 ret['members'] = members
414
423
415 expected = ret
424 expected = ret
416 self._compare_ok(id_, expected, given=response.body)
425 self._compare_ok(id_, expected, given=response.body)
417 destroy_users_group(new_group)
426 destroy_users_group(new_group)
418
427
419 def test_api_get_repo_that_doesn_not_exist(self):
428 def test_api_get_repo_that_doesn_not_exist(self):
420 id_, params = _build_data(self.apikey, 'get_repo',
429 id_, params = _build_data(self.apikey, 'get_repo',
421 repoid='no-such-repo')
430 repoid='no-such-repo')
422 response = self.app.post(API_URL, content_type='application/json',
431 response = self.app.post(API_URL, content_type='application/json',
423 params=params)
432 params=params)
424
433
425 ret = 'repository `%s` does not exist' % 'no-such-repo'
434 ret = 'repository `%s` does not exist' % 'no-such-repo'
426 expected = ret
435 expected = ret
427 self._compare_error(id_, expected, given=response.body)
436 self._compare_error(id_, expected, given=response.body)
428
437
429 def test_api_get_repos(self):
438 def test_api_get_repos(self):
430 id_, params = _build_data(self.apikey, 'get_repos')
439 id_, params = _build_data(self.apikey, 'get_repos')
431 response = self.app.post(API_URL, content_type='application/json',
440 response = self.app.post(API_URL, content_type='application/json',
432 params=params)
441 params=params)
433
442
434 result = []
443 result = []
435 for repo in RepoModel().get_all():
444 for repo in RepoModel().get_all():
436 result.append(repo.get_api_data())
445 result.append(repo.get_api_data())
437 ret = jsonify(result)
446 ret = jsonify(result)
438
447
439 expected = ret
448 expected = ret
440 self._compare_ok(id_, expected, given=response.body)
449 self._compare_ok(id_, expected, given=response.body)
441
450
442 @parameterized.expand([('all', 'all'),
451 @parameterized.expand([('all', 'all'),
443 ('dirs', 'dirs'),
452 ('dirs', 'dirs'),
444 ('files', 'files'), ])
453 ('files', 'files'), ])
445 def test_api_get_repo_nodes(self, name, ret_type):
454 def test_api_get_repo_nodes(self, name, ret_type):
446 rev = 'tip'
455 rev = 'tip'
447 path = '/'
456 path = '/'
448 id_, params = _build_data(self.apikey, 'get_repo_nodes',
457 id_, params = _build_data(self.apikey, 'get_repo_nodes',
449 repoid=self.REPO, revision=rev,
458 repoid=self.REPO, revision=rev,
450 root_path=path,
459 root_path=path,
451 ret_type=ret_type)
460 ret_type=ret_type)
452 response = self.app.post(API_URL, content_type='application/json',
461 response = self.app.post(API_URL, content_type='application/json',
453 params=params)
462 params=params)
454
463
455 # we don't the actual return types here since it's tested somewhere
464 # we don't the actual return types here since it's tested somewhere
456 # else
465 # else
457 expected = json.loads(response.body)['result']
466 expected = json.loads(response.body)['result']
458 self._compare_ok(id_, expected, given=response.body)
467 self._compare_ok(id_, expected, given=response.body)
459
468
460 def test_api_get_repo_nodes_bad_revisions(self):
469 def test_api_get_repo_nodes_bad_revisions(self):
461 rev = 'i-dont-exist'
470 rev = 'i-dont-exist'
462 path = '/'
471 path = '/'
463 id_, params = _build_data(self.apikey, 'get_repo_nodes',
472 id_, params = _build_data(self.apikey, 'get_repo_nodes',
464 repoid=self.REPO, revision=rev,
473 repoid=self.REPO, revision=rev,
465 root_path=path,)
474 root_path=path,)
466 response = self.app.post(API_URL, content_type='application/json',
475 response = self.app.post(API_URL, content_type='application/json',
467 params=params)
476 params=params)
468
477
469 expected = 'failed to get repo: `%s` nodes' % self.REPO
478 expected = 'failed to get repo: `%s` nodes' % self.REPO
470 self._compare_error(id_, expected, given=response.body)
479 self._compare_error(id_, expected, given=response.body)
471
480
472 def test_api_get_repo_nodes_bad_path(self):
481 def test_api_get_repo_nodes_bad_path(self):
473 rev = 'tip'
482 rev = 'tip'
474 path = '/idontexits'
483 path = '/idontexits'
475 id_, params = _build_data(self.apikey, 'get_repo_nodes',
484 id_, params = _build_data(self.apikey, 'get_repo_nodes',
476 repoid=self.REPO, revision=rev,
485 repoid=self.REPO, revision=rev,
477 root_path=path,)
486 root_path=path,)
478 response = self.app.post(API_URL, content_type='application/json',
487 response = self.app.post(API_URL, content_type='application/json',
479 params=params)
488 params=params)
480
489
481 expected = 'failed to get repo: `%s` nodes' % self.REPO
490 expected = 'failed to get repo: `%s` nodes' % self.REPO
482 self._compare_error(id_, expected, given=response.body)
491 self._compare_error(id_, expected, given=response.body)
483
492
484 def test_api_get_repo_nodes_bad_ret_type(self):
493 def test_api_get_repo_nodes_bad_ret_type(self):
485 rev = 'tip'
494 rev = 'tip'
486 path = '/'
495 path = '/'
487 ret_type = 'error'
496 ret_type = 'error'
488 id_, params = _build_data(self.apikey, 'get_repo_nodes',
497 id_, params = _build_data(self.apikey, 'get_repo_nodes',
489 repoid=self.REPO, revision=rev,
498 repoid=self.REPO, revision=rev,
490 root_path=path,
499 root_path=path,
491 ret_type=ret_type)
500 ret_type=ret_type)
492 response = self.app.post(API_URL, content_type='application/json',
501 response = self.app.post(API_URL, content_type='application/json',
493 params=params)
502 params=params)
494
503
495 expected = 'ret_type must be one of %s' % (['files', 'dirs', 'all'])
504 expected = 'ret_type must be one of %s' % (['files', 'dirs', 'all'])
496 self._compare_error(id_, expected, given=response.body)
505 self._compare_error(id_, expected, given=response.body)
497
506
498 def test_api_create_repo(self):
507 def test_api_create_repo(self):
499 repo_name = 'api-repo'
508 repo_name = 'api-repo'
500 id_, params = _build_data(self.apikey, 'create_repo',
509 id_, params = _build_data(self.apikey, 'create_repo',
501 repo_name=repo_name,
510 repo_name=repo_name,
502 owner=TEST_USER_ADMIN_LOGIN,
511 owner=TEST_USER_ADMIN_LOGIN,
503 repo_type='hg',
512 repo_type='hg',
504 )
513 )
505 response = self.app.post(API_URL, content_type='application/json',
514 response = self.app.post(API_URL, content_type='application/json',
506 params=params)
515 params=params)
507
516
508 repo = RepoModel().get_by_repo_name(repo_name)
517 repo = RepoModel().get_by_repo_name(repo_name)
509 ret = {
518 ret = {
510 'msg': 'Created new repository `%s`' % repo_name,
519 'msg': 'Created new repository `%s`' % repo_name,
511 'repo': jsonify(repo.get_api_data())
520 'repo': jsonify(repo.get_api_data())
512 }
521 }
513 expected = ret
522 expected = ret
514 self._compare_ok(id_, expected, given=response.body)
523 self._compare_ok(id_, expected, given=response.body)
515 destroy_repo(repo_name)
524 destroy_repo(repo_name)
516
525
517 def test_api_create_repo_unknown_owner(self):
526 def test_api_create_repo_unknown_owner(self):
518 repo_name = 'api-repo'
527 repo_name = 'api-repo'
519 owner = 'i-dont-exist'
528 owner = 'i-dont-exist'
520 id_, params = _build_data(self.apikey, 'create_repo',
529 id_, params = _build_data(self.apikey, 'create_repo',
521 repo_name=repo_name,
530 repo_name=repo_name,
522 owner=owner,
531 owner=owner,
523 repo_type='hg',
532 repo_type='hg',
524 )
533 )
525 response = self.app.post(API_URL, content_type='application/json',
534 response = self.app.post(API_URL, content_type='application/json',
526 params=params)
535 params=params)
527 expected = 'user `%s` does not exist' % owner
536 expected = 'user `%s` does not exist' % owner
528 self._compare_error(id_, expected, given=response.body)
537 self._compare_error(id_, expected, given=response.body)
529
538
530 def test_api_create_repo_exists(self):
539 def test_api_create_repo_exists(self):
531 repo_name = self.REPO
540 repo_name = self.REPO
532 id_, params = _build_data(self.apikey, 'create_repo',
541 id_, params = _build_data(self.apikey, 'create_repo',
533 repo_name=repo_name,
542 repo_name=repo_name,
534 owner=TEST_USER_ADMIN_LOGIN,
543 owner=TEST_USER_ADMIN_LOGIN,
535 repo_type='hg',
544 repo_type='hg',
536 )
545 )
537 response = self.app.post(API_URL, content_type='application/json',
546 response = self.app.post(API_URL, content_type='application/json',
538 params=params)
547 params=params)
539 expected = "repo `%s` already exist" % repo_name
548 expected = "repo `%s` already exist" % repo_name
540 self._compare_error(id_, expected, given=response.body)
549 self._compare_error(id_, expected, given=response.body)
541
550
542 @mock.patch.object(RepoModel, 'create_repo', crash)
551 @mock.patch.object(RepoModel, 'create_repo', crash)
543 def test_api_create_repo_exception_occurred(self):
552 def test_api_create_repo_exception_occurred(self):
544 repo_name = 'api-repo'
553 repo_name = 'api-repo'
545 id_, params = _build_data(self.apikey, 'create_repo',
554 id_, params = _build_data(self.apikey, 'create_repo',
546 repo_name=repo_name,
555 repo_name=repo_name,
547 owner=TEST_USER_ADMIN_LOGIN,
556 owner=TEST_USER_ADMIN_LOGIN,
548 repo_type='hg',
557 repo_type='hg',
549 )
558 )
550 response = self.app.post(API_URL, content_type='application/json',
559 response = self.app.post(API_URL, content_type='application/json',
551 params=params)
560 params=params)
552 expected = 'failed to create repository `%s`' % repo_name
561 expected = 'failed to create repository `%s`' % repo_name
553 self._compare_error(id_, expected, given=response.body)
562 self._compare_error(id_, expected, given=response.body)
554
563
555 def test_api_delete_repo(self):
564 def test_api_delete_repo(self):
556 repo_name = 'api_delete_me'
565 repo_name = 'api_delete_me'
557 create_repo(repo_name, self.REPO_TYPE)
566 create_repo(repo_name, self.REPO_TYPE)
558
567
559 id_, params = _build_data(self.apikey, 'delete_repo',
568 id_, params = _build_data(self.apikey, 'delete_repo',
560 repoid=repo_name,)
569 repoid=repo_name,)
561 response = self.app.post(API_URL, content_type='application/json',
570 response = self.app.post(API_URL, content_type='application/json',
562 params=params)
571 params=params)
563
572
564 ret = {
573 ret = {
565 'msg': 'Deleted repository `%s`' % repo_name,
574 'msg': 'Deleted repository `%s`' % repo_name,
566 'success': True
575 'success': True
567 }
576 }
568 expected = ret
577 expected = ret
569 self._compare_ok(id_, expected, given=response.body)
578 self._compare_ok(id_, expected, given=response.body)
570
579
571 def test_api_delete_repo_exception_occurred(self):
580 def test_api_delete_repo_exception_occurred(self):
572 repo_name = 'api_delete_me'
581 repo_name = 'api_delete_me'
573 create_repo(repo_name, self.REPO_TYPE)
582 create_repo(repo_name, self.REPO_TYPE)
583 try:
574 with mock.patch.object(RepoModel, 'delete', crash):
584 with mock.patch.object(RepoModel, 'delete', crash):
575 id_, params = _build_data(self.apikey, 'delete_repo',
585 id_, params = _build_data(self.apikey, 'delete_repo',
576 repoid=repo_name,)
586 repoid=repo_name,)
577 response = self.app.post(API_URL, content_type='application/json',
587 response = self.app.post(API_URL, content_type='application/json',
578 params=params)
588 params=params)
579
589
580 expected = 'failed to delete repository `%s`' % repo_name
590 expected = 'failed to delete repository `%s`' % repo_name
581 self._compare_error(id_, expected, given=response.body)
591 self._compare_error(id_, expected, given=response.body)
592 finally:
582 destroy_repo(repo_name)
593 destroy_repo(repo_name)
583
594
584 def test_api_fork_repo(self):
595 def test_api_fork_repo(self):
585 self.failIf(False, 'TODO:')
596 fork_name = 'api-repo-fork'
597 id_, params = _build_data(self.apikey, 'fork_repo',
598 repoid=self.REPO,
599 fork_name=fork_name,
600 owner=TEST_USER_ADMIN_LOGIN,
601 )
602 response = self.app.post(API_URL, content_type='application/json',
603 params=params)
604
605 ret = {
606 'msg': 'Created fork of `%s` as `%s`' % (self.REPO,
607 fork_name),
608 'success': True
609 }
610 expected = ret
611 self._compare_ok(id_, expected, given=response.body)
612 destroy_repo(fork_name)
613
614 def test_api_fork_repo_unknown_owner(self):
615 fork_name = 'api-repo-fork'
616 owner = 'i-dont-exist'
617 id_, params = _build_data(self.apikey, 'fork_repo',
618 repoid=self.REPO,
619 fork_name=fork_name,
620 owner=owner,
621 )
622 response = self.app.post(API_URL, content_type='application/json',
623 params=params)
624 expected = 'user `%s` does not exist' % owner
625 self._compare_error(id_, expected, given=response.body)
626
627 def test_api_fork_repo_fork_exists(self):
628 fork_name = 'api-repo-fork'
629 create_fork(fork_name, self.REPO_TYPE, self.REPO)
630
631 try:
632 fork_name = 'api-repo-fork'
633
634 id_, params = _build_data(self.apikey, 'fork_repo',
635 repoid=self.REPO,
636 fork_name=fork_name,
637 owner=TEST_USER_ADMIN_LOGIN,
638 )
639 response = self.app.post(API_URL, content_type='application/json',
640 params=params)
641
642 expected = "fork `%s` already exist" % fork_name
643 self._compare_error(id_, expected, given=response.body)
644 finally:
645 destroy_repo(fork_name)
646
647 def test_api_fork_repo_repo_exists(self):
648 fork_name = self.REPO
649
650 id_, params = _build_data(self.apikey, 'fork_repo',
651 repoid=self.REPO,
652 fork_name=fork_name,
653 owner=TEST_USER_ADMIN_LOGIN,
654 )
655 response = self.app.post(API_URL, content_type='application/json',
656 params=params)
657
658 expected = "repo `%s` already exist" % fork_name
659 self._compare_error(id_, expected, given=response.body)
660
661 @mock.patch.object(RepoModel, 'create_fork', crash)
662 def test_api_fork_repo_exception_occurred(self):
663 fork_name = 'api-repo-fork'
664 id_, params = _build_data(self.apikey, 'fork_repo',
665 repoid=self.REPO,
666 fork_name=fork_name,
667 owner=TEST_USER_ADMIN_LOGIN,
668 )
669 response = self.app.post(API_URL, content_type='application/json',
670 params=params)
671
672 expected = 'failed to fork repository `%s` as `%s`' % (self.REPO,
673 fork_name)
674 self._compare_error(id_, expected, given=response.body)
586
675
587 def test_api_get_users_group(self):
676 def test_api_get_users_group(self):
588 id_, params = _build_data(self.apikey, 'get_users_group',
677 id_, params = _build_data(self.apikey, 'get_users_group',
589 usersgroupid=TEST_USERS_GROUP)
678 usersgroupid=TEST_USERS_GROUP)
590 response = self.app.post(API_URL, content_type='application/json',
679 response = self.app.post(API_URL, content_type='application/json',
591 params=params)
680 params=params)
592
681
593 users_group = UsersGroupModel().get_group(TEST_USERS_GROUP)
682 users_group = UsersGroupModel().get_group(TEST_USERS_GROUP)
594 members = []
683 members = []
595 for user in users_group.members:
684 for user in users_group.members:
596 user = user.user
685 user = user.user
597 members.append(user.get_api_data())
686 members.append(user.get_api_data())
598
687
599 ret = users_group.get_api_data()
688 ret = users_group.get_api_data()
600 ret['members'] = members
689 ret['members'] = members
601 expected = ret
690 expected = ret
602 self._compare_ok(id_, expected, given=response.body)
691 self._compare_ok(id_, expected, given=response.body)
603
692
604 def test_api_get_users_groups(self):
693 def test_api_get_users_groups(self):
605
694
606 make_users_group('test_users_group2')
695 make_users_group('test_users_group2')
607
696
608 id_, params = _build_data(self.apikey, 'get_users_groups',)
697 id_, params = _build_data(self.apikey, 'get_users_groups',)
609 response = self.app.post(API_URL, content_type='application/json',
698 response = self.app.post(API_URL, content_type='application/json',
610 params=params)
699 params=params)
611
700
612 expected = []
701 expected = []
613 for gr_name in [TEST_USERS_GROUP, 'test_users_group2']:
702 for gr_name in [TEST_USERS_GROUP, 'test_users_group2']:
614 users_group = UsersGroupModel().get_group(gr_name)
703 users_group = UsersGroupModel().get_group(gr_name)
615 ret = users_group.get_api_data()
704 ret = users_group.get_api_data()
616 expected.append(ret)
705 expected.append(ret)
617 self._compare_ok(id_, expected, given=response.body)
706 self._compare_ok(id_, expected, given=response.body)
618
707
619 UsersGroupModel().delete(users_group='test_users_group2')
708 UsersGroupModel().delete(users_group='test_users_group2')
620 self.Session().commit()
709 self.Session().commit()
621
710
622 def test_api_create_users_group(self):
711 def test_api_create_users_group(self):
623 group_name = 'some_new_group'
712 group_name = 'some_new_group'
624 id_, params = _build_data(self.apikey, 'create_users_group',
713 id_, params = _build_data(self.apikey, 'create_users_group',
625 group_name=group_name)
714 group_name=group_name)
626 response = self.app.post(API_URL, content_type='application/json',
715 response = self.app.post(API_URL, content_type='application/json',
627 params=params)
716 params=params)
628
717
629 ret = {
718 ret = {
630 'msg': 'created new users group `%s`' % group_name,
719 'msg': 'created new users group `%s`' % group_name,
631 'users_group': jsonify(UsersGroupModel()\
720 'users_group': jsonify(UsersGroupModel()\
632 .get_by_name(group_name)\
721 .get_by_name(group_name)\
633 .get_api_data())
722 .get_api_data())
634 }
723 }
635 expected = ret
724 expected = ret
636 self._compare_ok(id_, expected, given=response.body)
725 self._compare_ok(id_, expected, given=response.body)
637
726
638 destroy_users_group(group_name)
727 destroy_users_group(group_name)
639
728
640 def test_api_get_users_group_that_exist(self):
729 def test_api_get_users_group_that_exist(self):
641 id_, params = _build_data(self.apikey, 'create_users_group',
730 id_, params = _build_data(self.apikey, 'create_users_group',
642 group_name=TEST_USERS_GROUP)
731 group_name=TEST_USERS_GROUP)
643 response = self.app.post(API_URL, content_type='application/json',
732 response = self.app.post(API_URL, content_type='application/json',
644 params=params)
733 params=params)
645
734
646 expected = "users group `%s` already exist" % TEST_USERS_GROUP
735 expected = "users group `%s` already exist" % TEST_USERS_GROUP
647 self._compare_error(id_, expected, given=response.body)
736 self._compare_error(id_, expected, given=response.body)
648
737
649 @mock.patch.object(UsersGroupModel, 'create', crash)
738 @mock.patch.object(UsersGroupModel, 'create', crash)
650 def test_api_get_users_group_exception_occurred(self):
739 def test_api_get_users_group_exception_occurred(self):
651 group_name = 'exception_happens'
740 group_name = 'exception_happens'
652 id_, params = _build_data(self.apikey, 'create_users_group',
741 id_, params = _build_data(self.apikey, 'create_users_group',
653 group_name=group_name)
742 group_name=group_name)
654 response = self.app.post(API_URL, content_type='application/json',
743 response = self.app.post(API_URL, content_type='application/json',
655 params=params)
744 params=params)
656
745
657 expected = 'failed to create group `%s`' % group_name
746 expected = 'failed to create group `%s`' % group_name
658 self._compare_error(id_, expected, given=response.body)
747 self._compare_error(id_, expected, given=response.body)
659
748
660 def test_api_add_user_to_users_group(self):
749 def test_api_add_user_to_users_group(self):
661 gr_name = 'test_group'
750 gr_name = 'test_group'
662 UsersGroupModel().create(gr_name)
751 UsersGroupModel().create(gr_name)
663 self.Session().commit()
752 self.Session().commit()
664 id_, params = _build_data(self.apikey, 'add_user_to_users_group',
753 id_, params = _build_data(self.apikey, 'add_user_to_users_group',
665 usersgroupid=gr_name,
754 usersgroupid=gr_name,
666 userid=TEST_USER_ADMIN_LOGIN)
755 userid=TEST_USER_ADMIN_LOGIN)
667 response = self.app.post(API_URL, content_type='application/json',
756 response = self.app.post(API_URL, content_type='application/json',
668 params=params)
757 params=params)
669
758
670 expected = {
759 expected = {
671 'msg': 'added member `%s` to users group `%s`' % (
760 'msg': 'added member `%s` to users group `%s`' % (
672 TEST_USER_ADMIN_LOGIN, gr_name
761 TEST_USER_ADMIN_LOGIN, gr_name
673 ),
762 ),
674 'success': True}
763 'success': True}
675 self._compare_ok(id_, expected, given=response.body)
764 self._compare_ok(id_, expected, given=response.body)
676
765
677 UsersGroupModel().delete(users_group=gr_name)
766 UsersGroupModel().delete(users_group=gr_name)
678 self.Session().commit()
767 self.Session().commit()
679
768
680 def test_api_add_user_to_users_group_that_doesnt_exist(self):
769 def test_api_add_user_to_users_group_that_doesnt_exist(self):
681 id_, params = _build_data(self.apikey, 'add_user_to_users_group',
770 id_, params = _build_data(self.apikey, 'add_user_to_users_group',
682 usersgroupid='false-group',
771 usersgroupid='false-group',
683 userid=TEST_USER_ADMIN_LOGIN)
772 userid=TEST_USER_ADMIN_LOGIN)
684 response = self.app.post(API_URL, content_type='application/json',
773 response = self.app.post(API_URL, content_type='application/json',
685 params=params)
774 params=params)
686
775
687 expected = 'users group `%s` does not exist' % 'false-group'
776 expected = 'users group `%s` does not exist' % 'false-group'
688 self._compare_error(id_, expected, given=response.body)
777 self._compare_error(id_, expected, given=response.body)
689
778
690 @mock.patch.object(UsersGroupModel, 'add_user_to_group', crash)
779 @mock.patch.object(UsersGroupModel, 'add_user_to_group', crash)
691 def test_api_add_user_to_users_group_exception_occurred(self):
780 def test_api_add_user_to_users_group_exception_occurred(self):
692 gr_name = 'test_group'
781 gr_name = 'test_group'
693 UsersGroupModel().create(gr_name)
782 UsersGroupModel().create(gr_name)
694 self.Session().commit()
783 self.Session().commit()
695 id_, params = _build_data(self.apikey, 'add_user_to_users_group',
784 id_, params = _build_data(self.apikey, 'add_user_to_users_group',
696 usersgroupid=gr_name,
785 usersgroupid=gr_name,
697 userid=TEST_USER_ADMIN_LOGIN)
786 userid=TEST_USER_ADMIN_LOGIN)
698 response = self.app.post(API_URL, content_type='application/json',
787 response = self.app.post(API_URL, content_type='application/json',
699 params=params)
788 params=params)
700
789
701 expected = 'failed to add member to users group `%s`' % gr_name
790 expected = 'failed to add member to users group `%s`' % gr_name
702 self._compare_error(id_, expected, given=response.body)
791 self._compare_error(id_, expected, given=response.body)
703
792
704 UsersGroupModel().delete(users_group=gr_name)
793 UsersGroupModel().delete(users_group=gr_name)
705 self.Session().commit()
794 self.Session().commit()
706
795
707 def test_api_remove_user_from_users_group(self):
796 def test_api_remove_user_from_users_group(self):
708 gr_name = 'test_group_3'
797 gr_name = 'test_group_3'
709 gr = UsersGroupModel().create(gr_name)
798 gr = UsersGroupModel().create(gr_name)
710 UsersGroupModel().add_user_to_group(gr, user=TEST_USER_ADMIN_LOGIN)
799 UsersGroupModel().add_user_to_group(gr, user=TEST_USER_ADMIN_LOGIN)
711 self.Session().commit()
800 self.Session().commit()
712 id_, params = _build_data(self.apikey, 'remove_user_from_users_group',
801 id_, params = _build_data(self.apikey, 'remove_user_from_users_group',
713 usersgroupid=gr_name,
802 usersgroupid=gr_name,
714 userid=TEST_USER_ADMIN_LOGIN)
803 userid=TEST_USER_ADMIN_LOGIN)
715 response = self.app.post(API_URL, content_type='application/json',
804 response = self.app.post(API_URL, content_type='application/json',
716 params=params)
805 params=params)
717
806
718 expected = {
807 expected = {
719 'msg': 'removed member `%s` from users group `%s`' % (
808 'msg': 'removed member `%s` from users group `%s`' % (
720 TEST_USER_ADMIN_LOGIN, gr_name
809 TEST_USER_ADMIN_LOGIN, gr_name
721 ),
810 ),
722 'success': True}
811 'success': True}
723 self._compare_ok(id_, expected, given=response.body)
812 self._compare_ok(id_, expected, given=response.body)
724
813
725 UsersGroupModel().delete(users_group=gr_name)
814 UsersGroupModel().delete(users_group=gr_name)
726 self.Session().commit()
815 self.Session().commit()
727
816
728 @mock.patch.object(UsersGroupModel, 'remove_user_from_group', crash)
817 @mock.patch.object(UsersGroupModel, 'remove_user_from_group', crash)
729 def test_api_remove_user_from_users_group_exception_occurred(self):
818 def test_api_remove_user_from_users_group_exception_occurred(self):
730 gr_name = 'test_group_3'
819 gr_name = 'test_group_3'
731 gr = UsersGroupModel().create(gr_name)
820 gr = UsersGroupModel().create(gr_name)
732 UsersGroupModel().add_user_to_group(gr, user=TEST_USER_ADMIN_LOGIN)
821 UsersGroupModel().add_user_to_group(gr, user=TEST_USER_ADMIN_LOGIN)
733 self.Session().commit()
822 self.Session().commit()
734 id_, params = _build_data(self.apikey, 'remove_user_from_users_group',
823 id_, params = _build_data(self.apikey, 'remove_user_from_users_group',
735 usersgroupid=gr_name,
824 usersgroupid=gr_name,
736 userid=TEST_USER_ADMIN_LOGIN)
825 userid=TEST_USER_ADMIN_LOGIN)
737 response = self.app.post(API_URL, content_type='application/json',
826 response = self.app.post(API_URL, content_type='application/json',
738 params=params)
827 params=params)
739
828
740 expected = 'failed to remove member from users group `%s`' % gr_name
829 expected = 'failed to remove member from users group `%s`' % gr_name
741 self._compare_error(id_, expected, given=response.body)
830 self._compare_error(id_, expected, given=response.body)
742
831
743 UsersGroupModel().delete(users_group=gr_name)
832 UsersGroupModel().delete(users_group=gr_name)
744 self.Session().commit()
833 self.Session().commit()
745
834
746 @parameterized.expand([('none', 'repository.none'),
835 @parameterized.expand([('none', 'repository.none'),
747 ('read', 'repository.read'),
836 ('read', 'repository.read'),
748 ('write', 'repository.write'),
837 ('write', 'repository.write'),
749 ('admin', 'repository.admin')])
838 ('admin', 'repository.admin')])
750 def test_api_grant_user_permission(self, name, perm):
839 def test_api_grant_user_permission(self, name, perm):
751 id_, params = _build_data(self.apikey, 'grant_user_permission',
840 id_, params = _build_data(self.apikey, 'grant_user_permission',
752 repoid=self.REPO,
841 repoid=self.REPO,
753 userid=TEST_USER_ADMIN_LOGIN,
842 userid=TEST_USER_ADMIN_LOGIN,
754 perm=perm)
843 perm=perm)
755 response = self.app.post(API_URL, content_type='application/json',
844 response = self.app.post(API_URL, content_type='application/json',
756 params=params)
845 params=params)
757
846
758 ret = {
847 ret = {
759 'msg': 'Granted perm: `%s` for user: `%s` in repo: `%s`' % (
848 'msg': 'Granted perm: `%s` for user: `%s` in repo: `%s`' % (
760 perm, TEST_USER_ADMIN_LOGIN, self.REPO
849 perm, TEST_USER_ADMIN_LOGIN, self.REPO
761 ),
850 ),
762 'success': True
851 'success': True
763 }
852 }
764 expected = ret
853 expected = ret
765 self._compare_ok(id_, expected, given=response.body)
854 self._compare_ok(id_, expected, given=response.body)
766
855
767 def test_api_grant_user_permission_wrong_permission(self):
856 def test_api_grant_user_permission_wrong_permission(self):
768 perm = 'haha.no.permission'
857 perm = 'haha.no.permission'
769 id_, params = _build_data(self.apikey, 'grant_user_permission',
858 id_, params = _build_data(self.apikey, 'grant_user_permission',
770 repoid=self.REPO,
859 repoid=self.REPO,
771 userid=TEST_USER_ADMIN_LOGIN,
860 userid=TEST_USER_ADMIN_LOGIN,
772 perm=perm)
861 perm=perm)
773 response = self.app.post(API_URL, content_type='application/json',
862 response = self.app.post(API_URL, content_type='application/json',
774 params=params)
863 params=params)
775
864
776 expected = 'permission `%s` does not exist' % perm
865 expected = 'permission `%s` does not exist' % perm
777 self._compare_error(id_, expected, given=response.body)
866 self._compare_error(id_, expected, given=response.body)
778
867
779 @mock.patch.object(RepoModel, 'grant_user_permission', crash)
868 @mock.patch.object(RepoModel, 'grant_user_permission', crash)
780 def test_api_grant_user_permission_exception_when_adding(self):
869 def test_api_grant_user_permission_exception_when_adding(self):
781 perm = 'repository.read'
870 perm = 'repository.read'
782 id_, params = _build_data(self.apikey, 'grant_user_permission',
871 id_, params = _build_data(self.apikey, 'grant_user_permission',
783 repoid=self.REPO,
872 repoid=self.REPO,
784 userid=TEST_USER_ADMIN_LOGIN,
873 userid=TEST_USER_ADMIN_LOGIN,
785 perm=perm)
874 perm=perm)
786 response = self.app.post(API_URL, content_type='application/json',
875 response = self.app.post(API_URL, content_type='application/json',
787 params=params)
876 params=params)
788
877
789 expected = 'failed to edit permission for user: `%s` in repo: `%s`' % (
878 expected = 'failed to edit permission for user: `%s` in repo: `%s`' % (
790 TEST_USER_ADMIN_LOGIN, self.REPO
879 TEST_USER_ADMIN_LOGIN, self.REPO
791 )
880 )
792 self._compare_error(id_, expected, given=response.body)
881 self._compare_error(id_, expected, given=response.body)
793
882
794 def test_api_revoke_user_permission(self):
883 def test_api_revoke_user_permission(self):
795 id_, params = _build_data(self.apikey, 'revoke_user_permission',
884 id_, params = _build_data(self.apikey, 'revoke_user_permission',
796 repoid=self.REPO,
885 repoid=self.REPO,
797 userid=TEST_USER_ADMIN_LOGIN,)
886 userid=TEST_USER_ADMIN_LOGIN,)
798 response = self.app.post(API_URL, content_type='application/json',
887 response = self.app.post(API_URL, content_type='application/json',
799 params=params)
888 params=params)
800
889
801 expected = {
890 expected = {
802 'msg': 'Revoked perm for user: `%s` in repo: `%s`' % (
891 'msg': 'Revoked perm for user: `%s` in repo: `%s`' % (
803 TEST_USER_ADMIN_LOGIN, self.REPO
892 TEST_USER_ADMIN_LOGIN, self.REPO
804 ),
893 ),
805 'success': True
894 'success': True
806 }
895 }
807 self._compare_ok(id_, expected, given=response.body)
896 self._compare_ok(id_, expected, given=response.body)
808
897
809 @mock.patch.object(RepoModel, 'revoke_user_permission', crash)
898 @mock.patch.object(RepoModel, 'revoke_user_permission', crash)
810 def test_api_revoke_user_permission_exception_when_adding(self):
899 def test_api_revoke_user_permission_exception_when_adding(self):
811 id_, params = _build_data(self.apikey, 'revoke_user_permission',
900 id_, params = _build_data(self.apikey, 'revoke_user_permission',
812 repoid=self.REPO,
901 repoid=self.REPO,
813 userid=TEST_USER_ADMIN_LOGIN,)
902 userid=TEST_USER_ADMIN_LOGIN,)
814 response = self.app.post(API_URL, content_type='application/json',
903 response = self.app.post(API_URL, content_type='application/json',
815 params=params)
904 params=params)
816
905
817 expected = 'failed to edit permission for user: `%s` in repo: `%s`' % (
906 expected = 'failed to edit permission for user: `%s` in repo: `%s`' % (
818 TEST_USER_ADMIN_LOGIN, self.REPO
907 TEST_USER_ADMIN_LOGIN, self.REPO
819 )
908 )
820 self._compare_error(id_, expected, given=response.body)
909 self._compare_error(id_, expected, given=response.body)
821
910
822 @parameterized.expand([('none', 'repository.none'),
911 @parameterized.expand([('none', 'repository.none'),
823 ('read', 'repository.read'),
912 ('read', 'repository.read'),
824 ('write', 'repository.write'),
913 ('write', 'repository.write'),
825 ('admin', 'repository.admin')])
914 ('admin', 'repository.admin')])
826 def test_api_grant_users_group_permission(self, name, perm):
915 def test_api_grant_users_group_permission(self, name, perm):
827 id_, params = _build_data(self.apikey, 'grant_users_group_permission',
916 id_, params = _build_data(self.apikey, 'grant_users_group_permission',
828 repoid=self.REPO,
917 repoid=self.REPO,
829 usersgroupid=TEST_USERS_GROUP,
918 usersgroupid=TEST_USERS_GROUP,
830 perm=perm)
919 perm=perm)
831 response = self.app.post(API_URL, content_type='application/json',
920 response = self.app.post(API_URL, content_type='application/json',
832 params=params)
921 params=params)
833
922
834 ret = {
923 ret = {
835 'msg': 'Granted perm: `%s` for users group: `%s` in repo: `%s`' % (
924 'msg': 'Granted perm: `%s` for users group: `%s` in repo: `%s`' % (
836 perm, TEST_USERS_GROUP, self.REPO
925 perm, TEST_USERS_GROUP, self.REPO
837 ),
926 ),
838 'success': True
927 'success': True
839 }
928 }
840 expected = ret
929 expected = ret
841 self._compare_ok(id_, expected, given=response.body)
930 self._compare_ok(id_, expected, given=response.body)
842
931
843 def test_api_grant_users_group_permission_wrong_permission(self):
932 def test_api_grant_users_group_permission_wrong_permission(self):
844 perm = 'haha.no.permission'
933 perm = 'haha.no.permission'
845 id_, params = _build_data(self.apikey, 'grant_users_group_permission',
934 id_, params = _build_data(self.apikey, 'grant_users_group_permission',
846 repoid=self.REPO,
935 repoid=self.REPO,
847 usersgroupid=TEST_USERS_GROUP,
936 usersgroupid=TEST_USERS_GROUP,
848 perm=perm)
937 perm=perm)
849 response = self.app.post(API_URL, content_type='application/json',
938 response = self.app.post(API_URL, content_type='application/json',
850 params=params)
939 params=params)
851
940
852 expected = 'permission `%s` does not exist' % perm
941 expected = 'permission `%s` does not exist' % perm
853 self._compare_error(id_, expected, given=response.body)
942 self._compare_error(id_, expected, given=response.body)
854
943
855 @mock.patch.object(RepoModel, 'grant_users_group_permission', crash)
944 @mock.patch.object(RepoModel, 'grant_users_group_permission', crash)
856 def test_api_grant_users_group_permission_exception_when_adding(self):
945 def test_api_grant_users_group_permission_exception_when_adding(self):
857 perm = 'repository.read'
946 perm = 'repository.read'
858 id_, params = _build_data(self.apikey, 'grant_users_group_permission',
947 id_, params = _build_data(self.apikey, 'grant_users_group_permission',
859 repoid=self.REPO,
948 repoid=self.REPO,
860 usersgroupid=TEST_USERS_GROUP,
949 usersgroupid=TEST_USERS_GROUP,
861 perm=perm)
950 perm=perm)
862 response = self.app.post(API_URL, content_type='application/json',
951 response = self.app.post(API_URL, content_type='application/json',
863 params=params)
952 params=params)
864
953
865 expected = 'failed to edit permission for users group: `%s` in repo: `%s`' % (
954 expected = 'failed to edit permission for users group: `%s` in repo: `%s`' % (
866 TEST_USERS_GROUP, self.REPO
955 TEST_USERS_GROUP, self.REPO
867 )
956 )
868 self._compare_error(id_, expected, given=response.body)
957 self._compare_error(id_, expected, given=response.body)
869
958
870 def test_api_revoke_users_group_permission(self):
959 def test_api_revoke_users_group_permission(self):
871 RepoModel().grant_users_group_permission(repo=self.REPO,
960 RepoModel().grant_users_group_permission(repo=self.REPO,
872 group_name=TEST_USERS_GROUP,
961 group_name=TEST_USERS_GROUP,
873 perm='repository.read')
962 perm='repository.read')
874 self.Session().commit()
963 self.Session().commit()
875 id_, params = _build_data(self.apikey, 'revoke_users_group_permission',
964 id_, params = _build_data(self.apikey, 'revoke_users_group_permission',
876 repoid=self.REPO,
965 repoid=self.REPO,
877 usersgroupid=TEST_USERS_GROUP,)
966 usersgroupid=TEST_USERS_GROUP,)
878 response = self.app.post(API_URL, content_type='application/json',
967 response = self.app.post(API_URL, content_type='application/json',
879 params=params)
968 params=params)
880
969
881 expected = {
970 expected = {
882 'msg': 'Revoked perm for users group: `%s` in repo: `%s`' % (
971 'msg': 'Revoked perm for users group: `%s` in repo: `%s`' % (
883 TEST_USERS_GROUP, self.REPO
972 TEST_USERS_GROUP, self.REPO
884 ),
973 ),
885 'success': True
974 'success': True
886 }
975 }
887 self._compare_ok(id_, expected, given=response.body)
976 self._compare_ok(id_, expected, given=response.body)
888
977
889 @mock.patch.object(RepoModel, 'revoke_users_group_permission', crash)
978 @mock.patch.object(RepoModel, 'revoke_users_group_permission', crash)
890 def test_api_revoke_users_group_permission_exception_when_adding(self):
979 def test_api_revoke_users_group_permission_exception_when_adding(self):
891
980
892 id_, params = _build_data(self.apikey, 'revoke_users_group_permission',
981 id_, params = _build_data(self.apikey, 'revoke_users_group_permission',
893 repoid=self.REPO,
982 repoid=self.REPO,
894 usersgroupid=TEST_USERS_GROUP,)
983 usersgroupid=TEST_USERS_GROUP,)
895 response = self.app.post(API_URL, content_type='application/json',
984 response = self.app.post(API_URL, content_type='application/json',
896 params=params)
985 params=params)
897
986
898 expected = 'failed to edit permission for users group: `%s` in repo: `%s`' % (
987 expected = 'failed to edit permission for users group: `%s` in repo: `%s`' % (
899 TEST_USERS_GROUP, self.REPO
988 TEST_USERS_GROUP, self.REPO
900 )
989 )
901 self._compare_error(id_, expected, given=response.body)
990 self._compare_error(id_, expected, given=response.body)
902
991
General Comments 0
You need to be logged in to leave comments. Login now