def register_group_member(self, session, group_id, message='', **params):
        # Safe to ignore csrf tokens here, because an attacker would need to know the group id a priori
        group = session.group(group_id, ignore_csrf=True)
        attendee = session.attendee(params, restricted=True, ignore_csrf=True)
        must_be_staffing = False
        
        if group.unassigned[0].staffing:
            must_be_staffing = True
            attendee.staffing = True
            params['staffing'] = True

        message = check_pii_consent(params, attendee) or message
        if not message and 'first_name' in params:
            message = check(attendee, prereg=True)
            if not message and not params['first_name']:
                message = 'First and Last Name are required fields'
            if not message:
                if not group.unassigned:
                    raise HTTPRedirect(
                        'register_group_member?group_id={}&message={}',
                        group_id,
                        'No more unassigned badges exist in this group')

                attrs_to_preserve_from_unassigned_group_member = [
                    'id',
                    'group_id',
                    'badge_type',
                    'badge_num',
                    'base_badge_price',
                    'ribbon',
                    'paid',
                    'overridden_price',
                    'requested_hotel_info']

                attendee = group.unassigned[0]
                for attr in attrs_to_preserve_from_unassigned_group_member:
                    if attr in params:
                        del params[attr]

                attendee.apply(params, restricted=True)

                # Free group badges are considered registered' when they are actually claimed.
                if group.cost == 0:
                    attendee.registered = localized_now()

                if attendee.amount_unpaid:
                    raise HTTPRedirect('attendee_donation_form?id={}', attendee.id)
                else:
                    raise HTTPRedirect('badge_updated?id={}&message={}', attendee.id, 'Badge registered successfully')

        return {
            'message':  message,
            'group_id': group_id,
            'group': group,
            'attendee': attendee,
            'affiliates': session.affiliates(),
            'badge_cost': 0,
            'must_be_staffing': must_be_staffing,
        }
    def register_group_member(self, session, group_id, message='', **params):
        # Safe to ignore csrf tokens here, because an attacker would need to know the group id a priori
        group = session.group(group_id, ignore_csrf=True)
        attendee = session.attendee(params, restricted=True, ignore_csrf=True)

        message = check_pii_consent(params, attendee) or message
        if not message and 'first_name' in params:
            message = check(attendee, prereg=True)
            if not message and not params['first_name']:
                message = 'First and Last Name are required fields'
            if not message:
                if not group.unassigned:
                    raise HTTPRedirect(
                        'register_group_member?group_id={}&message={}',
                        group_id,
                        'No more unassigned badges exist in this group')

                attrs_to_preserve_from_unassigned_group_member = [
                    'id',
                    'group_id',
                    'badge_type',
                    'badge_num',
                    'base_badge_price',
                    'ribbon',
                    'paid',
                    'overridden_price',
                    'requested_hotel_info']

                attendee = group.unassigned[0]
                for attr in attrs_to_preserve_from_unassigned_group_member:
                    if attr in params:
                        del params[attr]

                attendee.apply(params, restricted=True)

                # Free group badges are considered registered' when they are actually claimed.
                if group.cost == 0:
                    attendee.registered = localized_now()

                if attendee.amount_unpaid:
                    raise HTTPRedirect('attendee_donation_form?id={}', attendee.id)
                else:
                    raise HTTPRedirect('badge_updated?id={}&message={}', attendee.id, 'Badge registered successfully')

        return {
            'message':  message,
            'group_id': group_id,
            'group': group,
            'attendee': attendee,
            'affiliates': session.affiliates(),
            'badge_cost': 0
        }
    def register(self, session, message='', error_message='', **params):
        params['id'] = 'None'
        attendee = session.attendee(params, restricted=True, ignore_csrf=True)
        error_message = check_pii_consent(params, attendee) or error_message
        if not error_message and 'first_name' in params:
            if not attendee.payment_method and (not c.BADGE_PRICE_WAIVED or
                                                c.BEFORE_BADGE_PRICE_WAIVED):
                error_message = 'Please select a payment type'
            elif attendee.payment_method == c.MANUAL and not re.match(
                    c.EMAIL_RE, attendee.email):
                error_message = 'Email address is required to pay with a credit card at our registration desk'
            elif attendee.badge_type not in [
                    badge for badge, desc in c.AT_THE_DOOR_BADGE_OPTS
            ]:
                error_message = 'No hacking allowed!'
            else:
                error_message = check(attendee)

            if not error_message and c.BADGE_PROMO_CODES_ENABLED and 'promo_code' in params:
                error_message = session.add_promo_code_to_attendee(
                    attendee, params.get('promo_code'))
            if not error_message:
                session.add(attendee)
                session.commit()
                if c.AFTER_BADGE_PRICE_WAIVED:
                    message = c.AT_DOOR_WAIVED_MSG
                    attendee.paid = c.NEED_NOT_PAY
                elif attendee.payment_method == c.STRIPE:
                    raise HTTPRedirect('pay?id={}', attendee.id)
                elif attendee.payment_method == c.CASH:
                    message = c.AT_DOOR_CASH_MSG.format('${}'.format(
                        attendee.total_cost))
                elif attendee.payment_method == c.MANUAL:
                    message = c.AT_DOOR_MANUAL_MSG
                raise HTTPRedirect(
                    'register?message={}', message or
                    "Thanks! Please proceed to the registration desk to pick up your badge."
                )

        return {
            'message': message,
            'error_message': error_message,
            'attendee': attendee,
            'promo_code': params.get('promo_code', ''),
        }
Exemple #4
0
    def register(self, session, message='', error_message='', **params):
        params['id'] = 'None'
        attendee = session.attendee(params, restricted=True, ignore_csrf=True)
        error_message = check_pii_consent(params, attendee) or error_message
        if not error_message and 'first_name' in params:
            if not attendee.payment_method and (not c.BADGE_PRICE_WAIVED or c.BEFORE_BADGE_PRICE_WAIVED):
                error_message = 'Please select a payment type'
            elif attendee.payment_method == c.MANUAL and not re.match(c.EMAIL_RE, attendee.email):
                error_message = 'Email address is required to pay with a credit card at our registration desk'
            elif attendee.badge_type not in [badge for badge, desc in c.AT_THE_DOOR_BADGE_OPTS]:
                error_message = 'No hacking allowed!'
            else:
                error_message = check(attendee)

            if not error_message and c.BADGE_PROMO_CODES_ENABLED and 'promo_code' in params:
                error_message = session.add_promo_code_to_attendee(attendee, params.get('promo_code'))
            if not error_message:
                session.add(attendee)
                session.commit()
                if c.AFTER_BADGE_PRICE_WAIVED:
                    message = c.AT_DOOR_WAIVED_MSG
                    attendee.paid = c.NEED_NOT_PAY
                elif attendee.payment_method == c.STRIPE:
                    raise HTTPRedirect('pay?id={}', attendee.id)
                elif attendee.payment_method == c.CASH:
                    message = c.AT_DOOR_CASH_MSG.format('${}'.format(attendee.total_cost))
                elif attendee.payment_method == c.MANUAL:
                    message = c.AT_DOOR_MANUAL_MSG
                raise HTTPRedirect('register?message={}', message)

        return {
            'message':  message,
            'error_message':  error_message,
            'attendee': attendee,
            'promo_code': params.get('promo_code', ''),
        }
    def form(self, session, message='', edit_id=None, **params):
        """
        Our production NGINX config caches the page at /preregistration/form.
        Since it's cached, we CAN'T return a session cookie with the page. We
        must POST to a different URL in order to bypass the cache and get a
        valid session cookie. Thus, this page is also exposed as "post_form".
        """
        params['id'] = 'None'   # security!
        group = Group()

        if edit_id is not None:
            attendee = self._get_unsaved(
                edit_id,
                if_not_found=HTTPRedirect('form?message={}', 'That preregistration has already been finalized'))
            attendee.apply(params, restricted=True)
            params.setdefault('pii_consent', True)
        else:
            attendee = session.attendee(params, ignore_csrf=True, restricted=True)

            if attendee.badge_type == c.PSEUDO_DEALER_BADGE:
                if not c.DEALER_REG_OPEN:
                    return render('static_views/dealer_reg_closed.html') if c.AFTER_DEALER_REG_START \
                        else render('static_views/dealer_reg_not_open.html')

                # Both the Attendee class and Group class have identically named
                # address fields. In order to distinguish the two sets of address
                # fields in the params, the Group fields are prefixed with "group_"
                # when the form is submitted. To prevent instantiating the Group object
                # with the Attendee's address fields, we must clone the params and
                # rename all the "group_" fields.
                group_params = dict(params)
                for field_name in ['country', 'region', 'zip_code', 'address1', 'address2', 'city']:
                    group_params[field_name] = params.get('group_{}'.format(field_name), '')
                    if params.get('copy_address'):
                        params[field_name] = group_params[field_name]
                        attendee.apply(params)

                group = session.group(group_params, ignore_csrf=True, restricted=True)

        if c.PAGE == 'post_dealer':
            attendee.badge_type = c.PSEUDO_DEALER_BADGE
        elif not attendee.badge_type:
            attendee.badge_type = c.ATTENDEE_BADGE

        if cherrypy.request.method == 'POST' or edit_id is not None:
            message = check_pii_consent(params, attendee) or message
            if not message and attendee.badge_type not in c.PREREG_BADGE_TYPES:
                message = 'Invalid badge type!'
            if not message and c.BADGE_PROMO_CODES_ENABLED and params.get('promo_code'):
                if session.lookup_promo_or_group_code(params.get('promo_code'), PromoCodeGroup):
                    Charge.universal_promo_codes[attendee.id] = params.get('promo_code')
                message = session.add_promo_code_to_attendee(attendee, params.get('promo_code'))

        if message:
            return {
                'message':    message,
                'attendee':   attendee,
                'group':      group,
                'edit_id':    edit_id,
                'affiliates': session.affiliates(),
                'cart_not_empty': Charge.unpaid_preregs,
                'copy_address': params.get('copy_address'),
                'promo_code_code': params.get('promo_code', ''),
                'pii_consent': params.get('pii_consent'),
                'name': params.get('name', ''),
                'badges': params.get('badges', 0),
            }

        if 'first_name' in params:
            if attendee.badge_type == c.PSEUDO_DEALER_BADGE:
                message = check(group, prereg=True)

            message = message or check(attendee, prereg=True)

            if attendee.badge_type in [c.PSEUDO_GROUP_BADGE, c.PSEUDO_DEALER_BADGE]:
                message = "Please enter a group name" if not params.get('name') else message
            else:
                params['badges'] = 0
                params['name'] = ''

            if not message:
                if attendee.badge_type == c.PSEUDO_DEALER_BADGE:
                    attendee.paid = c.PAID_BY_GROUP
                    group.attendees = [attendee]
                    session.assign_badges(group, params['badges'])
                    group.status = c.WAITLISTED if c.DEALER_REG_SOFT_CLOSED else c.UNAPPROVED
                    attendee.ribbon = add_opt(attendee.ribbon_ints, c.DEALER_RIBBON)
                    attendee.badge_type = c.ATTENDEE_BADGE

                    session.add_all([attendee, group])
                    session.commit()
                    try:
                        send_email.delay(
                            c.MARKETPLACE_EMAIL,
                            c.MARKETPLACE_EMAIL,
                            '{} Received'.format(c.DEALER_APP_TERM.title()),
                            render('emails/dealers/reg_notification.txt', {'group': group}, encoding=None),
                            model=group.to_dict('id'))
                        send_email.delay(
                            c.MARKETPLACE_EMAIL,
                            attendee.email,
                            '{} Received'.format(c.DEALER_APP_TERM.title()),
                            render('emails/dealers/application.html', {'group': group}, encoding=None),
                            'html',
                            model=group.to_dict('id'))
                    except Exception:
                        log.error('unable to send marketplace application confirmation email', exc_info=True)
                    raise HTTPRedirect('dealer_confirmation?id={}', group.id)
                else:
                    track_type = c.UNPAID_PREREG
                    if attendee.id in Charge.unpaid_preregs:
                        track_type = c.EDITED_PREREG
                        # Clear out any previously cached targets, in case the unpaid badge
                        # has been edited and changed from a single to a group or vice versa.
                        del Charge.unpaid_preregs[attendee.id]

                    Charge.unpaid_preregs[attendee.id] = Charge.to_sessionized(attendee,
                                                                               params.get('name'),
                                                                               params.get('badges'))
                    Tracking.track(track_type, attendee)

                if session.attendees_with_badges().filter_by(
                        first_name=attendee.first_name, last_name=attendee.last_name, email=attendee.email).count():

                    raise HTTPRedirect('duplicate?id={}', group.id if attendee.paid == c.PAID_BY_GROUP else attendee.id)

                if attendee.banned:
                    raise HTTPRedirect('banned?id={}', group.id if attendee.paid == c.PAID_BY_GROUP else attendee.id)

                if c.PREREG_REQUEST_HOTEL_INFO_OPEN:
                    hotel_page = 'hotel?edit_id={}' if edit_id else 'hotel?id={}'
                    raise HTTPRedirect(hotel_page, group.id if attendee.paid == c.PAID_BY_GROUP else attendee.id)
                else:
                    raise HTTPRedirect('index')

        else:
            if edit_id is None:
                if attendee.badge_type == c.PSEUDO_DEALER_BADGE:
                    # All new dealer signups should default to receiving the
                    # hotel info email, even if the deadline has passed.
                    # There's a good chance some dealers will apply for a table
                    # AFTER the hotel booking deadline, but BEFORE the hotel
                    # booking is sent out. This ensures they'll still receive
                    # the email, as requested by the Marketplace Department.
                    attendee.requested_hotel_info = True

            if attendee.badge_type == c.PSEUDO_DEALER_BADGE and c.DEALER_REG_SOFT_CLOSED:
                message = '{} is closed, but you can ' \
                    'fill out this form to add yourself to our waitlist'.format(c.DEALER_REG_TERM.title())

        promo_code_group = None
        if attendee.promo_code:
            promo_code_group = session.query(PromoCode).filter_by(code=attendee.promo_code.code).first().group

        return {
            'message':    message,
            'attendee':   attendee,
            'badges': params.get('badges', 0),
            'name': params.get('name', ''),
            'group':      group,
            'promo_code_group': promo_code_group,
            'edit_id':    edit_id,
            'affiliates': session.affiliates(),
            'cart_not_empty': Charge.unpaid_preregs,
            'copy_address': params.get('copy_address'),
            'promo_code_code': params.get('promo_code', ''),
            'pii_consent': params.get('pii_consent'),
        }
    def form(self, session, message='', edit_id=None, **params):
        """
        Our production NGINX config caches the page at /preregistration/form.
        Since it's cached, we CAN'T return a session cookie with the page. We
        must POST to a different URL in order to bypass the cache and get a
        valid session cookie. Thus, this page is also exposed as "post_form".
        """
        params['id'] = 'None'   # security!
        group = Group()

        if edit_id is not None:
            attendee = self._get_unsaved(
                edit_id,
                if_not_found=HTTPRedirect('form?message={}', 'That preregistration has already been finalized'))
            attendee.apply(params, restricted=True)
            params.setdefault('pii_consent', True)
        else:
            attendee = session.attendee(params, ignore_csrf=True, restricted=True)

            if attendee.badge_type == c.PSEUDO_DEALER_BADGE:
                if not c.DEALER_REG_OPEN:
                    return render('static_views/dealer_reg_closed.html') if c.AFTER_DEALER_REG_START \
                        else render('static_views/dealer_reg_not_open.html')

                # Both the Attendee class and Group class have identically named
                # address fields. In order to distinguish the two sets of address
                # fields in the params, the Group fields are prefixed with "group_"
                # when the form is submitted. To prevent instantiating the Group object
                # with the Attendee's address fields, we must clone the params and
                # rename all the "group_" fields.
                group_params = dict(params)
                for field_name in ['country', 'region', 'zip_code', 'address1', 'address2', 'city']:
                    group_params[field_name] = params.get('group_{}'.format(field_name), '')
                    if params.get('copy_address'):
                        params[field_name] = group_params[field_name]

                group = session.group(group_params, ignore_csrf=True, restricted=True)

        if c.PAGE == 'post_dealer':
            attendee.badge_type = c.PSEUDO_DEALER_BADGE
        elif not attendee.badge_type:
            attendee.badge_type = c.ATTENDEE_BADGE

        if cherrypy.request.method == 'POST' or edit_id is not None:
            message = check_pii_consent(params, attendee) or message
            if not message and attendee.badge_type not in c.PREREG_BADGE_TYPES:
                message = 'Invalid badge type!'
            if not message and c.BADGE_PROMO_CODES_ENABLED and params.get('promo_code'):
                message = session.add_promo_code_to_attendee(attendee, params.get('promo_code'))

        if message:
            return {
                'message':    message,
                'attendee':   attendee,
                'group':      group,
                'edit_id':    edit_id,
                'affiliates': session.affiliates(),
                'cart_not_empty': Charge.unpaid_preregs,
                'copy_address': params.get('copy_address'),
                'promo_code': params.get('promo_code', ''),
                'pii_consent': params.get('pii_consent'),
            }

        if 'first_name' in params:
            message = check(attendee, prereg=True)
            if not message and attendee.badge_type == c.PSEUDO_DEALER_BADGE:
                message = check(group, prereg=True)

            if attendee.badge_type in [c.PSEUDO_GROUP_BADGE, c.PSEUDO_DEALER_BADGE]:
                message = "Please enter a group name" if not params.get('name') else ''
            else:
                params['badges'] = 0
                params['name'] = ''

            if not message:
                if attendee.badge_type == c.PSEUDO_DEALER_BADGE:
                    attendee.paid = c.PAID_BY_GROUP
                    group.attendees = [attendee]
                    session.assign_badges(group, params['badges'])
                    group.status = c.WAITLISTED if c.DEALER_REG_SOFT_CLOSED else c.UNAPPROVED
                    attendee.ribbon = add_opt(attendee.ribbon_ints, c.DEALER_RIBBON)
                    attendee.badge_type = c.ATTENDEE_BADGE

                    session.add_all([attendee, group])
                    session.commit()
                    try:
                        send_email.delay(
                            c.MARKETPLACE_EMAIL,
                            c.MARKETPLACE_EMAIL,
                            'Dealer Application Received',
                            render('emails/dealers/reg_notification.txt', {'group': group}, encoding=None),
                            model=group.to_dict('id'))
                        send_email.delay(
                            c.MARKETPLACE_EMAIL,
                            attendee.email,
                            'Dealer Application Received',
                            render('emails/dealers/application.html', {'group': group}, encoding=None),
                            'html',
                            model=group.to_dict('id'))
                    except Exception:
                        log.error('unable to send marketplace application confirmation email', exc_info=True)
                    raise HTTPRedirect('dealer_confirmation?id={}', group.id)
                else:
                    track_type = c.UNPAID_PREREG
                    if attendee.id in Charge.unpaid_preregs:
                        track_type = c.EDITED_PREREG
                        # Clear out any previously cached targets, in case the unpaid badge
                        # has been edited and changed from a single to a group or vice versa.
                        del Charge.unpaid_preregs[attendee.id]

                    Charge.unpaid_preregs[attendee.id] = Charge.to_sessionized(attendee,
                                                                               params.get('name'),
                                                                               params.get('badges'))
                    Tracking.track(track_type, attendee)

                if session.attendees_with_badges().filter_by(
                        first_name=attendee.first_name, last_name=attendee.last_name, email=attendee.email).count():

                    raise HTTPRedirect('duplicate?id={}', group.id if attendee.paid == c.PAID_BY_GROUP else attendee.id)

                if attendee.banned:
                    raise HTTPRedirect('banned?id={}', group.id if attendee.paid == c.PAID_BY_GROUP else attendee.id)

                if c.PREREG_REQUEST_HOTEL_INFO_OPEN:
                    hotel_page = 'hotel?edit_id={}' if edit_id else 'hotel?id={}'
                    raise HTTPRedirect(hotel_page, group.id if attendee.paid == c.PAID_BY_GROUP else attendee.id)
                else:
                    raise HTTPRedirect('index')

        else:
            if edit_id is None:
                if attendee.badge_type == c.PSEUDO_DEALER_BADGE:
                    # All new dealer signups should default to receiving the
                    # hotel info email, even if the deadline has passed.
                    # There's a good chance some dealers will apply for a table
                    # AFTER the hotel booking deadline, but BEFORE the hotel
                    # booking is sent out. This ensures they'll still receive
                    # the email, as requested by the Marketplace Department.
                    attendee.requested_hotel_info = True

            if attendee.badge_type == c.PSEUDO_DEALER_BADGE and c.DEALER_REG_SOFT_CLOSED:
                message = 'Dealer registration is closed, but you can ' \
                    'fill out this form to add yourself to our waitlist'

        promo_code_group = None
        if attendee.promo_code:
            promo_code_group = session.query(PromoCode).filter_by(code=attendee.promo_code.code).first().group

        return {
            'message':    message,
            'attendee':   attendee,
            'group':      group,
            'promo_code_group': promo_code_group,
            'edit_id':    edit_id,
            'affiliates': session.affiliates(),
            'cart_not_empty': Charge.unpaid_preregs,
            'copy_address': params.get('copy_address'),
            'promo_code': params.get('promo_code', ''),
            'pii_consent': params.get('pii_consent'),
        }