def draft_reg_util(): DraftRegistration.remove() ensure_schemas() return MetaSchema.find_one( Q('name', 'eq', 'Prereg Challenge') & Q('schema_version', 'eq', 2) )
def get_queryset(self): query = (Q('registration_schema', 'eq', get_prereg_schema()) & Q('approval', 'ne', None)) ordering = self.get_ordering() if 'initiator' in ordering: return DraftRegistration.find(query).sort(ordering) if ordering == SORT_BY['title']: return DraftRegistration.find(query).sort( 'registration_metadata.q1.value') if ordering == SORT_BY['n_title']: return DraftRegistration.find(query).sort( '-registration_metadata.q1.value') return sort_drafts(DraftRegistration.find(query), ordering)
def get_queryset(self): query = ( Q('registration_schema', 'eq', get_prereg_schema()) & Q('approval', 'ne', None) ) ordering = self.get_ordering() if 'initiator' in ordering: return DraftRegistration.find(query).sort(ordering) if ordering == SORT_BY['title']: return DraftRegistration.find(query).sort( 'registration_metadata.q1.value') if ordering == SORT_BY['n_title']: return DraftRegistration.find(query).sort( '-registration_metadata.q1.value') return sort_drafts(DraftRegistration.find(query), ordering)
def get_object(self, queryset=None): try: return serializers.serialize_draft_registration( DraftRegistration.load(self.kwargs.get('draft_pk'))) except AttributeError: raise Http404('{} with id "{}" not found.'.format( self.context_object_name.title(), self.kwargs.get('draft_pk')))
def check_access(node, auth, action, cas_resp): """Verify that user can perform requested action on resource. Raise appropriate error code if action cannot proceed. """ permission = permission_map.get(action, None) if permission is None: raise HTTPError(httplib.BAD_REQUEST) if cas_resp: if permission == 'read': if node.is_public: return True required_scope = oauth_scopes.CoreScopes.NODE_FILE_READ else: required_scope = oauth_scopes.CoreScopes.NODE_FILE_WRITE if not cas_resp.authenticated \ or required_scope not in oauth_scopes.normalize_scopes(cas_resp.attributes['accessTokenScope']): raise HTTPError(httplib.FORBIDDEN) if permission == 'read' and node.can_view(auth): return True if permission == 'write' and node.can_edit(auth): return True # Users attempting to register projects with components might not have # `write` permissions for all components. This will result in a 403 for # all `copyto` actions as well as `copyfrom` actions if the component # in question is not public. To get around this, we have to recursively # check the node's parent node to determine if they have `write` # permissions up the stack. # TODO(hrybacki): is there a way to tell if this is for a registration? # All nodes being registered that receive the `copyto` action will have # `node.is_registration` == True. However, we have no way of telling if # `copyfrom` actions are originating from a node being registered. # TODO This is raise UNAUTHORIZED for registrations that have not been archived yet if action == 'copyfrom' or (action == 'copyto' and node.is_registration): parent = node.parent_node while parent: if parent.can_edit(auth): return True parent = parent.parent_node # Users with the PREREG_ADMIN_TAG should be allowed to download files # from prereg challenge draft registrations. try: prereg_schema = MetaSchema.find_one( Q('name', 'eq', 'Prereg Challenge') & Q('schema_version', 'eq', 2)) allowed_nodes = [node] + node.parents prereg_draft_registration = DraftRegistration.find( Q('branched_from', 'in', [n._id for n in allowed_nodes]) & Q('registration_schema', 'eq', prereg_schema)) if action == 'download' and \ auth.user is not None and \ prereg_draft_registration.count() > 0 and \ settings.PREREG_ADMIN_TAG in auth.user.system_tags: return True except NoResultsFound: pass raise HTTPError(httplib.FORBIDDEN if auth.user else httplib.UNAUTHORIZED)
def post(self, request, *args, **kwargs): try: data = json.loads(request.body).get('schema_data', {}) draft = DraftRegistration.load(self.kwargs.get('draft_pk')) draft.update_metadata(data) draft.save() log_message = list() for key, value in data.iteritems(): comments = data.get(key, {}).get('comments', []) for comment in comments: log_message.append('{}: {}'.format(key, comment['value'])) update_admin_log( user_id=request.user.id, object_id=draft._id, object_repr='Draft Registration', message='Comments: <p>{}</p>'.format('</p><p>'.join(log_message)), action_flag=COMMENT_PREREG ) return JsonResponse(serializers.serialize_draft_registration(draft)) except AttributeError: raise Http404('{} with id "{}" not found.'.format( self.context_object_name.title(), self.kwargs.get('draft_pk') )) except NodeStateError as e: return bad_request(request, e)
def delete_draft_registration(auth, node, draft, *args, **kwargs): """Permanently delete a draft registration :return: None :rtype: NoneType """ if draft.registered_node: raise HTTPError( http.FORBIDDEN, data={ 'message_short': 'Can\'t delete draft', 'message_long': 'This draft has already been registered and cannot be deleted.' } ) DraftRegistration.remove_one(draft) return None, http.NO_CONTENT
def __init__(self, registration, missing_files, *args, **kwargs): super(ArchivedFileNotFound, self).__init__(*args, **kwargs) self.draft_registration = DraftRegistration.find_one( Q('registered_node', 'eq', registration) ) self.missing_files = missing_files
def dispatch(self, request, *args, **kwargs): self.draft = DraftRegistration.load(self.kwargs.get('draft_pk')) if self.draft is None: raise Http404('{} with id "{}" not found.'.format( self.context_object_name.title(), self.kwargs.get('draft_pk') )) return super(DraftFormView, self).dispatch(request, *args, **kwargs)
def get_draft_obj(draft_pk): auth = Auth(adminUser) draft = DraftRegistration.find( Q('_id', 'eq', draft_pk) ) return draft[0], auth
def get_draft(draft_pk): auth = Auth(adminUser) draft = DraftRegistration.find( Q('_id', 'eq', draft_pk) ) return utils.serialize_draft_registration(draft[0], auth), http.OK
def _on_reject(self, user, *args, **kwargs): from website.project.model import DraftRegistration # clear out previous registration options self.meta = {} self.save() draft = DraftRegistration.find_one(Q('approval', 'eq', self)) self._send_rejection_email(draft.initiator, draft)
def _on_reject(self, user, *args, **kwargs): from website.project.model import DraftRegistration # clear out previous registration options self.meta = {} self.save() draft = DraftRegistration.find_one(Q("approval", "eq", self)) self._send_rejection_email(draft.initiator, draft)
def get_object(self, queryset=None): try: return serializers.serialize_draft_registration( DraftRegistration.load(self.kwargs.get('draft_pk')) ) except AttributeError: raise Http404('{} with id "{}" not found.'.format( self.context_object_name.title(), self.kwargs.get('draft_pk') ))
def get_queryset(self): prereg_schema = MetaSchema.find_one( Q('name', 'eq', 'Prereg Challenge') & Q('schema_version', 'eq', 2) ) query = ( Q('registration_schema', 'eq', prereg_schema) & Q('approval', 'ne', None) ) return DraftRegistration.find(query).sort(self.ordering)
def get_all_drafts(): # TODO[lauren]: add query parameters to only retrieve submitted drafts, they will have an approval associated with them all_drafts = DraftRegistration.find() auth = Auth(adminUser) serialized_drafts = { 'drafts': [utils.serialize_draft_registration(d, auth) for d in all_drafts] } return serialized_drafts
def get_all_drafts(): # TODO # add query parameters to only retrieve submitted drafts all_drafts = DraftRegistration.find() auth = Auth(adminUser) serialized_drafts = { 'drafts': [utils.serialize_draft_registration(d, auth) for d in all_drafts] } return serialized_drafts
def get_prereg_drafts(user=None, filters=tuple()): prereg_schema = MetaSchema.find_one( Q('name', 'eq', 'Prereg Challenge') & Q('schema_version', 'eq', 2)) query = (Q('registration_schema', 'eq', prereg_schema) & Q('approval', 'ne', None)) if user: pass # TODO: filter by assignee; this requires multiple levels of Prereg admins- # one level that can see all drafts, and another than can see only the ones they're assigned. # As a followup to this, we need to make sure this applies to approval/rejection/commenting endpoints # query = query & Q('_metaschema_flags.assignee', 'eq', user._id) return sorted(DraftRegistration.find(query), key=operator.attrgetter('approval.initiation_date'))
def _notify_initiator(self): from website.project.model import DraftRegistration registration = self._get_registration() prereg_schema = prereg_utils.get_prereg_schema() draft = DraftRegistration.find_one( Q('registered_node', 'eq', registration)) if prereg_schema in registration.registered_schema: mails.send_mail(draft.initiator.username, mails.PREREG_CHALLENGE_ACCEPTED, user=draft.initiator, registration_url=registration.absolute_url, mimetype='html')
def _notify_initiator(self): from website.project.model import DraftRegistration registration = self._get_registration() prereg_schema = prereg_utils.get_prereg_schema() draft = DraftRegistration.find_one(Q("registered_node", "eq", registration)) if prereg_schema in registration.registered_schema: mails.send_mail( draft.initiator.username, mails.PREREG_CHALLENGE_ACCEPTED, user=draft.initiator, registration_url=registration.absolute_url, mimetype="html", )
def main(dry_run=True): if dry_run: logger.warn('DRY RUN mode') pending_approval_drafts = DraftRegistration.find() need_approval_drafts = [draft for draft in pending_approval_drafts if draft.approval and draft.requires_approval and draft.approval.state == Sanction.UNAPPROVED] for draft in need_approval_drafts: sanction = draft.approval try: if not dry_run: sanction.state = Sanction.APPROVED sanction._on_complete(None) sanction.save() logger.warn('Approved {0}'.format(draft._id)) except Exception as e: logger.error(e)
def _on_complete(self, user): from website.project.model import DraftRegistration draft = DraftRegistration.find_one(Q("approval", "eq", self)) auth = Auth(draft.initiator) registration = draft.register(auth=auth, save=True) registration_choice = self.meta["registration_choice"] if registration_choice == "immediate": sanction = functools.partial(registration.require_approval, draft.initiator) elif registration_choice == "embargo": sanction = functools.partial( registration.embargo_registration, draft.initiator, parse_date(self.meta.get("embargo_end_date"), ignoretz=True), ) else: raise ValueError("'registration_choice' must be either 'embargo' or 'immediate'") sanction(notify_initiator_on_complete=True)
def get_prereg_drafts(user=None, filters=tuple()): prereg_schema = MetaSchema.find_one( Q('name', 'eq', 'Prereg Challenge') & Q('schema_version', 'eq', 2) ) query = ( Q('registration_schema', 'eq', prereg_schema) & Q('approval', 'ne', None) ) if user: pass # TODO: filter by assignee; this requires multiple levels of Prereg admins- # one level that can see all drafts, and another than can see only the ones they're assigned. # As a followup to this, we need to make sure this applies to approval/rejection/commenting endpoints # query = query & Q('_metaschema_flags.assignee', 'eq', user._id) return sorted( DraftRegistration.find(query), key=operator.attrgetter('approval.initiation_date') )
def _on_complete(self, user): from website.project.model import DraftRegistration draft = DraftRegistration.find_one(Q('approval', 'eq', self)) auth = Auth(draft.initiator) registration = draft.register(auth=auth, save=True) registration_choice = self.meta['registration_choice'] if registration_choice == 'immediate': sanction = functools.partial(registration.require_approval, draft.initiator) elif registration_choice == 'embargo': sanction = functools.partial( registration.embargo_registration, draft.initiator, parse_date(self.meta.get('embargo_end_date'), ignoretz=True)) else: raise ValueError( "'registration_choice' must be either 'embargo' or 'immediate'" ) sanction(notify_initiator_on_complete=True)
def main(dry_run=True): if dry_run: logger.warn('DRY RUN mode') pending_approval_drafts = DraftRegistration.find() need_approval_drafts = [ draft for draft in pending_approval_drafts if draft.approval and draft.requires_approval and draft.approval.state == Sanction.UNAPPROVED ] for draft in need_approval_drafts: sanction = draft.approval try: if not dry_run: sanction.state = Sanction.APPROVED sanction._on_complete(None) sanction.save() logger.warn('Approved {0}'.format(draft._id)) except Exception as e: logger.error(e)
def _create(cls, *args, **kwargs): branched_from = kwargs.get("branched_from") initiator = kwargs.get("initiator") registration_schema = kwargs.get("registration_schema") registration_metadata = kwargs.get("registration_metadata") if not branched_from: project_params = {} if initiator: project_params["creator"] = initiator branched_from = ProjectFactory(**project_params) initiator = branched_from.creator try: registration_schema = registration_schema or MetaSchema.find()[0] except IndexError: ensure_schemas() registration_metadata = registration_metadata or {} draft = DraftRegistration.create_from_node( branched_from, user=initiator, schema=registration_schema, data=registration_metadata ) return draft
def main(dry_run=True): if dry_run: logger.warn('DRY RUN mode') pending_approval_drafts = DraftRegistration.find() need_approval_drafts = [draft for draft in pending_approval_drafts if draft.requires_approval and draft.approval and draft.approval.state == Sanction.UNAPPROVED] for draft in need_approval_drafts: add_comments(draft) sanction = draft.approval try: if not dry_run: sanction.forcibly_reject() #manually do the on_reject functionality to prevent send_mail problems sanction.meta = {} sanction.save() draft.approval = None draft.save() logger.warn('Rejected {0}'.format(draft._id)) except Exception as e: logger.error(e)
def _create(cls, *args, **kwargs): branched_from = kwargs.get('branched_from') initiator = kwargs.get('initiator') registration_schema = kwargs.get('registration_schema') registration_metadata = kwargs.get('registration_metadata') if not branched_from: project_params = {} if initiator: project_params['creator'] = initiator branched_from = ProjectFactory(**project_params) initiator = branched_from.creator try: registration_schema = registration_schema or MetaSchema.find()[0] except IndexError: ensure_schemas() registration_metadata = registration_metadata or {} draft = DraftRegistration.create_from_node( branched_from, user=initiator, schema=registration_schema, data=registration_metadata, ) return draft
def new_draft_registration(auth, node, *args, **kwargs): """Create a new draft registration for the node :return: Redirect to the new draft's edit page :rtype: flask.redirect :raises: HTTPError """ if node.is_registration: raise HTTPError(http.FORBIDDEN, data={ 'message_short': "Can't create draft", 'message_long': "Creating draft registrations on registered projects is not allowed." }) data = request.values schema_name = data.get('schema_name') if not schema_name: raise HTTPError( http.BAD_REQUEST, data={ 'message_short': 'Must specify a schema_name', 'message_long': 'Please specify a schema_name' } ) schema_version = data.get('schema_version', 2) meta_schema = get_schema_or_fail( Q('name', 'eq', schema_name) & Q('schema_version', 'eq', int(schema_version)) ) draft = DraftRegistration.create_from_node( node, user=auth.user, schema=meta_schema, data={} ) return redirect(node.web_url_for('edit_draft_registration_page', draft_id=draft._id))
def new_draft_registration(auth, node, *args, **kwargs): """Create a new draft registration for the node :return: Redirect to the new draft's edit page :rtype: flask.redirect :raises: HTTPError """ if node.is_registration: raise HTTPError( http.FORBIDDEN, data={ 'message_short': "Can't create draft", 'message_long': "Creating draft registrations on registered projects is not allowed." }) data = request.values schema_name = data.get('schema_name') if not schema_name: raise HTTPError(http.BAD_REQUEST, data={ 'message_short': 'Must specify a schema_name', 'message_long': 'Please specify a schema_name' }) schema_version = data.get('schema_version', 2) meta_schema = get_schema_or_fail( Q('name', 'eq', schema_name) & Q('schema_version', 'eq', int(schema_version))) draft = DraftRegistration.create_from_node(node, user=auth.user, schema=meta_schema, data={}) return redirect( node.web_url_for('edit_draft_registration_page', draft_id=draft._id))
def post(self, request, *args, **kwargs): try: data = json.loads(request.body).get('schema_data', {}) draft = DraftRegistration.load(self.kwargs.get('draft_pk')) draft.update_metadata(data) draft.save() log_message = list() for key, value in data.iteritems(): comments = data.get(key, {}).get('comments', []) for comment in comments: log_message.append('{}: {}'.format(key, comment['value'])) update_admin_log(user_id=request.user.id, object_id=draft._id, object_repr='Draft Registration', message='Comments: <p>{}</p>'.format( '</p><p>'.join(log_message)), action_flag=COMMENT_PREREG) return JsonResponse( serializers.serialize_draft_registration(draft)) except AttributeError: raise Http404('{} with id "{}" not found.'.format( self.context_object_name.title(), self.kwargs.get('draft_pk'))) except NodeStateError as e: return bad_request(request, e)
def get_draft_obj(draft_pk): auth = Auth(adminUser) draft = DraftRegistration.find(Q('_id', 'eq', draft_pk)) return draft[0], auth
def check_access(node, auth, action, cas_resp): """Verify that user can perform requested action on resource. Raise appropriate error code if action cannot proceed. """ permission = permission_map.get(action, None) if permission is None: raise HTTPError(httplib.BAD_REQUEST) if cas_resp: if permission == 'read': if node.is_public: return True required_scope = oauth_scopes.CoreScopes.NODE_FILE_READ else: required_scope = oauth_scopes.CoreScopes.NODE_FILE_WRITE if not cas_resp.authenticated \ or required_scope not in oauth_scopes.normalize_scopes(cas_resp.attributes['accessTokenScope']): raise HTTPError(httplib.FORBIDDEN) if permission == 'read' and node.can_view(auth): return True if permission == 'write' and node.can_edit(auth): return True # Users attempting to register projects with components might not have # `write` permissions for all components. This will result in a 403 for # all `copyto` actions as well as `copyfrom` actions if the component # in question is not public. To get around this, we have to recursively # check the node's parent node to determine if they have `write` # permissions up the stack. # TODO(hrybacki): is there a way to tell if this is for a registration? # All nodes being registered that receive the `copyto` action will have # `node.is_registration` == True. However, we have no way of telling if # `copyfrom` actions are originating from a node being registered. # TODO This is raise UNAUTHORIZED for registrations that have not been archived yet if action == 'copyfrom' or (action == 'copyto' and node.is_registration): parent = node.parent_node while parent: if parent.can_edit(auth): return True parent = parent.parent_node # Users with the PREREG_ADMIN_TAG should be allowed to download files # from prereg challenge draft registrations. try: prereg_schema = MetaSchema.find_one( Q('name', 'eq', 'Prereg Challenge') & Q('schema_version', 'eq', 2) ) allowed_nodes = [node] + node.parents prereg_draft_registration = DraftRegistration.find( Q('branched_from', 'in', [n._id for n in allowed_nodes]) & Q('registration_schema', 'eq', prereg_schema) ) if action == 'download' and \ auth.user is not None and \ prereg_draft_registration.count() > 0 and \ settings.PREREG_ADMIN_TAG in auth.user.system_tags: return True except NoResultsFound: pass raise HTTPError(httplib.FORBIDDEN if auth.user else httplib.UNAUTHORIZED)
def dispatch(self, request, *args, **kwargs): self.draft = DraftRegistration.load(self.kwargs.get('draft_pk')) if self.draft is None: raise Http404('{} with id "{}" not found.'.format( self.context_object_name.title(), self.kwargs.get('draft_pk'))) return super(DraftFormView, self).dispatch(request, *args, **kwargs)
def get_draft(draft_pk): auth = Auth(adminUser) draft = DraftRegistration.find(Q('_id', 'eq', draft_pk)) return utils.serialize_draft_registration(draft[0], auth), http.OK
def draft_reg_util(): DraftRegistration.remove() ensure_schemas() return MetaSchema.find_one( Q('name', 'eq', 'Prereg Challenge') & Q('schema_version', 'eq', 2))
def get_queryset(self): prereg_schema = MetaSchema.find_one( Q('name', 'eq', 'Prereg Challenge') & Q('schema_version', 'eq', 2)) query = (Q('registration_schema', 'eq', prereg_schema) & Q('approval', 'ne', None)) return DraftRegistration.find(query).sort(self.ordering)
def addon_view_or_download_file(auth, path, provider, **kwargs): extras = request.args.to_dict() extras.pop('_', None) # Clean up our url params a bit action = extras.get('action', 'view') node = kwargs.get('node') or kwargs['project'] node_addon = node.get_addon(provider) provider_safe = markupsafe.escape(provider) path_safe = markupsafe.escape(path) project_safe = markupsafe.escape(node.project_or_component) if not path: raise HTTPError(httplib.BAD_REQUEST) if not isinstance(node_addon, StorageAddonBase): raise HTTPError(httplib.BAD_REQUEST, data={ 'message_short': 'Bad Request', 'message_long': 'The {} add-on containing {} is no longer connected to {}.'.format(provider_safe, path_safe, project_safe) }) if not node_addon.has_auth: raise HTTPError(httplib.UNAUTHORIZED, data={ 'message_short': 'Unauthorized', 'message_long': 'The {} add-on containing {} is no longer authorized.'.format(provider_safe, path_safe) }) if not node_addon.complete: raise HTTPError(httplib.BAD_REQUEST, data={ 'message_short': 'Bad Request', 'message_long': 'The {} add-on containing {} is no longer configured.'.format(provider_safe, path_safe) }) file_node = FileNode.resolve_class(provider, FileNode.FILE).get_or_create(node, path) # Note: Cookie is provided for authentication to waterbutler # it is overriden to force authentication as the current user # the auth header is also pass to support basic auth version = file_node.touch( request.headers.get('Authorization'), **dict( extras, cookie=request.cookies.get(settings.COOKIE_NAME) ) ) if version is None: return addon_deleted_file(file_node=file_node, path=path, **kwargs) # TODO clean up these urls and unify what is used as a version identifier if request.method == 'HEAD': return make_response(('', 200, { 'Location': file_node.generate_waterbutler_url(**dict(extras, direct=None, version=version.identifier)) })) if action == 'download': return redirect(file_node.generate_waterbutler_url(**dict(extras, direct=None, version=version.identifier))) if action == 'get_guid': draft_id = extras.get('draft') draft = DraftRegistration.load(draft_id) if draft is None or draft.is_approved: raise HTTPError(httplib.BAD_REQUEST, data={ 'message_short': 'Bad Request', 'message_long': 'File not associated with required object.' }) guid = file_node.get_guid(create=True) guid.referent.save() return dict(guid=guid._id) if len(request.path.strip('/').split('/')) > 1: guid = file_node.get_guid(create=True) return redirect(furl.furl('/{}/'.format(guid._id)).set(args=extras).url) return addon_view_file(auth, node, file_node, version)
def addon_view_or_download_file(auth, path, provider, **kwargs): extras = request.args.to_dict() extras.pop('_', None) # Clean up our url params a bit action = extras.get('action', 'view') node = kwargs.get('node') or kwargs['project'] node_addon = node.get_addon(provider) provider_safe = markupsafe.escape(provider) path_safe = markupsafe.escape(path) project_safe = markupsafe.escape(node.project_or_component) if not path: raise HTTPError(httplib.BAD_REQUEST) if not isinstance(node_addon, StorageAddonBase): raise HTTPError( httplib.BAD_REQUEST, data={ 'message_short': 'Bad Request', 'message_long': 'The {} add-on containing {} is no longer connected to {}.'. format(provider_safe, path_safe, project_safe) }) if not node_addon.has_auth: raise HTTPError( httplib.UNAUTHORIZED, data={ 'message_short': 'Unauthorized', 'message_long': 'The {} add-on containing {} is no longer authorized.'.format( provider_safe, path_safe) }) if not node_addon.complete: raise HTTPError( httplib.BAD_REQUEST, data={ 'message_short': 'Bad Request', 'message_long': 'The {} add-on containing {} is no longer configured.'.format( provider_safe, path_safe) }) file_node = FileNode.resolve_class(provider, FileNode.FILE).get_or_create( node, path) # Note: Cookie is provided for authentication to waterbutler # it is overriden to force authentication as the current user # the auth header is also pass to support basic auth version = file_node.touch( request.headers.get('Authorization'), **dict(extras, cookie=request.cookies.get(settings.COOKIE_NAME))) if version is None: return addon_deleted_file(file_node=file_node, path=path, **kwargs) # TODO clean up these urls and unify what is used as a version identifier if request.method == 'HEAD': return make_response(('', 200, { 'Location': file_node.generate_waterbutler_url( **dict(extras, direct=None, version=version.identifier)) })) if action == 'download': return redirect( file_node.generate_waterbutler_url( **dict(extras, direct=None, version=version.identifier))) if action == 'get_guid': draft_id = extras.get('draft') draft = DraftRegistration.load(draft_id) if draft is None or draft.is_approved: raise HTTPError(httplib.BAD_REQUEST, data={ 'message_short': 'Bad Request', 'message_long': 'File not associated with required object.' }) guid = file_node.get_guid(create=True) guid.referent.save() return dict(guid=guid._id) if len(request.path.strip('/').split('/')) > 1: guid = file_node.get_guid(create=True) return redirect( furl.furl('/{}/'.format(guid._id)).set(args=extras).url) return addon_view_file(auth, node, file_node, version)
def addon_view_or_download_file(auth, path, provider, **kwargs): extras = request.args.to_dict() extras.pop('_', None) # Clean up our url params a bit action = extras.get('action', 'view') node = kwargs.get('node') or kwargs['project'] node_addon = node.get_addon(provider) provider_safe = markupsafe.escape(provider) path_safe = markupsafe.escape(path) project_safe = markupsafe.escape(node.project_or_component) if not path: raise HTTPError(httplib.BAD_REQUEST) if not isinstance(node_addon, BaseStorageAddon): raise HTTPError( httplib.BAD_REQUEST, data={ 'message_short': 'Bad Request', 'message_long': 'The {} add-on containing {} is no longer connected to {}.'. format(provider_safe, path_safe, project_safe) }) if not node_addon.has_auth: raise HTTPError( httplib.UNAUTHORIZED, data={ 'message_short': 'Unauthorized', 'message_long': 'The {} add-on containing {} is no longer authorized.'.format( provider_safe, path_safe) }) if not node_addon.complete: raise HTTPError( httplib.BAD_REQUEST, data={ 'message_short': 'Bad Request', 'message_long': 'The {} add-on containing {} is no longer configured.'.format( provider_safe, path_safe) }) savepoint_id = transaction.savepoint() file_node = FileNode.resolve_class(provider, FileNode.FILE).get_or_create( node, path) # Note: Cookie is provided for authentication to waterbutler # it is overriden to force authentication as the current user # the auth header is also pass to support basic auth version = file_node.touch( request.headers.get('Authorization'), **dict(extras, cookie=request.cookies.get(settings.COOKIE_NAME))) if version is None: # File is either deleted or unable to be found in the provider location # Rollback the insertion of the file_node transaction.savepoint_rollback(savepoint_id) if not file_node.pk: raise HTTPError(httplib.NOT_FOUND, data={ 'message_short': 'File Not Found', 'message_long': 'The requested file could not be found.' }) return addon_deleted_file(file_node=file_node, path=path, **kwargs) else: transaction.savepoint_commit(savepoint_id) # TODO clean up these urls and unify what is used as a version identifier if request.method == 'HEAD': return make_response(('', 200, { 'Location': file_node.generate_waterbutler_url( **dict(extras, direct=None, version=version.identifier, _internal=extras.get('mode') == 'render')) })) if action == 'download': format = extras.get('format') _, extension = os.path.splitext(file_node.name) # avoid rendering files with the same format type. if format and '.{}'.format(format) != extension: return redirect('{}/export?format={}&url={}'.format( MFR_SERVER_URL, format, urllib.quote( file_node.generate_waterbutler_url( **dict(extras, direct=None, version=version.identifier, _internal=extras.get('mode') == 'render'))))) return redirect( file_node.generate_waterbutler_url( **dict(extras, direct=None, version=version.identifier, _internal=extras.get('mode') == 'render'))) if action == 'get_guid': draft_id = extras.get('draft') draft = DraftRegistration.load(draft_id) if draft is None or draft.is_approved: raise HTTPError(httplib.BAD_REQUEST, data={ 'message_short': 'Bad Request', 'message_long': 'File not associated with required object.' }) guid = file_node.get_guid(create=True) guid.referent.save() return dict(guid=guid._id) if len(request.path.strip('/').split('/')) > 1: guid = file_node.get_guid(create=True) return redirect( furl.furl('/{}/'.format(guid._id)).set(args=extras).url) return addon_view_file(auth, node, file_node, version)