Exemplo n.º 1
0
def member_dict_from_request(request, actor, join_or_renew):
    """Creates and returns a dict of member info from the request.
    new_or_renew should be "join" if this is (or expected to be) for a new
    member, or "renew" for a member being renewed.
    """

    logging.info('member_dict_from_request')
    logging.info(request.params.items())

    # Make sure the user/form/request isn't trying to mess with fields that it
    # shouldn't be.
    for name, field in config.MEMBER_FIELDS._asdict().items():
        if not field.form_field and request.POST.get(name) is not None:
            # This causes the request processing to stop
            webapp2.abort(400, detail='invalid field')

        if field.values is not None and request.POST.get(name) is not None \
           and not set(request.POST.get(name).split(config.MULTIVALUE_DIVIDER)).issubset(field.values):
            # This causes the request processing to stop
            webapp2.abort(400, detail='invalid field value')

    member = config.validate_member(request.POST)

    if not member:
        # This causes the request processing to stop
        webapp2.abort(400, detail='invalid input')

    # We didn't validate the geoposition above, so do it now
    geoposition = request.POST.get('geoposition', '')  # TODO: don't hardcode field name
    geoposition_required = config.MEMBER_FIELDS.joined_latlong.required \
                            if join_or_renew == 'join' else \
                            config.MEMBER_FIELDS.renewed_latlong.required
    if not utils.latlong_validator(geoposition, geoposition_required):
        webapp2.abort(400, detail='invalid input')
    geoaddress = helpers.address_from_latlong(geoposition)

    if join_or_renew == 'join':
        # Set the GUID field
        member[config.MEMBER_FIELDS.id.name] = str(uuid.uuid4())
        # Set the timestamps
        member[config.MEMBER_FIELDS.joined.name] = utils.current_datetime()
        member[config.MEMBER_FIELDS.joined_by.name] = actor
        member[config.MEMBER_FIELDS.joined_latlong.name] = geoposition
        member[config.MEMBER_FIELDS.joined_address.name] = geoaddress

    # These get set regardless of mode
    member[config.MEMBER_FIELDS.renewed.name] = utils.current_datetime()
    member[config.MEMBER_FIELDS.renewed_by.name] = actor
    member[config.MEMBER_FIELDS.renewed_latlong.name] = geoposition
    member[config.MEMBER_FIELDS.renewed_address.name] = geoaddress

    member[config.MEMBER_FIELDS.address_latlong.name] = helpers.latlong_for_record(
                                                            config.MEMBER_FIELDS,
                                                            member)

    # We want the "MailChimp Updated" field to be cleared, regardless of mode
    member[config.MEMBER_FIELDS.mailchimp_updated.name] = ''

    return member
Exemplo n.º 2
0
def member_dict_from_request(request, actor, join_or_renew):
    """Creates and returns a dict of member info from the request.
    new_or_renew should be "join" if this is (or expected to be) for a new
    member, or "renew" for a member being renewed.
    """

    logging.info('member_dict_from_request')
    logging.info(request.params.items())

    # Make sure the user/form/request isn't trying to mess with fields that it
    # shouldn't be.
    for name, field in config.MEMBER_FIELDS._asdict().items():
        if not field.form_field and request.POST.get(name) is not None:
            # This causes the request processing to stop
            webapp2.abort(400, detail='invalid field')

        if field.values is not None and request.POST.get(name) is not None \
           and not set(request.POST.get(name).split(config.MULTIVALUE_DIVIDER)).issubset(field.values):
            # This causes the request processing to stop
            webapp2.abort(400, detail='invalid field value')

    member = config.validate_member(request.POST)

    if not member:
        # This causes the request processing to stop
        webapp2.abort(400, detail='invalid input')

    # We didn't validate the geoposition above, so do it now
    geoposition = request.POST.get('geoposition',
                                   '')  # TODO: don't hardcode field name
    geoposition_required = config.MEMBER_FIELDS.joined_latlong.required \
                            if join_or_renew == 'join' else \
                            config.MEMBER_FIELDS.renewed_latlong.required
    if not utils.latlong_validator(geoposition, geoposition_required):
        webapp2.abort(400, detail='invalid input')
    geoaddress = helpers.address_from_latlong(geoposition)

    if join_or_renew == 'join':
        # Set the GUID field
        member[config.MEMBER_FIELDS.id.name] = str(uuid.uuid4())
        # Set the timestamps
        member[config.MEMBER_FIELDS.joined.name] = utils.current_datetime()
        member[config.MEMBER_FIELDS.joined_by.name] = actor
        member[config.MEMBER_FIELDS.joined_latlong.name] = geoposition
        member[config.MEMBER_FIELDS.joined_address.name] = geoaddress

    # These get set regardless of mode
    member[config.MEMBER_FIELDS.renewed.name] = utils.current_datetime()
    member[config.MEMBER_FIELDS.renewed_by.name] = actor
    member[config.MEMBER_FIELDS.renewed_latlong.name] = geoposition
    member[config.MEMBER_FIELDS.renewed_address.name] = geoaddress

    member[config.MEMBER_FIELDS.address_latlong.
           name] = helpers.latlong_for_record(config.MEMBER_FIELDS, member)

    # We want the "MailChimp Updated" field to be cleared, regardless of mode
    member[config.MEMBER_FIELDS.mailchimp_updated.name] = ''

    return member
Exemplo n.º 3
0
def volunteer_dict_from_request(request: flask.Request, actor: str) -> dict:
    """Creates and returns a dict of volunteer info from the request.
    `actor` is the ID/email of the person or entity that is triggering this.
    """

    logging.debug('gapps.volunteer_dict_from_request: %s',
                  list(request.values.items()))

    # Make sure the user/form/request isn't trying to mess with fields that it
    # shouldn't be.
    for name, field in _S.volunteer.fields._asdict().items():
        if not field.form_field and request.values.get(name) is not None:
            # This causes the request processing to stop
            flask.abort(400, description='invalid field')

        if field.values is not None and request.values.get(name) is not None \
           and not set(request.values.get(name).split(config.MULTIVALUE_DIVIDER)).issubset(field.values):
            # This causes the request processing to stop
            flask.abort(400, description='invalid field value')

    volunteer = config.validate_volunteer(request.values)

    if not volunteer:
        logging.warning(
            'gapps.volunteer_dict_from_request: config.validate_volunteer failed'
        )
        # This causes the request processing to stop
        flask.abort(400, description='invalid input')

    # We didn't validate the geoposition above, so do it now
    geoposition = request.values.get(_GEOPOSITION_VALUE_KEY, '')
    geoposition_required = _S.volunteer.fields.joined_latlong.required
    if not utils.latlong_validator(geoposition, geoposition_required):
        logging.warning(
            'gapps.volunteer_dict_from_request: utils.latlong_validator failed'
        )
        flask.abort(400, description='invalid input')
    geoaddress = helpers.address_from_latlong(geoposition)

    # Set the GUID field
    volunteer[_S.volunteer.fields.id.name] = str(uuid.uuid4())
    # Set the timestamps
    volunteer[_S.volunteer.fields.joined.name] = utils.current_datetime()
    volunteer[_S.volunteer.fields.joined_by.name] = actor
    volunteer[_S.volunteer.fields.joined_latlong.name] = geoposition
    volunteer[_S.volunteer.fields.joined_address.name] = geoaddress

    volunteer[_S.volunteer.fields.address_latlong.name] = \
        helpers.latlong_for_record(_S.volunteer.fields, volunteer)

    return volunteer
Exemplo n.º 4
0
def volunteer_dict_from_request(request, actor):
    """Creates and returns a dict of volunteer info from the request.
    """

    logging.debug('volunteer_dict_from_request')
    logging.debug(request.params.items())

    # Make sure the user/form/request isn't trying to mess with fields that it
    # shouldn't be.
    for name, field in config.VOLUNTEER_FIELDS._asdict().items():
        if not field.form_field and request.POST.get(name) is not None:
            # This causes the request processing to stop
            webapp2.abort(400, detail='invalid field')

        if field.values is not None and request.POST.get(name) is not None \
           and not set(request.POST.get(name).split(config.MULTIVALUE_DIVIDER)).issubset(field.values):
            # This causes the request processing to stop
            webapp2.abort(400, detail='invalid field value')

    volunteer = config.validate_volunteer(request.POST)

    if not volunteer:
        # This causes the request processing to stop
        webapp2.abort(400, detail='invalid input')

    # We didn't validate the geoposition above, so do it now
    geoposition = request.POST.get('geoposition',
                                   '')  # TODO: don't hardcode field name
    geoposition_required = config.VOLUNTEER_FIELDS.joined_latlong.required
    if not utils.latlong_validator(geoposition, geoposition_required):
        webapp2.abort(400, detail='invalid input')
    geoaddress = helpers.address_from_latlong(geoposition)

    # Set the GUID field
    volunteer[config.VOLUNTEER_FIELDS.id.name] = str(uuid.uuid4())
    # Set the timestamps
    volunteer[config.VOLUNTEER_FIELDS.joined.name] = utils.current_datetime()
    volunteer[config.VOLUNTEER_FIELDS.joined_by.name] = actor
    volunteer[config.VOLUNTEER_FIELDS.joined_latlong.name] = geoposition
    volunteer[config.VOLUNTEER_FIELDS.joined_address.name] = geoaddress

    volunteer[config.VOLUNTEER_FIELDS.address_latlong.name] = \
        helpers.latlong_for_record(config.VOLUNTEER_FIELDS, volunteer)

    return volunteer
Exemplo n.º 5
0
def volunteer_dict_from_request(request, actor):
    """Creates and returns a dict of volunteer info from the request.
    """

    logging.debug('volunteer_dict_from_request')
    logging.debug(request.params.items())

    # Make sure the user/form/request isn't trying to mess with fields that it
    # shouldn't be.
    for name, field in config.VOLUNTEER_FIELDS._asdict().items():
        if not field.form_field and request.POST.get(name) is not None:
            # This causes the request processing to stop
            webapp2.abort(400, detail='invalid field')

        if field.values is not None and request.POST.get(name) is not None \
           and not set(request.POST.get(name).split(config.MULTIVALUE_DIVIDER)).issubset(field.values):
            # This causes the request processing to stop
            webapp2.abort(400, detail='invalid field value')

    volunteer = config.validate_volunteer(request.POST)

    if not volunteer:
        # This causes the request processing to stop
        webapp2.abort(400, detail='invalid input')

    # We didn't validate the geoposition above, so do it now
    geoposition = request.POST.get('geoposition', '')  # TODO: don't hardcode field name
    geoposition_required = config.VOLUNTEER_FIELDS.joined_latlong.required
    if not utils.latlong_validator(geoposition, geoposition_required):
        webapp2.abort(400, detail='invalid input')
    geoaddress = helpers.address_from_latlong(geoposition)

    # Set the GUID field
    volunteer[config.VOLUNTEER_FIELDS.id.name] = str(uuid.uuid4())
    # Set the timestamps
    volunteer[config.VOLUNTEER_FIELDS.joined.name] = utils.current_datetime()
    volunteer[config.VOLUNTEER_FIELDS.joined_by.name] = actor
    volunteer[config.VOLUNTEER_FIELDS.joined_latlong.name] = geoposition
    volunteer[config.VOLUNTEER_FIELDS.joined_address.name] = geoaddress

    volunteer[config.VOLUNTEER_FIELDS.address_latlong.name] = \
        helpers.latlong_for_record(config.VOLUNTEER_FIELDS, volunteer)

    return volunteer
Exemplo n.º 6
0
def _update_all_members_address_latlong():
    """One-off helper to fill in the `address_latlong` field for legacy members.
    """

    googledata = GoogleData()
    list_entries = googledata.get_list_entries(config.MEMBERS_SPREADSHEET_KEY,
                                               config.MEMBERS_WORKSHEET_KEY)

    for list_entry in list_entries:
        member_dict = list_entry.to_dict()

        if member_dict.get(config.MEMBER_FIELDS.address_latlong.name):
            continue

        latlong = helpers.latlong_for_record(config.MEMBER_FIELDS, member_dict)

        if not latlong:
            continue

        list_entry.set_value(config.MEMBER_FIELDS.address_latlong.name,
                             latlong)

        _update_list_entry(list_entry)
Exemplo n.º 7
0
def _update_all_members_address_latlong():
    """One-off helper to fill in the `address_latlong` field for legacy members.
    """

    googledata = GoogleData()
    list_entries = googledata.get_list_entries(config.MEMBERS_SPREADSHEET_KEY,
                                               config.MEMBERS_WORKSHEET_KEY)

    for list_entry in list_entries:
        member_dict = list_entry.to_dict()

        if member_dict.get(config.MEMBER_FIELDS.address_latlong.name):
            continue

        latlong = helpers.latlong_for_record(config.MEMBER_FIELDS, member_dict)

        if not latlong:
            continue

        list_entry.set_value(config.MEMBER_FIELDS.address_latlong.name,
                             latlong)

        _update_list_entry(list_entry)
Exemplo n.º 8
0
def member_dict_from_request(request: flask.Request, actor: str,
                             join_or_renew: str) -> dict:
    """Creates and returns a dict of member info from the request.
    new_or_renew should be "join" if this is (or expected to be) for a new
    member, or "renew" for a member being renewed.
    `actor` is the ID/email of the person or entity that is triggering this.
    """

    logging.info('member_dict_from_request')
    logging.info(list(request.values.items()))

    # Make sure the user/form/request isn't trying to mess with fields that it
    # shouldn't be.
    for name, field in _S.member.fields._asdict().items():
        if not field.form_field and request.values.get(name) is not None:
            # There is a field provided in the request that isn't one that's allowed to be
            # set via the form. This can be achieved by an attacker by modifying the page
            # elements. This causes the request processing to stop.
            flask.abort(400, description='invalid field')

        if field.values is not None and request.values.get(name) is not None \
            and not set(request.values.get(name).split(config.MULTIVALUE_DIVIDER)).issubset(field.values):
            # This field has a restricted set of allowed values, and the form has provided
            # one that isn't allowed. This causes the request processing to stop.
            flask.abort(400, description='invalid field value')

    member = config.validate_member(request.values)

    if not member:
        logging.warning(
            'gapps.member_dict_from_request: config.validate_member failed')
        # This causes the request processing to stop
        flask.abort(400, description='invalid input')

    # We didn't validate the geoposition above, so do it now
    geoposition = request.values.get(_GEOPOSITION_VALUE_KEY, '')
    geoposition_required = _S.member.fields.joined_latlong.required \
                            if join_or_renew == 'join' else \
                            _S.member.fields.renewed_latlong.required
    if not utils.latlong_validator(geoposition, geoposition_required):
        logging.warning(
            'gapps.member_dict_from_request: utils.latlong_validator failed')
        flask.abort(400, description='invalid input')
    geoaddress = helpers.address_from_latlong(geoposition)

    if join_or_renew == 'join':
        # Set the GUID field
        member[_S.member.fields.id.name] = str(uuid.uuid4())
        # Set the timestamps
        member[_S.member.fields.joined.name] = utils.current_datetime()
        member[_S.member.fields.joined_by.name] = actor
        member[_S.member.fields.joined_latlong.name] = geoposition
        member[_S.member.fields.joined_address.name] = geoaddress

    # These get set regardless of mode
    member[_S.member.fields.renewed.name] = utils.current_datetime()
    member[_S.member.fields.renewed_by.name] = actor
    member[_S.member.fields.renewed_latlong.name] = geoposition
    member[_S.member.fields.renewed_address.name] = geoaddress

    member[_S.member.fields.address_latlong.name] = helpers.latlong_for_record(
        _S.member.fields, member)

    # We want the "MailChimp Updated" field to be cleared, regardless of mode
    member[_S.member.fields.mailchimp_updated.name] = ''

    # Fields clear if we're in demo mode. We don't want to record a demo user's email address.
    if config.DEMO:
        member[_S.member.fields.joined_by.name] = '*****@*****.**'
        member[_S.member.fields.renewed_by.name] = '*****@*****.**'
        member[_S.member.fields.joined_latlong.name] = ''
        member[_S.member.fields.joined_address.name] = 'Demo'
        member[_S.member.fields.renewed_latlong.name] = ''
        member[_S.member.fields.renewed_address.name] = 'Demo'

    return member