- 
                Notifications
    You must be signed in to change notification settings 
- Fork 5
Description
Specification
MR: https://gitlab.com/MatrixAI/Engineering/Polykey/js-polykey/-/merge_requests/213
When a user executes a CLI command without having been authenticated previously the command sent to the agent will be rejected as "unauthorised". Instead of throwing an exception here, we can prompt the user for the root password in order to authenticate the client. Provided we know that the user is not a machine (which would classify as unattended usage), we can continue to prompt the user for the root password until the correct password is supplied and they can be authenticated. We will refer to this loop as the CLI Authentication Retry Loop (CARL):
Before we can activate the CARL and begin to prompt the user for the password, we need to ensure that the command is not unattended (since we need to account for both machine and human usage). We can do this by checking if either of the two environment variables PK_PASSWORD (for the root password) or PK_TOKEN (for the session token) are set (since the purpose of setting these is for unattended usage). Before we activate the CARL we also need to check that the first exception we receive back from the agent is ErrorClientAuthMissing (thrown when the call has no authorisation metadata), since we only want to retry the call if the client is not authenticated, rather than if the authentication metadata is invalid or if there is some other error on the agent side. Once we are inside the loop we only want to restart it if the error we receive back from the agent is ErrorClientAuthDenied (thrown when the authorisation metadata is invalid), since this means that the password supplied by the user was invalid and we want to prompt them to try again. The user can always manually exit the loop from the terminal if they have forgotten their password or otherwise wish to cancel the call.
Since we want this loop to be as automated as possible, prompting the user to enter their password should be our last option. As such, the retry function can be optionally called with an initial metadata object that is constructed during parsing of command line options for each call. This metadata is encoded using the first set value from the following in order:
- Password File (optional for every CLI call)
- PK_PASSWORDenvironment variable
- PK_TOKENenvironment variable
In this way, if the password is already supplied it will be made use of. Once we enter the CARL we know that all other options have been exhausted and we have to prompt the user for the password.
Additional context
- Previous @DrFacepalm had asked how this is supposed to be done in an efficient way. This should be done by separating the phases of the UI/UX loop above procedure functions, and then using a while loop to enable recursion. Note that we don't use function recursion in JavaScript runtimes due to the lack of tail-call optimisation in JS runtimes.
Tasks
-  - Update the design of the sequence diagrams in the sessions reference article https://github.com/MatrixAI/js-polykey/wiki/Sessions to include the CLI command retry loop
- Use plantuml now, see notes from Wiki Reference Articles for Session Management and Node Protocols, Gestalt Protocols, Identity Protocols Polykey-Docs#4
 
-  - Break up the loop into separate named phases, and create procedure functions for each phase in the CLI src/binlocation
-  - Add these tests to the tests/bin(these are singular tests, you can pick any CLI command for this):- Retry loop when the session token is missing, succeeds in unlocking, succeeds in retrying the call
- Failure to unlock session when prompted
- Failure to to do the repeated call because session token is invalid
- Ensure that if password is supplied, and the token is missing, the root password can be substituted for the session token, and the token is established
 
-  - Integrate functions into bin/utilsand all relevant commands