diff --git a/nixbld-etc-nixos/configuration.nix b/nixbld-etc-nixos/configuration.nix index 5227255..3fdbee9 100644 --- a/nixbld-etc-nixos/configuration.nix +++ b/nixbld-etc-nixos/configuration.nix @@ -526,9 +526,13 @@ in "hooks.m-labs.hk" = { forceSSL = true; useACMEHost = "nixbld.m-labs.hk"; - locations."/".extraConfig = '' + locations."/mattermost-github".extraConfig = '' include ${pkgs.nginx}/conf/uwsgi_params; - uwsgi_pass unix:${config.services.uwsgi.runDir}/uwsgi.sock; + uwsgi_pass unix:${config.services.uwsgi.runDir}/uwsgi-mgi.sock; + ''; + locations."/rfq".extraConfig = '' + include ${pkgs.nginx}/conf/uwsgi_params; + uwsgi_pass unix:${config.services.uwsgi.runDir}/uwsgi-rfq.sock; ''; }; "forum.m-labs.hk" = { @@ -581,6 +585,7 @@ in type = "emperor"; vassals = { mattermostgithub = import ./mattermost-github-integration/uwsgi-config.nix { inherit config pkgs; }; + rfq = import ./rfq/uwsgi-config.nix { inherit config pkgs; }; }; }; }; diff --git a/nixbld-etc-nixos/mattermost-github-integration/uwsgi-config.nix b/nixbld-etc-nixos/mattermost-github-integration/uwsgi-config.nix index d08dcff..51387c6 100644 --- a/nixbld-etc-nixos/mattermost-github-integration/uwsgi-config.nix +++ b/nixbld-etc-nixos/mattermost-github-integration/uwsgi-config.nix @@ -9,7 +9,7 @@ in { env = [ "MGI_CONFIG_FILE=${./../secret/mattermost-github-integration.py}" ]; - socket = "${config.services.uwsgi.runDir}/uwsgi.sock"; + socket = "${config.services.uwsgi.runDir}/uwsgi-mgi.sock"; # allow access from nginx chmod-socket = 666; } diff --git a/nixbld-etc-nixos/rfq/pkg.nix b/nixbld-etc-nixos/rfq/pkg.nix new file mode 100644 index 0000000..d7fcc0b --- /dev/null +++ b/nixbld-etc-nixos/rfq/pkg.nix @@ -0,0 +1,9 @@ +{ python3Packages, runCommand }: + +# Note: we do not use fetchgit but a local copy instead to avoid +# chicken-and-egg problem if reinstalling nixbld.m-labs.hk from scratch. +with python3Packages; buildPythonPackage rec { + name = "rfq"; + src = ./src; + propagatedBuildInputs = [ flask flask_mail python-dotenv ]; +} diff --git a/nixbld-etc-nixos/rfq/src/requirements.txt b/nixbld-etc-nixos/rfq/src/requirements.txt new file mode 100644 index 0000000..df5ebfe --- /dev/null +++ b/nixbld-etc-nixos/rfq/src/requirements.txt @@ -0,0 +1,10 @@ +blinker +click +Flask +Flask-Mail +itsdangerous +Jinja2 +MarkupSafe +python-dotenv +six +Werkzeug diff --git a/nixbld-etc-nixos/rfq/src/rfq/__init__.py b/nixbld-etc-nixos/rfq/src/rfq/__init__.py new file mode 100644 index 0000000..35734cf --- /dev/null +++ b/nixbld-etc-nixos/rfq/src/rfq/__init__.py @@ -0,0 +1,75 @@ +from os import getenv + +from dotenv import load_dotenv +from flask import Flask +from flask import current_app +from flask import json +from flask import jsonify +from flask import make_response +from flask import request +from flask_mail import Mail +from flask_mail import Message +from werkzeug.middleware.proxy_fix import ProxyFix + + +load_dotenv() + +app = Flask(__name__) +app.config.update( + DEBUG=getenv("FLASK_DEBUG") == "True", + MAIL_SERVER=getenv("FLASK_MAIL_SERVER"), + MAIL_PORT=getenv("FLASK_MAIL_PORT"), + MAIL_USE_SSL=getenv("FLASK_MAIL_USE_SSL"), + MAIL_DEBUG=False, + MAIL_USERNAME=getenv("FLASK_MAIL_USERNAME"), + MAIL_PASSWORD=getenv("FLASK_MAIL_PASSWORD"), + MAIL_RECIPIENT=getenv("FLASK_MAIL_RECIPIENT"), + MAIL_SENDER=getenv("FLASK_MAIL_SENDER") +) +app.wsgi_app = ProxyFix(app.wsgi_app) + +mail = Mail(app) + + +@app.after_request +def after(response): + response.headers["Access-Control-Allow-Origin"] = "*" + response.headers["Access-Control-Allow-Headers"] = "*" + return response + + +@app.route("/rfq", methods=["POST"]) +def send_rfq(): + payload = request.json + payload = json.loads(json.htmlsafe_dumps(payload)) + + if payload is None: + resp = jsonify(error="invalid data") + return make_response(resp, 400) + + if "email" not in payload: + resp = jsonify(error="missing email") + return make_response(resp, 400) + + if "note" not in payload: + resp = jsonify(error="missing note") + return make_response(resp, 400) + + if "configuration" not in payload: + resp = jsonify(error="missing configuration") + return make_response(resp, 400) + + sender = current_app.config["MAIL_SENDER"] + recipient = current_app.config["MAIL_RECIPIENT"] + + msg = Message( + "RFQ for Sinara hardware from {}".format(payload["email"]), + sender=sender, + recipients=[recipient, payload["email"]]) + msg.body = ("From: {}\nConfiguration: {}\nNote: {}" + .format(payload["email"], payload["configuration"], payload["note"])) + + with mail.connect() as conn: + conn.send(msg) + + return jsonify("ok") diff --git a/nixbld-etc-nixos/rfq/src/setup.py b/nixbld-etc-nixos/rfq/src/setup.py new file mode 100644 index 0000000..df9cf61 --- /dev/null +++ b/nixbld-etc-nixos/rfq/src/setup.py @@ -0,0 +1,14 @@ +from setuptools import setup +from setuptools import find_packages + +setup( + name='rfq', + version='1.0.0', + packages=find_packages(), + zip_safe=False, + install_requires=[ + 'Flask', + 'Flask-Mail', + 'python-dotenv' + ] +) diff --git a/nixbld-etc-nixos/rfq/uwsgi-config.nix b/nixbld-etc-nixos/rfq/uwsgi-config.nix new file mode 100644 index 0000000..b301fa3 --- /dev/null +++ b/nixbld-etc-nixos/rfq/uwsgi-config.nix @@ -0,0 +1,21 @@ +{ config, pkgs }: + +let + pkg = pkgs.callPackage ./pkg.nix {}; +in { + type = "normal"; + pythonPackages = self: [ pkg ]; + module = "rfq:app"; + env = [ + "FLASK_MAIL_SERVER=ssl.serverraum.org" + "FLASK_MAIL_PORT=465" + "FLASK_MAIL_USE_SSL=True" + "FLASK_MAIL_USERNAME=sales@m-labs.hk" + "FLASK_MAIL_PASSWORD=${import /etc/nixos/secret/sales_password.nix}" + "FLASK_MAIL_RECIPIENT=sales@m-labs.hk" + "FLASK_MAIL_SENDER=sales@m-labs.hk" + ]; + socket = "${config.services.uwsgi.runDir}/uwsgi-rfq.sock"; + # allow access from nginx + chmod-socket = 666; +}