Esempio n. 1
0
    def create_from_data(cls,
                         room,
                         data,
                         user,
                         prebook=None,
                         ignore_admin=False):
        """Creates a new reservation.

        :param room: The Room that's being booked.
        :param data: A dict containing the booking data, usually from a :class:`NewBookingConfirmForm` instance
        :param user: The :class:`.User` who creates the booking.
        :param prebook: Instead of determining the booking type from the user's
                        permissions, always use the given mode.
        """

        populate_fields = ('start_dt', 'end_dt', 'repeat_frequency',
                           'repeat_interval', 'room_id', 'contact_email',
                           'contact_phone', 'booking_reason',
                           'needs_assistance', 'uses_vc',
                           'needs_vc_assistance')
        if data['repeat_frequency'] == RepeatFrequency.NEVER and data[
                'start_dt'].date() != data['end_dt'].date():
            raise ValueError('end_dt != start_dt for non-repeating booking')

        if prebook is None:
            prebook = not room.can_book(user, allow_admin=(not ignore_admin))
            if prebook and not room.can_prebook(
                    user, allow_admin=(not ignore_admin)):
                raise NoReportError(u'You cannot book this room')

        room.check_advance_days(data['end_dt'].date(), user)
        room.check_bookable_hours(data['start_dt'].time(),
                                  data['end_dt'].time(), user)

        reservation = cls()
        for field in populate_fields:
            if field in data:
                setattr(reservation, field, data[field])
        reservation.room = room
        # if 'room_usage' is not specified, we'll take whatever is passed in 'booked_for_user'
        reservation.booked_for_user = data['booked_for_user'] if data.get(
            'room_usage') != 'current_user' else user
        reservation.booked_for_name = reservation.booked_for_user.full_name
        reservation.state = ReservationState.pending if prebook else ReservationState.accepted
        reservation.created_by_user = user
        reservation.create_occurrences(True)
        if not any(occ.is_valid for occ in reservation.occurrences):
            raise NoReportError(_(u'Reservation has no valid occurrences'))
        db.session.flush()
        signals.rb.booking_created.send(reservation)
        notify_creation(reservation)
        return reservation
Esempio n. 2
0
 def _check_version(self, distribution, current_version=None):
     try:
         response = requests.get('https://pypi.org/pypi/{}/json'.format(distribution))
     except requests.RequestException as exc:
         Logger.get('versioncheck').warning('Version check for %s failed: %s', distribution, exc)
         raise NoReportError.wrap_exc(ServiceUnavailable())
     try:
         data = response.json()
     except ValueError:
         return None
     if current_version is None:
         try:
             current_version = get_distribution(distribution).version
         except DistributionNotFound:
             return None
     current_version = Version(current_version)
     if current_version.is_prerelease:
         # if we are on a prerelease, get the latest one even if it's also a prerelease
         latest_version = Version(data['info']['version'])
     else:
         # if we are stable, get the latest stable version
         versions = [v for v in map(Version, data['releases']) if not v.is_prerelease]
         latest_version = max(versions) if versions else None
     return {'current_version': unicode(current_version),
             'latest_version': unicode(latest_version) if latest_version else None,
             'outdated': (current_version < latest_version) if latest_version else False}
Esempio n. 3
0
    def _process(self):
        from_preview = request.args.get('from_preview') == '1'
        force_download = request.args.get('download') == '1'

        signals.attachments.attachment_accessed.send(self.attachment,
                                                     user=session.user,
                                                     from_preview=from_preview)
        if request.values.get('preview') == '1':
            if self.attachment.type != AttachmentType.file:
                raise BadRequest
            previewer = get_file_previewer(self.attachment.file)
            if not previewer:
                raise NoReportError.wrap_exc(
                    BadRequest(
                        _('There is no preview available for this file type. '
                          'Please refresh the page.')))
            preview_content = previewer.generate_content(self.attachment)
            return jsonify_template('attachments/preview.html',
                                    attachment=self.attachment,
                                    preview_content=preview_content)
        else:
            if self.attachment.type == AttachmentType.link:
                return redirect(self.attachment.link_url)
            else:
                return self.attachment.file.send(inline=not force_download)
Esempio n. 4
0
 def _check_version(self, distribution, current_version=None):
     try:
         response = requests.get('https://pypi.org/pypi/{}/json'.format(distribution))
     except requests.RequestException as exc:
         Logger.get('versioncheck').warning('Version check for %s failed: %s', distribution, exc)
         raise NoReportError.wrap_exc(ServiceUnavailable())
     try:
         data = response.json()
     except ValueError:
         return None
     if current_version is None:
         try:
             current_version = get_distribution(distribution).version
         except DistributionNotFound:
             return None
     current_version = Version(current_version)
     if current_version.is_prerelease:
         # if we are on a prerelease, get the latest one even if it's also a prerelease
         latest_version = Version(data['info']['version'])
     else:
         # if we are stable, get the latest stable version
         versions = [v for v in map(Version, data['releases']) if not v.is_prerelease]
         latest_version = max(versions) if versions else None
     return {'current_version': unicode(current_version),
             'latest_version': unicode(latest_version) if latest_version else None,
             'outdated': (current_version < latest_version) if latest_version else False}
 def _entries(self):
     if self.session_block:
         # if we have a session block we reschedule the entries inside that block
         for entry in self.session_block.timetable_entry.children:
             # the block should only have entries on the same day
             if entry.start_dt.astimezone(
                     self.event.tzinfo).date() != self.day:
                 raise NoReportError.wrap_exc(
                     BadRequest(
                         _('This action cannot be completed because the event dates'
                           ' have changed. Please reload the page and try again.'
                           )))
             yield entry
     elif self.session:
         # if we have a session we reschedule the blocks of that session on the day
         for block in self.session.blocks:
             if not block.timetable_entry:
                 continue
             if block.timetable_entry.start_dt.astimezone(
                     self.event.tzinfo).date() == self.day:
                 yield block.timetable_entry
     else:
         # if we are on the top level we reschedule all top-level entries on the day
         query = (self.event.timetable_entries.filter(
             TimetableEntry.parent_id.is_(None),
             db.cast(TimetableEntry.start_dt.astimezone(self.event.tzinfo),
                     db.Date) == self.day))
         for entry in query:
             yield entry
Esempio n. 6
0
 def _check_access(self):
     cfa = self.event.cfa
     if session.user and not cfa.is_open and not cfa.can_submit_abstracts(session.user):
         raise NoReportError.wrap_exc(Forbidden(_('The Call for Abstracts is closed. '
                                                  'Please contact the event organizer for further assistance.')))
     elif not session.user or not cfa.can_submit_abstracts(session.user):
         raise Forbidden
     RHAbstractsBase._check_access(self)
Esempio n. 7
0
def check_event_locked(rh, event, force=False):
    if (not getattr(rh, 'ALLOW_LOCKED', False)
            or force) and event.is_locked and request.method not in ('GET',
                                                                     'HEAD'):
        raise NoReportError.wrap_exc(
            Forbidden(
                _('This event has been locked so no modifications are possible.'
                  )))
Esempio n. 8
0
 def _check_access(self):
     cfa = self.event.cfa
     if session.user and not cfa.is_open and not cfa.can_submit_abstracts(session.user):
         raise NoReportError.wrap_exc(Forbidden(_('The Call for Abstracts is closed. '
                                                  'Please contact the event organizer for further assistance.')))
     elif not session.user or not cfa.can_submit_abstracts(session.user):
         raise Forbidden
     RHAbstractsBase._check_access(self)
Esempio n. 9
0
 def _checkParams(self, params):
     RHConferenceModifBase._checkParams(self, params)
     self.event = self._conf
     try:
         self.event_id = int(self.event.getId())
     except ValueError:
         raise NoReportError(
             _('Room booking tools are not available for legacy events.'))
Esempio n. 10
0
 def _process_args(self):
     RHRoomBookingEventBase._process_args(self)
     RHRoomBookingNewBooking._process_args(self)
     assign = request.args.get('assign')
     if not assign or assign == 'nothing':
         self._assign_to = None
     elif assign == 'event':
         self._assign_to = self.event
     else:
         element, _, element_id = assign.partition('-')
         if element == 'session':
             self._assign_to = self.event.get_session(element_id)
         elif element == 'contribution':
             self._assign_to = self.event.get_contribution(element_id)
         else:
             raise NoReportError('Invalid assignment')
         if not self._assign_to:
             raise NoReportError('Invalid assignment')
Esempio n. 11
0
    def create_from_data(cls, room, data, user, prebook=None):
        """Creates a new reservation.

        :param room: The Room that's being booked.
        :param data: A dict containing the booking data, usually from a :class:`NewBookingConfirmForm` instance
        :param user: The :class:`Avatar` who creates the booking.
        :param prebook: Instead of determining the booking type from the user's
                        permissions, always use the given mode.
        """

        populate_fields = ('start_dt', 'end_dt', 'repeat_frequency',
                           'repeat_interval', 'room_id', 'booked_for_id',
                           'contact_email', 'contact_phone', 'booking_reason',
                           'used_equipment', 'needs_assistance', 'uses_vc',
                           'needs_vc_assistance')

        if data['repeat_frequency'] == RepeatFrequency.NEVER and data[
                'start_dt'].date() != data['end_dt'].date():
            raise ValueError('end_dt != start_dt for non-repeating booking')

        if prebook is None:
            prebook = not room.can_be_booked(user)
            if prebook and not room.can_be_prebooked(user):
                raise NoReportError('You cannot book this room')

        room.check_advance_days(data['end_dt'].date(), user)
        room.check_bookable_hours(data['start_dt'].time(),
                                  data['end_dt'].time(), user)

        reservation = cls()
        for field in populate_fields:
            if field in data:
                setattr(reservation, field, data[field])
        reservation.room = room
        reservation.booked_for_name = reservation.booked_for_user.getFullName()
        reservation.is_accepted = not prebook
        reservation.created_by_user = user
        reservation.create_occurrences(True)
        if not any(occ.is_valid for occ in reservation.occurrences):
            raise NoReportError(_('Reservation has no valid occurrences'))
        notify_creation(reservation)
        return reservation
Esempio n. 12
0
 def _process(self):
     if not self.registrations:
         raise NoReportError.wrap_exc(BadRequest(_("The selected registrants have been removed.")))
     registration = self.registrations[0]
     email_body = replace_placeholders('registration-email', request.form['body'], regform=self.regform,
                                       registration=registration)
     tpl = get_template_module('events/registration/emails/custom_email.html', email_subject=request.form['subject'],
                               email_body=email_body)
     html = render_template('events/registration/management/email_preview.html', subject=tpl.get_subject(),
                            body=tpl.get_body())
     return jsonify(html=html)
Esempio n. 13
0
 def _process(self):
     pdf = RegistrantsListToPDF(self.event, reglist=self.registrations, display=self.export_config['regform_items'],
                                static_items=self.export_config['static_item_ids'])
     try:
         data = pdf.getPDFBin()
     except Exception:
         if config.DEBUG:
             raise
         raise NoReportError(_("Text too large to generate a PDF with table style. "
                               "Please try again generating with book style."))
     return send_file('RegistrantsList.pdf', BytesIO(data), 'application/pdf')
Esempio n. 14
0
 def _check_access(self):
     cfa = self.event.cfa
     if session.user and not cfa.is_open and not cfa.can_submit_abstracts(
             session.user):
         raise NoReportError(_(
             'The Call for Abstracts is closed. Please contact the event organizer for further '
             'assistance.'),
                             http_status_code=403)
     elif not session.user or not cfa.can_submit_abstracts(session.user):
         raise Forbidden
     RHAbstractsBase._check_access(self)
Esempio n. 15
0
 def get_conflicting_occurrences(self):
     valid_occurrences = self.occurrences.filter(ReservationOccurrence.is_valid).all()
     if not valid_occurrences:
         raise NoReportError(_('Reservation has no valid occurrences'))
     colliding_occurrences = ReservationOccurrence.find_overlapping_with(self.room, valid_occurrences, self.id).all()
     conflicts = defaultdict(lambda: dict(confirmed=[], pending=[]))
     for occurrence in valid_occurrences:
         for colliding in colliding_occurrences:
             if occurrence.overlaps(colliding):
                 key = 'confirmed' if colliding.reservation.is_accepted else 'pending'
                 conflicts[occurrence][key].append(colliding)
     return conflicts
Esempio n. 16
0
 def check_advance_days(self, end_date, user=None, quiet=False):
     if not self.max_advance_days:
         return True
     if user and (rb_is_admin(user) or self.is_owned_by(user)):
         return True
     advance_days = (end_date - date.today()).days
     ok = advance_days < self.max_advance_days
     if quiet or ok:
         return ok
     else:
         msg = _(u'You cannot book this room more than {} days in advance')
         raise NoReportError(msg.format(self.max_advance_days))
Esempio n. 17
0
 def check_bookable_hours(self, start_time, end_time, user=None, quiet=False):
     if user and (rb_is_admin(user) or self.is_owned_by(user)):
         return True
     bookable_hours = self.bookable_hours.all()
     if not bookable_hours:
         return True
     for bt in bookable_hours:
         if bt.fits_period(start_time, end_time):
             return True
     if quiet:
         return False
     raise NoReportError(u'Room cannot be booked at this time')
Esempio n. 18
0
 def _process(self):
     if not self.registrations:
         raise NoReportError.wrap_exc(BadRequest(_("The selected registrants have been removed.")))
     registration = self.registrations[0]
     email_body = replace_placeholders('registration-email', request.form['body'], regform=self.regform,
                                       registration=registration)
     email_subject = replace_placeholders('registration-email', request.form['subject'], regform=self.regform,
                                          registration=registration)
     tpl = get_template_module('events/registration/emails/custom_email.html', email_subject=email_subject,
                               email_body=email_body)
     html = render_template('events/registration/management/email_preview.html', subject=tpl.get_subject(),
                            body=tpl.get_body())
     return jsonify(html=html)
Esempio n. 19
0
 def _sanitize(params, level, doNotSanitize=frozenset()):
     for i in params:
         if i in doNotSanitize:
             continue
         if isinstance(params, dict):
             param = params[i]
         else:
             param = i
         if isinstance(param, str):
             res = restrictedHTML(param, level)
             if res is not None:
                 raise NoReportError(res)
         elif isinstance(param, list) or isinstance(param, dict):
             Sanitization._sanitize(param, level)
Esempio n. 20
0
 def _checkParams(self, params):
     RHAgreementManagerDetails._checkParams(self, params)
     if 'id' in request.view_args:
         self.agreement = Agreement.find_one(id=request.view_args['id'])
         if self._conf != self.agreement.event:
             raise NotFound
         if not self.agreement.pending:
             raise NoReportError(_("The agreement is already signed"))
     else:
         self.agreement = None
         identifier = request.args['identifier']
         try:
             self.person = self.definition.get_people(self._conf)[identifier]
         except KeyError:
             raise NotFound
Esempio n. 21
0
 def _process_args(self):
     RHAgreementManagerDetails._process_args(self)
     if 'id' in request.view_args:
         self.agreement = Agreement.get_one(request.view_args['id'])
         if self.event != self.agreement.event:
             raise NotFound
         if not self.agreement.pending:
             raise NoReportError(_("The agreement is already signed"))
     else:
         self.agreement = None
         identifier = request.args['identifier']
         try:
             self.person = self.definition.get_people(self.event)[identifier]
         except KeyError:
             raise NotFound
Esempio n. 22
0
 def _process(self):
     if self.registration.has_conflict():
         raise NoReportError(_('Cannot reset this registration since there is another valid registration for the '
                               'same user or email.'))
     if self.registration.state in (RegistrationState.complete, RegistrationState.unpaid):
         self.registration.update_state(approved=False)
     elif self.registration.state == RegistrationState.rejected:
         self.registration.rejection_reason = ''
         self.registration.update_state(rejected=False)
     elif self.registration.state == RegistrationState.withdrawn:
         self.registration.update_state(withdrawn=False)
         notify_registration_state_update(self.registration)
     else:
         raise BadRequest(_('The registration cannot be reset in its current state.'))
     self.registration.checked_in = False
     logger.info('Registration %r was reset by %r', self.registration, session.user)
     return jsonify_data(html=_render_registration_details(self.registration))
Esempio n. 23
0
    def _process(self):
        from_preview = request.args.get('from_preview') == '1'
        force_download = request.args.get('download') == '1'

        signals.attachments.attachment_accessed.send(self.attachment, user=session.user, from_preview=from_preview)
        if request.values.get('preview') == '1':
            if self.attachment.type != AttachmentType.file:
                raise BadRequest
            previewer = get_file_previewer(self.attachment.file)
            if not previewer:
                raise NoReportError.wrap_exc(BadRequest(_('There is no preview available for this file type. '
                                                          'Please refresh the page.')))
            preview_content = previewer.generate_content(self.attachment)
            return jsonify_template('attachments/preview.html', attachment=self.attachment,
                                    preview_content=preview_content)
        else:
            if self.attachment.type == AttachmentType.link:
                return redirect(self.attachment.link_url)
            else:
                return self.attachment.file.send(inline=not force_download)
Esempio n. 24
0
    def _redirect_if_insecure():
        if not request.endpoint:
            return

        if (
            request.blueprint == 'assets' or
            request.endpoint.endswith('.static') or
            request.endpoint in ('auth.logout', 'auth.accounts', 'core.contact', 'core.change_lang')
        ):
            return

        if 'insecure_password_error' not in session:
            return

        if request.method != 'GET':
            raise NoReportError.wrap_exc(Forbidden(_('You need to change your password')))

        if request.is_xhr or request.is_json:
            return

        return redirect(url_for('auth.accounts'))
Esempio n. 25
0
 def _entries(self):
     if self.session_block:
         # if we have a session block we reschedule the entries inside that block
         for entry in self.session_block.timetable_entry.children:
             # the block should only have entries on the same day
             if entry.start_dt.astimezone(self.event.tzinfo).date() != self.day:
                 raise NoReportError.wrap_exc(BadRequest(_('This action cannot be completed because the event dates'
                                                           ' have changed. Please reload the page and try again.')))
             yield entry
     elif self.session:
         # if we have a session we reschedule the blocks of that session on the day
         for block in self.session.blocks:
             if not block.timetable_entry:
                 continue
             if block.timetable_entry.start_dt.astimezone(self.event.tzinfo).date() == self.day:
                 yield block.timetable_entry
     else:
         # if we are on the top level we reschedule all top-level entries on the day
         query = (self.event.timetable_entries
                  .filter(TimetableEntry.parent_id.is_(None),
                          db.cast(TimetableEntry.start_dt.astimezone(self.event.tzinfo), db.Date) == self.day))
         for entry in query:
             yield entry
Esempio n. 26
0
    def modify(self, data, user):
        """Modifies an existing reservation.

        :param data: A dict containing the booking data, usually from a :class:`ModifyBookingForm` instance
        :param user: The :class:`.User` who modifies the booking.
        """

        populate_fields = ('start_dt', 'end_dt', 'repeat_frequency', 'repeat_interval', 'booked_for_user',
                           'booking_reason')
        # fields affecting occurrences
        occurrence_fields = {'start_dt', 'end_dt', 'repeat_frequency', 'repeat_interval'}
        # fields where date and time are compared separately
        date_time_fields = {'start_dt', 'end_dt'}
        # fields for the repetition
        repetition_fields = {'repeat_frequency', 'repeat_interval'}
        # pretty names for logging
        field_names = {
            'start_dt/date': u"start date",
            'end_dt/date': u"end date",
            'start_dt/time': u"start time",
            'end_dt/time': u"end time",
            'repetition': u"booking type",
            'booked_for_user': u"'Booked for' user",
            'booking_reason': u"booking reason",
        }

        self.room.check_advance_days(data['end_dt'].date(), user)
        self.room.check_bookable_hours(data['start_dt'].time(), data['end_dt'].time(), user)

        changes = {}
        update_occurrences = False
        old_repetition = self.repetition

        for field in populate_fields:
            if field not in data:
                continue
            old = getattr(self, field)
            new = data[field]
            converter = unicode
            if old != new:
                # Booked for user updates the (redundant) name
                if field == 'booked_for_user':
                    old = self.booked_for_name
                    new = self.booked_for_name = data[field].full_name
                # Apply the change
                setattr(self, field, data[field])
                # If any occurrence-related field changed we need to recreate the occurrences
                if field in occurrence_fields:
                    update_occurrences = True
                # Record change for history entry
                if field in date_time_fields:
                    # The date/time fields create separate entries for the date and time parts
                    if old.date() != new.date():
                        changes[field + '/date'] = {'old': old.date(), 'new': new.date(), 'converter': format_date}
                    if old.time() != new.time():
                        changes[field + '/time'] = {'old': old.time(), 'new': new.time(), 'converter': format_time}
                elif field in repetition_fields:
                    # Repetition needs special handling since it consists of two fields but they are tied together
                    # We simply update it whenever we encounter such a change; after the last change we end up with
                    # the correct change data
                    changes['repetition'] = {'old': old_repetition,
                                             'new': self.repetition,
                                             'converter': lambda x: RepeatMapping.get_message(*x)}
                else:
                    changes[field] = {'old': old, 'new': new, 'converter': converter}

        if not changes:
            return False

        # Create a verbose log entry for the modification
        log = [u'Booking modified']
        for field, change in changes.iteritems():
            field_title = field_names.get(field, field)
            converter = change['converter']
            old = to_unicode(converter(change['old']))
            new = to_unicode(converter(change['new']))
            if not old:
                log.append(u"The {} was set to '{}'".format(field_title, new))
            elif not new:
                log.append(u"The {} was cleared".format(field_title))
            else:
                log.append(u"The {} was changed from '{}' to '{}'".format(field_title, old, new))

        self.edit_logs.append(ReservationEditLog(user_name=user.full_name, info=log))

        # Recreate all occurrences if necessary
        if update_occurrences:
            cols = [col.name for col in ReservationOccurrence.__table__.columns
                    if not col.primary_key and col.name not in {'start_dt', 'end_dt'}]

            old_occurrences = {occ.date: occ for occ in self.occurrences}
            self.occurrences.delete(synchronize_session='fetch')
            self.create_occurrences(True, user)
            db.session.flush()
            # Restore rejection data etc. for recreated occurrences
            for occurrence in self.occurrences:
                old_occurrence = old_occurrences.get(occurrence.date)
                # Copy data from old occurrence UNLESS the new one is invalid (e.g. because of collisions)
                # Otherwise we'd end up with valid occurrences ignoring collisions!
                if old_occurrence and occurrence.is_valid:
                    for col in cols:
                        setattr(occurrence, col, getattr(old_occurrence, col))
            # Don't cause new notifications for the entire booking in case of daily repetition
            if self.repeat_frequency == RepeatFrequency.DAY and all(occ.notification_sent
                                                                    for occ in old_occurrences.itervalues()):
                for occurrence in self.occurrences:
                    occurrence.notification_sent = True

        # Sanity check so we don't end up with an "empty" booking
        if not any(occ.is_valid for occ in self.occurrences):
            raise NoReportError(_(u'Reservation has no valid occurrences'))

        notify_modification(self, changes)
        return True
Esempio n. 27
0
def test11():
    from indico.core.errors import NoReportError
    raise NoReportError('we do not care about your error')
Esempio n. 28
0
def check_event_locked(rh, event, force=False):
    if (not getattr(rh, 'ALLOW_LOCKED', False) or force) and event.is_locked and request.method not in ('GET', 'HEAD'):
        raise NoReportError.wrap_exc(Forbidden(_('This event has been locked so no modifications are possible.')))
Esempio n. 29
0
 def _checkParams(self):
     resv_id = request.view_args['resvID']
     self._reservation = Reservation.get(resv_id)
     if not self._reservation:
         raise NoReportError('No booking with id: {}'.format(resv_id))
Esempio n. 30
0
 def _process_args(self):
     self._location = Location.get(int(request.form['location_id']))
     if not self._location:
         raise NoReportError(u'No such location')
Esempio n. 31
0
 def _checkParams(self, params):
     RHAgreementManagerDetailsAgreementBase._checkParams(self, params)
     if self.agreement.state != AgreementState.accepted_on_behalf:
         raise NoReportError("The agreement was not accepted manually by an admin")
Esempio n. 32
0
 def _checkParams(self):
     self._location = Location.get(int(request.form['location_id']))
     if not self._location:
         raise NoReportError(u'No such location')
Esempio n. 33
0
 def _process_args(self):
     RHAgreementManagerDetailsAgreementBase._process_args(self)
     if self.agreement.state != AgreementState.accepted_on_behalf:
         raise NoReportError("The agreement was not accepted manually by an admin")