forked from datopian/ckanext-iaea
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
da83fb0
commit 35784b9
Showing
5 changed files
with
168 additions
and
0 deletions.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import logging | ||
import ckan.lib.datapreview as datapreview | ||
import ckan.logic as l | ||
import ckan.plugins as p | ||
from ckan.logic.schema import default_create_resource_view_schema, default_update_resource_view_schema | ||
|
||
from ckanext.iaea.helpers import get_main_organization | ||
|
||
log = logging.getLogger(__name__) | ||
|
||
ignore_missing = p.toolkit.get_validator('ignore_missing') | ||
|
||
|
||
@p.toolkit.chained_action | ||
def resource_view_create(up_func, context, data_dict): | ||
view_plugin = datapreview.get_view_plugin(data_dict['view_type']) | ||
if not view_plugin: | ||
raise l.ValidationError( | ||
{"view_type": "No plugin found for view_type {view_type}".format( | ||
view_type=data_dict['view_type'] | ||
)} | ||
) | ||
schema = default_create_resource_view_schema(view_plugin) | ||
schema.update({ | ||
'suggested_filter_fields': [ignore_missing] | ||
}) | ||
context['schema'] = schema | ||
result = up_func(context, data_dict) | ||
return result | ||
|
||
|
||
@p.toolkit.chained_action | ||
def resource_view_update(up_func, context, data_dict): | ||
model = context['model'] | ||
resource_view = model.ResourceView.get(data_dict['id']) | ||
if not resource_view: | ||
raise l.NotFound | ||
view_plugin = datapreview.get_view_plugin(resource_view.view_type) | ||
schema = default_update_resource_view_schema(view_plugin) | ||
schema.update({ | ||
'suggested_filter_fields': [ignore_missing] | ||
}) | ||
context['schema'] = schema | ||
result = up_func(context, data_dict) | ||
return result |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
from sqlalchemy.sql import exists | ||
from sqlalchemy import or_ | ||
|
||
import ckan.model as model | ||
import ckan.plugins as p | ||
from ckan.common import config, g, _ | ||
|
||
|
||
@p.toolkit.chained_auth_function | ||
def package_create(next_auth, context, data_dict): | ||
return _check_dataset_write_actions_restricted(next_auth, context, data_dict) | ||
|
||
|
||
def _check_dataset_write_actions_restricted(next_auth, context, data_dict): | ||
res = next_auth(context, data_dict) | ||
if not res.get('success'): | ||
return res | ||
|
||
allowed_orgs = config.get('ckanext.iaea.allow_dataset_create_from_organization') or '' | ||
allowed_orgs = [o.strip() for o in allowed_orgs.strip().split(',') if o.strip()] | ||
|
||
if not allowed_orgs: | ||
return res | ||
|
||
user = context.get('auth_user_obj') | ||
if user: | ||
org_ids = get_organization_ids(allowed_orgs) | ||
if not org_ids: | ||
return res | ||
|
||
if not user_has_sufficient_roles_in_org(user.id, org_ids, ['editor', 'admin']): | ||
return { | ||
'success': False, | ||
'message': _('User {} cannot create datasets.').format(user.name), | ||
} | ||
|
||
return res | ||
|
||
def get_allowed_organizations_ids(): | ||
allowed_orgs = config.get('ckanext.iaea.allow_dataset_create_from_organization') or '' | ||
allowed_orgs = [o.strip() for o in allowed_orgs.strip().split(',') if o.strip()] | ||
|
||
if not allowed_orgs: | ||
return [] | ||
return get_organization_ids(allowed_orgs) | ||
|
||
def user_has_sufficient_roles_in_org(user_id, org_ids, roles): | ||
q = (model.Session.query(model.Member.group_id) | ||
.filter(model.Member.state=='active') | ||
.filter(model.Member.table_name=='user') | ||
.filter(model.Member.group_id.in_(org_ids)) | ||
.filter(model.Member.table_id == user_id) | ||
.filter(model.Member.capacity.in_(roles))).exists() | ||
return model.Session.query(q).scalar() | ||
|
||
def get_organization_ids(org_names_ids): | ||
q = (model.Session.query(model.Group.id) | ||
.filter(or_(model.Group.id.in_(org_names_ids), model.Group.name.in_(org_names_ids))) | ||
.filter(model.Group.state == 'active') | ||
.filter(model.Group.type == 'organization')) | ||
return [org_id[0] for org_id in q] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import ckan.plugins.toolkit as tk | ||
import ckan.lib.helpers as h | ||
import ckan.lib.navl.dictization_functions as df | ||
from ckan.common import _ | ||
|
||
from ckanext.iaea.helpers import get_main_organization | ||
from ckanext.iaea.logic.auth import get_allowed_organizations_ids | ||
|
||
|
||
def package_organization_validator(value, context): | ||
'''Validates the organization on create/update package. | ||
The organization must be one of: | ||
- Empty value i.e. no owner organization for the package. | ||
- If set, then it must be set to the main organization of the portal. | ||
- If the package already was owned by an organization, the value must either be that old | ||
organization or the main portal organization (this is for compatibility with older packages). | ||
''' | ||
if not value: | ||
return value | ||
|
||
main_org = get_main_organization() | ||
package = context.get('package') | ||
|
||
if not package and not main_org: | ||
raise df.Invalid(_('Only datasets without organization are allowed')) | ||
|
||
if not package: | ||
# Check that the current owner_org is the main owner_org | ||
if value.lower() != main_org.get('name').lower() and value.lower() != main_org.get('id').lower(): | ||
# Check if we can allow from additional organizations for load testing, but only if specified | ||
if value not in get_allowed_organizations_ids(): | ||
raise df.Invalid(_('The dataset owner organization must be {} or empty').format(main_org.get('name'))) | ||
|
||
if package and main_org: | ||
new_org = _get_organization(value) | ||
if not new_org: | ||
raise df.Invalid(_('Package owner organization does not exist')) | ||
if new_org.get('id') != package.owner_org: | ||
# The owner organization was updated, so it must be set to the main organization or not at all. | ||
if new_org.get('id') != main_org.get('id'): | ||
# The new owner org is not the main org. | ||
raise df.Invalid(_('You can only update the package owner organization to {} or leave the old one.').format(main_org.get('name'))) | ||
|
||
return value | ||
|
||
|
||
def _get_organization(value): | ||
try: | ||
return tk.get_action('organization_show')({ | ||
'ignore_auth': True, | ||
}, { | ||
'id': value, | ||
}) | ||
except tk.ObjectNotFound: | ||
return None |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters