Example #1
0
    def clone(self, new_event, options):
        if 'attachments' not in options:
            return
        folder_mapping = {}
        attrs = get_simple_column_attrs(AttachmentFolder)
        for old_folder in self.find_folders():
            new_folder = AttachmentFolder(event_id=new_event.id, **{attr: getattr(old_folder, attr) for attr in attrs})
            if new_folder.linked_object is None:
                continue
            new_folder.acl = old_folder.acl
            db.session.add(new_folder)
            folder_mapping[old_folder] = new_folder

        attrs = get_simple_column_attrs(Attachment) - {'modified_dt'}
        for old_attachment in self.find_attachments():
            folder = folder_mapping.get(old_attachment.folder)
            if not folder:
                continue
            new_attachment = Attachment(folder=folder, user_id=old_attachment.user_id, acl=old_attachment.acl,
                                        **{attr: getattr(old_attachment, attr) for attr in attrs})
            if new_attachment.type == AttachmentType.file:
                old_file = old_attachment.file
                new_attachment.file = AttachmentFile(
                    attachment=new_attachment,
                    user_id=old_file.user_id,
                    filename=old_file.filename,
                    content_type=old_file.content_type
                )
                with old_file.open() as fd:
                    new_attachment.file.save(fd)
            db.session.add(new_attachment)

        db.session.flush()
Example #2
0
def _merge_users(target, source, **kwargs):
    from indico.modules.attachments.models.attachments import Attachment, AttachmentFile
    from indico.modules.attachments.models.principals import AttachmentPrincipal, AttachmentFolderPrincipal
    Attachment.find(user_id=source.id).update({Attachment.user_id: target.id})
    AttachmentFile.find(user_id=source.id).update({AttachmentFile.user_id: target.id})
    AttachmentPrincipal.merge_users(target, source, 'attachment')
    AttachmentFolderPrincipal.merge_users(target, source, 'folder')
 def _process(self):
     from indico_conversion.plugin import ConversionPlugin
     try:
         payload = secure_serializer.loads(request.form['directory'], salt='pdf-conversion')
     except BadData:
         ConversionPlugin.logger.exception('Received invalid payload (%s)', request.form['directory'])
         return jsonify(success=False)
     attachment = Attachment.get(payload['attachment_id'])
     if not attachment or attachment.is_deleted or attachment.folder.is_deleted:
         ConversionPlugin.logger.info('Attachment has been deleted: %s', attachment)
         return jsonify(success=True)
     elif request.form['status'] != '1':
         ConversionPlugin.logger.error('Received invalid status %s for %s', request.form['status'], attachment)
         return jsonify(success=False)
     name, ext = os.path.splitext(attachment.file.filename)
     title = get_pdf_title(attachment)
     pdf_attachment = Attachment(folder=attachment.folder, user=attachment.user, title=title,
                                 description=attachment.description, type=AttachmentType.file,
                                 protection_mode=attachment.protection_mode, acl=attachment.acl)
     data = request.files['content'].stream.read()
     pdf_attachment.file = AttachmentFile(user=attachment.file.user, filename=f'{name}.pdf',
                                          content_type='application/pdf')
     pdf_attachment.file.save(data)
     db.session.add(pdf_attachment)
     db.session.flush()
     pdf_state_cache.set(str(attachment.id), 'finished', timeout=timedelta(minutes=15))
     ConversionPlugin.logger.info('Added PDF attachment %s for %s', pdf_attachment, attachment)
     signals.attachments.attachment_created.send(pdf_attachment, user=None)
     return jsonify(success=True)
Example #4
0
    def clone(self, new_event, options):
        if 'attachments' not in options:
            return
        folder_mapping = {}
        attrs = get_simple_column_attrs(AttachmentFolder)
        for old_folder in self.find_folders():
            new_folder = AttachmentFolder(event_id=new_event.id, **{attr: getattr(old_folder, attr) for attr in attrs})
            if new_folder.linked_object is None:
                continue
            new_folder.acl = old_folder.acl
            db.session.add(new_folder)
            folder_mapping[old_folder] = new_folder

        attrs = get_simple_column_attrs(Attachment) - {'modified_dt'}
        for old_attachment in self.find_attachments():
            folder = folder_mapping.get(old_attachment.folder)
            if not folder:
                continue
            new_attachment = Attachment(folder=folder, user_id=old_attachment.user_id, acl=old_attachment.acl,
                                        **{attr: getattr(old_attachment, attr) for attr in attrs})
            if new_attachment.type == AttachmentType.file:
                old_file = old_attachment.file
                new_attachment.file = AttachmentFile(
                    attachment=new_attachment,
                    user_id=old_file.user_id,
                    filename=old_file.filename,
                    content_type=old_file.content_type
                )
                with old_file.open() as fd:
                    new_attachment.file.save(fd)
            db.session.add(new_attachment)

        db.session.flush()
Example #5
0
def _merge_users(target, source, **kwargs):
    from indico.modules.attachments.models.attachments import Attachment, AttachmentFile
    from indico.modules.attachments.models.principals import AttachmentPrincipal, AttachmentFolderPrincipal
    Attachment.find(user_id=source.id).update({Attachment.user_id: target.id})
    AttachmentFile.find(user_id=source.id).update({AttachmentFile.user_id: target.id})
    AttachmentPrincipal.merge_users(target, source, 'attachment')
    AttachmentFolderPrincipal.merge_users(target, source, 'folder')
 def _process(self):
     from indico_conversion.plugin import ConversionPlugin
     try:
         payload = secure_serializer.loads(request.form['directory'], salt='pdf-conversion')
     except BadData:
         ConversionPlugin.logger.exception('Received invalid payload (%s)', request.form['directory'])
         return jsonify(success=False)
     attachment = Attachment.get(payload['attachment_id'])
     if not attachment or attachment.is_deleted or attachment.folder.is_deleted:
         ConversionPlugin.logger.info('Attachment has been deleted: %s', attachment)
         return jsonify(success=True)
     elif request.form['status'] != '1':
         ConversionPlugin.logger.error('Received invalid status %s for %s', request.form['status'], attachment)
         return jsonify(success=False)
     name, ext = os.path.splitext(attachment.file.filename)
     title = get_pdf_title(attachment)
     pdf_attachment = Attachment(folder=attachment.folder, user=attachment.user, title=title,
                                 description=attachment.description, type=AttachmentType.file,
                                 protection_mode=attachment.protection_mode, acl=attachment.acl)
     # TODO: remove first case when Conversion Server is fully on new version
     if 'content' in request.form:
         # handling of legacy API
         data = BytesIO(base64.decodestring(request.form['content']))
     else:
         filepdf = request.files['content']
         data = filepdf.stream.read()
     pdf_attachment.file = AttachmentFile(user=attachment.file.user, filename='{}.pdf'.format(name),
                                          content_type='application/pdf')
     pdf_attachment.file.save(data)
     db.session.add(pdf_attachment)
     db.session.flush()
     cache.set(unicode(attachment.id), 'finished', timedelta(minutes=15))
     ConversionPlugin.logger.info('Added PDF attachment %s for %s', pdf_attachment, attachment)
     signals.attachments.attachment_created.send(pdf_attachment, user=None)
     return jsonify(success=True)
Example #7
0
def create_contribution_from_abstract(abstract, contrib_session=None):
    from indico.modules.events.abstracts.settings import abstracts_settings

    event = abstract.event
    contrib_person_links = set()
    author_submission_rights = (
        event.cfa.contribution_submitters == SubmissionRightsType.all)
    person_link_attrs = {
        '_title', 'address', 'affiliation', 'first_name', 'last_name', 'phone',
        'author_type', 'is_speaker', 'display_order'
    }
    for abstract_person_link in abstract.person_links:
        link = ContributionPersonLink(person=abstract_person_link.person)
        link.populate_from_attrs(abstract_person_link, person_link_attrs)
        contrib_person_links.add(link)
    if contrib_session:
        duration = contrib_session.default_contribution_duration
    else:
        duration = contribution_settings.get(event, 'default_duration')
    custom_fields_data = {
        f'custom_{field_value.contribution_field.id}': field_value.data
        for field_value in abstract.field_values
    }
    contrib = create_contribution(event, {
        'friendly_id': abstract.friendly_id,
        'title': abstract.title,
        'duration': duration,
        'description': abstract.description,
        'type': abstract.accepted_contrib_type,
        'track': abstract.accepted_track,
        'session': contrib_session,
        'person_link_data': {
            link: (author_submission_rights or link.is_speaker)
            for link in contrib_person_links
        }
    },
                                  custom_fields_data=custom_fields_data)
    if abstracts_settings.get(event, 'copy_attachments') and abstract.files:
        folder = AttachmentFolder.get_or_create_default(contrib)
        for abstract_file in abstract.files:
            attachment = Attachment(user=abstract.submitter,
                                    type=AttachmentType.file,
                                    folder=folder,
                                    title=abstract_file.filename)
            attachment.file = AttachmentFile(
                user=abstract.submitter,
                filename=abstract_file.filename,
                content_type=abstract_file.content_type)
            with abstract_file.open() as fd:
                attachment.file.save(fd)
    db.session.flush()
    return contrib
Example #8
0
def add_attachment_link(data, linked_object):
    """Add a link attachment to linked_object"""
    folder = data.pop('folder', None)
    if not folder:
        folder = AttachmentFolder.get_or_create_default(linked_object=linked_object)
    assert folder.object == linked_object
    link = Attachment(user=session.user, type=AttachmentType.link, folder=folder)
    link.populate_from_dict(data, skip={'acl', 'protected'})
    if link.is_self_protected:
        link.acl = data['acl']
    db.session.flush()
    logger.info('Attachment %s added by %s', link, session.user)
    signals.attachments.attachment_created.send(link, user=session.user)
Example #9
0
def add_attachment_link(data, linked_object):
    """Add a link attachment to linked_object."""
    folder = data.pop('folder', None)
    if not folder:
        folder = AttachmentFolder.get_or_create_default(linked_object=linked_object)
    assert folder.object == linked_object
    link = Attachment(user=session.user, type=AttachmentType.link, folder=folder)
    link.populate_from_dict(data, skip={'acl', 'protected'})
    if link.is_self_protected:
        link.acl = data['acl']
    db.session.flush()
    logger.info('Attachment %s added by %s', link, session.user)
    signals.attachments.attachment_created.send(link, user=session.user)
Example #10
0
 def _clone_attachment_folder(self, old_folder, new_object):
     folder_attrs = get_simple_column_attrs(AttachmentFolder) | {'acl'}
     attachment_attrs = (get_simple_column_attrs(Attachment) | {'user', 'acl'}) - {'modified_dt'}
     folder = AttachmentFolder(object=new_object)
     folder.populate_from_attrs(old_folder, folder_attrs)
     for old_attachment in old_folder.attachments:
         attachment = Attachment(folder=folder)
         attachment.populate_from_attrs(old_attachment, attachment_attrs)
         if attachment.type == AttachmentType.file:
             old_file = old_attachment.file
             attachment.file = AttachmentFile(attachment=attachment, user=old_file.user, filename=old_file.filename,
                                              content_type=old_file.content_type)
             with old_file.open() as fd:
                 attachment.file.save(fd)
Example #11
0
 def _clone_attachment_folder(self, old_folder, new_object):
     folder_attrs = get_simple_column_attrs(AttachmentFolder) | {'acl'}
     attachment_attrs = (get_simple_column_attrs(Attachment) | {'user', 'acl'}) - {'modified_dt'}
     folder = AttachmentFolder(object=new_object)
     folder.populate_from_attrs(old_folder, folder_attrs)
     for old_attachment in old_folder.attachments:
         attachment = Attachment(folder=folder)
         attachment.populate_from_attrs(old_attachment, attachment_attrs)
         if attachment.type == AttachmentType.file:
             old_file = old_attachment.file
             attachment.file = AttachmentFile(attachment=attachment, user=old_file.user, filename=old_file.filename,
                                              content_type=old_file.content_type)
             with old_file.open() as fd:
                 attachment.file.save(fd)
Example #12
0
    def clone(self, new_event, options):
        if 'attachments' not in options:
            return
        folder_mapping = {}
        for old_folder in self.find_folders():
            new_folder = AttachmentFolder(
                title=old_folder.title,
                description=old_folder.description,
                is_default=old_folder.is_default,
                is_always_visible=old_folder.is_always_visible,
                protection_mode=old_folder.protection_mode,
                link_type=old_folder.link_type,
                event_id=new_event.id,
                session_id=old_folder.session_id,
                contribution_id=old_folder.contribution_id,
                subcontribution_id=old_folder.subcontribution_id
            )
            if new_folder.linked_object is None:
                continue
            new_folder.acl = old_folder.acl
            db.session.add(new_folder)
            folder_mapping[old_folder] = new_folder

        for old_attachment in self.find_attachments():
            folder = folder_mapping.get(old_attachment.folder)
            if not folder:
                continue
            new_attachment = Attachment(
                folder=folder,
                user_id=old_attachment.user_id,
                title=old_attachment.title,
                description=old_attachment.description,
                type=old_attachment.type,
                link_url=old_attachment.link_url,
                protection_mode=old_attachment.protection_mode,
                acl=old_attachment.acl
            )
            if new_attachment.type == AttachmentType.file:
                old_file = old_attachment.file
                new_attachment.file = AttachmentFile(
                    attachment=new_attachment,
                    user_id=old_file.user_id,
                    filename=old_file.filename,
                    content_type=old_file.content_type
                )
                with old_file.open() as fd:
                    new_attachment.file.save(fd)
            db.session.add(new_attachment)

        db.session.flush()
Example #13
0
 def _build_base_query(self, added_since=None):
     query = Attachment.find(Attachment.type == AttachmentType.file, ~AttachmentFolder.is_deleted,
                             ~Attachment.is_deleted, AttachmentFolder.event == self.event,
                             _join=AttachmentFolder)
     if added_since is not None:
         query = query.join(Attachment.file).filter(cast(AttachmentFile.created_dt, Date) >= added_since)
     return query
Example #14
0
 def _build_base_query(self, added_since=None):
     query = Attachment.find(Attachment.type == AttachmentType.file, ~AttachmentFolder.is_deleted,
                             ~Attachment.is_deleted, AttachmentFolder.event_new == self.event_new,
                             _join=AttachmentFolder)
     if added_since is not None:
         query = query.join(Attachment.file).filter(cast(AttachmentFile.created_dt, Date) >= added_since)
     return query
Example #15
0
def create_link(indico_id, cds_id, user):
    from indico_audiovisual.plugin import AVRequestsPlugin

    obj = parse_indico_id(indico_id)
    if obj is None:
        return False

    url = AVRequestsPlugin.settings.get('recording_cds_url')
    if not url:
        return False

    url = url.format(cds_id=cds_id)
    if cds_link_exists(obj, url):
        return True

    folder = AttachmentFolder.get_or_create_default(obj)
    attachment = Attachment(folder=folder,
                            user=user,
                            title='Recording',
                            type=AttachmentType.link,
                            link_url=url)
    db.session.add(attachment)
    db.session.flush()
    signals.attachments.attachment_created.send(attachment, user=user)
    return True
Example #16
0
    def _getParams(self):
        super()._getParams()

        self._attachment = Attachment.get(int(self._pathParams['res']))

        if not self._attachment:
            raise HTTPAPIError("File not found", 404)
Example #17
0
 def _clone_attachment_folder(self, old_folder, new_object):
     folder_attrs = get_simple_column_attrs(AttachmentFolder)
     attachment_attrs = (get_simple_column_attrs(Attachment)
                         | {'user'}) - {'modified_dt'}
     folder = AttachmentFolder(object=new_object)
     folder.populate_from_attrs(old_folder, folder_attrs)
     folder.acl_entries = clone_principals(AttachmentFolderPrincipal,
                                           old_folder.acl_entries,
                                           self._event_role_map,
                                           self._regform_map)
     for old_attachment in old_folder.attachments:
         self._attachment_map[old_attachment] = attachment = Attachment(
             folder=folder)
         attachment.populate_from_attrs(old_attachment, attachment_attrs)
         attachment.acl_entries = clone_principals(
             AttachmentPrincipal, old_attachment.acl_entries,
             self._event_role_map, self._regform_map)
         if attachment.type == AttachmentType.file:
             old_file = old_attachment.file
             attachment.file = AttachmentFile(
                 attachment=attachment,
                 user=old_file.user,
                 filename=old_file.filename,
                 content_type=old_file.content_type)
             with old_file.open() as fd:
                 attachment.file.save(fd)
     return folder
Example #18
0
    def _getParams(self):
        super(FileHook, self)._getParams()

        self._attachment = Attachment.get(int(self._pathParams['res']))

        if not self._attachment:
            raise HTTPAPIError("File not found", 404)
Example #19
0
def cds_link_exists(obj, url):
    query = (Attachment.find(~Attachment.is_deleted,
                             ~AttachmentFolder.is_deleted,
                             AttachmentFolder.object == obj,
                             Attachment.type == AttachmentType.link,
                             Attachment.link_url == url,
                             _join=AttachmentFolder).options(noload('*')))
    return db.session.query(query.exists()).scalar()
Example #20
0
    def _process(self):
        form = AddAttachmentLinkForm(linked_object=self.object)
        if form.validate_on_submit():
            folder = form.folder.data or AttachmentFolder.get_or_create_default(linked_object=self.object)
            link = Attachment(user=session.user, type=AttachmentType.link)
            form.populate_obj(link, skip={'acl'})
            if link.is_protected:
                link.acl = form.acl.data
            link.folder = folder

            db.session.flush()
            logger.info('Attachment {} added by {}'.format(link, session.user))
            signals.attachments.attachment_created.send(link, user=session.user)
            flash(_("The link has been added"), 'success')
            return jsonify_data(attachment_list=_render_attachment_list(self.object))
        return jsonify_template('attachments/add_link.html', form=form,
                                protection_message=_render_protection_message(self.object),
                                folders_protection_info=_get_folders_protection_info(self.object))
Example #21
0
def test_acls(dummy_event, dummy_contribution, dummy_user, create_user,
              obj_type):
    from .schemas import ACLSchema

    class TestSchema(ACLSchema, mm.Schema):
        pass

    if obj_type == 'event':
        obj = dummy_event
    elif obj_type == 'contrib':
        obj = dummy_contribution
    elif obj_type == 'subcontrib':
        obj = SubContribution(contribution=dummy_contribution,
                              title='Test',
                              duration=timedelta(minutes=10))
    elif obj_type == 'attachment':
        folder = AttachmentFolder(title='Dummy Folder',
                                  description='a dummy folder')
        obj = Attachment(folder=folder,
                         user=dummy_user,
                         title='Dummy Attachment',
                         type=AttachmentType.link,
                         link_url='https://example.com')
        obj.folder.object = dummy_event
    elif obj_type == 'note':
        obj = EventNote(object=dummy_event)
        obj.create_revision(RenderMode.html, 'this is a dummy note',
                            dummy_user)

    def assert_acl(expected_read_acl):
        __tracebackhide__ = True
        data = schema.dump(obj)
        read_acl = data['_access'].pop('read', None)
        assert data == {
            '_access': {
                'delete': ['IndicoAdmin'],
                'owner': ['IndicoAdmin'],
                'update': ['IndicoAdmin']
            }
        }
        if read_acl is not None:
            read_acl = set(read_acl)
        assert read_acl == expected_read_acl

    schema = TestSchema()
    user = create_user(1, email='*****@*****.**')

    # everything is public
    assert_acl(None)

    # event is protected and the acl is empty (nobody has regular access)
    dummy_event.protection_mode = ProtectionMode.protected
    assert_acl({'IndicoAdmin'})

    # user on the acl has access
    dummy_event.update_principal(user, read_access=True)
    assert_acl({'IndicoAdmin', 'User:1'})
Example #22
0
 def materialToXMLMarc21(self, obj, out=None):
     if not out:
         out = self._XMLGen
     for attachment in (Attachment.find(~AttachmentFolder.is_deleted, AttachmentFolder.object == obj,
                                        is_deleted=False, _join=AttachmentFolder)
                                  .options(joinedload(Attachment.legacy_mapping))):
         if attachment.can_access(self.__aw.getUser().user):
             self.resourceToXMLMarc21(attachment, out)
             self._generateAccessList(acl=self._attachment_access_list(attachment), out=out,
                                      objId=self._attachment_unique_id(attachment, add_prefix=False))
Example #23
0
 def materialToXMLMarc21(self, obj, out=None):
     if not out:
         out = self._XMLGen
     for attachment in (Attachment.find(~AttachmentFolder.is_deleted, AttachmentFolder.object == obj,
                                        is_deleted=False, _join=AttachmentFolder)
                                  .options(joinedload(Attachment.legacy_mapping))):
         if attachment.can_access(self.__aw.getUser().user):
             self.resourceToXMLMarc21(attachment, out)
             self._generateAccessList(acl=self._attachment_access_list(attachment), out=out,
                                      objId=self._attachment_unique_id(attachment, add_prefix=False))
Example #24
0
def dummy_attachment(dummy_user):
    folder = AttachmentFolder(title='dummy_folder',
                              description='a dummy folder')
    file_ = AttachmentFile(user=dummy_user,
                           filename='dummy_file.txt',
                           content_type='text/plain')
    return Attachment(folder=folder,
                      user=dummy_user,
                      title='dummy_attachment',
                      type=AttachmentType.file,
                      file=file_)
Example #25
0
 def _process(self):
     form = AddAttachmentFilesForm(linked_object=self.object)
     if form.validate_on_submit():
         files = form.files.data
         folder = form.folder.data or AttachmentFolder.get_or_create_default(
             linked_object=self.object)
         for f in files:
             filename = secure_client_filename(f.filename)
             attachment = Attachment(
                 folder=folder,
                 user=session.user,
                 title=f.filename,
                 type=AttachmentType.file,
                 protection_mode=form.protection_mode.data)
             if attachment.is_self_protected:
                 attachment.acl = form.acl.data
             content_type = mimetypes.guess_type(
                 f.filename)[0] or f.mimetype or 'application/octet-stream'
             attachment.file = AttachmentFile(user=session.user,
                                              filename=filename,
                                              content_type=content_type)
             attachment.file.save(f.stream)
             db.session.add(attachment)
             db.session.flush()
             logger.info('Attachment %s uploaded by %s', attachment,
                         session.user)
             signals.attachments.attachment_created.send(attachment,
                                                         user=session.user)
         flash(
             ngettext("The attachment has been uploaded",
                      "{count} attachments have been uploaded",
                      len(files)).format(count=len(files)), 'success')
         return jsonify_data(
             attachment_list=_render_attachment_list(self.object))
     return jsonify_template(
         'attachments/upload.html',
         form=form,
         action=url_for('.upload', self.object),
         protection_message=_render_protection_message(self.object),
         folders_protection_info=_get_folders_protection_info(self.object),
         existing_attachment=None)
Example #26
0
    def _create_material(self, logs):
        folder = AttachmentFolder.find_first(object=self.event_new, is_default=False, title='Chat Logs',
                                             is_deleted=False)
        if folder is None:
            folder = AttachmentFolder(protection_mode=ProtectionMode.protected, linked_object=self.event_new,
                                      title='Chat Logs', description='Chat logs for this event')
            db.session.add(folder)

        filename = '{}.html'.format(secure_filename(self.material_name, 'logs'))
        attachment = Attachment(folder=folder, user=session.user, title=self.material_name, type=AttachmentType.file,
                                description="Chat logs for the chat room '{}'".format(self.chatroom.name))
        attachment.file = AttachmentFile(user=session.user, filename=filename, content_type='text/html')
        attachment.file.save(logs.encode('utf-8'))
        db.session.flush()
        signals.attachments.attachment_created.send(attachment, user=session.user)
        log_data = [
            ('Range', 'Everything' if not self.date_filter else
                      '{} - {}'.format(format_date(self.start_date), format_date(self.end_date))),
        ]
        self.event.log(EventLogRealm.management, EventLogKind.positive, 'Chat',
                       'Created material: {}'.format(filename), session.user, data=log_data)
 def _process(self):
     ids = request.args.getlist('a')
     results = {int(id_): cache.get(id_) for id_ in ids}
     finished = [id_ for id_, status in results.iteritems() if status == 'finished']
     pending = [id_ for id_, status in results.iteritems() if status == 'pending']
     containers = {}
     if finished:
         tpl = get_template_module('attachments/_display.html')
         for attachment in Attachment.find(Attachment.id.in_(finished)):
             if not attachment.folder.can_view(session.user):
                 continue
             containers[attachment.id] = tpl.render_attachments_folders(item=attachment.folder.object)
     return jsonify(finished=finished, pending=pending, containers=containers)
Example #28
0
    def _create_material(self, logs):
        folder = AttachmentFolder.find_first(object=self.event,
                                             is_default=False,
                                             title='Chat Logs',
                                             is_deleted=False)
        if folder is None:
            folder = AttachmentFolder(protection_mode=ProtectionMode.protected,
                                      linked_object=self.event,
                                      title='Chat Logs',
                                      description='Chat logs for this event')
            db.session.add(folder)

        filename = '{}.html'.format(secure_filename(self.material_name,
                                                    'logs'))
        attachment = Attachment(
            folder=folder,
            user=session.user,
            title=self.material_name,
            type=AttachmentType.file,
            description="Chat logs for the chat room '{}'".format(
                self.chatroom.name))
        attachment.file = AttachmentFile(user=session.user,
                                         filename=filename,
                                         content_type='text/html')
        attachment.file.save(logs.encode('utf-8'))
        db.session.flush()
        signals.attachments.attachment_created.send(attachment,
                                                    user=session.user)
        log_data = [
            ('Range',
             'Everything' if not self.date_filter else '{} - {}'.format(
                 format_date(self.start_date), format_date(self.end_date))),
        ]
        self.event.log(EventLogRealm.management,
                       EventLogKind.positive,
                       'Chat',
                       'Created material: {}'.format(filename),
                       session.user,
                       data=log_data)
Example #29
0
def create_contribution_from_abstract(abstract, contrib_session=None):
    from indico.modules.events.abstracts.settings import abstracts_settings

    event = abstract.event
    contrib_person_links = set()
    person_link_attrs = {'_title', 'address', 'affiliation', 'first_name', 'last_name', 'phone', 'author_type',
                         'is_speaker', 'display_order'}
    for abstract_person_link in abstract.person_links:
        link = ContributionPersonLink(person=abstract_person_link.person)
        link.populate_from_attrs(abstract_person_link, person_link_attrs)
        contrib_person_links.add(link)

    if contrib_session:
        duration = contrib_session.default_contribution_duration
    else:
        duration = contribution_settings.get(event, 'default_duration')
    custom_fields_data = {'custom_{}'.format(field_value.contribution_field.id): field_value.data for
                          field_value in abstract.field_values}
    contrib = create_contribution(event, {'friendly_id': abstract.friendly_id,
                                          'title': abstract.title,
                                          'duration': duration,
                                          'description': abstract.description,
                                          'type': abstract.accepted_contrib_type,
                                          'track': abstract.accepted_track,
                                          'session': contrib_session,
                                          'person_link_data': {link: True for link in contrib_person_links}},
                                  custom_fields_data=custom_fields_data)
    if abstracts_settings.get(event, 'copy_attachments') and abstract.files:
        folder = AttachmentFolder.get_or_create_default(contrib)
        for abstract_file in abstract.files:
            attachment = Attachment(user=abstract.submitter, type=AttachmentType.file, folder=folder,
                                    title=abstract_file.filename)
            attachment.file = AttachmentFile(user=abstract.submitter, filename=abstract_file.filename,
                                             content_type=abstract_file.content_type)
            with abstract_file.open() as fd:
                attachment.file.save(fd)
    db.session.flush()
    return contrib
Example #30
0
    def _process(self):
        form = AddAttachmentLinkForm(linked_object=self.object)
        if form.validate_on_submit():
            folder = form.folder.data or AttachmentFolder.get_or_create_default(
                linked_object=self.object)
            link = Attachment(user=session.user, type=AttachmentType.link)
            form.populate_obj(link, skip={'acl'})
            if link.is_protected:
                link.acl = form.acl.data
            link.folder = folder

            db.session.flush()
            logger.info('Attachment {} added by {}'.format(link, session.user))
            signals.attachments.attachment_created.send(link,
                                                        user=session.user)
            flash(_("The link has been added"), 'success')
            return jsonify_data(
                attachment_list=_render_attachment_list(self.object))
        return jsonify_template(
            'attachments/add_link.html',
            form=form,
            protection_message=_render_protection_message(self.object),
            folders_protection_info=_get_folders_protection_info(self.object))
Example #31
0
def _make_attachment(user, obj):
    folder = AttachmentFolder(title='dummy_folder',
                              description='a dummy folder')
    file = AttachmentFile(user=user,
                          filename='dummy_file.txt',
                          content_type='text/plain')
    attachment = Attachment(folder=folder,
                            user=user,
                            title='dummy_attachment',
                            type=AttachmentType.file,
                            file=file)
    attachment.folder.object = obj
    attachment.file.save(BytesIO(b'hello world'))
    return attachment
Example #32
0
File: base.py Project: fph/indico
 def _process(self):
     form = AddAttachmentFilesForm(linked_object=self.object)
     if form.validate_on_submit():
         files = request.files.getlist('file')
         folder = form.folder.data or AttachmentFolder.get_or_create_default(linked_object=self.object)
         for f in files:
             filename = secure_filename(f.filename, 'attachment')
             attachment = Attachment(folder=folder, user=session.user, title=to_unicode(f.filename),
                                     type=AttachmentType.file, protection_mode=form.protection_mode.data)
             if attachment.is_self_protected:
                 attachment.acl = form.acl.data
             content_type = mimetypes.guess_type(f.filename)[0] or f.mimetype or 'application/octet-stream'
             attachment.file = AttachmentFile(user=session.user, filename=filename, content_type=content_type)
             attachment.file.save(f.file)
             db.session.add(attachment)
             db.session.flush()
             logger.info('Attachment %s uploaded by %s', attachment, session.user)
             signals.attachments.attachment_created.send(attachment, user=session.user)
         flash(ngettext("The attachment has been uploaded", "{count} attachments have been uploaded", len(files))
               .format(count=len(files)), 'success')
         return jsonify_data(attachment_list=_render_attachment_list(self.object))
     return jsonify_template('attachments/upload.html', form=form, action=url_for('.upload', self.object),
                             protection_message=_render_protection_message(self.object),
                             folders_protection_info=_get_folders_protection_info(self.object))
Example #33
0
    def _process(self):
        params = self._getRequestParams()
        if params["title"] == "":
            params["title"] = "No Title"
        # change number of dates (lecture)
        if self._confirm == True:
            if self._event_type != "simple_event":
                c = self._createEvent(self._params)
                self.alertCreation([c])
            # lectures
            else:
                lectures = []
                for i in range(1, int(self._params["nbDates"]) + 1):
                    self._params["sDay"] = self._params.get("sDay_%s" % i, "")
                    self._params["sMonth"] = self._params.get(
                        "sMonth_%s" % i, "")
                    self._params["sYear"] = self._params.get(
                        "sYear_%s" % i, "")
                    self._params["sHour"] = self._params.get(
                        "sHour_%s" % i, "")
                    self._params["sMinute"] = self._params.get(
                        "sMinute_%s" % i, "")
                    self._params["duration"] = int(
                        self._params.get("dur_%s" % i, 60))
                    lectures.append(self._createEvent(self._params))
                self.alertCreation(lectures)
                lectures.sort(sortByStartDate)
                # create links
                for i, source in enumerate(lectures, 1):
                    if len(lectures) > 1:
                        source.setTitle("{} ({}/{})".format(
                            source.getTitle(), i, len(lectures)))

                    for j, target in enumerate(lectures, 1):
                        if j != i:
                            folder = AttachmentFolder(linked_object=source,
                                                      title="part{}".format(j))
                            link = Attachment(user=session.user,
                                              type=AttachmentType.link,
                                              folder=folder,
                                              title="Part {}".format(j),
                                              link_url=target.getURL())
                            db.session.add(link)
                c = lectures[0]
            self._redirect(urlHandlers.UHConferenceModification.getURL(c))
        else:
            url = urlHandlers.UHCategoryDisplay.getURL(self._target)
            self._redirect(url)
Example #34
0
def obj_deref(ref):
    """Return the object identified by `ref`."""
    from indico_livesync.models.queue import EntryType
    if ref['type'] == EntryType.category:
        return Category.get_or_404(ref['category_id'])
    elif ref['type'] == EntryType.event:
        return Event.get_or_404(ref['event_id'])
    elif ref['type'] == EntryType.session:
        return Session.get_or_404(ref['session_id'])
    elif ref['type'] == EntryType.contribution:
        return Contribution.get_or_404(ref['contrib_id'])
    elif ref['type'] == EntryType.subcontribution:
        return SubContribution.get_or_404(ref['subcontrib_id'])
    elif ref['type'] == EntryType.note:
        return EventNote.get_or_404(ref['note_id'])
    elif ref['type'] == EntryType.attachment:
        return Attachment.get_or_404(ref['attachment_id'])
    else:
        raise ValueError('Unexpected object type: {}'.format(ref['type']))
Example #35
0
def test_dump_attachment(db, dummy_user, dummy_contribution):
    from indico.modules.search.schemas import AttachmentSchema

    folder = AttachmentFolder(title='Dummy Folder',
                              description='a dummy folder')
    file = AttachmentFile(user=dummy_user,
                          filename='dummy_file.txt',
                          content_type='text/plain')
    attachment = Attachment(folder=folder,
                            user=dummy_user,
                            title='Dummy Attachment',
                            type=AttachmentType.file,
                            file=file)
    attachment.folder.object = dummy_contribution
    attachment.file.save(BytesIO(b'hello world'))
    db.session.flush()

    category_id = dummy_contribution.event.category_id
    schema = AttachmentSchema()
    assert schema.dump(attachment) == {
        'filename':
        'dummy_file.txt',
        'title':
        'Dummy Attachment',
        'user': {
            'affiliation': None,
            'name': 'Guinea Pig'
        },
        'attachment_id':
        attachment.id,
        'attachment_type':
        'file',
        'category_id':
        category_id,
        'category_path': [
            {
                'id': 0,
                'title': 'Home',
                'url': '/'
            },
            {
                'id': category_id,
                'title': 'dummy',
                'url': f'/category/{category_id}/'
            },
        ],
        'contribution_id':
        dummy_contribution.id,
        'subcontribution_id':
        None,
        'event_id':
        0,
        'folder_id':
        folder.id,
        'modified_dt':
        attachment.modified_dt.isoformat(),
        'type':
        'attachment',
        'url':
        (f'/event/0/contributions/'
         f'{dummy_contribution.id}/attachments/{folder.id}/{attachment.id}/dummy_file.txt'
         ),
    }
Example #36
0
 def _count_attachments(cls, obj):
     return Attachment.find(~AttachmentFolder.is_deleted, AttachmentFolder.linked_object == obj,
                            is_deleted=False, _join=AttachmentFolder).count()
Example #37
0
 def has_data(self):
     return AttachmentFolder.has_rows() or Attachment.has_rows()
Example #38
0
 def find_attachments(self):
     return Attachment.find(~AttachmentFolder.is_deleted, ~Attachment.is_deleted,
                            AttachmentFolder.event_id == int(self.event.id), _join=AttachmentFolder)
Example #39
0
 def _process_args(self):
     self.attachment = Attachment.find_one(id=request.view_args['attachment_id'], is_deleted=False)
     if self.attachment.folder.is_deleted:
         raise NotFound
Example #40
0
def test_attachment_acls(dummy_event, dummy_user, create_user):
    from .schemas import ACLSchema

    class TestSchema(ACLSchema, mm.Schema):
        pass

    folder = AttachmentFolder(title='Dummy Folder',
                              description='a dummy folder')
    attachment = Attachment(folder=folder,
                            user=dummy_user,
                            title='Dummy Attachment',
                            type=AttachmentType.link,
                            link_url='https://example.com')
    attachment.folder.object = dummy_event

    def assert_acl(expected_read_acl):
        __tracebackhide__ = True
        data = schema.dump(attachment)
        read_acl = data['_access'].pop('read', None)
        assert data == {
            '_access': {
                'delete': ['IndicoAdmin'],
                'owner': ['IndicoAdmin'],
                'update': ['IndicoAdmin']
            }
        }
        if read_acl is not None:
            read_acl = set(read_acl)
        assert read_acl == expected_read_acl

    schema = TestSchema()
    u1 = create_user(1, email='*****@*****.**')
    u2 = create_user(2, email='*****@*****.**')
    u3 = create_user(3, email='*****@*****.**')

    # event is inheriting public, so no acl
    assert_acl(None)

    # event is protected and the acl is empty (nobody has regular access)
    dummy_event.protection_mode = ProtectionMode.protected
    assert_acl({'IndicoAdmin'})

    dummy_event.update_principal(u1, read_access=True)
    dummy_event.category.update_principal(u2, read_access=True)
    dummy_event.category.parent.update_principal(u3, read_access=True)

    # self-protected, so no acl inherited
    assert_acl({'IndicoAdmin', 'User:1'})

    # event is inheriting from public categories, so there is no acl
    dummy_event.protection_mode = ProtectionMode.inheriting
    assert_acl(None)

    # event it itself public, so no acl here as well
    dummy_event.protection_mode = ProtectionMode.public
    assert_acl(None)

    # inheriting, so all parent acl entries
    dummy_event.protection_mode = ProtectionMode.inheriting
    dummy_event.category.parent.protection_mode = ProtectionMode.protected
    assert_acl({'IndicoAdmin', 'User:1', 'User:2', 'User:3'})

    # category protected, so no parent category acl inherited
    dummy_event.category.protection_mode = ProtectionMode.protected
    assert_acl({'IndicoAdmin', 'User:1', 'User:2'})

    # parent category acl entry is a manager, that one is inherited
    dummy_event.category.parent.update_principal(u3, full_access=True)
    assert_acl({'IndicoAdmin', 'User:1', 'User:2', 'User:3'})

    # attachment self-protected, only the category/event manager has access
    folder.update_principal(u2, read_access=True)
    attachment.protection_mode = ProtectionMode.protected
    assert_acl({'IndicoAdmin', 'User:3'})

    # the user in the attachment acl has access as well
    attachment.update_principal(u1, read_access=True)
    attachment.protection_mode = ProtectionMode.protected
    assert_acl({'IndicoAdmin', 'User:3', 'User:1'})

    # attachment inheriting from self-protected folder - only the folder acl is used
    attachment.protection_mode = ProtectionMode.inheriting
    folder.protection_mode = ProtectionMode.protected
    assert_acl({'IndicoAdmin', 'User:3', 'User:2'})
Example #41
0
def test_dump_attachment(db, dummy_user, dummy_contribution):
    from .schemas import AttachmentRecordSchema

    folder = AttachmentFolder(title='Dummy Folder',
                              description='a dummy folder')
    file = AttachmentFile(user=dummy_user,
                          filename='dummy_file.txt',
                          content_type='text/plain')
    attachment = Attachment(folder=folder,
                            user=dummy_user,
                            title='Dummy Attachment',
                            type=AttachmentType.file,
                            file=file)
    attachment.folder.object = dummy_contribution
    attachment.file.save(BytesIO(b'hello world'))
    db.session.flush()

    category_id = dummy_contribution.event.category_id
    schema = AttachmentRecordSchema(context={'schema': 'test-attachment'})
    assert schema.dump(attachment) == {
        '$schema':
        'test-attachment',
        '_access': {
            'delete': ['IndicoAdmin'],
            'owner': ['IndicoAdmin'],
            'update': ['IndicoAdmin'],
        },
        '_data': {
            'filename': 'dummy_file.txt',
            'site': 'http://localhost',
            'title': 'Dummy Attachment',
            'persons': {
                'name': 'Guinea Pig'
            },
        },
        'attachment_id':
        attachment.id,
        'category_id':
        category_id,
        'category_path': [
            {
                'id': 0,
                'title': 'Home',
                'url': '/'
            },
            {
                'id': category_id,
                'title': 'dummy',
                'url': f'/category/{category_id}/'
            },
        ],
        'contribution_id':
        dummy_contribution.id,
        'event_id':
        0,
        'folder_id':
        folder.id,
        'modified_dt':
        attachment.modified_dt.isoformat(),
        'type':
        'attachment',
        'type_format':
        'file',
        'url':
        (f'http://localhost/event/0/contributions/'
         f'{dummy_contribution.id}/attachments/{folder.id}/{attachment.id}/dummy_file.txt'
         ),
    }
Example #42
0
    def search_attachments(self, q, user, page, category_id, event_id,
                           admin_override_enabled):
        contrib_event = db.aliased(Event)
        contrib_session = db.aliased(Session)
        subcontrib_contrib = db.aliased(Contribution)
        subcontrib_session = db.aliased(Session)
        subcontrib_event = db.aliased(Event)
        session_event = db.aliased(Event)

        attachment_strategy = _apply_acl_entry_strategy(
            selectinload(Attachment.acl_entries), AttachmentPrincipal)
        folder_strategy = contains_eager(Attachment.folder)
        folder_strategy.load_only('id', 'protection_mode', 'link_type',
                                  'category_id', 'event_id', 'linked_event_id',
                                  'contribution_id', 'subcontribution_id',
                                  'session_id')
        _apply_acl_entry_strategy(
            folder_strategy.selectinload(AttachmentFolder.acl_entries),
            AttachmentFolderPrincipal)
        # event
        event_strategy = folder_strategy.contains_eager(
            AttachmentFolder.linked_event)
        _apply_event_access_strategy(event_strategy)
        _apply_acl_entry_strategy(
            event_strategy.selectinload(Event.acl_entries), EventPrincipal)
        # contribution
        contrib_strategy = folder_strategy.contains_eager(
            AttachmentFolder.contribution)
        _apply_contrib_access_strategy(contrib_strategy)
        _apply_acl_entry_strategy(
            contrib_strategy.selectinload(Contribution.acl_entries),
            ContributionPrincipal)
        contrib_event_strategy = contrib_strategy.contains_eager(
            Contribution.event.of_type(contrib_event))
        _apply_event_access_strategy(contrib_event_strategy)
        _apply_acl_entry_strategy(
            contrib_event_strategy.selectinload(contrib_event.acl_entries),
            EventPrincipal)
        contrib_session_strategy = contrib_strategy.contains_eager(
            Contribution.session.of_type(contrib_session))
        contrib_session_strategy.load_only('id', 'event_id', 'protection_mode')
        _apply_acl_entry_strategy(
            contrib_session_strategy.selectinload(contrib_session.acl_entries),
            SessionPrincipal)
        # subcontribution
        subcontrib_strategy = folder_strategy.contains_eager(
            AttachmentFolder.subcontribution)
        subcontrib_strategy.load_only('id', 'contribution_id', 'title')
        subcontrib_contrib_strategy = subcontrib_strategy.contains_eager(
            SubContribution.contribution.of_type(subcontrib_contrib))
        _apply_contrib_access_strategy(subcontrib_contrib_strategy)
        _apply_acl_entry_strategy(
            subcontrib_contrib_strategy.selectinload(
                subcontrib_contrib.acl_entries), ContributionPrincipal)
        subcontrib_event_strategy = subcontrib_contrib_strategy.contains_eager(
            subcontrib_contrib.event.of_type(subcontrib_event))
        _apply_event_access_strategy(subcontrib_event_strategy)
        _apply_acl_entry_strategy(
            subcontrib_event_strategy.selectinload(
                subcontrib_event.acl_entries), EventPrincipal)
        subcontrib_session_strategy = subcontrib_contrib_strategy.contains_eager(
            subcontrib_contrib.session.of_type(subcontrib_session))
        subcontrib_session_strategy.load_only('id', 'event_id',
                                              'protection_mode')
        _apply_acl_entry_strategy(
            subcontrib_session_strategy.selectinload(
                subcontrib_session.acl_entries), SessionPrincipal)
        # session
        session_strategy = folder_strategy.contains_eager(
            AttachmentFolder.session)
        session_strategy.load_only('id', 'event_id', 'protection_mode')
        session_event_strategy = session_strategy.contains_eager(
            Session.event.of_type(session_event))
        _apply_event_access_strategy(session_event_strategy)
        session_event_strategy.selectinload(session_event.acl_entries)
        _apply_acl_entry_strategy(
            session_strategy.selectinload(Session.acl_entries),
            SessionPrincipal)

        attachment_filters = [
            Attachment.title_matches(q), ~Attachment.is_deleted,
            ~AttachmentFolder.is_deleted,
            AttachmentFolder.link_type != LinkType.category,
            db.or_(
                AttachmentFolder.link_type != LinkType.event,
                ~Event.is_deleted,
            ),
            db.or_(AttachmentFolder.link_type != LinkType.contribution,
                   ~Contribution.is_deleted & ~contrib_event.is_deleted),
            db.or_(
                AttachmentFolder.link_type != LinkType.subcontribution,
                db.and_(
                    ~SubContribution.is_deleted,
                    ~subcontrib_contrib.is_deleted,
                    ~subcontrib_event.is_deleted,
                )),
            db.or_(AttachmentFolder.link_type != LinkType.session,
                   ~Session.is_deleted & ~session_event.is_deleted)
        ]

        if category_id is not None:
            attachment_filters.append(
                AttachmentFolder.event.has(
                    Event.category_chain_overlaps(category_id)))
        if event_id is not None:
            attachment_filters.append(AttachmentFolder.event_id == event_id)

        query = (
            Attachment.query.join(
                Attachment.folder).filter(*attachment_filters).options(
                    folder_strategy, attachment_strategy,
                    joinedload(
                        Attachment.user).joinedload('_affiliation')).outerjoin(
                            AttachmentFolder.linked_event).outerjoin(
                                AttachmentFolder.contribution).outerjoin(
                                    Contribution.event.of_type(contrib_event)).
            outerjoin(Contribution.session.of_type(contrib_session)).outerjoin(
                AttachmentFolder.subcontribution).outerjoin(
                    SubContribution.contribution.of_type(subcontrib_contrib)).
            outerjoin(
                subcontrib_contrib.event.of_type(subcontrib_event)).outerjoin(
                    subcontrib_contrib.session.of_type(
                        subcontrib_session)).outerjoin(
                            AttachmentFolder.session).outerjoin(
                                Session.event.of_type(session_event)))

        objs, pagenav = self._paginate(query, page, Attachment.id, user,
                                       admin_override_enabled)

        query = (Attachment.query.filter(Attachment.id.in_(
            a.id for a in objs)).options(
                joinedload(Attachment.folder).options(
                    joinedload(AttachmentFolder.subcontribution),
                    joinedload(AttachmentFolder.event).options(
                        undefer(Event.detailed_category_chain)))))
        attachments_by_id = {a.id: a for a in query}
        attachments = [attachments_by_id[a.id] for a in objs]

        res = AttachmentSchema(many=True).dump(attachments)
        return pagenav, AttachmentResultSchema(many=True).load(res)
Example #43
0
 def _count_attachments(cls, obj):
     return Attachment.find(~AttachmentFolder.is_deleted,
                            AttachmentFolder.linked_object == obj,
                            is_deleted=False,
                            _join=AttachmentFolder).count()
Example #44
0
 def _checkParams(self):
     self.attachment = Attachment.find_one(id=request.view_args['attachment_id'], is_deleted=False)
     if self.attachment.folder.is_deleted:
         raise NotFound
Example #45
0
 def find_attachments(self):
     return Attachment.find(~AttachmentFolder.is_deleted, ~Attachment.is_deleted,
                            AttachmentFolder.event_id == int(self.event.id), _join=AttachmentFolder)
Example #46
0
 def has_data(self):
     return AttachmentFolder.has_rows() or Attachment.has_rows()