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)
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 )
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)
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)
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)
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)
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", )
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 )