def fail_if_unauthorized(node_addon, auth, file_id): node = node_addon.owner user_settings = node_addon.user_settings if file_id is None: raise HTTPError(http.NOT_FOUND) try: connection = connect_from_settings_or_403(user_settings) except HTTPError as error: if error.code == 403: connection = None else: raise dataverse = get_dataverse(connection, node_addon.dataverse_alias) study = get_study(dataverse, node_addon.study_hdl) released_file_ids = [f.id for f in get_files(study, released=True)] all_file_ids = [f.id for f in get_files(study)] + released_file_ids if file_id not in all_file_ids: raise HTTPError(http.FORBIDDEN) elif not node.can_edit(auth) and file_id not in released_file_ids: raise HTTPError(http.UNAUTHORIZED)
def dataverse_get_widget_contents(node_addon, **kwargs): data = { 'connected': False, } if not node_addon.is_fully_configured: return {'data': data}, http.OK doi = node_addon.study_hdl alias = node_addon.dataverse_alias connection = connect_from_settings_or_403(node_addon.user_settings) dataverse = get_dataverse(connection, alias) study = get_study(dataverse, doi) if study is None: return {'data': data}, http.BAD_REQUEST dataverse_url = 'http://{0}/dvn/dv/'.format(HOST) + alias study_url = 'http://dx.doi.org/' + doi data.update({ 'connected': True, 'dataverse': node_addon.dataverse, 'dataverseUrl': dataverse_url, 'study': node_addon.study, 'doi': doi, 'studyUrl': study_url, 'citation': study.citation, }) return {'data': data}, http.OK
def fail_if_unauthorized(node_addon, auth, file_id): node = node_addon.owner user_settings = node_addon.user_settings if file_id is None: raise HTTPError(httplib.NOT_FOUND) try: connection = connect_from_settings_or_403(user_settings) except HTTPError as error: if error.code == 403: connection = None else: raise dataverse = get_dataverse(connection, node_addon.dataverse_alias) study = get_study(dataverse, node_addon.study_hdl) released_file_ids = [f.id for f in get_files(study, released=True)] all_file_ids = [f.id for f in get_files(study)] + released_file_ids if file_id not in all_file_ids: raise HTTPError(httplib.FORBIDDEN) elif not node.can_edit(auth) and file_id not in released_file_ids: raise HTTPError(httplib.UNAUTHORIZED)
def test_get_study(self): self.mock_study.get_state.return_value = 'DRAFT' self.mock_dataverse.get_study_by_doi.return_value = self.mock_study s = get_study(self.mock_dataverse, 'My hdl') self.mock_dataverse.get_study_by_doi.assert_called_once_with('My hdl') assert_equal(s, self.mock_study)
def test_get_bad_study(self): error = UnicodeDecodeError('utf-8', b'', 1, 2, 'jeepers') self.mock_study.get_state.side_effect = error self.mock_dataverse.get_study_by_doi.return_value = self.mock_study with assert_raises(HTTPError) as e: s = get_study(self.mock_dataverse, 'My hdl') self.mock_dataverse.get_study_by_doi.assert_called_once_with('My hdl') assert_equal(e.exception.code, 406)
def test_get_deaccessioned_study(self): self.mock_study.get_state.return_value = 'DEACCESSIONED' self.mock_dataverse.get_study_by_doi.return_value = self.mock_study with assert_raises(HTTPError) as e: s = get_study(self.mock_dataverse, 'My hdl') self.mock_dataverse.get_study_by_doi.assert_called_once_with('My hdl') assert_equal(e.exception.code, 410)
def dataverse_hgrid_data_contents(node_addon, auth, **kwargs): node = node_addon.owner user_settings = node_addon.user_settings state = request.args.get('state') default_state = 'released' state = 'released' if not node.can_edit(auth) else state or default_state released = state == 'released' can_edit = node.can_edit(auth) and not node.is_registration and not released can_view = node.can_view(auth) connection = connect_from_settings(user_settings) if node_addon.study_hdl is None or connection is None: return [] dataverse = get_dataverse(connection, node_addon.dataverse_alias) study = get_study(dataverse, node_addon.study_hdl) # Quit if hdl does not produce a study if study is None: return [] info = [] for f in get_files(study, released): item = { 'addon': 'dataverse', 'provider': 'dataverse', rubeus.KIND: 'file', 'name': f.name, 'path': f.name, 'file_id': f.id, 'ext': os.path.splitext(f.name)[1], 'urls': { 'view': node.web_url_for('dataverse_view_file', path=f.id), 'download': node.web_url_for('dataverse_download_file', path=f.id), 'delete': node.api_url_for('dataverse_delete_file', path=f.id), }, 'permissions': { 'view': can_view, 'edit': can_edit, }, } info.append(item) return {'data': info}
def dataverse_hgrid_data_contents(node_addon, auth, **kwargs): node = node_addon.owner user_settings = node_addon.user_settings state = request.args.get('state') default_state = 'released' state = 'released' if not node.can_edit(auth) else state or default_state released = state == 'released' can_edit = node.can_edit( auth) and not node.is_registration and not released can_view = node.can_view(auth) connection = connect_from_settings(user_settings) if node_addon.study_hdl is None or connection is None: return [] dataverse = get_dataverse(connection, node_addon.dataverse_alias) study = get_study(dataverse, node_addon.study_hdl) # Quit if hdl does not produce a study if study is None: return [] info = [] for f in get_files(study, released): item = { 'addon': 'dataverse', 'provider': 'dataverse', rubeus.KIND: 'file', 'name': f.name, 'path': f.name, 'file_id': f.id, 'ext': os.path.splitext(f.name)[1], 'urls': { 'view': node.web_url_for('dataverse_view_file', path=f.id), 'download': node.web_url_for('dataverse_download_file', path=f.id), 'delete': node.api_url_for('dataverse_delete_file', path=f.id), }, 'permissions': { 'view': can_view, 'edit': can_edit, }, } info.append(item) return {'data': info}
def set_dataverse_and_study(node_addon, auth, **kwargs): user_settings = node_addon.user_settings user = auth.user if user_settings and user_settings.owner != user: raise HTTPError(http.FORBIDDEN) try: assert_clean(request.json) except AssertionError: # TODO: Test me! raise HTTPError(http.NOT_ACCEPTABLE) alias = request.json.get('dataverse').get('alias') hdl = request.json.get('study').get('hdl') if hdl is None: return HTTPError(http.BAD_REQUEST) connection = client.connect_from_settings(user_settings) dataverse = client.get_dataverse(connection, alias) study = client.get_study(dataverse, hdl) node_addon.dataverse_alias = dataverse.alias node_addon.dataverse = dataverse.title node_addon.study_hdl = study.doi node_addon.study = study.title node = node_addon.owner node.add_log( action='dataverse_study_linked', params={ 'project': node.parent_id, 'node': node._primary_key, 'study': study.title, }, auth=auth, ) node_addon.save() return {'dataverse': dataverse.title, 'study': study.title}, http.OK
def set_dataverse_and_study(node_addon, auth, **kwargs): user_settings = node_addon.user_settings user = get_current_user() if user_settings and user_settings.owner != user: raise HTTPError(http.FORBIDDEN) try: assert_clean(request.json) except AssertionError: # TODO: Test me! raise HTTPError(http.NOT_ACCEPTABLE) alias = request.json.get('dataverse').get('alias') hdl = request.json.get('study').get('hdl') if hdl is None: return HTTPError(http.BAD_REQUEST) connection = connect_from_settings(user_settings) dataverse = get_dataverse(connection, alias) study = get_study(dataverse, hdl) node_addon.dataverse_alias = dataverse.alias node_addon.dataverse = dataverse.title node_addon.study_hdl = study.doi node_addon.study = study.title node = node_addon.owner node.add_log( action='dataverse_study_linked', params={ 'project': node.parent_id, 'node': node._primary_key, 'study': study.title, }, auth=auth, ) node_addon.save() return {'dataverse': dataverse.title, 'study': study.title}, http.OK
def dataverse_delete_file(node_addon, auth, **kwargs): node = node_addon.owner user_settings = node_addon.user_settings now = datetime.datetime.utcnow() file_id = kwargs.get('path') if file_id is None: raise HTTPError(http.NOT_FOUND) try: connection = connect_from_settings_or_403(user_settings) except HTTPError as error: if error.code == 403: connection = None else: raise dataverse = get_dataverse(connection, node_addon.dataverse_alias) study = get_study(dataverse, node_addon.study_hdl) file = get_file_by_id(study, file_id) delete_file(file) # Check if file was deleted if get_file_by_id(study, file_id) is not None: raise HTTPError(http.BAD_REQUEST) node.add_log( action='dataverse_file_removed', params={ 'project': node.parent_id, 'node': node._primary_key, 'filename': file.name, 'study': study.title, }, auth=auth, log_date=now, ) return {}
def dataverse_delete_file(node_addon, auth, **kwargs): node = node_addon.owner user_settings = node_addon.user_settings now = datetime.datetime.utcnow() file_id = kwargs.get('path') if file_id is None: raise HTTPError(httplib.NOT_FOUND) try: connection = connect_from_settings_or_403(user_settings) except HTTPError as error: if error.code == httplib.FORBIDDEN: connection = None else: raise dataverse = get_dataverse(connection, node_addon.dataverse_alias) study = get_study(dataverse, node_addon.study_hdl) file = get_file_by_id(study, file_id) delete_file(file) # Check if file was deleted if get_file_by_id(study, file_id) is not None: raise HTTPError(httplib.BAD_REQUEST) node.add_log( action='dataverse_file_removed', params={ 'project': node.parent_id, 'node': node._primary_key, 'filename': file.name, 'study': study.title, }, auth=auth, log_date=now, ) return {}
def dataverse_release_study(node_addon, auth, **kwargs): node = node_addon.owner user_settings = node_addon.user_settings now = datetime.datetime.utcnow() try: connection = connect_from_settings_or_403(user_settings) except HTTPError as error: if error.code == 403: connection = None else: raise dataverse = get_dataverse(connection, node_addon.dataverse_alias) study = get_study(dataverse, node_addon.study_hdl) if study.get_state() == 'RELEASED': raise HTTPError(httplib.CONFLICT) release_study(study) # Add a log node.add_log( action='dataverse_study_released', params={ 'project': node.parent_id, 'node': node._primary_key, 'study': study.title, }, auth=auth, log_date=now, ) return {'study': study.title}, httplib.OK
def dataverse_release_study(node_addon, auth, **kwargs): node = node_addon.owner user_settings = node_addon.user_settings now = datetime.datetime.utcnow() try: connection = connect_from_settings_or_403(user_settings) except HTTPError as error: if error.code == 403: connection = None else: raise dataverse = get_dataverse(connection, node_addon.dataverse_alias) study = get_study(dataverse, node_addon.study_hdl) if study.get_state() == 'RELEASED': raise HTTPError(http.CONFLICT) release_study(study) # Add a log node.add_log( action='dataverse_study_released', params={ 'project': node.parent_id, 'node': node._primary_key, 'study': study.title, }, auth=auth, log_date=now, ) return {'study': study.title}, http.OK
def dataverse_hgrid_root(node_addon, auth, state=None, **kwargs): node = node_addon.owner user_settings = node_addon.user_settings default_state = 'released' state = 'released' if not node.can_edit(auth) else state or default_state connection = connect_from_settings(user_settings) # Quit if no study linked if node_addon.study_hdl is None or connection is None: return [] dataverse = get_dataverse(connection, node_addon.dataverse_alias) study = get_study(dataverse, node_addon.study_hdl) # Quit if hdl does not produce a study if study is None: return [] released_files = get_files(study, released=True) authorized = node.can_edit(auth) # Produce draft version or quit if no released version is available if not released_files: if authorized: state = 'draft' else: return [] study_name = node_addon.study if len(study_name) > 23: study_name = u'{0}...'.format(study_name[:20]) permissions = { 'edit': node.can_edit(auth) and not node.is_registration, 'view': node.can_view(auth) } urls = { 'upload': node.api_url_for('dataverse_upload_file'), 'fetch': node.api_url_for('dataverse_hgrid_data_contents', state=state), 'state': node.api_url_for('dataverse_root_folder_public'), 'release': node.api_url_for('dataverse_release_study'), } buttons = [rubeus.build_addon_button( '<i class="fa fa-globe"></i> Release Study', 'releaseStudy')] if state == 'draft' else None return [rubeus.build_addon_root( node_addon, study_name, urls=urls, permissions=permissions, buttons=buttons, study=study_name, doi=study.doi, dataverse=dataverse.title, citation=study.citation, hasReleasedFiles=bool(released_files), state=state, )]
def dataverse_upload_file(node_addon, auth, **kwargs): node = node_addon.owner user_settings = node_addon.user_settings try: name = request.args['name'] except KeyError: raise HTTPError(httplib.BAD_REQUEST) now = datetime.datetime.utcnow() can_edit = node.can_edit(auth) and not node.is_registration can_view = node.can_view(auth) try: connection = connect_from_settings_or_403(user_settings) except HTTPError as error: if error.code == httplib.FORBIDDEN: connection = None else: raise dataverse = get_dataverse(connection, node_addon.dataverse_alias) study = get_study(dataverse, node_addon.study_hdl) filename = secure_filename(name) status_code = httplib.CREATED old_id = None # Fail if file is too small (Dataverse issue) content = request.data if len(content) < 5: raise HTTPError(httplib.UNSUPPORTED_MEDIA_TYPE) # Replace file if old version exists old_file = get_file(study, filename) if old_file is not None: status_code = httplib.OK old_id = old_file.id delete_file(old_file) # Check if file was deleted if get_file_by_id(study, old_id) is not None: raise HTTPError(httplib.BAD_REQUEST) upload_file(study, filename, content) file = get_file(study, filename) if file is None: raise HTTPError(httplib.BAD_REQUEST) node.add_log( action='dataverse_file_added', params={ 'project': node.parent_id, 'node': node._primary_key, 'filename': filename, 'path': node.web_url_for('dataverse_view_file', path=file.id), 'study': study.title, }, auth=auth, log_date=now, ) info = { 'addon': 'dataverse', 'file_id': file.id, 'old_id': old_id, 'name': filename, 'path': filename, 'size': [ len(content), rubeus.format_filesize(len(content)) ], rubeus.KIND: rubeus.FILE, 'urls': { 'view': node.web_url_for('dataverse_view_file', path=file.id), 'download': node.web_url_for('dataverse_download_file', path=file.id), 'delete': node.api_url_for('dataverse_delete_file', path=file.id), }, 'permissions': { 'view': can_view, 'edit': can_edit, }, } return info, status_code
def dataverse_upload_file(node_addon, auth, **kwargs): node = node_addon.owner user_settings = node_addon.user_settings try: name = request.args['name'] except KeyError: raise HTTPError(http.BAD_REQUEST) now = datetime.datetime.utcnow() can_edit = node.can_edit(auth) and not node.is_registration can_view = node.can_view(auth) try: connection = connect_from_settings_or_403(user_settings) except HTTPError as error: if error.code == 403: connection = None else: raise dataverse = get_dataverse(connection, node_addon.dataverse_alias) study = get_study(dataverse, node_addon.study_hdl) filename = secure_filename(name) action = 'file_uploaded' old_id = None # Fail if file is too small (Dataverse issue) content = request.data if len(content) < 5: raise HTTPError(http.UNSUPPORTED_MEDIA_TYPE) # Replace file if old version exists old_file = get_file(study, filename) if old_file is not None: action = 'file_updated' old_id = old_file.id delete_file(old_file) # Check if file was deleted if get_file_by_id(study, old_id) is not None: raise HTTPError(http.BAD_REQUEST) upload_file(study, filename, content) file = get_file(study, filename) if file is None: raise HTTPError(http.BAD_REQUEST) node.add_log( action='dataverse_file_added', params={ 'project': node.parent_id, 'node': node._primary_key, 'filename': filename, 'path': node.web_url_for('dataverse_view_file', path=file.id), 'study': study.title, }, auth=auth, log_date=now, ) info = { 'addon': 'dataverse', 'file_id': file.id, 'old_id': old_id, 'name': filename, 'path': filename, 'size': [len(content), rubeus.format_filesize(len(content))], rubeus.KIND: rubeus.FILE, 'urls': { 'view': node.web_url_for('dataverse_view_file', path=file.id), 'download': node.web_url_for('dataverse_download_file', path=file.id), 'delete': node.api_url_for('dataverse_delete_file', path=file.id), }, 'permissions': { 'view': can_view, 'edit': can_edit, }, 'actionTaken': action, } return info, 201
def dataverse_hgrid_root(node_addon, auth, state=None, **kwargs): node = node_addon.owner user_settings = node_addon.user_settings default_state = 'released' state = 'released' if not node.can_edit(auth) else state or default_state connection = connect_from_settings(user_settings) # Quit if no study linked if node_addon.study_hdl is None or connection is None: return [] dataverse = get_dataverse(connection, node_addon.dataverse_alias) study = get_study(dataverse, node_addon.study_hdl) # Quit if hdl does not produce a study if study is None: return [] released_files = get_files(study, released=True) authorized = node.can_edit(auth) # Produce draft version or quit if no released version is available if not released_files: if authorized: state = 'draft' else: return [] study_name = node_addon.study if len(study_name) > 23: study_name = u'{0}...'.format(study_name[:20]) permissions = { 'edit': node.can_edit(auth) and not node.is_registration, 'view': node.can_view(auth) } urls = { 'upload': node.api_url_for('dataverse_upload_file'), 'fetch': node.api_url_for('dataverse_hgrid_data_contents', state=state), 'state': node.api_url_for('dataverse_root_folder_public'), 'release': node.api_url_for('dataverse_release_study'), } buttons = [ rubeus.build_addon_button('<i class="fa fa-globe"></i> Release Study', 'releaseStudy') ] if state == 'draft' else None return [ rubeus.build_addon_root( node_addon, study_name, urls=urls, permissions=permissions, buttons=buttons, study=study_name, doi=study.doi, dataverse=dataverse.title, citation=study.citation, hasReleasedFiles=bool(released_files), state=state, ) ]