示例#1
0
    def before_update_object(self, speaker, data, view_kwargs):
        """
        method to save image urls before updating speaker object
        :param speaker:
        :param data:
        :param view_kwargs:
        :return:
        """
        if not can_edit_after_cfs_ends(speaker.event_id):
            raise ForbiddenError(
                {'source': ''},
                "Cannot edit speaker after the call for speaker is ended")

        if data.get('photo_url') and data['photo_url'] != speaker.photo_url:
            start_image_resizing_tasks(speaker, data['photo_url'])

        if data.get('is_email_overridden') and not has_access(
                'is_organizer', event_id=speaker.event_id):
            raise ForbiddenError(
                {'pointer': 'data/attributes/is_email_overridden'},
                'Organizer access required to override email',
            )
        if (data.get('is_email_overridden')
                and has_access('is_organizer', event_id=speaker.event_id)
                and not data.get('email')):
            data['email'] = current_user.email

        data[
            'complex_field_values'] = validate_custom_form_constraints_request(
                'speaker', self.resource.schema, speaker, data)
示例#2
0
    def before_update_object(self, session, data, view_kwargs):
        """
        before update method to verify if session is locked before updating session object
        :param event:
        :param data:
        :param view_kwargs:
        :return:
        """
        is_organizer = has_access('is_admin') or has_access(
            'is_organizer', event_id=session.event_id
        )
        if session.is_locked and not is_organizer:
            raise ForbiddenError(
                {'pointer': '/data/attributes/is-locked'},
                "Locked sessions cannot be edited",
            )

        new_state = data.get('state')

        if (
            new_state
            and new_state != session.state
            and (
                is_organizer
                or (session.ends_at and session.ends_at > datetime.now(pytz.utc))
            )
        ):
            # State change detected. Verify that state change is allowed
            g.send_email = new_state in [
                'accepted',
                'rejected',
                'confirmed',
                'rejected',
                'canceled',
                'withdrawn',
            ]
            key = 'speaker'
            if is_organizer:
                key = 'organizer'
            state_dict = SESSION_STATE_DICT[key]
            try:
                state_dict[session.state][new_state]
            except KeyError:
                raise ForbiddenError(
                    {'pointer': '/data/attributes/state'},
                    f'You cannot change a session state from "{session.state}" to "{new_state}"',
                )

        # We allow organizers and admins to edit session without validations
        complex_field_values = data.get('complex_field_values', 'absent')
        # Set default to 'absent' to differentiate between None and not sent
        is_absent = complex_field_values == 'absent'
        # True if values are not sent in data JSON
        is_same = data.get('complex_field_values') == session.complex_field_values
        # Using original value to ensure None instead of absent
        # We stop checking validations for organizers only if they may result in data change or absent. See test_session_forms_api.py for more info
        if not (is_organizer and (is_absent or is_same)):
            data['complex_field_values'] = validate_custom_form_constraints_request(
                'session', self.resource.schema, session, data
            )
示例#3
0
    def before_update_object(self, speaker, data, view_kwargs):
        """
        method to save image urls before updating speaker object
        :param speaker:
        :param data:
        :param view_kwargs:
        :return:
        """
        if not can_edit_after_cfs_ends(speaker.event_id):
            raise ForbiddenError(
                {'source': ''},
                "Cannot edit speaker after the call for speaker is ended")

        if data.get('photo_url') and data['photo_url'] != speaker.photo_url:
            start_image_resizing_tasks(speaker, data['photo_url'])

        check_email_override(data, speaker.event_id)

        excluded = []
        if not data.get('email'):
            # Don't check requirement of email if overriden
            excluded = ['email']
        data[
            'complex_field_values'] = validate_custom_form_constraints_request(
                'speaker', self.resource.schema, speaker, data, excluded)
示例#4
0
    def before_post(self, args, kwargs, data=None):
        """
        method to add user_id to view_kwargs before post
        :param args:
        :param kwargs:
        :param data:
        :return:
        """
        data['user'] = current_user.id
        require_relationship(['event', 'user'], data)

        if not has_access('is_coorganizer', event_id=data['event']):
            event = db.session.query(Event).filter_by(id=data['event']).one()
            if event.state == "draft":
                raise ObjectNotFound(
                    {'parameter': 'event_id'},
                    "Event: {} not found".format(data['event']),
                )

        if (get_count(
                db.session.query(Event).filter_by(
                    id=int(data['event']), is_sessions_speakers_enabled=False))
                > 0):
            raise ForbiddenError({'pointer': ''},
                                 "Speakers are disabled for this Event")

        if (not data.get('is_email_overridden') and get_count(
                db.session.query(Speaker).filter_by(event_id=int(
                    data['event']),
                                                    email=data['email'],
                                                    deleted_at=None)) > 0):
            raise ForbiddenError({'pointer': ''},
                                 'Speaker with this Email ID already exists')

        if data.get('is_email_overridden') and not has_access(
                'is_organizer', event_id=data['event']):
            raise ForbiddenError(
                {'pointer': 'data/attributes/is_email_overridden'},
                'Organizer access required to override email',
            )
        if (data.get('is_email_overridden')
                and has_access('is_organizer', event_id=data['event'])
                and not data.get('email')):
            data['email'] = current_user.email

        if 'sessions' in data:
            session_ids = data['sessions']
            for session_id in session_ids:
                if not has_access('is_session_self_submitted',
                                  session_id=session_id):
                    raise ObjectNotFound(
                        {'parameter': 'session_id'},
                        f"Session: {session_id} not found",
                    )

        data[
            'complex_field_values'] = validate_custom_form_constraints_request(
                'speaker', self.schema, Speaker(event_id=data['event']), data)
示例#5
0
    def before_post(self, args, kwargs, data):
        """
        before post method to check for required relationship and proper permission
        :param args:
        :param kwargs:
        :param data:
        :return:
        """
        require_relationship(['event', 'track'], data)
        data['creator_id'] = current_user.id
        if (get_count(
                db.session.query(Event).filter_by(
                    id=int(data['event']), is_sessions_speakers_enabled=False))
                > 0):
            raise ForbiddenError({'pointer': ''},
                                 "Sessions are disabled for this Event")

        data[
            'complex_field_values'] = validate_custom_form_constraints_request(
                'session', self.schema, Session(event_id=data['event']), data)
示例#6
0
    def before_update_object(self, speaker, data, view_kwargs):
        """
        method to save image urls before updating speaker object
        :param speaker:
        :param data:
        :param view_kwargs:
        :return:
        """
        if data.get('photo_url') and data['photo_url'] != speaker.photo_url:
            start_image_resizing_tasks(speaker, data['photo_url'])

        check_email_override(data, speaker.event_id, speaker)

        excluded = []
        if not data.get('email'):
            # Don't check requirement of email if overriden
            excluded = ['email']
        data[
            'complex_field_values'] = validate_custom_form_constraints_request(
                'speaker', self.resource.schema, speaker, data, excluded)
示例#7
0
    def before_update_object(self, order, data, view_kwargs):
        """
        before update object method of order details
        1. admin can update all the fields.
        2. event organizer
            a. own orders: he/she can update selected fields.
            b. other's orders: can only update the status that too when the order mode is free. No refund system.
        3. order user can update selected fields of his/her order when the status is initializing.
        The selected fields mentioned above can be taken from get_updatable_fields method from order model.
        :param order:
        :param data:
        :param view_kwargs:
        :return:
        """
        if data.get('status') in ['pending', 'placed', 'completed']:
            attendees = order.ticket_holders
            for attendee in attendees:
                validate_custom_form_constraints_request(
                    'attendee', AttendeeSchema, attendee, {})

        if data.get('amount') and (data.get('is_billing_enabled')
                                   or order.event.is_billing_info_mandatory):
            check_billing_info(data)
        if (not has_access('is_coorganizer', event_id=order.event_id)) and (
                not current_user.id == order.user_id):
            raise ForbiddenError({'pointer': ''}, "Access Forbidden")

        relationships = ['event', 'ticket_holders', 'user']
        if has_access('is_coorganizer_but_not_admin', event_id=order.event_id):
            if current_user.id == order.user_id:
                # Order created from the tickets tab.
                for element in data:
                    if data[element]:
                        if (element not in relationships and
                                data[element] != getattr(order, element, None)
                                and element not in get_updatable_fields()):
                            raise ForbiddenError(
                                {'pointer': f'data/{element}'},
                                f"You cannot update {element} of an order",
                            )
                        check_event_user_ticket_holders(order, data, element)

            else:
                # Order created from the public pages.
                for element in data:
                    if data[element]:
                        if element not in relationships and data[
                                element] != getattr(order, element, None):
                            if element != 'status' and element != 'deleted_at':
                                raise ForbiddenError(
                                    {'pointer': f'data/{element}'},
                                    f"You cannot update {element} of an order",
                                )
                            if (element == 'status' and order.amount
                                    and order.status == 'completed'):
                                # Since we don't have a refund system.
                                raise ForbiddenError(
                                    {'pointer': 'data/status'},
                                    "You cannot update the status of a completed paid order",
                                )
                            if element == 'status' and order.status == 'cancelled':
                                # Since the tickets have been unlocked and we can't revert it.
                                raise ForbiddenError(
                                    {'pointer': 'data/status'},
                                    "You cannot update the status of a cancelled order",
                                )
                        else:
                            check_event_user_ticket_holders(
                                order, data, element)

        elif current_user.id == order.user_id:
            if order.status != 'initializing' and order.status != 'pending':
                raise ForbiddenError(
                    {'pointer': ''},
                    "You cannot update a non-initialized or non-pending order",
                )
            for element in data:
                if data[element]:
                    if (element == 'is_billing_enabled'
                            and order.status == 'completed' and
                            data[element] != getattr(order, element, None)):
                        raise ForbiddenError(
                            {'pointer': f'data/{element}'},
                            "You cannot update {} of a completed order".format(
                                element),
                        )
                    if (element not in relationships
                            and data[element] != getattr(order, element, None)
                            and element not in get_updatable_fields()):
                        raise ForbiddenError(
                            {'pointer': f'data/{element}'},
                            f"You cannot update {element} of an order",
                        )
                    check_event_user_ticket_holders(order, data, element)

        if has_access('is_organizer',
                      event_id=order.event_id) and 'order_notes' in data:
            if order.order_notes and data[
                    'order_notes'] not in order.order_notes.split(","):
                data['order_notes'] = '{},{}'.format(order.order_notes,
                                                     data['order_notes'])

        if data.get('payment_mode') == 'free' and data.get('amount') > 0:
            raise UnprocessableEntityError(
                {'pointer': '/data/attributes/payment-mode'},
                "payment-mode cannot be free for order with amount > 0",
            )
        if (data.get('status') == 'completed'
                and data.get('payment_mode') == 'stripe'
                and not is_payment_valid(order, 'stripe')):
            raise UnprocessableEntityError(
                {'pointer': '/data/attributes/payment-mode'},
                "insufficient data to verify stripe payment",
            )
        if (data.get('status') == 'completed'
                and data.get('payment_mode') == 'paypal'
                and not is_payment_valid(order, 'paypal')):
            raise UnprocessableEntityError(
                {'pointer': '/data/attributes/payment-mode'},
                "insufficient data to verify paypal payment",
            )
示例#8
0
    def before_update_object(self, obj, data, kwargs):
        """
        before update object method for attendee detail
        :param obj:
        :param data:
        :param kwargs:
        :return:
        """
        order = safe_query_by_id(Order, obj.order_id)

        if not (current_user.is_staff or current_user.id == order.user_id):
            raise ForbiddenError(
                'Only admin or that user itself can update attendee info',
            )

        if order.status != 'initializing' and (
            'checkin_times' not in data
        ):
            raise UnprocessableEntityError(
                {'pointer': '/data/id'},
                "Attendee can't be updated because the corresponding order is not in initializing state",
            )

        if 'device_name_checkin' in data:
            if 'checkin_times' not in data or data['checkin_times'] is None:
                raise UnprocessableEntityError(
                    {'pointer': '/data/attributes/device_name_checkin'},
                    "Check in Times missing",
                )

        if 'is_checked_in' in data and data['is_checked_in']:
            if 'checkin_times' not in data or data['checkin_times'] is None:
                raise UnprocessableEntityError(
                    {'pointer': '/data/attributes/checkin_times'},
                    "Check in time missing while trying to check in attendee",
                )
            if obj.checkin_times and data['checkin_times'] not in obj.checkin_times.split(
                ","
            ):
                data['checkin_times'] = '{},{}'.format(
                    obj.checkin_times, data['checkin_times']
                )

            if 'device_name_checkin' in data and data['device_name_checkin'] is not None:
                if obj.device_name_checkin is not None:
                    data['device_name_checkin'] = '{},{}'.format(
                        obj.device_name_checkin, data['device_name_checkin']
                    )

                if len(data['checkin_times'].split(",")) != len(
                    data['device_name_checkin'].split(",")
                ):
                    raise UnprocessableEntityError(
                        {'pointer': '/data/attributes/device_name_checkin'},
                        "Check in Time missing for the corresponding device name",
                    )
            else:
                if obj.device_name_checkin is not None:
                    data['device_name_checkin'] = '{},{}'.format(
                        obj.device_name_checkin, '-'
                    )
                else:
                    data['device_name_checkin'] = '-'

        if 'is_checked_out' in data and data['is_checked_out']:
            attendee = safe_query(TicketHolder, 'id', kwargs['id'], 'attendee_id')
            if not attendee.is_checked_out:
                checkout_times = (
                    obj.checkout_times.split(',') if obj.checkout_times else []
                )
                checkout_times.append(str(datetime.datetime.utcnow()))
                data['checkout_times'] = ','.join(checkout_times)

        if 'attendee_notes' in data:
            if obj.attendee_notes and data[
                'attendee_notes'
            ] not in obj.attendee_notes.split(","):
                data['attendee_notes'] = '{},{}'.format(
                    obj.attendee_notes, data['attendee_notes']
                )

        data['complex_field_values'] = (
            validate_custom_form_constraints_request(
                'attendee', self.resource.schema, obj, data
            )
            if obj.event.is_ticket_form_enabled
            else None
        )