From 0d6a953944b01173d3a1a56e1a135e9704c309a4 Mon Sep 17 00:00:00 2001 From: Daniel Bosk Date: Mon, 20 Jan 2025 09:27:31 +0100 Subject: [PATCH] Changes priority of credentials This helps us with the problem that the keyring requires a password on WSL. --- src/ladok3/cli.nw | 112 ++++++++++++++++++++++++---------------------- 1 file changed, 59 insertions(+), 53 deletions(-) diff --git a/src/ladok3/cli.nw b/src/ladok3/cli.nw index f81d82d..4d95b58 100644 --- a/src/ladok3/cli.nw +++ b/src/ladok3/cli.nw @@ -299,21 +299,17 @@ the user. Manages the user's LADOK login credentials. There are three ways to supply the login credentials, in order of priority: -1) Through the system keyring: Just run `ladok login` and you'll be asked to - enter the credentials and they will be stored in the keyring. Note that for - this to work on the WSL platform (and possibly on Windows), you need to - install the `keyrings.alt` package: `python3 -m pip install keyrings.alt`. +1) Through the environment: Just set the environment variables -2) Through the environment: Just set the environment variables + a) LADOK_INST, the name of the institution, e.g. KTH Royal Institute of + Technology; - a) LADOK_INST, the name of the institution, e.g. KTH Royal Institute of - Technology; - b) LADOK_VARS, a colon-separated list of environment variables, similarly to - what's done in `ladok login` --- most don't need this, but can rather set - LADOK_USER (the username, e.g. dbosk@ug.kth.se) and - LADOK_PASS (the password) instead. + b) LADOK_VARS, a colon-separated list of environment variables, similarly to + what's done in `ladok login` --- most don't need this, but can rather set + LADOK_USER (the username, e.g. dbosk@ug.kth.se) and LADOK_PASS (the + password) instead. -3) Through the configuration file: Just write +2) Through the configuration file: Just write {{ "institution": "the name of the university" @@ -325,6 +321,17 @@ login credentials, in order of priority: option). (The keys 'username' and 'password' can be renamed to correspond to the necessary values if the university login system uses other names.) +3) Through the system keyring: Just run `ladok login` and you'll be asked to + enter the credentials and they will be stored in the keyring. Note that for + this to work on the WSL platform (and possibly on Windows), you need to + install the `keyrings.alt` package: `python3 -m pip install keyrings.alt`. + +The keyring is the most secure. However, sometimes one want to try different +credentials, so the environment should override the keyring. Also, on WSL the +keyring might require you to enter a password in the terminal---this is very +inconvenient in scripts. However, when logging in, we first try to store the +credentials in the keyring. + <>= login_parser = subp.add_parser("login", help="Manage login credentials", @@ -510,52 +517,17 @@ def load_credentials(filename="config.json"): can be passed to `LadokSession(instiution, credential dictionary)`. """ - <> - <> <> <> <> <> + <> + <> return None, None @ -First we try the newest format. -We try to fetch the institution and vars from the keyring. - -Note that [[keyring]] returns [[None]] if the key doesn't exist, it doesn't -raise an exception. -<>= -try: - institution = keyring.get_password("ladok3", "institution") - vars_keys = keyring.get_password("ladok3", "vars") - - vars = {} - for key in vars_keys.split(";"): - value = keyring.get_password("ladok3", key) - if value: - vars[key] = value - - if institution and vars: - return institution, vars -except: - pass -@ - -However, if that fails, we fall back on the previous format, that only -supported KTH. -<>= -try: - institution = "KTH Royal Institute of Technology" - username = keyring.get_password("ladok3", "username") - password = keyring.get_password("ladok3", "password") - if username and password: - return institution, {"username": username, "password": password} -except: - pass -@ - -Next in priority is to read from the environment. +First in priority is to read from the environment. We try to read the institution. If that fails, we assume we're using the old format that only supported KTH. <>= @@ -563,7 +535,6 @@ try: institution = os.environ["LADOK_INST"] except: institution = "KTH Royal Institute of Technology" - <>= try: vars = { @@ -578,6 +549,8 @@ except: If we couldn't read the old [[LADOK_USER]] and [[LADOK_PASS]], we try to read the [[vars]] from the environment using [[LADOK_VARS]]. +Note that we need the [[institution]] to be set from [[LADOK_INST]] above for +this. <>= try: vars_keys = os.environ["LADOK_VARS"] @@ -605,8 +578,7 @@ it doesn't exist. warn(f"Variable {key} not set, ignoring.") @ -If none of the above worked, the last resort is to try to read the -configuration file. +If none of the above worked, we try the config file next. We pop the institution from the configuration file (a dictionary), because then the remaining entries will be used as [[vars]]. <>= @@ -621,6 +593,40 @@ except: pass @ +Lastly, if nothing else worked, we try to fetch the institution and vars from +the keyring. +Note that [[keyring]] returns [[None]] if the key doesn't exist, it doesn't +raise an exception. +<>= +try: + institution = keyring.get_password("ladok3", "institution") + vars_keys = keyring.get_password("ladok3", "vars") + + vars = {} + for key in vars_keys.split(";"): + value = keyring.get_password("ladok3", key) + if value: + vars[key] = value + + if institution and vars: + return institution, vars +except: + pass +@ + +However, if that fails, we fall back on the previous format, that only +supported KTH. +<>= +try: + institution = "KTH Royal Institute of Technology" + username = keyring.get_password("ladok3", "username") + password = keyring.get_password("ladok3", "password") + if username and password: + return institution, {"username": username, "password": password} +except: + pass +@ + \section{Managing the cache: the \texttt{cache} command and subcommands}