Browse Source

Move stuff around

main
Sam Hatfield 3 months ago
parent
commit
04bb61b2f7
  1. 17
      Makefile
  2. 2
      api/default.nix
  3. 0
      api/mach.nix
  4. 2
      api/shell.nix
  5. 5
      cli/.envrc
  6. 2
      cli/.gitignore
  7. 1
      cli/default.nix
  8. 3
      cli/pyproject.toml
  9. 30
      cli/setup.cfg
  10. 4
      cli/setup.py
  11. 2
      cli/shell.nix
  12. 0
      cli/src/pea_cli/__init__.py
  13. 56
      cli/src/pea_cli/auth.py
  14. 15
      cli/src/pea_cli/main.py
  15. 113
      cli/src/pea_cli/user.py
  16. 12
      flake.lock
  17. 49
      flake.nix
  18. 4
      scripts/backup.sh
  19. 1
      tests/.envrc
  20. 15
      tests/Makefile
  21. 123
      tests/flake.lock
  22. 58
      tests/flake.nix

17
Makefile

@ -1,7 +1,6 @@
.PHONY: clean
clean:
if [[ -L "result" ]]; then rm result; fi
${MAKE} -C tests clean
${MAKE} -C app clean
.PHONY: api
@ -12,10 +11,14 @@ api:
app:
nix build .#app
.PHONY: test-build
test-build:
${MAKE} -C tests build
.PHONY: build
build: update
nix build .#nixosConfigurations.pea-test.config.system.build.toplevel
.PHONY: container
container:
${MAKE} -C tests deploy
.PHONY: deploy
deploy: update
sudo nixos-container update pea-test --flake .
.PHONY: update
update:
nix flake update

2
api/default.nix

@ -1 +1 @@
{ mach-nix ? import ../mach.nix, ... }: mach-nix.mkPython [ ./. ]
{ mach-nix ? import ./mach.nix, ... }: mach-nix.mkPython [ ./. ]

0
mach.nix → api/mach.nix

2
api/shell.nix

@ -1,2 +1,2 @@
{ mach-nix ? import ../mach.nix, ... }:
{ mach-nix ? import ./mach.nix, ... }:
mach-nix.mkPythonShell [ ./. ]

5
cli/.envrc

@ -1,5 +0,0 @@
use nix
dotenv ../.env
layout python

2
cli/.gitignore vendored

@ -1,2 +0,0 @@
__pycache__
*.egg-info

1
cli/default.nix

@ -1 +0,0 @@
{ mach-nix ? import ../mach.nix, ... }: mach-nix.mkPython [ ./. ]

3
cli/pyproject.toml

@ -1,3 +0,0 @@
[build-system]
requires = ["setuptools>=42", "wheel"]
build-backend = "setuptools.build_meta"

30
cli/setup.cfg

@ -1,30 +0,0 @@
[metadata]
name = pea_cli
version = 0.1.0
author = Sam Hatfield (@sehqlr)
author_email = hey@samhatfield.me
description = CLI tool for Personal Effectivity Application
long_description = file: README.md
long_description_content_type = text/markdown
url = https://git.bytes.zone/sehqlr/personal-effectivity-application
project_urls =
Bug Tracker = https://git.bytes.zone/sehqlr/personal-effectivity-application/issues
classifiers =
Programming Language :: Python :: 3
License :: OSI Approved :: MIT License
Operating System :: OS Independent
[options]
package_dir =
= src
packages = find:
python_requires = >= 3.8
include_package_data = True
install_requires =
black
requests
requests_oauthlib
typer[all]
[options.packages.find]
where = src

4
cli/setup.py

@ -1,4 +0,0 @@
from setuptools import setup
if __name__ == "__main__":
setup()

2
cli/shell.nix

@ -1,2 +0,0 @@
{ mach-nix ? import ../mach.nix, ... }:
mach-nix.mkPythonShell [ ./. ]

0
cli/src/pea_cli/__init__.py

56
cli/src/pea_cli/auth.py

@ -1,56 +0,0 @@
from os import environ
import typer
import requests
from dotenv import load_dotenv
load_dotenv()
PEA_API_URL = environ.get("PEA_API_URL")
class TokenAuth(requests.auth.AuthBase):
def __init__(self, username, password):
self.data = {
"username": username,
"password": password,
}
if env_token is None:
self.save_token(self.fetch_token())
else:
self.save_token(
@property
def token(self):
env_token = environ.get("PEA_API_AUTH_TOKEN", None)
if env_token is None:
response = requests.post(PEA_API_URL, data=self.data)
self.token = response.json()["access_token"]
return env_token
@token.setter
def token(self, new_token):
environ["PEA_API_AUTH_TOKEN"] = new_token
@token.deleter
def token(self):
del environ["PEA_API_AUTH_TOKEN"]
def __eq__(self, other):
return self.token == getattr(other, "token", None)
def __ne__(self, other):
return not self == other
def __call__(self, r):
r.headers["Authorization"] = f"Bearer {self.token}"
return r
app = typer.Typer()
@app.command("login")
def save_credentials(username: str, password: str):
environ["PEA_CLI_USERNAME"] = username
environ["PEA_CLI_PASSWORD"] = password

15
cli/src/pea_cli/main.py

@ -1,15 +0,0 @@
from __future__ import annotations
import requests
import typer
from pea_cli.auth import TokenAuth
app = typer.Typer()
session = requests.Session()
session.auth(
if __name__ == "__main__":
app()

113
cli/src/pea_cli/user.py

@ -1,113 +0,0 @@
from __future__ import annotations
from pathlib import Path
import typer
from passlib.context import CryptContext
import requests
from pea_cli.auth import TokenAuth
app = typer.Typer()
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
def hash_passwd(password: str):
return pwd_context.hash(password)
def password_callback(value: str):
if not len(value) > 0:
raise typer.BadParameter("Passwords cannot be empty")
@app.command("create")
def create_user(
username: str,
email: str,
disabled: bool = False,
superuser: bool = False,
api_url: Path = typer.Argument(..., envvar="PEA_API_URL")
):
password = typer.prompt("Password", hide_input=True)
typer.echo(f"User {db_user.username} has been created")
@app.command("list")
def list_users():
db_users = db.query(DB.User).all()
typer.echo("ID\tUSERNAME\tEMAIL")
for user in db_users:
typer.echo(f"{user.id}\t{user.username}\t{user.email}")
@app.command("rename")
def update_user_username(old_username: str, new_username):
db_query = db.query(DB.User).filter(DB.User.username == old_username)
if db_query.count() == 0:
typer.echo("Username not register")
else:
db_user = db_query.first()
db_user.username = new_username
db.commit()
@app.command("passwd")
def update_user_password(
username: str,
):
password = typer.prompt("New Password", hide_input=True)
db_user = db.query(DB.User).filter(DB.User.username == username).first()
hashed_password = hash_passwd(password)
db_user.hashed_password = hashed_password
db.commit()
typer.echo(f"User {db_user.id}'s password has been updated")
@app.command("disable")
def disable_user(username: str):
db_user = db.query(DB.User).filter(DB.User.username == username).first()
if db_user.disabled:
typer.echo("User already disabled")
else:
db_user.disabled = True
db.commit()
typer.echo(f"User {db_user.id} has been disabled")
@app.command("activate")
def activate_user(username: str):
db_user = db.query(DB.User).filter(DB.User.username == username).first()
if not db_user.disabled:
typer.echo("User already activated")
else:
db_user.disabled = False
db.commit()
typer.echo(f"User {db_user.id} has been activated")
@app.command("promote")
def promote_user(username: str):
db_user = db.query(DB.User).filter(DB.User.username == username).first()
if db_user.superuser:
typer.echo("User already promoted")
else:
db_user.superuser = True
db.commit()
typer.echo(f"User {db_user.id} has been promoted")
@app.command("demote")
def demote_user(email: str):
db_user = db.query(DB.User).filter(DB.User.username == username).first()
if not db_user.superuser:
typer.echo("User already demoted")
else:
db_user.superuser = False
db.commit()
typer.echo(f"User {db_user.id} has been demoted")
if __name__ == "__main__":
app()

12
flake.lock

@ -2,11 +2,11 @@
"nodes": {
"flake-utils": {
"locked": {
"lastModified": 1644229661,
"narHash": "sha256-1YdnJAsNy69bpcjuoKdOYQX0YxZBiCYZo4Twxerqv7k=",
"lastModified": 1652776076,
"narHash": "sha256-gzTw/v1vj4dOVbpBSJX4J0DwUR6LIyXo7/SuuTJp1kM=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "3cecb5b042f7f209c56ffd8371b2711a290ec797",
"rev": "04c1b180862888302ddfb2e3ad9eaa63afc60cf8",
"type": "github"
},
"original": {
@ -67,11 +67,11 @@
},
"nixpkgs_2": {
"locked": {
"lastModified": 1644600908,
"narHash": "sha256-TLWxMZAgn4o+y4DgCwzbzhI0vrZ45CmQo4EbhzhH1Ko=",
"lastModified": 1653087707,
"narHash": "sha256-zfno3snrzZTWQ2B7K53QHrGZwrjnJLTRPalymrSsziU=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b1396e289d341cbd0a6751f2ffd014ac461526dd",
"rev": "cbd40c72b2603ab54e7208f99f9b35fc158bc009",
"type": "github"
},
"original": {

49
flake.nix

@ -224,9 +224,7 @@
alias = pkg;
tryFiles = "$uri /index.html";
};
"/index.html" = {
root = pkg;
};
"/index.html" = { root = pkg; };
};
};
}
@ -263,5 +261,48 @@
};
*/
};
});
}) // {
nixosConfigurations.pea-test = let system = "x86_64-linux"; in nixpkgs.lib.nixosSystem {
modules = [
({ lib, ... }: {
boot.isContainer = true;
system.configurationRevision = lib.mkIf (self ? rev) self.rev;
networking.useDHCP = false;
})
self.nixosModules.${system}.api
self.nixosModules.${system}.app
({ config, ... }:
let apiSubdir = "/api";
in {
networking.firewall.allowedTCPPorts =
[ config.services.postgresql.port ];
services.pea = {
api = {
enable = true;
dotEnvFile = "/run/keys/pea.env";
webAttrs.subdir = apiSubdir;
};
app = {
enable = true;
webAttrs = {
scheme = null;
domain = null;
subdir = "/app";
};
apiAttrs.subdir = apiSubdir;
};
};
services.postgresql = {
enableTCPIP = true;
authentication = ''
local pea-db pea-user trust
host pea-db pea-user 10.233.1.1/32 trust
host pea-db pea-user samehost trust
'';
};
})
];
};
};
}

4
scripts/backup.sh

@ -1,4 +0,0 @@
#! /usr/bin/env nix-shell
#! nix-shell -i bash -p sqlite
sqlite3 $PEA_DB_CONNECTION ".dump" >> "$PEA_DB_BACKUPS_DIR/"`date -Iseconds`.sql

1
tests/.envrc

@ -1 +0,0 @@
use flake

15
tests/Makefile

@ -1,15 +0,0 @@
.PHONY: build
build: update
nix build .#nixosConfigurations.container.config.system.build.toplevel
.PHONY: deploy
deploy: update
sudo nixos-container update pea-test --flake .
.PHONY: update
update:
nix flake update
.PHONY: clean
clean:
if [[ -L "result" ]]; then rm result; fi

123
tests/flake.lock

@ -1,123 +0,0 @@
{
"nodes": {
"flake-utils": {
"locked": {
"lastModified": 1644229661,
"narHash": "sha256-1YdnJAsNy69bpcjuoKdOYQX0YxZBiCYZo4Twxerqv7k=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "3cecb5b042f7f209c56ffd8371b2711a290ec797",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_2": {
"locked": {
"lastModified": 1642700792,
"narHash": "sha256-XqHrk7hFb+zBvRg6Ghl+AZDq03ov6OshJLiSWOoX5es=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "846b2ae0fc4cc943637d3d1def4454213e203cba",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"mach-nix": {
"inputs": {
"flake-utils": "flake-utils_2",
"nixpkgs": "nixpkgs",
"pypi-deps-db": "pypi-deps-db"
},
"locked": {
"lastModified": 1643953409,
"narHash": "sha256-CJDg/RpZdUVyI3QIAXUqIoYDl7VkxFtNE4JWih0ucKc=",
"owner": "DavHau",
"repo": "mach-nix",
"rev": "fe5255e6fd8df57e9507b7af82fc59dda9e9ff2b",
"type": "github"
},
"original": {
"id": "mach-nix",
"ref": "3.4.0",
"type": "indirect"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1643805626,
"narHash": "sha256-AXLDVMG+UaAGsGSpOtQHPIKB+IZ0KSd9WS77aanGzgc=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "554d2d8aa25b6e583575459c297ec23750adb6cb",
"type": "github"
},
"original": {
"id": "nixpkgs",
"ref": "nixos-unstable",
"type": "indirect"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1644600908,
"narHash": "sha256-TLWxMZAgn4o+y4DgCwzbzhI0vrZ45CmQo4EbhzhH1Ko=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b1396e289d341cbd0a6751f2ffd014ac461526dd",
"type": "github"
},
"original": {
"id": "nixpkgs",
"ref": "release-21.11",
"type": "indirect"
}
},
"pea": {
"inputs": {
"flake-utils": "flake-utils",
"mach-nix": "mach-nix",
"nixpkgs": "nixpkgs_2"
},
"locked": {
"narHash": "sha256-QJWmOFSv7RAdPohg5Am51XAGvYmXal1WpEQRTcCux2c=",
"path": "..",
"type": "path"
},
"original": {
"path": "..",
"type": "path"
}
},
"pypi-deps-db": {
"flake": false,
"locked": {
"lastModified": 1643877077,
"narHash": "sha256-jv8pIvRFTP919GybOxXE5TfOkrjTbdo9QiCO1TD3ZaY=",
"owner": "DavHau",
"repo": "pypi-deps-db",
"rev": "da53397f0b782b0b18deb72ef8e0fb5aa7c98aa3",
"type": "github"
},
"original": {
"owner": "DavHau",
"repo": "pypi-deps-db",
"type": "github"
}
},
"root": {
"inputs": {
"pea": "pea"
}
}
},
"root": "root",
"version": 7
}

58
tests/flake.nix

@ -1,58 +0,0 @@
{
description = "NixOS container flake configuration, for testing PEA";
inputs = { pea.url = "path:.."; };
outputs = { self, pea, ... }:
let
nixpkgs = pea.inputs.nixpkgs;
system = "x86_64-linux";
pkgs = nixpkgs.legacyPackages.${system};
in {
devShell.${system} =
pkgs.mkShell { buildInputs = with pkgs; [ gnumake ]; };
nixosConfigurations.container = nixpkgs.lib.nixosSystem {
inherit system;
modules = [
({ lib, ... }: {
boot.isContainer = true;
system.configurationRevision = lib.mkIf (self ? rev) self.rev;
networking.useDHCP = false;
})
pea.nixosModules.${system}.api
pea.nixosModules.${system}.app
({ config, ... }:
let apiSubdir = "/api";
in {
networking.firewall.allowedTCPPorts =
[ config.services.postgresql.port ];
services.pea = {
api = {
enable = true;
dotEnvFile = "/run/keys/pea.env";
webAttrs.subdir = apiSubdir;
};
app = {
enable = true;
webAttrs = {
scheme = null;
domain = null;
subdir = "/app";
};
apiAttrs.subdir = apiSubdir;
};
};
services.postgresql = {
enableTCPIP = true;
authentication = ''
local pea-db pea-user trust
host pea-db pea-user 10.233.1.1/32 trust
host pea-db pea-user samehost trust
'';
};
})
];
};
};
}
Loading…
Cancel
Save