예제 #1
0
def member_add_membership_days(
    entity_id=None,
    type=Arg(Enum(Span.MEMBERSHIP, Span.LABACCESS, Span.SPECIAL_LABACESS)),
    days=Arg(natural1),
    creation_reason=Arg(non_empty_str),
    default_start_date=Arg(iso_date, required=False)):
    return add_membership_days(entity_id, type, days, creation_reason,
                               default_start_date).as_json()
예제 #2
0
def memberbooth_member(member_number=Arg(int)):
    member = db_session.query(Member).filter(
        Member.member_number == member_number,
        Member.deleted_at.is_(None)).first()

    if not member:
        return None

    membership_data = get_membership_summary(member.member_id)
    return memberbooth_response_object(member, membership_data)
예제 #3
0
def memberbooth_tag(tagid=Arg(int)):
    key = db_session.query(Key)\
        .join(Key.member) \
        .filter(Key.tagid == tagid) \
        .filter(
            Member.deleted_at.is_(None),
            Key.deleted_at.is_(None),
        ) \
        .first()

    if key is None:
        return None

    membership_data = get_membership_summary(key.member_id)
    return memberbooth_response_object(key.member, membership_data)
예제 #4
0
def login(grant_type=Arg(Enum('password')), username=Arg(str), password=Arg(str)):
    """ Login user with username and password, returns token. """
    assert grant_type
    username = username.strip()

    return auth.login(request.remote_addr, request.user_agent.string, username, password)
예제 #5
0
def password_reset(reset_token: str=Arg(non_empty_str), unhashed_password: str=Arg(str)):
    """ Reset the password for a user. """
    return auth.password_reset(reset_token, unhashed_password)
예제 #6
0
def request_password_reset(user_identification: str=Arg(non_empty_str)):
    """ Send a reset password link to the users email. """
    user_identification = user_identification.strip()
    return auth.request_password_reset(user_identification)
예제 #7
0
def send_access_token(redirect=Arg(str, required=False),
                      user_identification: str = Arg(str)):
    """ Send access token email to user with username or member_number user_identification. """
    return send_access_token_email(redirect or "/member", user_identification,
                                   request.remote_addr,
                                   request.user_agent.string)
예제 #8
0
def box_terminator_nag_route(member_number=Arg(int),
                             box_label_id=Arg(int),
                             nag_type=Arg(symbol)):
    """ Send a nag email for this box. """
    return box_terminator_nag(member_number, box_label_id, nag_type)
예제 #9
0
def box_terminator_validate_route(member_number=Arg(int),
                                  box_label_id=Arg(int)):
    """ Used when scanning boxes. """
    return box_terminator_validate(member_number, box_label_id,
                                   g.session_token)
예제 #10
0
    def list(self,
             sort_by=Arg(symbol, required=False),
             sort_order=Arg(Enum(DESC, ASC), required=False),
             search: str = Arg(str, required=False),
             page_size=Arg(natural0, required=False),
             page=Arg(natural1, required=False),
             expand=Arg(symbol, required=False),
             relation=None,
             related_entity_id=None):

        query = db_session.query(self.model)

        if not self.list_deleted:
            query = query.filter(self.model.deleted_at.is_(None))

        if relation and related_entity_id:
            query = relation.filter(query, related_entity_id)

        if search:
            for term in search.split():
                expression = or_(*[
                    self.columns[column_name].like(f"%{term}%")
                    for column_name in self.search_columns
                ])
                query = query.filter(expression)

        if expand:
            expand_field = self.expand_fields.get(expand)
            if not expand_field:
                raise UnprocessableEntity(f"Expand of {expand} not allowed.",
                                          fields='expand',
                                          what=BAD_VALUE)
            query = query.outerjoin(
                expand_field.relation).add_columns(*expand_field.columns)

            column_obj_converter = [
                to_obj_converters[type(c.type)] for c in expand_field.columns
            ]

            # Use to_obj that can unpack result row.
            def to_obj(row):
                obj = self.to_obj(row[0])
                for value, column, converter in zip(row[1:],
                                                    expand_field.columns,
                                                    column_obj_converter):
                    obj[column.name] = converter(value)
                return obj
        else:
            # Use regular to_obj.
            to_obj = self.to_obj

        sort_column = sort_by or self.default_sort_column
        sort_order = sort_order or self.default_sort_order

        if sort_column:
            try:
                column = self.columns[sort_column]
            except KeyError:
                raise UnprocessableEntity(
                    f"Can't sort on column {sort_column}.",
                    fields='sort_column',
                    what=BAD_VALUE)
            order = desc if sort_order == DESC else asc
            query = query.order_by(order(column))

        count = query.count()

        page_size = 25 if page_size is None else page_size
        page = page or 1

        if page_size:
            query = query.limit(page_size).offset((page - 1) * page_size)

        return dict(total=count,
                    page=page,
                    page_size=page_size,
                    last_page=max(1, ceil(count /
                                          page_size)) if page_size else 1,
                    data=[to_obj(entity) for entity in query])
예제 #11
0
def process_stripe_events_route(start=Arg(str, required=False),
                                source_id=Arg(str, required=False),
                                type=Arg(str, required=False)):
    """ Used to make server fetch stripe events, used for testing since webhook is hard to use. """
    return process_stripe_events(start, source_id, type)
예제 #12
0
            def view_wrapper(*args, **kwargs):
                try:
                    has_permission = (permission == PUBLIC
                                      or permission in g.permissions)

                    if not has_permission:
                        raise Forbidden(
                            message=
                            f"'{permission}' permission is required for this operation."
                        )

                    Arg.fill_args(params, kwargs)

                    data = f(*args, **kwargs)

                    if flat_return:
                        result = jsonify({**data, 'status': status}), code
                    else:
                        result = jsonify({
                            'status': status,
                            'data': data
                        }), code

                    if commit and not commit_on_error:
                        db_session.commit()

                except IntegrityError as e:
                    if isinstance(e.orig, pymysql.err.IntegrityError):
                        # This parsing of db errors is very sketchy, but there are tests for it so at least we know
                        # if it stops working.
                        errno, error = e.orig.args
                        if errno == DUP_ENTRY:
                            m = re.match(r".*?'([^']*)'.*?'([^']*)'.*", error)
                            if m:
                                value = m.group(1)
                                index = m.group(2)
                                try:
                                    fields = fields_by_index[index]
                                    raise UnprocessableEntity(
                                        f"Duplicate '{fields}', '{value}' already exists.",
                                        what=NOT_UNIQUE,
                                        fields=fields)
                                except KeyError:
                                    logger.warning(
                                        f"index {index} is missing in index to fields mapping"
                                    )
                                    raise UnprocessableEntity(
                                        f"Duplicate '{value}' not allowed.",
                                        what=NOT_UNIQUE)
                            else:
                                raise UnprocessableEntity(f"Duplicate entry.",
                                                          what=NOT_UNIQUE)

                        if errno == BAD_NULL_ERROR:
                            m = re.match(r".*?'([^']*)'.*", error)
                            if m:
                                field = m.group(1)
                            else:
                                field = None

                            raise UnprocessableEntity(
                                f"'{field}' is required."
                                if field else "Required field missing.",
                                fields=field,
                                what=REQUIRED)

                    raise UnprocessableEntity(
                        "Could not save entity using the sent data.",
                        log=f"unrecoginized integrity error: {str(e)}")

                finally:
                    if commit_on_error:
                        db_session.commit()

                return result