Exemplo n.º 1
0
def drop_audit_trail():
    """
    Remove PGMemento audit trail
    """
    db = get_database()
    db.exec_sql(relative_path(__file__, "drop-audit.sql"))
    drop_audit_columns(db)
Exemplo n.º 2
0
async def users(request):
    db = get_database()
    with db.session_scope(commit=False):
        if request.method == "POST":
            data = await request.json()
            return create_user(db, data)

        res = db.session.query(User).all()
        return UserResponse(res)
Exemplo n.º 3
0
def create_user(db, data):
    db = get_database()
    try:
        username = data["username"]
        password = data["password"]
    except IndexError:
        raise SparrowAPIError("Must provide both username and password")
    if db.session.query(User).get(username) is not None:
        raise SparrowAPIError(f"User {username} already exists", 409)
    res = _create_user(db, username, validate_password(password))
    return UserResponse(res)
Exemplo n.º 4
0
    async def get(self, request):

        db = get_database()
        sample = db.model.sample
        sampleSchema = db.interface.sample(many=True)

        data = (db.session.query(
            sample.id, sample.name,
            sample.location).filter(sample.location != None).all())

        json_data = sampleSchema.dump(data)

        return JSONResponse({"data": json_data, "total_count": len(json_data)})
Exemplo n.º 5
0
    async def get(self, request):
        """Handler for all GET requests"""

        model_names = await parser.parse(self.args_schema,
                                         request,
                                         location="querystring")

        db = get_database()

        n_models = sum(len(v) for v in model_names.values())
        if n_models == 0:
            raise SparrowAPIError("No IDs were passed to filter by")

        # Wrap entire query infrastructure in error-handling block.
        # We should probably make this a "with" statement or something
        # to use throughout our API code.
        with db.session_scope(commit=False):

            DataFile = db.model.data_file
            DataFileLink = db.model.data_file_link

            data = []
            for model_name, model_ids in model_names.items():

                q = db.session.query(
                    DataFile.file_hash,
                    DataFile.file_mtime,
                    DataFile.basename,
                    DataFile.type_id,
                    getattr(DataFileLink, model_name),
                ).order_by(DataFile.file_mtime)

                q = q.join(DataFile.data_file_link_collection).filter(
                    getattr(DataFileLink, model_name).in_(model_ids))

                res = q.all()

                # SUPER messy way to create a custom json serialization
                for row in res:
                    row_obj = {}
                    file_hash, file_mtime, basename, type_id, model_id = row
                    row_obj["file_hash"] = file_hash
                    row_obj["file_mtime"] = file_mtime.isoformat()
                    row_obj["basename"] = basename
                    row_obj["type"] = type_id
                    row_obj["model"] = model_name[:-3]
                    row_obj["model_id"] = model_id
                    data.append(row_obj)

            return JSONResponse(dict(data=data, total_count=len(data)))
Exemplo n.º 6
0
    async def get(self, request):
        """Handler for all GET requests"""

        args = await parser.parse(self.args_schema,
                                  request,
                                  location="querystring")

        db = get_database()

        if not len(request.query_params.keys()):
            return JSONResponse({})

        # Wrap entire query infrastructure in error-handling block.
        # We should probably make this a "with" statement or something
        # to use throughout our API code.
        with db.session_scope(commit=False):

            try:
                DataFile = self.model

                q = db.session.query(
                    DataFile.file_hash,
                    DataFile.file_mtime,
                    DataFile.basename,
                    DataFile.type_id,
                ).order_by(DataFile.file_mtime)

                if args["all"]:
                    res = q.all()
                    return APIResponse(res,
                                       schema=self.schema(many=True),
                                       total_count=len(res))

                for _filter in self._filters:
                    q = _filter(q, args)

                try:
                    res = get_page(q,
                                   per_page=args["per_page"],
                                   page=args["page"])

                except ValueError:
                    raise ValidationError("Invalid page token.")

                # Note: we don't need to use a schema to serialize here. but it is nice if we have it
                return APIResponse(res, schema=self.schema(many=True))
            except Exception as err:
                raise ApplicationError(str(err))
Exemplo n.º 7
0
async def login(request, username: str, password: str):
    db = get_database()
    backend = get_backend()

    current_user = db.session.query(User).get(username)
    log.debug(current_user)

    if current_user is not None and current_user.is_correct_password(password):
        day = 24 * 60 * 60
        token = backend.set_cookie(None,
                                   "access",
                                   max_age=day,
                                   identity=username)
        resp = JSONResponse(dict(login=True, username=username, token=token))
        return backend.set_login_cookies(resp, identity=username)

    return backend.logout(UnauthorizedResponse(status_code=401))
Exemplo n.º 8
0
def validate_data(model_name):
    """Try to import data into the database to see if errors are raised.
    Pipe JSON into this command's stdin to see if the import will be successful.
    """
    setup_stderr_logs()
    setup_stderr_logs("sqlalchemy.engine")
    db = get_database()
    data = load(stdin)
    # In some cases, we might have data in the "data" key
    # NOTE: this is likely a bad assumption in many cases, probably
    schema = getattr(db.interface, model_name)()
    t0 = time()
    with on_conflict("do-nothing"):
        res = schema.load(data, session=db.session)
        db.session.add(res)
    t_delta = time() - t0
    print(f"Elapsed time: {t_delta:.2f} seconds")
Exemplo n.º 9
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        db = get_database()
        self.schema = db.interface.data_file
        self.model = db.model.data_file

        self._filters = []
        self.register_filter(OpenSearchFilter)
        self.register_filter(AuthorityFilter)
        self.register_filter(FieldExistsFilter)
        self.register_filter(FieldNotExistsFilter)
        self.register_filter(EmbargoFilter)
        self.register_filter(DateFilter)
        self.register_filter(TextSearchFilter)
        self.register_filter(AgeRangeFilter)
        self.register_filter(IdListFilter)
        self.register_filter(TagsFilter)
Exemplo n.º 10
0
async def user(request):
    auth = get_backend()
    db = get_database()
    username = request.path_params["username"]
    user = db.session.query(User).get(username)
    if user is None:
        raise SparrowAPIError(f"User {username} does not exist", 404)
    if request.method == "GET":
        return UserResponse(user)
    elif request.method == "PUT":
        data = await request.json()
        return update_user(db, user, data)
    elif request.method == "DELETE":
        # Make sure we aren't trying to delete ourselves
        if user.username == auth.get_identity(request):
            raise SparrowAPIError("Cannot delete yourself", 403)
        with db.session_scope():
            db.session.delete(user)
        return JSONResponse({"success": "True", "deleted": [username]})
    raise SparrowAPIError("Method not allowed", 405)
Exemplo n.º 11
0
    async def put(self, request):
        db = get_database()
        sample = db.model.sample

        id_ = request.path_params["id"]

        sample_ = db.session.query(sample).get(id_)

        data = await request.json()

        if "member_of" in data:
            member_id = data["member_of"]

            sample_.member_of = member_id

            try:
                db.session.commit()
                return JSONResponse({"id": id_, "member_of": member_id})
            except Exception as err:
                db.session.rollback()
                raise ApplicationError(str(err))
Exemplo n.º 12
0
    async def get(self, request):
        db = get_database()
        sample = db.model.sample
        sampleSchema = db.interface.sample(many=True)

        if "id" not in request.path_params:
            return JSONResponse({})

        id_ = request.path_params["id"]

        sample_ = db.session.query(sample).get(id_)

        if len(sample_.sample_collection) == 0:
            return JSONResponse({"id": id_, "sample_collection": []})

        sample_collection = sampleSchema.dump(sample_.sample_collection)

        return JSONResponse({
            "id": id_,
            "sample_collection": sample_collection
        })
Exemplo n.º 13
0
 def __init__(self, user_):
     db = get_database()
     _many = isinstance(user_, Iterable)
     _schema = db.interface.user(many=_many, exclude=("password", ))
     super().__init__(user_, schema=_schema)