Beispiel #1
0
    def restore_version(self, id, doc):
        item_id = id
        old_version = int(doc.get('old_version', 0))
        last_version = int(doc.get('last_version', 0))
        if (not all([item_id, old_version, last_version])):
            return None

        old = get_resource_service('archive_versions').find_one(
            req=None, _id_document=item_id, _version=old_version)
        if old is None:
            raise SuperdeskError(payload='Invalid version %s' % old_version)

        curr = get_resource_service('archive').find_one(req=None, _id=item_id)
        if curr is None:
            raise SuperdeskError(payload='Invalid item id %s' % item_id)

        if curr[config.VERSION] != last_version:
            raise SuperdeskError(payload='Invalid last version %s' %
                                 last_version)
        old['_id'] = old['_id_document']
        old['_updated'] = old['versioncreated'] = utcnow()
        del old['_id_document']

        resolve_document_version(old, 'archive', 'PATCH', curr)
        res = super().replace(id=item_id, document=old)
        del doc['old_version']
        del doc['last_version']
        doc.update(old)
        return res
Beispiel #2
0
    def autosave(self, item_id, updates, user, etag):
        item_model = get_model(ItemModel)
        item = item_model.find_one({'_id': item_id})
        if item is None:
            raise SuperdeskError('Invalid item identifier', 404)
        if etag:
            item_model.validate_etag(item, etag)

        lock_user = item.get('lock_user', None)
        if lock_user and str(lock_user) != str(user['_id']):
            raise SuperdeskError(payload='The item was locked by another user')

        autosave_model = get_model(ItemAutosaveModel)
        item.update(updates)
        self.app.on_item_autosave(item)
        try:
            autosave_model.create(item)
        except:
            id = item['_id']
            del item['_id']
            autosave_model.update({'_id': item_id}, item)
            item['_id'] = id
        self.app.on_item_autosaved(item)
        updates.update(item)
        return updates
Beispiel #3
0
    def check_for_duplicates(self, package, associations):
        counter = Counter()
        package_id = package[config.ID_FIELD]
        for itemRef in [assoc[ITEM_REF] for assoc in associations]:
            if itemRef == package_id:
                raise SuperdeskError(message='Trying to self reference as an association.')
            counter[itemRef] += 1

        if any(itemRef for itemRef, value in counter.items() if value > 1):
            raise SuperdeskError(message='Content associated multiple times')
Beispiel #4
0
 def on_create(self, docs):
     if not docs:
         raise SuperdeskError('Content is missing', 400)
     req = parse_request(self.endpoint_name)
     c = get_component(ItemAutosave)
     try:
         c.autosave(docs[0]['_id'], docs[0], get_user(required=True),
                    req.if_match)
     except InvalidEtag:
         raise SuperdeskError('Client and server etags don\'t match', 412)
Beispiel #5
0
 def create(self, docs, **kwargs):
     if not docs:
         raise SuperdeskError('Content is missing', 400)
     req = parse_request(self.datasource)
     try:
         get_component(ItemAutosave).autosave(docs[0]['_id'], docs[0],
                                              get_user(required=True),
                                              req.if_match)
     except InvalidEtag:
         raise SuperdeskError('Client and server etags don\'t match', 412)
     return [docs[0]['_id']]
Beispiel #6
0
    def spike(self, filter, user):
        item_model = get_model(ItemModel)
        item = item_model.find_one(filter)
        if item and can_lock(item, user):
            expiry_minutes = app.settings['SPIKE_EXPIRY_MINUTES']
            # check if item is in a desk
            if "task" in item and "desk" in item["task"]:
                # then use the desks spike_expiry
                desk = get_resource_service('desks').find_one(
                    _id=item["task"]["desk"], req=None)
                expiry_minutes = desk.get('spike_expiry', expiry_minutes)

            updates = {
                IS_SPIKED: True,
                EXPIRY: get_expiry_date(expiry_minutes)
            }
            item_model.update(filter, updates)
            push_notification('item:spike',
                              item=str(item.get('_id')),
                              user=str(user))
        else:
            raise SuperdeskError(
                "Item couldn't be spiked. It is locked by another user")
        item = item_model.find_one(filter)
        return item
Beispiel #7
0
 def on_update(self, updates, original):
     user = get_user()
     lock_user = original.get('lock_user', None)
     if lock_user and str(lock_user) != str(user['_id']):
         raise SuperdeskError(payload='The item was locked by another user')
     updates['versioncreated'] = utcnow()
     updates['version_creator'] = str(user.get('_id'))
Beispiel #8
0
    def put(self, content, filename=None, content_type=None, metadata=None):
        """ Saves a new file using the storage system, preferably with the name
        specified. If there already exists a file with this name name, the
        storage system may modify the filename as necessary to get a unique
        name. Depending on the storage system, a unique id or the actual name
        of the stored file will be returned. The content type argument is used
        to appropriately identify the file when it is retrieved.
        """
        logger.debug('Going to save media file with %s ' % filename)
        found, existing_file = self._check_exists(filename, raise_error=False)
        if found:
            return filename

        try:
            file_metadata = self.transform_metadata_to_amazon_format(metadata)
            res = self.conn.upload(filename,
                                   content,
                                   self.container_name,
                                   content_type=content_type,
                                   headers=file_metadata)
            if res.status_code not in (200, 201):
                raise SuperdeskError(
                    payload='Uploading file to amazon S3 failed')
            return filename
        except Exception as ex:
            logger.exception(ex)
            raise
Beispiel #9
0
    def store_file(self, doc, content, filename, content_type):
        res = process_file_from_stream(content,
                                       filename=filename,
                                       content_type=content_type)
        file_name, content_type, metadata = res

        cropping_data = self.get_cropping_data(doc)
        _, out = crop_image(content, filename, cropping_data)
        metadata['length'] = json.dumps(len(out.getvalue()))

        try:
            logger.debug('Going to save media file with %s ' % file_name)
            out.seek(0)
            id = app.media.put(out,
                               filename=file_name,
                               content_type=content_type,
                               metadata=metadata)
            doc['media'] = id
            doc['mime_type'] = content_type
            doc['filemeta'] = decode_metadata(metadata)
            inserted = [doc['media']]
            file_type = content_type.split('/')[0]

            rendition_spec = config.RENDITIONS['avatar']
            renditions = generate_renditions(out, doc['media'], inserted,
                                             file_type, content_type,
                                             rendition_spec, url_for_media)
            doc['renditions'] = renditions
        except Exception as io:
            logger.exception(io)
            for file_id in inserted:
                delete_file_on_error(doc, file_id)
            raise SuperdeskError(message='Generating renditions failed')
Beispiel #10
0
    def check_package_associations(self, docs):
        for (doc, group) in [(doc, group['group']) for doc in docs for group in doc.get('groups', [])]:
            associations = group.get(ASSOCIATIONS, [])
            if len(associations) == 0:
                raise SuperdeskError(message='No content associated with the package.')

            self.check_for_duplicates(doc, associations)
            for assoc in associations:
                self.extract_default_association_data(group, assoc)
Beispiel #11
0
 def update_metadata(self, key, metadata):
     if not metadata:
         return
     metadata = self.transform_metadata_to_amazon_format(metadata)
     res = self.conn.update_metadata(key,
                                     metadata,
                                     bucket=self.container_name)
     if res.status_code not in (200, 201):
         payload = 'Updating metadata for file %s failed' % key
         raise SuperdeskError(payload=payload)
Beispiel #12
0
 def on_replace(self, document, original):
     user = get_user()
     lock_user = original.get('lock_user', None)
     force_unlock = document.get('force_unlock', False)
     user_id = str(user.get('_id'))
     if lock_user and str(lock_user) != user_id and not force_unlock:
         raise SuperdeskError(payload='The item was locked by another user')
     document['versioncreated'] = utcnow()
     document['version_creator'] = user_id
     if force_unlock:
         del document['force_unlock']
Beispiel #13
0
 def get_bucket_objects(self, marker=None, bucket=None):
     '''
     Fetch the objects available in the specified bucket.
     '''
     bucket = bucket or self.container_name
     params = {'marker': marker}
     rv = self.conn.get_bucket_objects(bucket=bucket, extra_params=params)
     if rv.status_code not in (200, 201):
         message = 'Retrieving the list of files from bucket %s failed' % bucket
         raise SuperdeskError(payload=message)
     content = rv.content.decode('UTF-8')
     return content
Beispiel #14
0
 def _check_exists(self, id_or_filename, raise_error=True):
     try:
         obj = self.conn.get(id_or_filename, self.container_name)
         if obj.status_code not in (200, 201) and raise_error:
             message = 'Retrieving file %s from amazon failed' % id_or_filename
             raise SuperdeskError(payload=message)
         return (True, obj)
     except Exception as ex:
         if raise_error:
             logger.exception(ex)
         # File not found
         return (False, None)
Beispiel #15
0
    def update_password(self, user_id, password):
        """
        Update the user password.
        Returns true if successful.
        """
        user = self.find_one(req=None, _id=user_id)

        if not user:
            raise SuperdeskError(payload='Invalid user.')

        if not self.user_is_active(user):
            raise SuperdeskError(status_code=403,
                                 message='Updating password is forbidden.')

        updates = {}
        updates['password'] = get_hash(
            password, app.config.get('BCRYPT_GENSALT_WORK_FACTOR', 12))
        updates[app.config['LAST_UPDATED']] = utcnow()
        if self.user_is_waiting_activation(user):
            updates['needs_activation'] = False

        self.patch(user_id, updates=updates)
Beispiel #16
0
 def on_created(self, docs):
     """Send email to user with reset password token."""
     super().on_created(docs)
     resetService = get_resource_service('reset_user_password')
     activate_ttl = app.config['ACTIVATE_ACCOUNT_TOKEN_TIME_TO_LIVE']
     for doc in docs:
         if self.user_is_waiting_activation(doc):
             tokenDoc = {'user': doc['_id'], 'email': doc['email']}
             id = resetService.store_reset_password_token(
                 tokenDoc, doc['email'], activate_ttl, doc['_id'])
             if not id:
                 raise SuperdeskError(
                     'Failed to send account activation email.')
             tokenDoc.update({'username': doc['username']})
             send_activate_account_email(tokenDoc)
 def lock(self, filter, user, etag):
     item_model = get_model(ItemModel)
     item = item_model.find_one(filter)
     if item and self._can_lock(item, user):
         self.app.on_item_lock(item, user)
         updates = {LOCK_USER: user, 'lock_time': utcnow()}
         item_model.update(filter, updates)
         item[LOCK_USER] = user
         self.app.on_item_locked(item, user)
         push_notification('item:lock',
                           item=str(item.get('_id')),
                           user=str(user))
     else:
         raise SuperdeskError('Item locked by another user')
     return item
Beispiel #18
0
    def on_create(self, docs):
        for doc in docs:
            if doc.get('URL') and doc.get('media'):
                message = 'Uploading file by URL and file stream in the same time is not supported.'
                raise SuperdeskError(payload=message)

            content = None
            filename = None
            content_type = None
            if doc.get('media'):
                content = doc['media']
                filename = content.filename
                content_type = content.mimetype
            elif doc.get('URL'):
                content, filename, content_type = self.download_file(doc)

            self.store_file(doc, content, filename, content_type)
Beispiel #19
0
    def on_update(self, updates, original):
        user = get_user()
        lock_user = original.get('lock_user', None)
        force_unlock = updates.get('force_unlock', False)

        original_creator = updates.get('original_creator', None)
        if not original_creator:
            updates['original_creator'] = original['original_creator']

        str_user_id = str(user.get('_id'))
        if lock_user and str(lock_user) != str_user_id and not force_unlock:
            raise SuperdeskError(payload='The item was locked by another user')

        updates['versioncreated'] = utcnow()
        updates['version_creator'] = str_user_id

        if force_unlock:
            del updates['force_unlock']
Beispiel #20
0
 def lock(self, filter, user, session, etag):
     item_model = get_model(ItemModel)
     item = item_model.find_one(filter)
     if item and can_lock(item, user):
         self.app.on_item_lock(item, user)
         updates = {
             LOCK_USER: user,
             LOCK_SESSION: session,
             'lock_time': utcnow()
         }
         item_model.update(filter, updates)
         superdesk.get_resource_service('tasks').assign_user(
             item['_id'], user)
         self.app.on_item_locked(item, user)
         push_notification('item:lock',
                           item=str(item.get('_id')),
                           user=str(user))
     else:
         raise SuperdeskError('Item locked by another user')
     item = item_model.find_one(filter)
     return item
Beispiel #21
0
def get_upload_as_data_uri(media_id):
    media_file = app.media.get(media_id)
    if media_file:
        return Response(media_file.read(), mimetype=media_file.content_type)
    raise SuperdeskError(status_code=404,
                         payload='File not found on media storage.')
Beispiel #22
0
 def get_associated_item(self, assoc):
     endpoint, item_id = assoc[ITEM_REF].split('/')[-2:]
     item = get_resource_service(endpoint).find_one(req=None, _id=item_id)
     if not item:
         raise SuperdeskError(message='Invalid item reference: ' + assoc['itemRef'])
     return item, item_id, endpoint