def form_to_db_schema_options(self, options={}): context = options.get('context', {}) schema = context.get('schema',None) if schema: return schema elif options.get('api'): if options.get('type') == 'create': return default_schema.default_create_package_schema() else: return default_schema.default_update_package_schema() schema = self.form_to_db_schema() # Sysadmins can save UKLP datasets with looser validation # constraints. This is because UKLP datasets are created using # a custom schema passed in from the harvester. However, when it # comes to re-saving the dataset via the dataset form, there are # some validation requirements we need to drop. That's what this # section of code does. pkg = context.get('package') user = context.get('user', '') if Authorizer().is_sysadmin(unicode(user)) and \ pkg and pkg.extras.get('UKLP', 'False') == 'True': schema.update(self._uklp_sysadmin_schema_updates) if Authorizer().is_sysadmin(unicode(user)) and \ pkg and pkg.extras.get('external_reference') == 'ONSHUB': self._ons_sysadmin_schema_updates(schema) return schema
def setup_template_variables(self, context, data_dict=None): """ Adds variables to c just prior to the template being rendered that can then be used within the form """ c.licences = [('', '')] + model.Package.get_license_options() c.publishers = [('lightbase publisher', 'lightbase publisher 2')] c.is_sysadmin = Authorizer().is_sysadmin(c.user) c.resource_columns = model.Resource.get_columns() try: c.genre_tags = get_action('tag_list')(context, { 'vocabulary_id': GENRE_VOCAB }) c.composer_tags = get_action('tag_list')( context, { 'vocabulary_id': COMPOSER_VOCAB }) except NotFound: c.vocab_tags = None c.composer_tags = None ## This is messy as auths take domain object not data_dict pkg = context.get('package') or c.pkg if pkg: c.auth_for_change_state = Authorizer().am_authorized( c, model.Action.CHANGE_STATE, pkg)
def _setup_template_variables(self, context): c.is_sysadmin = Authorizer().is_sysadmin(c.user) ## This is messy as auths take domain object not data_dict group = context.get('group') or c.pkg if group: c.auth_for_change_state = Authorizer().am_authorized( c, model.Action.CHANGE_STATE, group)
def ignore_not_admin(key, data, errors, context): model = context['model'] user = context.get('user') if user and Authorizer.is_sysadmin(user): return pkg = context.get('package') if (user and pkg and Authorizer().is_authorized( user, model.Action.CHANGE_STATE, pkg)): return data.pop(key)
def dgu_package_update(context, data_dict): model = context['model'] user = context.get('user') user_obj = model.User.get(user) package = get_package_object(context, data_dict) if Authorizer().is_sysadmin(user_obj): return {'success': True} # Only sysadmins can edit UKLP packages. # Note: the harvest user *is* a sysadmin # Note: if changing this, check the code and comments in # ckanext/forms/dataset_form.py:DatasetForm.form_to_db_schema_options() if package.extras.get('UKLP', '') == 'True': return { 'success': False, 'msg': _('User %s not authorized to edit packages in these groups') % str(user) } if not user_obj or \ not _groups_intersect( user_obj.get_groups('publisher'), package.get_groups('publisher') ): return { 'success': False, 'msg': _('User %s not authorized to edit packages of this publisher') % str(user) } return {'success': True}
def dgu_group_update(context, data_dict): """ Group edit permission. Checks that a valid user is supplied and that the user is a member of the group with a capacity of admin. """ model = context['model'] user = context.get('user','') group = get_group_object(context, data_dict) if not user: return {'success': False, 'msg': _('Only members of this group are authorized to edit this group')} # Sys admins should be allowed to update groups if Authorizer().is_sysadmin(unicode(user)): return { 'success': True } # Only allow package update if the user and package groups intersect user_obj = model.User.get( user ) if not user_obj: return { 'success' : False, 'msg': _('Could not find user %s') % str(user) } parent_groups = list(publib.go_up_tree(group)) # Check if user is an admin of a parent group, and if so allow them to edit. if _groups_intersect( user_obj.get_groups('publisher', 'admin'), parent_groups ): return {'success': True} # Check admin of just this group if _groups_intersect( user_obj.get_groups('publisher', 'admin'), [group] ): return {'success': True} return { 'success': False, 'msg': _('User %s not authorized to edit this group') % str(user) }
def am_authorized(c, action, domain_object=None): ''' Deprecated. Please use check_access instead''' from ckan.authz import Authorizer if domain_object is None: from ckan import model domain_object = model.System() return Authorizer.am_authorized(c, action, domain_object)
def get_publishers(self): from ckan.model.group import Group if Authorizer().is_sysadmin(c.user): groups = Group.all(group_type='publisher') elif c.userobj: # need to get c.userobj again as it may be detached from the # session since the last time we called get_groups (it caches) c.userobj = model.User.by_name(c.user) groups = c.userobj.get_groups('publisher') else: # anonymous user shouldn't have access to this page anyway. groups = [] # Be explicit about which fields we make available in the template groups = [{ 'name': g.name, 'id': g.id, 'title': g.title, 'contact-name': g.extras.get('contact-name', ''), 'contact-email': g.extras.get('contact-email', ''), 'contact-phone': g.extras.get('contact-phone', ''), 'foi-name': g.extras.get('foi-name', ''), 'foi-email': g.extras.get('foi-email', ''), 'foi-phone': g.extras.get('foi-phone', ''), } for g in groups] return dict((g['name'], g) for g in groups)
def related_delete(context, data_dict): model = context['model'] user = context['user'] if not user: return { 'success': False, 'msg': _('Only the owner can delete a related item') } if Authorizer().is_sysadmin(unicode(user)): return {'success': True} related = get_related_object(context, data_dict) userobj = model.User.get(user) if related.datasets: package = related.datasets[0] if _groups_intersect(userobj.get_groups('organization'), package.get_groups('organization')): return {'success': True} if not userobj or userobj.id != related.owner_id: return { 'success': False, 'msg': _('Only the owner can delete a related item') } return {'success': True}
def ignore_not_package_admin(key, data, errors, context): '''Ignore if the user is not allowed to administer the package specified.''' model = context['model'] user = context.get('user') if 'ignore_auth' in context: return if user and Authorizer.is_sysadmin(user): return authorized = False pkg = context.get('package') if pkg: try: check_access('package_change_state',context) authorized = True except NotAuthorized: authorized = False if (user and pkg and authorized): return data.pop(key)
def new(self, data=None, errors=None, error_summary=None): '''GET to display a form for registering a new user. or POST the form data to actually do the user registration. ''' context = { 'model': model, 'session': model.Session, 'user': c.user or c.author, 'schema': self._new_form_to_db_schema(), 'save': 'save' in request.params } try: check_access('user_create', context) except NotAuthorized: abort(401, _('Unauthorized to create a user')) if context['save'] and not data: return self._save_new(context) if c.user and not data: # #1799 Don't offer the registration form if already logged in return render('user/logout_first.html') data = data or {} errors = errors or {} error_summary = error_summary or {} vars = {'data': data, 'errors': errors, 'error_summary': error_summary} c.is_sysadmin = Authorizer().is_sysadmin(c.user) c.form = render(self.new_user_form, extra_vars=vars) return render('user/new.html')
def package_show(context, data_dict): """ Package show permission checks the user group if the state is deleted """ model = context['model'] package = get_package_object(context, data_dict) if package.state == 'deleted': if 'ignore_auth' in context and context['ignore_auth']: return {'success': True} user = context.get('user') if not user: return {'success': False, 'msg': _('User not authorized to read package %s') % (package.id)} userobj = model.User.get( user ) if Authorizer().is_sysadmin(unicode(user)): return {'success': True} if not userobj: return {'success': False, 'msg': _('User %s not authorized to read package %s') % (str(user),package.id)} if not _groups_intersect( userobj.get_groups('publisher'), package.get_groups('publisher') ): return {'success': False, 'msg': _('User %s not authorized to read package %s') % (str(user),package.id)} return {'success': True}
def group_create(context, data_dict=None): """ Group create permission. If a group is provided, within which we want to create a group then we check that the user is within that group. If not then we just say Yes for now although there may be some approval issues elsewhere. """ model = context['model'] user = context['user'] if not model.User.get(user): return {'success': False, 'msg': _('User is not authorized to create groups') } if Authorizer.is_sysadmin(user): return {'success': True} try: # If the user is doing this within another group then we need to make sure that # the user has permissions for this group. group = get_group_object( context ) except logic.NotFound: return { 'success' : True } userobj = model.User.get( user ) if not userobj: return {'success': False, 'msg': _('User %s not authorized to create groups') % str(user)} authorized = _groups_intersect( userobj.get_groups('organization'), [group] ) if not authorized: return {'success': False, 'msg': _('User %s not authorized to create groups') % str(user)} else: return {'success': True}
def harvest_job_show(context, data_dict): model = context['model'] user = context.get('user') job = get_job_object(context, data_dict) if not user: return { 'success': False, 'msg': _('Non-logged in users are not authorized to see harvest jobs') } if Authorizer().is_sysadmin(user): return {'success': True} user_obj = User.get(user) if not user_obj or not job.source.publisher_id in [ g.id for g in user_obj.get_groups(u'publisher') ]: return { 'success': False, 'msg': _('User %s not authorized to read harvest job %s') % (str(user), job.id) } else: return {'success': True}
def related_delete(context, data_dict): model = context['model'] user = context['user'] if not user: return { 'success': False, 'msg': _('Only the owner can delete a related item') } if Authorizer().is_sysadmin(unicode(user)): return {'success': True} related = get_related_object(context, data_dict) userobj = model.User.get(user) if related.datasets: package = related.datasets[0] pkg_dict = {'id': package.id} authorized = package_delete(context, pkg_dict).get('success') if authorized: return {'success': True} if not userobj or userobj.id != related.owner_id: return { 'success': False, 'msg': _('Only the owner can delete a related item') } return {'success': True}
def harvesters_info_show(context, data_dict): model = context['model'] user = context.get('user', '') # Non-logged users can not create sources if not user: return { 'success': False, 'msg': _('Non-logged in users can not see the harvesters info') } # Sysadmins and the rest of logged users can see the harvesters info, # as long as they belong to a publisher user_obj = User.get(user) if not user_obj or not Authorizer().is_sysadmin(user) and len( user_obj.get_groups(u'publisher')) == 0: return { 'success': False, 'msg': _('User %s must belong to a publisher to see the harvesters info') % str(user) } else: return {'success': True}
def harvest_source_list(context, data_dict): model = context['model'] user = context.get('user') # Here we will just check that the user is logged in. # The logic action will return an empty list if the user does not # have permissons on any source. if not user: return { 'success': False, 'msg': _('Only logged users are authorized to see their sources') } else: user_obj = User.get(user) assert user_obj # Only users belonging to a publisher can list sources, # unless they are sysadmins if Authorizer().is_sysadmin(user_obj): return {'success': True} if len(user_obj.get_groups(u'publisher')) > 0: return {'success': True} else: return { 'success': False, 'msg': _('User %s must belong to a publisher to list harvest sources') % str(user) }
def ignore_not_package_admin(key, data, errors, context): '''Ignore if the user is not allowed to administer the package specified.''' model = context['model'] user = context.get('user') if 'ignore_auth' in context: return if user and Authorizer.is_sysadmin(user): return authorized = False pkg = context.get('package') if pkg: try: check_access('package_change_state', context) authorized = True except NotAuthorized: authorized = False if (user and pkg and authorized): return data.pop(key)
def resource_update(context, data_dict): """ Update resource permission checks the user is in a group that the resource's package is also a member of. """ model = context['model'] user = context.get('user') resource = get_resource_object(context, data_dict) userobj = model.User.get(user) if Authorizer().is_sysadmin(unicode(user)): return {'success': True} if not userobj: return { 'success': False, 'msg': _('User %s not authorized to edit resources in this package') % str(user) } if not _groups_intersect( userobj.get_groups('organization'), resource.resource_group.package.get_groups('organization')): return { 'success': False, 'msg': _('User %s not authorized to edit resources in this package') % str(user) } return {'success': True}
def ignore_not_package_admin(key, data, errors, context): '''Ignore if the user is not allowed to administer the package specified.''' model = context['model'] user = context.get('user') if 'ignore_auth' in context: return if user and Authorizer.is_sysadmin(user): return authorized = False pkg = context.get('package') if pkg: try: check_access('package_change_state',context) authorized = True except NotAuthorized: authorized = False if (user and pkg and authorized): return # allow_state_change in the context will allow the state to be changed # FIXME is this the best way to cjeck for state only? if key == ('state',) and context.get('allow_state_change'): return data.pop(key)
def harvest_job_create(context, data_dict): model = context['model'] user = context.get('user') source_id = data_dict['source_id'] if not user: return { 'success': False, 'msg': _('Non-logged in users are not authorized to create harvest jobs') } if Authorizer().is_sysadmin(user): return {'success': True} user_obj = User.get(user) source = HarvestSource.get(source_id) if not source: raise NotFound if not user_obj or not source.publisher_id in [ g.id for g in user_obj.get_groups(u'publisher') ]: return { 'success': False, 'msg': _('User %s not authorized to create a job for source %s') % (str(user), source.id) } else: return {'success': True}
def harvest_source_update(context, data_dict): model = context['model'] user = context.get('user', '') source = get_source_object(context, data_dict) # Non-logged users can not update this source if not user: return { 'success': False, 'msg': _('Non-logged in users are not authorized to update harvest sources' ) } # Sysadmins can update the source if Authorizer().is_sysadmin(user): return {'success': True} # Check if the source publisher id exists on the user's groups user_obj = User.get(user) if not user_obj or not source.publisher_id in [ g.id for g in user_obj.get_groups(u'publisher') ]: return { 'success': False, 'msg': _('User %s not authorized to update harvest source %s') % (str(user), source.id) } else: return {'success': True}
def _setup_template_variables(self, context, data_dict=None, package_type=None): log.debug("_setup_template_variables") c.update_frequency = update_frequency c.categorization = categorization c.groups_authz = get_action('group_list_authz')(context, data_dict) data_dict.update({'available_only': True}) #c.groups_available = get_action('group_list_authz')(context, data_dict) c.groups_available = c.userobj and c.userobj.get_groups( 'organization') or [] c.licences = [('', '')] + model.Package.get_license_options() c.is_sysadmin = Authorizer().is_sysadmin(c.user) if c.is_sysadmin: c.groups_available = Group.all('organization') log.fatal("is_sysadmin: %s" % c.is_sysadmin) log.fatal("groups: %s" % c.groups_available) ## This is messy as auths take domain object not data_dict context_pkg = context.get('package', None) pkg = context_pkg or c.pkg if pkg: try: if not context_pkg: context['package'] = pkg check_access('package_change_state', context) c.auth_for_change_state = True except NotAuthorized: c.auth_for_change_state = False
def ignore_not_package_admin(key, data, errors, context): '''Ignore if the user is not allowed to administer the package specified.''' model = context['model'] user = context.get('user') if 'ignore_auth' in context: return if user and Authorizer.is_sysadmin(user): return authorized = False pkg = context.get('package') if pkg: try: check_access('package_change_state', context) authorized = True except NotAuthorized: authorized = False if (user and pkg and authorized): return # allow_state_change in the context will allow the state to be changed # FIXME is this the best way to cjeck for state only? if key == ('state', ) and context.get('allow_state_change'): return data.pop(key)
def related_create(context, data_dict=None): '''Users must be logged-in to create related items. To create a featured item the user must be a sysadmin. ''' model = context['model'] user = context['user'] userobj = model.User.get(user) if userobj: if (data_dict.get('featured', 0) != 0 and not Authorizer().is_sysadmin(unicode(user))): return { 'success': False, 'msg': _('You must be a sysadmin to create a featured ' 'related item') } return {'success': True} return { 'success': False, 'msg': _('You must be logged in to add a related item') }
def harvest_objects_import(context,data_dict): model = context['model'] user = context.get('user') if not Authorizer().is_sysadmin(user): return {'success': False, 'msg': _('User %s not authorized to reimport harvest objects') % str(user)} else: return {'success': True}
def harvest_jobs_run(context,data_dict): model = context['model'] user = context.get('user') if not Authorizer().is_sysadmin(user): return {'success': False, 'msg': _('User %s not authorized to run the pending harvest jobs') % str(user)} else: return {'success': True}
def dgu_group_create(context, data_dict=None): model = context['model'] user = context['user'] if Authorizer().is_sysadmin(unicode(user)): return {'success': True} return {'success': False, 'msg': _('User %s not authorized to create groups') % str(user)}
def harvest_source_delete(context,data_dict): model = context['model'] user = context.get('user') if not Authorizer().is_sysadmin(user): return {'success': False, 'msg': _('User %s not authorized to delete harvest sources') % str(user)} else: return {'success': True}
def setup_template_variables(self, context, data_dict=None): """ Adds variables to c just prior to the template being rendered that can then be used within the form """ c.licences = [('', '')] + model.Package.get_license_options() c.publishers = [('Example publisher', 'Example publisher 2')] c.is_sysadmin = Authorizer().is_sysadmin(c.user) c.resource_columns = model.Resource.get_columns() c.groups_available = c.userobj.get_groups( 'publisher') if c.userobj else [] ## This is messy as auths take domain object not data_dict pkg = context.get('package') or c.pkg if pkg: c.auth_for_change_state = Authorizer().am_authorized( c, model.Action.CHANGE_STATE, pkg)
def task_status_delete(context, data_dict): model = context['model'] user = context['user'] authorized = Authorizer().is_sysadmin(unicode(user)) if not authorized: return {'success': False, 'msg': _('User %s not authorized to delete task_status') % str(user)} else: return {'success': True}
def user_update(context, data_dict): user = context['user'] user_obj = get_user_object(context, data_dict) if not (Authorizer().is_sysadmin(unicode(user)) or user == user_obj.name) and \ not ('reset_key' in data_dict and data_dict['reset_key'] == user_obj.reset_key): return {'success': False, 'msg': _('User %s not authorized to edit user %s') % (str(user), user_obj.id)} return {'success': True}
def revision_change_state(context, data_dict): model = context['model'] user = context['user'] authorized = Authorizer().is_authorized(user, model.Action.CHANGE_STATE, model.Revision) if not authorized: return {'success': False, 'msg': _('User %s not authorized to change state of revision' ) % str(user)} else: return {'success': True}
def test_index(self): offset = url_for(controller='authorization_group') res = self.app.get(offset, extra_environ={'REMOTE_USER': '******'}) assert '<h2>Authorization Groups</h2>' in res, res group_count = Authorizer.authorized_query(u'russianfan', model.AuthorizationGroup).count() assert 'There are %s authorization groups.' % group_count in self.strip_tags(res), res authz_groupname = u'treasury' authz_group = model.AuthorizationGroup.by_name(unicode(authz_groupname)) group_users_count = len(authz_group.users) self.check_named_element(res, 'tr', authz_groupname, group_users_count)
def group_list_authz(context, data_dict): """ Returns a list of groups which the user is allowed to edit If 'available_only' is specified, the existing groups in the package are removed. """ model = context["model"] user = context["user"] available_only = data_dict.get("available_only", False) check_access("group_list_authz", context, data_dict) query = Authorizer().authorized_query(user, model.Group, model.Action.EDIT) groups = set(query.all()) if available_only: package = context.get("package") if package: groups = groups - set(package.groups) return [{"id": group.id, "name": group.name} for group in groups]
def group_list_authz(context, data_dict): ''' Returns a list of groups which the user is allowed to edit If 'available_only' is specified, the existing groups in the package are removed. ''' model = context['model'] user = context['user'] available_only = data_dict.get('available_only',False) check_access('group_list_authz',context, data_dict) query = Authorizer().authorized_query(user, model.Group, model.Action.EDIT) groups = set(query.all()) if available_only: package = context.get('package') if package: groups = groups - set(package.get_groups()) return [{'id':group.id,'name':group.name} for group in groups]
def ignore_not_admin(key, data, errors, context): model = context['model'] user = context.get('user') if user and Authorizer.is_sysadmin(user): return pkg = context.get('package') if (user and pkg and Authorizer().is_authorized(user, model.Action.CHANGE_STATE, pkg)): return data.pop(key)
def ignore_not_admin(key, data, errors, context): model = context['model'] user = context.get('user') if user and Authorizer.is_sysadmin(user): return authorized = False pkg = context.get('package') if pkg: try: check_access('package_change_state',context) authorized = True except NotAuthorized: authorized = False if (user and pkg and authorized): return data.pop(key)
def ignore_not_group_admin(key, data, errors, context): '''Ignore if the user is not allowed to administer for the group specified.''' model = context['model'] user = context.get('user') if user and Authorizer.is_sysadmin(user): return authorized = False group = context.get('group') if group: try: check_access('group_change_state',context) authorized = True except NotAuthorized: authorized = False if (user and group and authorized): return data.pop(key)
def activity_create(context, data_dict): user = context["user"] return {"success": Authorizer.is_sysadmin(user)}
def tag_delete(context, data_dict): user = context['user'] return {'success': Authorizer.is_sysadmin(user)}
def vocabulary_update(context, data_dict): user = context["user"] return {"success": Authorizer.is_sysadmin(user)}
def vocabulary_update(context, data_dict): user = context['user'] return {'success': Authorizer.is_sysadmin(user)}
def am_authorized(c, action, domain_object=None): from ckan.authz import Authorizer if domain_object is None: from ckan import model domain_object = model.System() return Authorizer.am_authorized(c, action, domain_object)
def activity_create(context, data_dict): user = context['user'] return {'success': Authorizer.is_sysadmin(user)}
def test_system_edit_authorized(self): authorizer = Authorizer() auth_for_create = authorizer.is_authorized(\ u'johndoe', model.Action.PACKAGE_CREATE, model.System()) assert not auth_for_create