From 6fcc8c450fbd0386adf9461955359ad882278f42 Mon Sep 17 00:00:00 2001 From: rndusr Date: Sat, 20 Jan 2024 11:00:03 -0600 Subject: [PATCH] add a mail sync thing for gmail --- README.md | 6 ++- boxes/netbox/default.nix | 14 ++++++- builds/gmail_mail_bridge.nix | 19 ++++++++++ builds/gmail_mail_bridge/.gitignore | 1 + builds/gmail_mail_bridge/README | 10 +++++ builds/gmail_mail_bridge/default.nix | 20 ++++++++++ .../gmail_mail_bridge/__init__.py | 37 +++++++++++++++++++ builds/gmail_mail_bridge/shell.nix | 12 ++++++ builds/gmail_mail_bridge/sync.gas | 23 ++++++++++++ flake.lock | 6 +-- 10 files changed, 142 insertions(+), 6 deletions(-) create mode 100644 builds/gmail_mail_bridge.nix create mode 100644 builds/gmail_mail_bridge/.gitignore create mode 100644 builds/gmail_mail_bridge/README create mode 100644 builds/gmail_mail_bridge/default.nix create mode 100644 builds/gmail_mail_bridge/gmail_mail_bridge/__init__.py create mode 100644 builds/gmail_mail_bridge/shell.nix create mode 100644 builds/gmail_mail_bridge/sync.gas diff --git a/README.md b/README.md index 07a6835..df68e69 100644 --- a/README.md +++ b/README.md @@ -16,9 +16,9 @@ installation `sudo nixos-rebuild --flake .#your-flake-name-here switch` -if you're trying to install `virtbox`, then use the `--impure` flag: +if you're trying to install `netbox`, then use the `--impure` flag: -`sudo nixos-rebuild --flake .#virtbox switch --impure` +`sudo nixos-rebuild --flake .#netbox switch --impure` for alternate installations on non-NixOS hosts, a Makefile will be made available @@ -28,6 +28,8 @@ things to do - integrate `disko` and `sops-nix` into the setup - switch from gitea to cgit - establish backup infrastructure for `netbox` +- move gmail-mail-bridge into mail-sync repo + * (perhaps figure out how to produce a flake for it) license ------- diff --git a/boxes/netbox/default.nix b/boxes/netbox/default.nix index ce56bad..1e015c7 100644 --- a/boxes/netbox/default.nix +++ b/boxes/netbox/default.nix @@ -113,6 +113,7 @@ in { [ ./hardware-configuration.nix ../../modules/bootstrap.nix + ../../builds/gmail_mail_bridge.nix ]; networking.networkmanager.enable = true; @@ -136,6 +137,8 @@ in { neovim ]; + services.gmail_mail_bridge.enable = true; + system.copySystemConfiguration = true; system.stateVersion = "23.05"; # don't change this, lol boot.loader.grub.enable = true; @@ -412,7 +415,16 @@ in { services.nginx.virtualHosts."mail.beepboop.systems" = { forceSSL = true; enableACME = true; - globalRedirect = "cube.beepboop.systems"; + locations."/bridge-submit" = { + extraConfig = '' + proxy_pass http://localhost:8041; + ''; + }; + locations."/" = { + extraConfig = '' + return 301 https://cube.beepboop.systems; + ''; + }; }; networking.firewall = { diff --git a/builds/gmail_mail_bridge.nix b/builds/gmail_mail_bridge.nix new file mode 100644 index 0000000..a81985c --- /dev/null +++ b/builds/gmail_mail_bridge.nix @@ -0,0 +1,19 @@ +{ lib, pkgs, config, ... }: +let + cfg = config.services.gmail_mail_bridge; + appEnv = pkgs.python3.withPackages (p: with p; [ waitress (callPackage ./gmail_mail_bridge/default.nix {}) ]); +in { + options.services.gmail_mail_bridge = { + enable = lib.mkEnableOption "Enable the gmail_mail_bridge"; + }; + + config = lib.mkIf cfg.enable { + systemd.services.gmail_mail_bridge = { + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + ExecStart = "${appEnv}/bin/waitress-serve --port=8041 gmail_mail_bridge:app"; + StandardOutput = "journal"; + }; + }; + }; +} diff --git a/builds/gmail_mail_bridge/.gitignore b/builds/gmail_mail_bridge/.gitignore new file mode 100644 index 0000000..aaca2e2 --- /dev/null +++ b/builds/gmail_mail_bridge/.gitignore @@ -0,0 +1 @@ +__pycache_/ diff --git a/builds/gmail_mail_bridge/README b/builds/gmail_mail_bridge/README new file mode 100644 index 0000000..eae7b1c --- /dev/null +++ b/builds/gmail_mail_bridge/README @@ -0,0 +1,10 @@ +synchronize email from gmail accounts whose OAuth access is heavily restricted + +background +---------- + +my school district disabled external OAuth access to email, which is not cool. this script gets around this and creates a bridge so you can recieve emails from your school email. + +do note that this is heavily unpolished and most definately insecure. there are some hardcoded credentials (which you can change, it just takes a little technical know-how) + +have fun! diff --git a/builds/gmail_mail_bridge/default.nix b/builds/gmail_mail_bridge/default.nix new file mode 100644 index 0000000..bde908a --- /dev/null +++ b/builds/gmail_mail_bridge/default.nix @@ -0,0 +1,20 @@ +{ pkgs, pythonPackages ? (import {}).python3Packages }: +pythonPackages.buildPythonPackage { + name = "gmail_mail_bridge"; + src = ./gmail_mail_bridge; + + propagatedBuildInputs = [ pythonPackages.flask pkgs.system-sendmail ]; + + installPhase = '' + runHook preInstall + + mkdir -p $out/${pythonPackages.python.sitePackages} + cp -r . $out/${pythonPackages.python.sitePackages}/gmail_mail_bridge + + runHook postInstall + ''; + + shellHook = "export FLASK_APP=gmail_mail_bridge"; + + format = "other"; +} diff --git a/builds/gmail_mail_bridge/gmail_mail_bridge/__init__.py b/builds/gmail_mail_bridge/gmail_mail_bridge/__init__.py new file mode 100644 index 0000000..e6a7241 --- /dev/null +++ b/builds/gmail_mail_bridge/gmail_mail_bridge/__init__.py @@ -0,0 +1,37 @@ +from flask import Flask +from flask import request +from flask import redirect +from flask import abort + +import logging + +import smtplib +import email + +from subprocess import Popen, PIPE, STDOUT + +pre_shared_secret = "amongus sussy imposter" +to = "ryan@beepboop.systems" + +app = Flask(__name__) + +def handle_post(request): + msg = email.message_from_string(request.form["payload"]) + del msg["To"] + msg["To"] = to + if not msg["From"]: + msg["From"] = "unknown-sender@mail.beepboop.systems" + + s = smtplib.SMTP('localhost') + s.send_message(msg) + s.quit() + +@app.route("/bridge-submit", methods = ["GET", "POST"]) +def testing(): + if request.method == 'POST': + data = request.form + if data['auth'] == pre_shared_secret: + handle_post(request) + else: + return 'you didn\'t use post' + return "default answer" diff --git a/builds/gmail_mail_bridge/shell.nix b/builds/gmail_mail_bridge/shell.nix new file mode 100644 index 0000000..abd9f69 --- /dev/null +++ b/builds/gmail_mail_bridge/shell.nix @@ -0,0 +1,12 @@ +{ pkgs ? import (fetchTarball "https://github.com/NixOS/nixpkgs/tarball/nixos-23.11") {} }: + +pkgs.mkShell { + packages = [ + (pkgs.python3.withPackages (ps: [ + ps.flask + ])) + + pkgs.curl + pkgs.jq + ]; +} diff --git a/builds/gmail_mail_bridge/sync.gas b/builds/gmail_mail_bridge/sync.gas new file mode 100644 index 0000000..0df9d17 --- /dev/null +++ b/builds/gmail_mail_bridge/sync.gas @@ -0,0 +1,23 @@ +// google-side synchronization +// add a minute-wise trigger for mail synchronization +// go to the sidebar, select triggers, add a new one, configure it +// to run syncMail every minute + +function syncMail() { + var threads = GmailApp.search("label:need_processing"); + var label = GmailApp.getUserLabelByName("need_processing"); + for (var thread of threads) { + for (var message of GmailApp.getMessagesForThread(thread)) { + var formData = { + auth: 'amongus sussy imposter', + payload: message.getRawContent(), + }; + var options = { + 'method' : 'POST', + 'payload' : formData + }; + var resp = UrlFetchApp.fetch('https://mail.beepboop.systems/bridge-submit', options); + } + thread.removeLabel(label); + } +} diff --git a/flake.lock b/flake.lock index a513034..ca92b72 100644 --- a/flake.lock +++ b/flake.lock @@ -209,12 +209,12 @@ }, "locked": { "lastModified": 1, - "narHash": "sha256-wGl3ZnqjhpAEpTkzgjWxgsbmGX9c7TPCM4I0okuOYFE=", - "path": "/nix/store/2fjha7mwjnlsmd4s3y7a3lfk3lq3w87z-source/builds", + "narHash": "sha256-laeQplEc8BPopbQGvBMcjkf3eP8WTjQsHGTOlmQ2eK4=", + "path": "/nix/store/yyh8xblrdvii3cdw9rzyvf8fpyra3ias-source/builds", "type": "path" }, "original": { - "path": "/nix/store/2fjha7mwjnlsmd4s3y7a3lfk3lq3w87z-source/builds", + "path": "/nix/store/yyh8xblrdvii3cdw9rzyvf8fpyra3ias-source/builds", "type": "path" } },