Skip to content

Commit

Permalink
[#652] Fix auth test in action, use the normal user in the search tes…
Browse files Browse the repository at this point in the history
…ts instead of the sysadmin user
  • Loading branch information
domoritz committed Apr 17, 2013
1 parent aef190a commit db1d6a6
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 43 deletions.
26 changes: 13 additions & 13 deletions ckanext/datastore/db.py
Expand Up @@ -880,12 +880,12 @@ def search_data(context, data_dict):
sql_string = u'''SELECT {select}, count(*) over() AS "_full_count" {rank}
FROM "{resource}" {ts_query}
{where} {sort} LIMIT {limit} OFFSET {offset}'''.format(
select=select_columns,
rank=rank_column,
resource=data_dict['resource_id'],
ts_query=ts_query,
where=where_clause,
sort=sort, limit=limit, offset=offset)
select=select_columns,
rank=rank_column,
resource=data_dict['resource_id'],
ts_query=ts_query,
where=where_clause,
sort=sort, limit=limit, offset=offset)
results = context['connection'].execute(sql_string, [where_values])

_insert_links(data_dict, limit, offset)
Expand Down Expand Up @@ -1080,7 +1080,7 @@ def search(context, data_dict):
id = data_dict['resource_id']
result = context['connection'].execute(
u"(SELECT 1 FROM pg_tables where tablename = '{0}') union"
u"(SELECT 1 FROM pg_views where viewname = '{0}')".format(id)
u"(SELECT 1 FROM pg_views where viewname = '{0}')".format(id)
).fetchone()
if not result:
raise ValidationError({
Expand Down Expand Up @@ -1114,12 +1114,12 @@ def search_sql(context, data_dict):

except ProgrammingError, e:
raise ValidationError({
'query': [str(e)],
'info': {
'statement': [e.statement],
'params': [e.params],
'orig': [str(e.orig)]
}
'query': [str(e)],
'info': {
'statement': [e.statement],
'params': [e.params],
'orig': [str(e.orig)]
}
})
except DBAPIError, e:
if int(e.orig.pgcode) == _PG_ERR_CODE['query_canceled']:
Expand Down
19 changes: 13 additions & 6 deletions ckanext/datastore/logic/action.py
Expand Up @@ -8,6 +8,8 @@
log = logging.getLogger(__name__)
_get_or_bust = logic.get_or_bust

WHITELISTED_RESOURCES = ['_table_metadata']


def datastore_create(context, data_dict):
'''Adds a new table to the datastore.
Expand Down Expand Up @@ -224,19 +226,24 @@ def datastore_search(context, data_dict):
data_dict['resource_id'] = data_dict['id']
res_id = _get_or_bust(data_dict, 'resource_id')

data_dict['connection_url'] = pylons.config.get('ckan.datastore.read_url',
pylons.config['ckan.datastore.write_url'])
data_dict['connection_url'] = pylons.config.get('ckan.datastore.write_url')

resources_sql = sqlalchemy.text(u'SELECT 1 FROM "_table_metadata" WHERE name = :id')
resources_sql = sqlalchemy.text(u'''SELECT alias_of FROM "_table_metadata"
WHERE name = :id''')
results = db._get_engine(None, data_dict).execute(resources_sql, id=res_id)
res_exists = results.rowcount > 0

if not res_exists:
if not results.rowcount > 0:
raise p.toolkit.ObjectNotFound(p.toolkit._(
'Resource "{0}" was not found.'.format(res_id)
))

p.toolkit.check_access('datastore_search', context, data_dict)
if not data_dict['resource_id'] in WHITELISTED_RESOURCES:
# replace potential alias with real id to simplify access checks
resource_id = results.fetchone()[0]
if resource_id:
data_dict['resource_id'] = resource_id

p.toolkit.check_access('datastore_search', context, data_dict)

result = db.search(context, data_dict)
result.pop('id', None)
Expand Down
49 changes: 25 additions & 24 deletions ckanext/datastore/tests/test_search.py
Expand Up @@ -25,9 +25,10 @@ def setup_class(cls):
ctd.CreateTestData.create()
cls.sysadmin_user = model.User.get('testsysadmin')
cls.normal_user = model.User.get('annafan')
resource = model.Package.get('annakarenina').resources[0]
cls.dataset = model.Package.get('annakarenina')
cls.resource = cls.dataset.resources[0]
cls.data = {
'resource_id': resource.id,
'resource_id': cls.resource.id,
'aliases': 'books3',
'fields': [{'id': u'b\xfck', 'type': 'text'},
{'id': 'author', 'type': 'text'},
Expand Down Expand Up @@ -75,7 +76,7 @@ def teardown_class(cls):
def test_search_basic(self):
data = {'resource_id': self.data['resource_id']}
postparams = '%s=1' % json.dumps(data)
auth = {'Authorization': str(self.sysadmin_user.apikey)}
auth = {'Authorization': str(self.normal_user.apikey)}
res = self.app.post('/api/action/datastore_search', params=postparams,
extra_environ=auth)
res_dict = json.loads(res.body)
Expand All @@ -87,7 +88,7 @@ def test_search_basic(self):
# search with parameter id should yield the same results
data = {'id': self.data['resource_id']}
postparams = '%s=1' % json.dumps(data)
auth = {'Authorization': str(self.sysadmin_user.apikey)}
auth = {'Authorization': str(self.normal_user.apikey)}
res = self.app.post('/api/action/datastore_search', params=postparams,
extra_environ=auth)
res_dict = json.loads(res.body)
Expand All @@ -111,7 +112,7 @@ def test_search_invalid_field(self):
data = {'resource_id': self.data['resource_id'],
'fields': [{'id': 'bad'}]}
postparams = '%s=1' % json.dumps(data)
auth = {'Authorization': str(self.sysadmin_user.apikey)}
auth = {'Authorization': str(self.normal_user.apikey)}
res = self.app.post('/api/action/datastore_search', params=postparams,
extra_environ=auth, status=409)
res_dict = json.loads(res.body)
Expand All @@ -121,7 +122,7 @@ def test_search_fields(self):
data = {'resource_id': self.data['resource_id'],
'fields': [u'b\xfck']}
postparams = '%s=1' % json.dumps(data)
auth = {'Authorization': str(self.sysadmin_user.apikey)}
auth = {'Authorization': str(self.normal_user.apikey)}
res = self.app.post('/api/action/datastore_search', params=postparams,
extra_environ=auth)
res_dict = json.loads(res.body)
Expand All @@ -134,7 +135,7 @@ def test_search_fields(self):
data = {'resource_id': self.data['resource_id'],
'fields': u'b\xfck, author'}
postparams = '%s=1' % json.dumps(data)
auth = {'Authorization': str(self.sysadmin_user.apikey)}
auth = {'Authorization': str(self.normal_user.apikey)}
res = self.app.post('/api/action/datastore_search', params=postparams,
extra_environ=auth)
res_dict = json.loads(res.body)
Expand All @@ -148,7 +149,7 @@ def test_search_filters(self):
data = {'resource_id': self.data['resource_id'],
'filters': {u'b\xfck': 'annakarenina'}}
postparams = '%s=1' % json.dumps(data)
auth = {'Authorization': str(self.sysadmin_user.apikey)}
auth = {'Authorization': str(self.normal_user.apikey)}
res = self.app.post('/api/action/datastore_search', params=postparams,
extra_environ=auth)
res_dict = json.loads(res.body)
Expand All @@ -161,7 +162,7 @@ def test_search_array_filters(self):
data = {'resource_id': self.data['resource_id'],
'filters': {u'characters': [u'Princess Anna', u'Sergius']}}
postparams = '%s=1' % json.dumps(data)
auth = {'Authorization': str(self.sysadmin_user.apikey)}
auth = {'Authorization': str(self.normal_user.apikey)}
res = self.app.post('/api/action/datastore_search', params=postparams,
extra_environ=auth)
res_dict = json.loads(res.body)
Expand All @@ -174,7 +175,7 @@ def test_search_sort(self):
data = {'resource_id': self.data['resource_id'],
'sort': u'b\xfck asc, author desc'}
postparams = '%s=1' % json.dumps(data)
auth = {'Authorization': str(self.sysadmin_user.apikey)}
auth = {'Authorization': str(self.normal_user.apikey)}
res = self.app.post('/api/action/datastore_search', params=postparams,
extra_environ=auth)
res_dict = json.loads(res.body)
Expand All @@ -200,7 +201,7 @@ def test_search_limit(self):
data = {'resource_id': self.data['resource_id'],
'limit': 1}
postparams = '%s=1' % json.dumps(data)
auth = {'Authorization': str(self.sysadmin_user.apikey)}
auth = {'Authorization': str(self.normal_user.apikey)}
res = self.app.post('/api/action/datastore_search', params=postparams,
extra_environ=auth)
res_dict = json.loads(res.body)
Expand All @@ -213,7 +214,7 @@ def test_search_invalid_limit(self):
data = {'resource_id': self.data['resource_id'],
'limit': 'bad'}
postparams = '%s=1' % json.dumps(data)
auth = {'Authorization': str(self.sysadmin_user.apikey)}
auth = {'Authorization': str(self.normal_user.apikey)}
res = self.app.post('/api/action/datastore_search', params=postparams,
extra_environ=auth, status=409)
res_dict = json.loads(res.body)
Expand All @@ -222,7 +223,7 @@ def test_search_invalid_limit(self):
data = {'resource_id': self.data['resource_id'],
'limit': -1}
postparams = '%s=1' % json.dumps(data)
auth = {'Authorization': str(self.sysadmin_user.apikey)}
auth = {'Authorization': str(self.normal_user.apikey)}
res = self.app.post('/api/action/datastore_search', params=postparams,
extra_environ=auth, status=409)
res_dict = json.loads(res.body)
Expand All @@ -233,7 +234,7 @@ def test_search_offset(self):
'limit': 1,
'offset': 1}
postparams = '%s=1' % json.dumps(data)
auth = {'Authorization': str(self.sysadmin_user.apikey)}
auth = {'Authorization': str(self.normal_user.apikey)}
res = self.app.post('/api/action/datastore_search', params=postparams,
extra_environ=auth)
res_dict = json.loads(res.body)
Expand All @@ -246,7 +247,7 @@ def test_search_invalid_offset(self):
data = {'resource_id': self.data['resource_id'],
'offset': 'bad'}
postparams = '%s=1' % json.dumps(data)
auth = {'Authorization': str(self.sysadmin_user.apikey)}
auth = {'Authorization': str(self.normal_user.apikey)}
res = self.app.post('/api/action/datastore_search', params=postparams,
extra_environ=auth, status=409)
res_dict = json.loads(res.body)
Expand All @@ -255,7 +256,7 @@ def test_search_invalid_offset(self):
data = {'resource_id': self.data['resource_id'],
'offset': -1}
postparams = '%s=1' % json.dumps(data)
auth = {'Authorization': str(self.sysadmin_user.apikey)}
auth = {'Authorization': str(self.normal_user.apikey)}
res = self.app.post('/api/action/datastore_search', params=postparams,
extra_environ=auth, status=409)
res_dict = json.loads(res.body)
Expand All @@ -266,7 +267,7 @@ def test_search_full_text(self):
'q': 'annakarenina'}

postparams = '%s=1' % json.dumps(data)
auth = {'Authorization': str(self.sysadmin_user.apikey)}
auth = {'Authorization': str(self.normal_user.apikey)}
res = self.app.post('/api/action/datastore_search', params=postparams,
extra_environ=auth)
res_dict = json.loads(res.body)
Expand Down Expand Up @@ -325,7 +326,7 @@ def test_search_full_text(self):
def test_search_table_metadata(self):
data = {'resource_id': "_table_metadata"}
postparams = '%s=1' % json.dumps(data)
auth = {'Authorization': str(self.sysadmin_user.apikey)}
auth = {'Authorization': str(self.normal_user.apikey)}
res = self.app.post('/api/action/datastore_search', params=postparams,
extra_environ=auth)
res_dict = json.loads(res.body)
Expand Down Expand Up @@ -365,7 +366,7 @@ def setup_class(cls):
]
)
postparams = '%s=1' % json.dumps(cls.data)
auth = {'Authorization': str(cls.sysadmin_user.apikey)}
auth = {'Authorization': str(cls.normal_user.apikey)}
res = cls.app.post('/api/action/datastore_create', params=postparams,
extra_environ=auth)
res_dict = json.loads(res.body)
Expand All @@ -380,7 +381,7 @@ def test_search_full_text(self):
data = {'resource_id': self.data['resource_id'],
'q': 'DE'}
postparams = '%s=1' % json.dumps(data)
auth = {'Authorization': str(self.sysadmin_user.apikey)}
auth = {'Authorization': str(self.normal_user.apikey)}
res = self.app.post('/api/action/datastore_search', params=postparams,
extra_environ=auth)
res_dict = json.loads(res.body)
Expand All @@ -391,7 +392,7 @@ def test_advanced_search_full_text(self):
'plain': 'False',
'q': 'DE | UK'}
postparams = '%s=1' % json.dumps(data)
auth = {'Authorization': str(self.sysadmin_user.apikey)}
auth = {'Authorization': str(self.normal_user.apikey)}
res = self.app.post('/api/action/datastore_search', params=postparams,
extra_environ=auth)
res_dict = json.loads(res.body)
Expand Down Expand Up @@ -474,7 +475,7 @@ def test_invalid_statement(self):
query = 'SELECT ** FROM public.foobar'
data = {'sql': query}
postparams = json.dumps(data)
auth = {'Authorization': str(self.sysadmin_user.apikey)}
auth = {'Authorization': str(self.normal_user.apikey)}
res = self.app.post('/api/action/datastore_search_sql', params=postparams,
extra_environ=auth, status=409)
res_dict = json.loads(res.body)
Expand All @@ -484,7 +485,7 @@ def test_select_basic(self):
query = 'SELECT * FROM public."{0}"'.format(self.data['resource_id'])
data = {'sql': query}
postparams = json.dumps(data)
auth = {'Authorization': str(self.sysadmin_user.apikey)}
auth = {'Authorization': str(self.normal_user.apikey)}
res = self.app.post('/api/action/datastore_search_sql', params=postparams,
extra_environ=auth)
res_dict = json.loads(res.body)
Expand Down Expand Up @@ -512,7 +513,7 @@ def test_self_join(self):
'''.format(self.data['resource_id'])
data = {'sql': query}
postparams = json.dumps(data)
auth = {'Authorization': str(self.sysadmin_user.apikey)}
auth = {'Authorization': str(self.normal_user.apikey)}
res = self.app.post('/api/action/datastore_search_sql', params=postparams,
extra_environ=auth)
res_dict = json.loads(res.body)
Expand Down

0 comments on commit db1d6a6

Please sign in to comment.