2021-11-11 18:31:28 +00:00
|
|
|
#!/usr/bin/env python3
|
2021-11-16 16:14:01 +00:00
|
|
|
"""SelfPrivacy server management API"""
|
|
|
|
import os
|
2021-12-06 06:48:29 +00:00
|
|
|
from gevent import monkey
|
|
|
|
|
|
|
|
|
2021-11-16 10:32:10 +00:00
|
|
|
from flask import Flask, request, jsonify
|
2021-11-11 18:31:28 +00:00
|
|
|
from flask_restful import Api
|
2021-11-16 16:14:01 +00:00
|
|
|
from flask_swagger import swagger
|
|
|
|
from flask_swagger_ui import get_swaggerui_blueprint
|
2022-06-24 17:25:49 +00:00
|
|
|
from flask_cors import CORS
|
2021-11-11 18:31:28 +00:00
|
|
|
|
2022-06-24 13:05:18 +00:00
|
|
|
from strawberry.flask.views import AsyncGraphQLView
|
|
|
|
|
2021-11-16 16:14:01 +00:00
|
|
|
from selfprivacy_api.resources.users import User, Users
|
2022-01-10 20:35:00 +00:00
|
|
|
from selfprivacy_api.resources.common import ApiVersion
|
2021-11-16 16:14:01 +00:00
|
|
|
from selfprivacy_api.resources.system import api_system
|
|
|
|
from selfprivacy_api.resources.services import services as api_services
|
2022-01-14 05:38:53 +00:00
|
|
|
from selfprivacy_api.resources.api_auth import auth as api_auth
|
2021-11-16 16:14:01 +00:00
|
|
|
|
2022-08-02 19:50:16 +00:00
|
|
|
from selfprivacy_api.utils.huey import huey
|
|
|
|
from selfprivacy_api.restic_controller.tasks import init_restic
|
2021-12-06 06:48:29 +00:00
|
|
|
|
2022-01-11 05:36:11 +00:00
|
|
|
from selfprivacy_api.migrations import run_migrations
|
|
|
|
|
2022-01-14 05:38:53 +00:00
|
|
|
from selfprivacy_api.utils.auth import is_token_valid
|
|
|
|
|
2022-06-24 17:12:32 +00:00
|
|
|
from selfprivacy_api.graphql.schema import schema
|
2022-06-24 13:05:18 +00:00
|
|
|
|
2021-11-16 16:14:01 +00:00
|
|
|
swagger_blueprint = get_swaggerui_blueprint(
|
|
|
|
"/api/docs", "/api/swagger.json", config={"app_name": "SelfPrivacy API"}
|
|
|
|
)
|
2021-11-11 18:31:28 +00:00
|
|
|
|
|
|
|
|
2021-11-29 19:16:08 +00:00
|
|
|
def create_app(test_config=None):
|
2021-11-16 16:14:01 +00:00
|
|
|
"""Initiate Flask app and bind routes"""
|
2021-11-11 18:31:28 +00:00
|
|
|
app = Flask(__name__)
|
|
|
|
api = Api(app)
|
2022-06-24 17:25:49 +00:00
|
|
|
CORS(app)
|
2021-11-11 18:31:28 +00:00
|
|
|
|
2021-11-29 19:16:08 +00:00
|
|
|
if test_config is None:
|
|
|
|
app.config["ENABLE_SWAGGER"] = os.environ.get("ENABLE_SWAGGER", "0")
|
2021-12-02 15:06:23 +00:00
|
|
|
app.config["B2_BUCKET"] = os.environ.get("B2_BUCKET")
|
2021-11-29 19:16:08 +00:00
|
|
|
else:
|
|
|
|
app.config.update(test_config)
|
2021-11-16 10:32:10 +00:00
|
|
|
|
|
|
|
# Check bearer token
|
|
|
|
@app.before_request
|
|
|
|
def check_auth():
|
2022-01-14 05:38:53 +00:00
|
|
|
# Exclude swagger-ui, /auth/new_device/authorize, /auth/recovery_token/use
|
|
|
|
if request.path.startswith("/api"):
|
|
|
|
pass
|
|
|
|
elif request.path.startswith("/auth/new_device/authorize"):
|
|
|
|
pass
|
|
|
|
elif request.path.startswith("/auth/recovery_token/use"):
|
|
|
|
pass
|
2022-06-24 15:21:13 +00:00
|
|
|
elif request.path.startswith("/graphql"):
|
|
|
|
pass
|
2022-01-14 05:38:53 +00:00
|
|
|
else:
|
2021-11-16 16:14:01 +00:00
|
|
|
auth = request.headers.get("Authorization")
|
|
|
|
if auth is None:
|
|
|
|
return jsonify({"error": "Missing Authorization header"}), 401
|
2022-01-14 05:38:53 +00:00
|
|
|
# Strip Bearer from auth header
|
|
|
|
auth = auth.replace("Bearer ", "")
|
|
|
|
if not is_token_valid(auth):
|
2021-11-16 16:14:01 +00:00
|
|
|
return jsonify({"error": "Invalid token"}), 401
|
|
|
|
|
2021-11-18 07:35:50 +00:00
|
|
|
api.add_resource(ApiVersion, "/api/version")
|
2021-11-11 18:31:28 +00:00
|
|
|
api.add_resource(Users, "/users")
|
2021-11-16 16:14:01 +00:00
|
|
|
api.add_resource(User, "/users/<string:username>")
|
2021-11-11 18:31:28 +00:00
|
|
|
|
|
|
|
app.register_blueprint(api_system)
|
|
|
|
app.register_blueprint(api_services)
|
2022-01-14 05:38:53 +00:00
|
|
|
app.register_blueprint(api_auth)
|
2021-11-11 18:31:28 +00:00
|
|
|
|
2021-11-16 16:14:01 +00:00
|
|
|
@app.route("/api/swagger.json")
|
|
|
|
def spec():
|
|
|
|
if app.config["ENABLE_SWAGGER"] == "1":
|
|
|
|
swag = swagger(app)
|
2022-05-31 08:46:58 +00:00
|
|
|
swag["info"]["version"] = "1.2.7"
|
2021-11-16 16:14:01 +00:00
|
|
|
swag["info"]["title"] = "SelfPrivacy API"
|
|
|
|
swag["info"]["description"] = "SelfPrivacy API"
|
|
|
|
swag["securityDefinitions"] = {
|
|
|
|
"bearerAuth": {
|
|
|
|
"type": "apiKey",
|
|
|
|
"name": "Authorization",
|
|
|
|
"in": "header",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
swag["security"] = [{"bearerAuth": []}]
|
|
|
|
|
|
|
|
return jsonify(swag)
|
|
|
|
return jsonify({}), 404
|
|
|
|
|
2022-06-24 13:05:18 +00:00
|
|
|
app.add_url_rule(
|
2022-06-24 18:14:20 +00:00
|
|
|
"/graphql", view_func=AsyncGraphQLView.as_view("graphql", schema=schema)
|
2022-06-24 13:05:18 +00:00
|
|
|
)
|
|
|
|
|
2021-11-16 16:14:01 +00:00
|
|
|
if app.config["ENABLE_SWAGGER"] == "1":
|
|
|
|
app.register_blueprint(swagger_blueprint, url_prefix="/api/docs")
|
|
|
|
|
2021-11-11 18:31:28 +00:00
|
|
|
return app
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
2021-12-06 06:48:29 +00:00
|
|
|
monkey.patch_all()
|
2021-11-16 16:14:01 +00:00
|
|
|
created_app = create_app()
|
2022-01-11 05:36:11 +00:00
|
|
|
run_migrations()
|
2021-12-06 06:48:29 +00:00
|
|
|
huey.start()
|
|
|
|
init_restic()
|
2021-11-16 16:14:01 +00:00
|
|
|
created_app.run(port=5050, debug=False)
|