Skip to content
Snippets Groups Projects
Commit 33363939 authored by ale's avatar ale
Browse files

Initial commit

parents
No related branches found
No related tags found
No related merge requests found
Pipeline #54057 failed
.tox
__pycache__
*.pyc
*.egg-info
include: "https://git.autistici.org/ai3/build-container/raw/master/common.yml"
stages:
- test
- build
- release
run_tests:
stage: test
image: registry.git.autistici.org/ai3/docker/test/python:master
script:
- tox
artifacts:
when: always
reports:
junit: report.xml
FROM debian:bookworm-slim AS build
RUN apt-get -q update && \
env DEBIAN_FRONTEND=noninteractive apt-get -qy install --no-install-recommends \
python3 python3-dev python3-pip python3-setuptools python3-wheel \
git build-essential libgirepository1.0-dev libcairo2-dev
ADD . /src
WORKDIR /src
RUN mkdir -p dist && \
pip3 wheel -r requirements.txt -w dist && \
python3 setup.py bdist_wheel
#FROM registry.git.autistici.org/ai3/docker/uwsgi-base:master
FROM localhost/uwsgi
COPY --from=build /src/dist/*.whl /tmp/wheels/
RUN cd /tmp/wheels \
&& /virtualenv/bin/pip3 install *.whl \
&& rm -fr /tmp/wheels \
&& apt-get -q update \
&& env DEBIAN_FRONTEND=noninteractive apt-get -qy install --no-install-recommends \
libimage-exiftool-perl gobject-introspection \
libgdk-pixbuf-2.0-0 gir1.2-poppler-0.18 gir1.2-gdkpixbuf-2.0 gir1.2-rsvg-2.0 \
&& apt-get clean \
&& rm -fr /var/lib/apt/lists/*
ENV VIRTUALENV=/virtualenv
ENV UWSGI_ENGINE=threads
ENV WSGI_APP=mat_api_server.api:create_app
wp-mat-server
===
This is a very simple packaging of the
[mat2](https://0xacab.org/jvoisin/mat2) framework as a HTTP RPC
application. It is meant to be run as an internal trusted service, so
it differs from the default
[mat2-web](https://0xacab.org/jvoisin/mat2-web) application because it
is not centered around a user upload / user download workflow: the RPC
API of *wp-mat-server* just returns the response inline.
The service is meant to be used as the backend for the
[wp-mat](https://git.autistici.org/noblogs/wp-mat) Wordpress plugin.
### Container image
The container image built by this repository's Dockerfile is meant to
be run as a non-root user, in a highly restricted environment. As a
consequence, wp-mat-server does not use *bubblewrap* to further
sandbox mat2 command invocations. If your environment is less
controlled, this might pose a security risk.
from flask import Flask, abort, request, send_file
from libmat2 import parser_factory
import mimetypes
import os
import tempfile
app = Flask(__name__)
def create_app():
# Simple config from environment variables.
app.config.update({
'UPLOAD_DIR': os.getenv('UPLOAD_DIR'),
})
return app
def get_parser_by_mime_type(path, mime_type):
for parser_class in parser_factory._get_parsers():
if mime_type in parser_class.mimetypes:
return parser_class(path)
def process_file(path, mime_type):
app.logger.info('processing file %s (%s)', path, mime_type)
parser = get_parser_by_mime_type(path, mime_type)
if not parser:
app.logger.error("unsupported mime type '%s'", mime_type)
abort(422)
if not parser.remove_all():
app.logger.error('failed to clean file')
abort(422)
return parser.output_filename
@app.route('/api/cleanup', methods=('POST',))
def cleanup():
if 'file' not in request.files:
abort(400)
mime_type = request.form['mime_type']
uploaded_file = request.files['file']
if uploaded_file.filename == '':
abort(400)
# Everything (input and output) needs to be file-backed because
# mat needs to invoke external programs. And the input extension
# needs to be correct as well, there are several checks for it
# in the mat2 code.
with tempfile.NamedTemporaryFile(
dir=app.config.get('UPLOAD_DIR'),
suffix=mimetypes.guess_extension(mime_type)) as tmpf:
uploaded_file.save(tmpf)
output_file = process_file(tmpf.name, mime_type)
try:
return send_file(output_file)
finally:
os.remove(output_file)
mat_api_server/test/test.jpg

53.7 KiB

import pathlib
import pytest
from mat_api_server.api import app as flask_app
resources = pathlib.Path(__file__).parent
@pytest.fixture()
def app():
flask_app.config.update({
"TESTING": True,
})
yield flask_app
@pytest.fixture()
def client(app):
return app.test_client()
def test_cleanup_image(client):
testfd = (resources / "test.jpg").open("rb")
response = client.post(
"/api/cleanup", data={
"mime_type": "image/jpeg",
"file": (testfd, "test.jpg", "image/jpeg"),
})
assert response.status_code == 200
# Dirty check for "have we got a bunch of data that looks a bit
# like a JPEG"?
assert len(response.data) > 1024
assert b'JFIF' in response.data
setup.py 0 → 100644
from setuptools import setup, find_packages
setup(
name='mat_api_server',
version='0.1',
description='Simple API server for MAT2',
packages=find_packages(),
install_requires=[
'Flask',
'mat2',
],
)
[tox]
envlist = py3
[testenv]
deps=
pytest
commands=
pytest --junitxml=report.xml []
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment