Esempio n. 1
0
 def _process(self, url):
     if editing_settings.get(self.event, 'service_url'):
         raise BadRequest('Service URL already set')
     url = url.rstrip('/')
     info = check_service_url(url)
     if info['error'] is not None:
         abort(422, messages={'url': [info['error']]})
     if not editing_settings.get(self.event, 'service_event_identifier'):
         editing_settings.set(self.event, 'service_event_identifier',
                              make_event_identifier(self.event))
     editing_settings.set_multi(self.event, {
         'service_url': url,
         'service_token': unicode(uuid4()),
     })
     # we need to commit the token so the service can already use it when processing
     # the enabled event in case it wants to set up tags etc
     db.session.commit()
     try:
         service_handle_enabled(self.event)
     except ServiceRequestFailed as exc:
         editing_settings.delete(self.event, 'service_url', 'service_token')
         db.session.commit()
         raise ServiceUnavailable(
             _('Could not register event with service: {}').format(exc))
     except Exception:
         editing_settings.delete(self.event, 'service_url', 'service_token')
         db.session.commit()
         raise
     return '', 204
Esempio n. 2
0
 def _process_args(self):
     RHEditingManagementBase._process_args(self)
     uuid = request.view_args['uuid']
     conditions = editing_settings.get(self.event, 'review_conditions')
     self.uuid = unicode(uuid)
     if self.uuid not in conditions:
         raise NotFound
Esempio n. 3
0
 def _clone_review_conditions(self, new_event):
     review_conditions = editing_settings.get(self.old_event,
                                              'review_conditions')
     new_conditions = OrderedDict(
         self._build_review_conditions(new_event, cond)
         for cond in review_conditions.viewvalues())
     editing_settings.set(new_event, 'review_conditions', new_conditions)
Esempio n. 4
0
    def _process(self):
        if self.editable:
            raise UserValueError(_('Editable already exists'))

        args = parser.parse({
            'files':
            EditingFilesField(self.event,
                              self.contrib,
                              self.editable_type,
                              required=True)
        })
        service_url = editing_settings.get(self.event, 'service_url')
        initial_state = InitialRevisionState.new if service_url else InitialRevisionState.ready_for_review

        editable = create_new_editable(self.contrib, self.editable_type,
                                       session.user, args['files'],
                                       initial_state)
        if service_url:
            try:
                service_handle_new_editable(editable, session.user)
            except ServiceRequestFailed:
                raise ServiceUnavailable(
                    _('Submission failed, please try again later.'))

        return '', 201
Esempio n. 5
0
    def _process(self, action, comment):
        argmap = {'tags': EditingTagsField(self.event, missing=set())}
        if action in (EditingReviewAction.update,
                      EditingReviewAction.update_accept):
            argmap['files'] = EditingFilesField(self.event,
                                                self.contrib,
                                                self.editable_type,
                                                allow_claimed_files=True,
                                                required=True)
        args = parser.parse(argmap, unknown=EXCLUDE)
        service_url = editing_settings.get(self.event, 'service_url')

        new_revision = review_editable_revision(self.revision, session.user,
                                                action, comment, args['tags'],
                                                args.get('files'))

        publish = True
        if service_url:
            try:
                resp = service_handle_review_editable(self.editable,
                                                      session.user, action,
                                                      self.revision,
                                                      new_revision)
                publish = resp.get('publish', True)
            except ServiceRequestFailed:
                raise ServiceUnavailable(
                    _('Failed processing review, please try again later.'))

        if publish and action in (EditingReviewAction.accept,
                                  EditingReviewAction.update_accept):
            publish_editable_revision(new_revision or self.revision)
        return '', 204
Esempio n. 6
0
 def _process(self):
     if not editing_settings.get(self.event, 'service_url'):
         return jsonify(connected=False, error=None, status=None)
     status = service_get_status(self.event)
     return jsonify(connected=True,
                    error=status['error'],
                    status=status['status'])
Esempio n. 7
0
 def review_conditions_valid(self):
     review_conditions = editing_settings.get(self.event,
                                              'review_conditions').values()
     file_types = {file.file_type_id for file in self.revisions[-1].files}
     if not review_conditions:
         return True
     return any(file_types >= set(cond) for cond in review_conditions)
Esempio n. 8
0
 def _check_revision_access(self):
     if not editing_settings.get(self.event, 'service_url'):
         return False
     # It's up to the editing service to decide who can do what, so we
     # just require the user to have more than just read access
     return (self.editable.can_perform_submitter_actions(session.user)
             or self.editable.can_perform_editor_actions(session.user))
Esempio n. 9
0
 def _process_args(self):
     RHEditingManagementBase._process_args(self)
     self.editable_type = EditableType[request.view_args['type']]
     uuid = request.view_args['uuid']
     conditions = editing_settings.get(self.event, self.editable_type.name + '_review_conditions')
     self.uuid = unicode(uuid)
     if self.uuid not in conditions:
         raise NotFound
Esempio n. 10
0
 def _clone_review_conditions(self, new_event):
     for type_ in EditableType:
         review_conditions = editing_settings.get(
             self.old_event, type_.name + '_review_conditions')
         new_conditions = OrderedDict(
             self._build_review_conditions(new_event, cond)
             for cond in review_conditions.viewvalues())
         editing_settings.set(new_event, type_.name + '_review_conditions',
                              new_conditions)
Esempio n. 11
0
def _get_headers(event, include_token=True):
    headers = {
        'Accept': 'application/json',
        'User-Agent': f'Indico/{indico.__version__}'
    }
    if include_token:
        headers['Authorization'] = 'Bearer {}'.format(
            editing_settings.get(event, 'service_token'))
    return headers
Esempio n. 12
0
    def _get_custom_actions(self):
        if not editing_settings.get(self.event, 'service_url'):
            return []

        try:
            return service_get_custom_actions(self.editable, self.editable.revisions[-1], session.user)
        except ServiceRequestFailed:
            # unlikely to fail, but if it does we don't break the whole timeline
            return []
Esempio n. 13
0
    def enabled_editables(self):
        """Return all submitted editables with enabled types."""
        from indico.modules.events.editing.settings import editing_settings
        if not self.event.has_feature('editing'):
            return []

        enabled_editable_types = editing_settings.get(self.event, 'editable_types')
        enabled_editables = [editable for editable in self.editables if editable.type.name in enabled_editable_types]
        order = list(EditableType)
        return sorted(enabled_editables, key=lambda editable: order.index(editable.type))
Esempio n. 14
0
    def _validate_file_types(self, file_types):
        event = self.context['event']
        event_file_types = {ft.id for ft in event.editing_file_types}
        condition_types = set(file_types)

        if condition_types - event_file_types:
            raise ValidationError(_('Invalid file type used'))

        event_conditions = editing_settings.get(event, 'review_conditions')
        if any(condition_types == set(event_condition) for event_condition in event_conditions.values()):
            raise ValidationError(_('Conditions have to be unique'))
Esempio n. 15
0
    def _token_can_access(self):
        # we need to "fish" the event here because at this point _check_params
        # hasn't run yet
        event = Event.get_or_404(int(request.view_args['confId']),
                                 is_deleted=False)
        if not self.SERVICE_ALLOWED or not request.bearer_token:
            return False

        event_token = editing_settings.get(event, 'service_token')
        if request.bearer_token != event_token:
            raise Unauthorized('Invalid bearer token')

        return True
Esempio n. 16
0
def service_handle_enabled(event):
    data = {
        'title': event.title,
        'url': event.external_url,
        'token': editing_settings.get(event, 'service_token'),
        'endpoints': _get_event_endpoints(event)
    }
    try:
        resp = requests.put(_build_url(event, '/event/{}'.format(_get_event_identifier(event))),
                            headers=_get_headers(event, include_token=False), json=data)
        resp.raise_for_status()
    except requests.RequestException as exc:
        _log_service_error(exc, 'Registering event with service failed')
        raise ServiceRequestFailed(exc)
Esempio n. 17
0
    def _process(self, action, comment):
        confirm_editable_changes(self.revision, session.user, action, comment)

        service_url = editing_settings.get(self.event, 'service_url')
        publish = True
        if service_url:
            try:
                resp = service_handle_review_editable(self.editable, session.user, action, self.revision)
                publish = resp.get('publish', True)
            except ServiceRequestFailed:
                raise ServiceUnavailable(_('Failed processing review, please try again later.'))

        if publish and action == EditingConfirmationAction.accept:
            publish_editable_revision(self.revision)
        return '', 204
Esempio n. 18
0
    def _process_DELETE(self):
        if EditingRevisionFile.query.with_parent(self.file_type).has_rows():
            raise UserValueError(_('Cannot delete file type which already has files'))

        review_conditions = editing_settings.get(self.event, self.editable_type.name + '_review_conditions')
        if any(self.file_type.id in cond for cond in review_conditions.values()):
            raise UserValueError(_('Cannot delete file type which is used in a review condition'))
        if self.file_type.publishable:
            is_last = not (EditingFileType.query
                           .with_parent(self.event)
                           .filter(EditingFileType.publishable, EditingFileType.id != self.file_type.id)
                           .has_rows())
            if is_last:
                raise UserValueError(_('Cannot delete the only publishable file type'))
        delete_file_type(self.file_type)
        return '', 204
Esempio n. 19
0
    def _process(self):
        args = parser.parse({
            'files': EditingFilesField(self.event, self.contrib, self.editable_type, allow_claimed_files=True,
                                       required=True)
        })

        service_url = editing_settings.get(self.event, 'service_url')
        new_revision = create_submitter_revision(self.revision, session.user, args['files'])

        if service_url:
            try:
                service_handle_review_editable(self.editable, session.user, EditingReviewAction.update,
                                               self.revision, new_revision)
            except ServiceRequestFailed:
                raise ServiceUnavailable(_('Failed processing review, please try again later.'))
        return '', 204
Esempio n. 20
0
class PaperSchema(mm.Schema):
    is_in_final_state = Boolean()
    contribution = Nested(ContributionSchema)
    event = Nested(PaperEventSchema)
    revisions = List(Nested(PaperRevisionSchema))
    last_revision = Nested(PaperRevisionSchema)
    state = Nested(PaperRevisionStateSchema)
    can_judge = Function(lambda paper, ctx: paper.can_judge(ctx.get('user')))
    can_comment = Function(lambda paper, ctx: paper.can_comment(
        ctx.get('user'), check_state=True))
    can_review = Function(lambda paper, ctx: paper.can_review(ctx.get('user')))
    can_submit_proceedings = Function(lambda paper, ctx: paper.contribution.
                                      can_submit_proceedings(ctx.get('user')))
    editing_open = Function(lambda paper, ctx: editable_type_settings[
        EditableType.paper].get(paper.event, 'submission_enabled'))
    editing_enabled = Function(
        lambda paper, ctx: paper.event.has_feature('editing') and 'paper' in
        editing_settings.get(paper.event, 'editable_types'))
Esempio n. 21
0
 def _process(self, force):
     if not editing_settings.get(self.event, 'service_url'):
         raise BadRequest('Service URL not set')
     status = service_get_status(self.event)
     notify_service = True
     if status['error']:
         if not force:
             # this only happens if the service went down between loading
             # the page and sending the disconnect request
             raise BadRequest('Cannot disconnect service')
         notify_service = False
     elif not status['status']['can_disconnect']:
         raise BadRequest('Cannot disconnect service')
     if notify_service:
         try:
             service_handle_disconnected(self.event)
         except ServiceRequestFailed as exc:
             raise ServiceUnavailable(_('Could not disconnect event from service: {}').format(exc))
     editing_settings.delete(self.event, 'service_url', 'service_token')
     return '', 204
Esempio n. 22
0
def service_handle_enabled(event):
    data = {
        'title': event.title,
        'url': event.external_url,
        'token': editing_settings.get(event, 'service_token'),
        'endpoints': {
            'tags': {
                'create': url_for('.api_create_tag', event, _external=True),
                'list': url_for('.api_tags', event, _external=True)
            },
            'editable_types':
            url_for('.api_enabled_editable_types', event, _external=True),
            'file_types': {
                t.name: {
                    'create':
                    url_for('.api_add_file_type',
                            event,
                            type=t.name,
                            _external=True),
                    'list':
                    url_for('.api_file_types',
                            event,
                            type=t.name,
                            _external=True),
                }
                for t in EditableType
            }
        }
    }
    try:
        resp = requests.put(_build_url(
            event, '/event/{}'.format(_get_event_identifier(event))),
                            headers=_get_headers(event, include_token=False),
                            json=data)
        resp.raise_for_status()
    except requests.RequestException as exc:
        logger.exception('Registering event with service failed')
        raise ServiceRequestFailed(exc)
Esempio n. 23
0
 def _process_GET(self):
     return jsonify(editing_settings.get(self.event, 'editable_types'))
Esempio n. 24
0
 def editable_types(self):
     from indico.modules.events.editing.settings import editing_settings
     return editing_settings.get(self, 'editable_types')
Esempio n. 25
0
 def _process_DELETE(self):
     new_conditions = editing_settings.get(self.event, 'review_conditions')
     del new_conditions[self.uuid]
     editing_settings.set(self.event, 'review_conditions', new_conditions)
     return '', 204
Esempio n. 26
0
 def _is_used_in_condition(self, file_type):
     conditions = editing_settings.get(
         file_type.event, file_type.type.name + '_review_conditions')
     return any(file_type.id in cond for cond in conditions.values())
Esempio n. 27
0
def _get_event_identifier(event):
    identifier = editing_settings.get(event, 'service_event_identifier')
    assert identifier
    return identifier
Esempio n. 28
0
def _build_url(event, path):
    return editing_settings.get(event, 'service_url') + path
Esempio n. 29
0
 def _check_revision_access(self):
     if not editing_settings.get(self.event, 'service_url'):
         return False
     # It's up to the editing service to decide who can do what, so we
     # just require the user to have editable access
     return self.editable.can_see_timeline(session.user)
Esempio n. 30
0
 def _process_PATCH(self, file_types):
     new_conditions = editing_settings.get(self.event, 'review_conditions')
     new_conditions[self.uuid] = file_types
     editing_settings.set(self.event, 'review_conditions', new_conditions)
     return '', 204