Users can choose if their datasets can or not be searched

This commit is contained in:
Aitor Magán 2014-07-04 11:49:36 +02:00
parent ab3ac4739b
commit 8bf820a15e
4 changed files with 174 additions and 4 deletions

View File

@ -16,14 +16,17 @@ this.ckan.module('allowed-users', function ($, _) {
if (ds_private == "True") {
$('#field-allowed_users').prop('disabled', false); //Enable
$('#field-adquire_url').prop('disabled', false); //Enable
$('#field-searchable').prop('disabled', false); //Enable
} else {
$('#field-allowed_users').prop('disabled', true); //Disable
$('#field-adquire_url').prop('disabled', true); //Disable
$('#field-searchable').prop('disabled', true); //Disable
//Remove previous values
$('#s2id_field-allowed_users .select2-search-choice').remove();
$('#field-allowed_users').val('');
$('#field-adquire_url').val('');
$('#field-searchable').val('True');
}
}
};

View File

@ -137,6 +137,7 @@ class PrivateDatasets(p.SingletonPlugin, tk.DefaultDatasetForm):
p.implements(p.IConfigurer)
p.implements(p.IRoutes, inherit=True)
p.implements(p.IActions)
p.implements(p.IPackageController)
######################################################################
############################ DATASET FORM ############################
@ -152,7 +153,11 @@ class PrivateDatasets(p.SingletonPlugin, tk.DefaultDatasetForm):
tk.get_converter('convert_to_extras')],
'adquire_url': [tk.get_validator('ignore_missing'),
private_datasets_metadata_checker,
tk.get_converter('convert_to_extras')]
tk.get_converter('convert_to_extras')],
'searchable': [tk.get_validator('ignore_missing'),
private_datasets_metadata_checker,
tk.get_converter('convert_to_extras'),
tk.get_validator('boolean_validator')]
}
def create_package_schema(self):
@ -173,7 +178,9 @@ class PrivateDatasets(p.SingletonPlugin, tk.DefaultDatasetForm):
'allowed_users': [tk.get_converter('convert_from_extras'),
tk.get_validator('ignore_missing')],
'adquire_url': [tk.get_converter('convert_from_extras'),
tk.get_validator('ignore_missing')]
tk.get_validator('ignore_missing')],
'searchable': [tk.get_converter('convert_from_extras'),
tk.get_validator('ignore_missing')]
})
return schema
@ -225,8 +232,8 @@ class PrivateDatasets(p.SingletonPlugin, tk.DefaultDatasetForm):
######################################################################
def get_actions(self):
# Update package_show function. When the URL is the URL used to
# check the datasets, the context parameter will me modified and
# Update package_search function. When the URL is the URL used to
# retrieve the datasets, the context parameter will me modified and
# the field 'ignore_capacity_check' will be added in order to
# get both the private and the public datasets.
@ -244,3 +251,55 @@ class PrivateDatasets(p.SingletonPlugin, tk.DefaultDatasetForm):
# Modify the package_show function used across the system
return {'package_search': _new_package_search}
######################################################################
######################### IPACKAGECONTROLLER #########################
######################################################################
def before_index(self, pkg_dict):
return pkg_dict
def before_view(self, pkg_dict):
return pkg_dict
def before_search(self, search_params):
# Filter mustn't be applied when a user serachs datasets within organizations
if ('q' not in search_params or 'owner_org' not in search_params['q']) and \
('fq' not in search_params or 'owner_org' not in search_params['fq']):
# Create the fq field if it does not exist
if 'fq' not in search_params:
search_params['fq'] = ''
# searchable does not exist or is equals to True
search_params['fq'] += ' -(-searchable:True AND searchable:[* TO *])'
return search_params
def create(self, pkg_dict):
return pkg_dict
def edit(self, pkg_dict):
return pkg_dict
def read(self, pkg_dict):
return pkg_dict
def delete(self, pkg_dict):
return pkg_dict
def after_create(self, context, pkg_dict):
return pkg_dict
def after_update(self, context, pkg_dict):
return pkg_dict
def after_show(self, context, pkg_dict):
return pkg_dict
def after_search(self, search_results, search_params):
return search_results
def after_delete(self, context, pkg_dict):
return pkg_dict

View File

@ -47,10 +47,37 @@
<option value="{{ option[0] }}" {% if option[0] == data.private|trim %}selected="selected"{% endif %}>{{ option[1] }}</option>
{% endfor %}
</select>
<span class="info-block info-inline">
<i class="icon-info-sign"></i>
{% trans %}
If private, the dataset will be only accesible to certain users. Otherwise, everyone will be able to access the dataset.
{% endtrans %}
</span>
</div>
</div>
{% endblock %}
{% block package_metadata_fields_protected %}
<div class="control-group">
<label for="field-searchable" class="control-label">{{ _('Searchable') }}</label>
<div class="controls">
<select id="field-searchable" name="searchable">
{% for option in [('True', _('True')), ('False', _('False'))] %}
<option value="{{ option[0] }}" {% if option[0] == data.searchable|trim %}selected="selected"{% endif %}>{{ option[1] }}</option>
{% endfor %}
</select>
<span class="info-block info-inline">
<i class="icon-info-sign"></i>
{% trans %}
When true, the dataset will be shown in search. Otherwise, it will only be accesible entering its URL directly.
{% endtrans %}
</span>
</div>
</div>
{% endblock %}
{% if show_organizations_selector and show_visibility_selector %}
</div>
{% endif %}

View File

@ -43,6 +43,7 @@ class PluginTest(unittest.TestCase):
self.assertTrue(plugin.p.IConfigurer.implemented_by(plugin.PrivateDatasets))
self.assertTrue(plugin.p.IRoutes.implemented_by(plugin.PrivateDatasets))
self.assertTrue(plugin.p.IActions.implemented_by(plugin.PrivateDatasets))
self.assertTrue(plugin.p.IPackageController.implemented_by(plugin.PrivateDatasets))
def test_decordators(self):
self.assertEquals(True, getattr(plugin.package_show, 'auth_allow_anonymous_access', False))
@ -348,3 +349,83 @@ class PluginTest(unittest.TestCase):
def test_package_types(self):
self.assertEquals([], self.privateDatasets.package_types())
@parameterized.expand([
('after_create',),
('after_update',),
('after_show',),
('after_delete',),
('after_create', 'False'),
('after_update', 'False'),
('after_show', 'False'),
('after_delete', 'False')
])
def test_packagecontroller_after(self, function, private='True'):
pkg_dict = {'test': 'a', 'private': private, 'allowed_users': 'a,b,c'}
expected_pkg_dict = pkg_dict.copy()
result = getattr(self.privateDatasets, function)({}, pkg_dict) # Call the function
self.assertEquals(expected_pkg_dict, result) # Check the result
def test_packagecontroller_after_search(self):
search_res = {'test': 'a', 'private': 'a', 'allowed_users': 'a,b,c'}
expected_search_res = search_res.copy()
result = getattr(self.privateDatasets, 'after_search')(search_res, {}) # Call the function
self.assertEquals(expected_search_res, result) # Check the result
@parameterized.expand([
('before_index',),
('before_view',),
('create',),
('edit',),
('read',),
('delete',),
('before_index', 'False'),
('before_view', 'False'),
('create', 'False'),
('edit', 'False'),
('read', 'False'),
('delete', 'False')
])
def test_before_and_CRUD(self, function, private='True'):
pkg_dict = {'test': 'a', 'private': private, 'allowed_users': 'a,b,c'}
expected_pkg_dict = pkg_dict.copy()
result = getattr(self.privateDatasets, function)(pkg_dict) # Call the function
self.assertEquals(expected_pkg_dict, result) # Check the result
@parameterized.expand([
(None, None, True),
(None, '', True),
('', None, True),
('', '', True),
('ow', 'ne', True),
('owner_org:"conwet"', None, False),
('owner_org:"conwet"', 'ne', False),
('ow', 'owner_org:"conwet"', False),
(None, 'owner_org:"conwet"', False),
('+owner_org:"conwet" +cap:public', None, False),
('+owner_org:"conwet" +cap_public', 'ne', False),
('ow', '+owner_org:"conwet" +cap:public', False),
(None, '+owner_org:"conwet" +cap:public', False),
('+owner_org:"conwet" +cap:public', '+owner_org:"conwet" +cap:public', False)
])
def test_before_serach(self, q=None, fq=None, expected_searchable=True):
search_params = {}
if q is not None:
search_params['q'] = q
if fq is not None:
search_params['fq'] = fq
expected_search_params = search_params.copy()
# Call the function
result = self.privateDatasets.before_search(search_params)
# Check the result
if expected_searchable:
if 'fq' not in expected_search_params:
expected_search_params['fq'] = ''
expected_search_params['fq'] += ' -(-searchable:True AND searchable:[* TO *])'
self.assertEquals(expected_search_params, result)