add password

This commit is contained in:
Valentin Boettcher 2024-04-05 22:11:51 -04:00
parent 1d96d930db
commit f5a0af281f
No known key found for this signature in database
GPG key ID: E034E12B7AF56ACE
6 changed files with 48 additions and 22 deletions

View file

@ -2,12 +2,18 @@ from pathlib import Path
import tomllib
from types import SimpleNamespace
import sys
import json
import gnupg
gpg = gnupg.GPG()
def get_config(profile):
with open(Path.home() / ".o365-auth-config.toml", "rb") as f:
toplevel_data = tomllib.load(f)
password = None
if "security" in toplevel_data and "password" in toplevel_data["security"]:
password = Path(toplevel_data["security"]["PasswordPath"]).read_text().strip()
default_data = toplevel_data["default"]
config_data = default_data | toplevel_data.get(profile, {})
@ -20,8 +26,33 @@ def get_config(profile):
Scopes = config_data["Scopes"],
CacheFile = cache_path / "cache.json",
Authority = config_data["Authority"] or None,
Password = password
)
def get_cache(config):
if not config.CacheFile.exists():
return None
data = config.CacheFile.read_text()
if config.Password:
data = gpg.decrypt(data, passphrase=config.Password).data.decode("utf-8")
return json.loads(data)
def write_cache(config, token):
with open(config.CacheFile, "w") as f:
payload = {'refresh_token': token['refresh_token'],
'expires_in': token['expires_in'],
'access_token': token['access_token']}
json_string = json.dumps(payload)
if config.Password:
encrypted_data = gpg.encrypt(json_string, symmetric="AES256", passphrase=config.Password, armor=True, recipients=None)
json_string = str(encrypted_data)
f.write(json_string)
if __name__ == "__main__":
if len(sys.argv) < 3:
sys.exit(f"Usage: {sys.argv[0]} <profile> <key>")

View file

@ -3,5 +3,4 @@ ClientId = "08162f7c-0fd2-4200-a84a-f25a4db0b584"
ClientSecret = "TxRBilcHdC6WGBee]fs?QR:SJ8nI[g82"
Scopes = ['https://outlook.office.com/IMAP.AccessAsUser.All','https://outlook.office.com/SMTP.Send']
Authority = false
[mcgill]
PasswordPath = false

View file

@ -22,7 +22,7 @@
name = "o365-auth";
propagatedBuildInputs = [
(pkgs.python3.withPackages (pythonPackages: with pythonPackages; [
msal
msal python-gnupg
]))
];
dontUnpack = true;

View file

@ -78,8 +78,4 @@ if 'error' in token:
print(token)
sys.exit("Failed to get access token")
with open(profile_config.CacheFile, 'w') as f:
json.dump({'refresh_token': token['refresh_token'],
'expires_in': token['expires_in'],
'access_token': token['access_token']}, f)
config.write_cache(profile_config, token)

View file

@ -17,6 +17,9 @@ in
type = types.package;
default = package;
};
passwordPath = mkOption {
type = types.str;
};
config = mkOption {
type = types.str;
default = ''
@ -25,12 +28,14 @@ in
ClientSecret = "TxRBilcHdC6WGBee]fs?QR:SJ8nI[g82"
Scopes = ['https://outlook.office.com/IMAP.AccessAsUser.All','https://outlook.office.com/SMTP.Send']
Authority = false
Timeout = 3600
'';
};
};
config = mkIf cfg.enable {
home.packages = [ cfg.package ];
home.file.".o365-auth-config.toml".text = cfg.config;
home.file.".o365-auth-config.toml".text = cfg.config + ''
[security]
PasswordPath = "${cfg.passwordPath}"
'';
};
}

View file

@ -4,7 +4,7 @@ import config
import sys
import os
import time
import json
print_access_token = True
if len(sys.argv) > 1:
@ -19,11 +19,10 @@ cache = SerializableTokenCache()
app = ConfidentialClientApplication(profile_config.ClientId, client_credential=profile_config.ClientSecret, token_cache=cache, authority=profile_config.Authority)
if not profile_config.CacheFile.exists():
token_cache = config.get_cache(profile_config)
if not token_cache:
sys.exit("Please get the initial token by running `o365-get-token` first.")
token_cache = json.loads(profile_config.CacheFile.read_text())
st = os.stat(profile_config.CacheFile)
if (time.time()-st.st_mtime) < token_cache["expires_in"]:
print(token_cache["access_token"])
@ -37,10 +36,6 @@ if 'error' in token:
sys.exit("Failed to get access token")
# you're supposed to save the old refresh token each time
with open(profile_config.CacheFile, 'w') as f:
json.dump({'refresh_token': token['refresh_token'],
'expires_in': token['expires_in'],
'access_token': token['access_token']}, f)
if print_access_token:
config.write_cache(profile_config, token)
if print_access_token:
print(token['access_token'])