/ckan/logic/auth/update.py

https://gitlab.com/iislod/ckan · Python · 337 lines · 238 code · 70 blank · 29 comment · 42 complexity · 52d32f29d25f9f14dd8974fce9faa18d MD5 · raw file

  1. import ckan.logic as logic
  2. import ckan.authz as authz
  3. import ckan.logic.auth as logic_auth
  4. from ckan.common import _
  5. # FIXME this import is evil and should be refactored
  6. from ckan.logic.auth.create import _check_group_auth
  7. @logic.auth_allow_anonymous_access
  8. def package_update(context, data_dict):
  9. user = context.get('user')
  10. package = logic_auth.get_package_object(context, data_dict)
  11. if package.owner_org:
  12. # if there is an owner org then we must have update_dataset
  13. # permission for that organization
  14. check1 = authz.has_user_permission_for_group_or_org(
  15. package.owner_org, user, 'update_dataset'
  16. )
  17. else:
  18. # If dataset is not owned then we can edit if config permissions allow
  19. if authz.auth_is_anon_user(context):
  20. check1 = all(authz.check_config_permission(p) for p in (
  21. 'anon_create_dataset',
  22. 'create_dataset_if_not_in_organization',
  23. 'create_unowned_dataset',
  24. ))
  25. else:
  26. check1 = all(authz.check_config_permission(p) for p in (
  27. 'create_dataset_if_not_in_organization',
  28. 'create_unowned_dataset',
  29. )) or authz.has_user_permission_for_some_org(
  30. user, 'create_dataset')
  31. if not check1:
  32. return {'success': False,
  33. 'msg': _('User %s not authorized to edit package %s') %
  34. (str(user), package.id)}
  35. else:
  36. check2 = _check_group_auth(context, data_dict)
  37. if not check2:
  38. return {'success': False,
  39. 'msg': _('User %s not authorized to edit these groups') %
  40. (str(user))}
  41. return {'success': True}
  42. def package_resource_reorder(context, data_dict):
  43. ## the action function runs package update so no need to run it twice
  44. return {'success': True}
  45. def resource_update(context, data_dict):
  46. model = context['model']
  47. user = context.get('user')
  48. resource = logic_auth.get_resource_object(context, data_dict)
  49. # check authentication against package
  50. pkg = model.Package.get(resource.package_id)
  51. if not pkg:
  52. raise logic.NotFound(
  53. _('No package found for this resource, cannot check auth.')
  54. )
  55. pkg_dict = {'id': pkg.id}
  56. authorized = authz.is_authorized('package_update', context, pkg_dict).get('success')
  57. if not authorized:
  58. return {'success': False,
  59. 'msg': _('User %s not authorized to edit resource %s') %
  60. (str(user), resource.id)}
  61. else:
  62. return {'success': True}
  63. def resource_view_update(context, data_dict):
  64. return resource_update(context, {'id': data_dict['resource_id']})
  65. def resource_view_reorder(context, data_dict):
  66. return resource_update(context, {'id': data_dict['resource_id']})
  67. def package_relationship_update(context, data_dict):
  68. return authz.is_authorized('package_relationship_create',
  69. context,
  70. data_dict)
  71. def package_change_state(context, data_dict):
  72. user = context['user']
  73. package = logic_auth.get_package_object(context, data_dict)
  74. # use the logic for package_update
  75. authorized = authz.is_authorized_boolean('package_update',
  76. context,
  77. data_dict)
  78. if not authorized:
  79. return {
  80. 'success': False,
  81. 'msg': _('User %s not authorized to change state of package %s') %
  82. (str(user), package.id)
  83. }
  84. else:
  85. return {'success': True}
  86. def group_update(context, data_dict):
  87. group = logic_auth.get_group_object(context, data_dict)
  88. user = context['user']
  89. authorized = authz.has_user_permission_for_group_or_org(group.id,
  90. user,
  91. 'update')
  92. if not authorized:
  93. return {'success': False,
  94. 'msg': _('User %s not authorized to edit group %s') %
  95. (str(user), group.id)}
  96. else:
  97. return {'success': True}
  98. def organization_update(context, data_dict):
  99. group = logic_auth.get_group_object(context, data_dict)
  100. user = context['user']
  101. authorized = authz.has_user_permission_for_group_or_org(
  102. group.id, user, 'update')
  103. if not authorized:
  104. return {'success': False,
  105. 'msg': _('User %s not authorized to edit organization %s') %
  106. (user, group.id)}
  107. else:
  108. return {'success': True}
  109. def related_update(context, data_dict):
  110. model = context['model']
  111. user = context['user']
  112. if not user:
  113. return {'success': False,
  114. 'msg': _('Only the owner can update a related item')}
  115. related = logic_auth.get_related_object(context, data_dict)
  116. userobj = model.User.get(user)
  117. if not userobj or userobj.id != related.owner_id:
  118. return {'success': False,
  119. 'msg': _('Only the owner can update a related item')}
  120. # Only sysadmins can change the featured field.
  121. if ('featured' in data_dict and data_dict['featured'] != related.featured):
  122. return {'success': False,
  123. 'msg': _('You must be a sysadmin to change a related item\'s '
  124. 'featured field.')}
  125. return {'success': True}
  126. def group_change_state(context, data_dict):
  127. user = context['user']
  128. group = logic_auth.get_group_object(context, data_dict)
  129. # use logic for group_update
  130. authorized = authz.is_authorized_boolean('group_update',
  131. context,
  132. data_dict)
  133. if not authorized:
  134. return {
  135. 'success': False,
  136. 'msg': _('User %s not authorized to change state of group %s') %
  137. (str(user), group.id)
  138. }
  139. else:
  140. return {'success': True}
  141. def group_edit_permissions(context, data_dict):
  142. user = context['user']
  143. group = logic_auth.get_group_object(context, data_dict)
  144. authorized = authz.has_user_permission_for_group_or_org(
  145. group.id, user, 'update')
  146. if not authorized:
  147. return {
  148. 'success': False,
  149. 'msg': _('User %s not authorized to'
  150. ' edit permissions of group %s') %
  151. (str(user), group.id)}
  152. else:
  153. return {'success': True}
  154. @logic.auth_allow_anonymous_access
  155. def user_update(context, data_dict):
  156. user = context['user']
  157. # FIXME: We shouldn't have to do a try ... except here, validation should
  158. # have ensured that the data_dict contains a valid user id before we get to
  159. # authorization.
  160. try:
  161. user_obj = logic_auth.get_user_object(context, data_dict)
  162. except logic.NotFound:
  163. return {'success': False, 'msg': _('User not found')}
  164. # If the user has a valid reset_key in the db, and that same reset key
  165. # has been posted in the data_dict, we allow the user to update
  166. # her account without using her password or API key.
  167. if user_obj.reset_key and 'reset_key' in data_dict:
  168. if user_obj.reset_key == data_dict['reset_key']:
  169. return {'success': True}
  170. if not user:
  171. return {'success': False,
  172. 'msg': _('Have to be logged in to edit user')}
  173. if user == user_obj.name:
  174. # Allow users to update their own user accounts.
  175. return {'success': True}
  176. else:
  177. # Don't allow users to update other users' accounts.
  178. return {'success': False,
  179. 'msg': _('User %s not authorized to edit user %s') %
  180. (user, user_obj.id)}
  181. def user_generate_apikey(context, data_dict):
  182. user = context['user']
  183. user_obj = logic_auth.get_user_object(context, data_dict)
  184. if user == user_obj.name:
  185. # Allow users to update only their own user accounts.
  186. return {'success': True}
  187. return {'success': False, 'msg': _('User {0} not authorized to update user'
  188. ' {1}'.format(user, user_obj.id))}
  189. def revision_change_state(context, data_dict):
  190. # FIXME currently only sysadmins can change state
  191. user = context['user']
  192. return {
  193. 'success': False,
  194. 'msg': _('User %s not authorized to change state of revision') % user
  195. }
  196. def task_status_update(context, data_dict):
  197. # sysadmins only
  198. user = context['user']
  199. return {
  200. 'success': False,
  201. 'msg': _('User %s not authorized to update task_status table') % user
  202. }
  203. def vocabulary_update(context, data_dict):
  204. # sysadmins only
  205. return {'success': False}
  206. def term_translation_update(context, data_dict):
  207. # sysadmins only
  208. user = context['user']
  209. return {
  210. 'success': False,
  211. 'msg': _('User %s not authorized to update term_translation table') % user
  212. }
  213. def dashboard_mark_activities_old(context, data_dict):
  214. return authz.is_authorized('dashboard_activity_list',
  215. context,
  216. data_dict)
  217. def send_email_notifications(context, data_dict):
  218. # Only sysadmins are authorized to send email notifications.
  219. return {'success': False}
  220. ## Modifications for rest api
  221. def package_update_rest(context, data_dict):
  222. model = context['model']
  223. user = context['user']
  224. if not user:
  225. return {'success': False,
  226. 'msg': _('Valid API key needed to edit a package')}
  227. return authz.is_authorized('package_update', context, data_dict)
  228. def group_update_rest(context, data_dict):
  229. model = context['model']
  230. user = context['user']
  231. if not user:
  232. return {'success': False,
  233. 'msg': _('Valid API key needed to edit a group')}
  234. return group_update(context, data_dict)
  235. def package_owner_org_update(context, data_dict):
  236. # sysadmins only
  237. return {'success': False}
  238. def bulk_update_private(context, data_dict):
  239. org_id = data_dict.get('org_id')
  240. user = context['user']
  241. authorized = authz.has_user_permission_for_group_or_org(
  242. org_id, user, 'update')
  243. if not authorized:
  244. return {'success': False}
  245. return {'success': True}
  246. def bulk_update_public(context, data_dict):
  247. org_id = data_dict.get('org_id')
  248. user = context['user']
  249. authorized = authz.has_user_permission_for_group_or_org(
  250. org_id, user, 'update')
  251. if not authorized:
  252. return {'success': False}
  253. return {'success': True}
  254. def bulk_update_delete(context, data_dict):
  255. org_id = data_dict.get('org_id')
  256. user = context['user']
  257. authorized = authz.has_user_permission_for_group_or_org(
  258. org_id, user, 'update')
  259. if not authorized:
  260. return {'success': False}
  261. return {'success': True}
  262. def config_option_update(context, data_dict):
  263. '''Update the runtime-editable configuration options
  264. Only sysdmins can do it
  265. '''
  266. return {'success': False}