galasa-dev / projectmanagement

Project Management repo for Issues and ZenHub
7 stars 4 forks source link

Galasa service to store when user last logged into the web UI #1975

Open techcobweb opened 1 month ago

techcobweb commented 1 month ago

Story

As a user of a galasa ecosystem, I want to see a list of other users using the command line. So that I can see who uses this system.

Background

We need to create a User record in couchdb whenever we discover a user in the system.

Neither of these cases is performance-sensitive, so we can spare the time to look the user up in the couchdb database, and create a record if one doesn't already exist.

This is a pre-req for having a role associated with each user.

Couchdb database layer

We need to create it if it doesn't already exist, when the API starts up.

Couchdb records look like this: Document 6789087678988678798:

{
  "_doc":"6789087678988678798", << This is the id field
  "_rev":"56798908680988798769",
  "login-id": "mcobbett@mydomain.co.uk",
  "activity" : [
    {
      "client-name" : "web-ui",
      "last-login": "2024-09-08:14:24" << Currently only keep one login. Using a structure in case we want to capture the IP address they used, or something else.
    },
    {
      "client-name" : "rest-api",
      << We may want to later add which token was used. cross-referencing the token. Hence the structure.
      "last-login": "2024-09-08:14:24"
    }
  ]
}

Currently we aim to capture only the last login from either interface. Later on we might capture the last 5, or the last 5 months' activity...etc.

Servlet layer

The existing web service should gather the list and return it using the endpoint we have already. ie: /api/users

That should return a list of all the users we know about in couchdb.

ie: GET https://myhost/api/users : returns:

[
  { 
    "login-id": "mcobbett@mydomain.co.uk",
    "activity": [
      { 
        "client-name" : "web-ui",
        "last-login": "2024-09-08:14:24"
      },
      { 
        "client-name" : "rest-api",
        "last-login": "2024-09-08:14:24"
      }
    ]
    "id":"6789087678988678798",
    "url": "https://myhost/api/users/6789087678988678798" << Note that this field is not stored in the couchdb document, but is available on the REST payload.
  },
  { 
    "login-id": "eamon@mydomain.co.uk",
    "activity": [
      { 
        "client-name" : "web-ui",
        "last-login": "2024-09-08:14:24"
      },
      { 
        "client-name" : "rest-api",
        "last-login": "2024-09-08:14:24"
      }
    ]
    "id": "5678908956789875678",
    "url": "https://myhost/api/users/5678908956789875678" 
  }
]

We also need an endpoint specifically for one user: eg: GET https://myhost/api/users/6789087678988678798 :

{ 
  "login-id": "mcobbett@mydomain.co.uk",
  "id": "6789087678988678798"
  "activity": [
    { 
        "client-name" : "web-ui",
        "last-login": "2024-09-08:14:24"
      },
      { 
        "client-name" : "rest-api",
        "last-login": "2024-09-08:14:24"
      }
  ],
  "url": "https://myhost/api/users/6789087678988678798"
 }

Because the rest API is being used to obtain JWTs, the rest API is aware of whether it's the web UI asking for the JWT, or whether it's a REST client program asking for it. As the REST API has access to the users extension API, and indirectly to couchdb, then there should be no need for a PUT REST command yet for the user resource.

We also need to be able to delete a user record: DELETE https://myhost/api/users/6789087678988678798 Return code: 204

Note that the REST interface deals with users based on their document ID, while the CLI deals with users based on their login ID (as that's more friendly to users). By doing this we byepass any problems with code pages, or users with weird characters in their names.

Given that the user login-id is supplied by git/ldap...etc we can't second-guess the validation rules for a login-id.

Without the DELETE, we will struggle to test this feature.

The CLI layer

The CLI should be able to query the list of users:

galasactl users get
galasactl users get --format details
galasactl users get --format summary
galasactl users get --login-id mike_cobbett@no.spam.ibm.com

It should support --format of type summary/details.

It should default to summary.

It should have a Title line and a total at the bottom.

For example:

$galasactl users get
login-id                web-last-login   rest-api-last-login 
mcobbett@mydomain.co.uk 2024-09-08:14:24 2024-09-08:14:24
eamon@mydomain.co.uk    2024-09-08:15:18 2024-09-08:15:18

Total : 2

or

$galasactl users get --format details << This format is the same as --format yaml 
login-id: mcobbett@mydomain.co.uk
id: 6789087678988678798
activity:
  - client-name: web-ui
    last-login: 2024-09-08:14:24
  - clent-name: rest-api
    last-login: 2024-09-08:14:24
url: https://myhost/api/users/6789087678988678798 
---
login-id:eamon@mydomain.co.uk
id: 67890123124234678798
activity:
  - client-name: web-ui
    last-login: 2024-09-08:14:24
  - client-name: rest-api
    last-login: 2024-09-08:14:24

url: https://myhost/api/users/67890123124234678798

The user can specify a filter for users:

$galasactl users get --login-id mcobbett@mydomain.co.uk
login-id                web-last-login   rest-api-last-login 
mcobbett@mydomain.co.uk 2024-09-08:14:24 2024-09-08:14:24

Total: 1

When a filtered option is used, using the --login-id field, then the default should be the details view.

The user can be deleted:

$galasactl users delete --login-id mcobbett@mydomain.co.uk

(There is no visible response, beyond a '0' exit code to indicate success).

The Web UI layer

The user's last-login information is visible on the user profile page.

Tasks

CLI tasks

Servlet layer tasks

Couchdb tasks

Web UI tasks

techcobweb commented 2 weeks ago

From @eamansour 👍🏻

Looks good, I just changed the DELETE endpoint’s response code to 204 (no content) instead of a 200 - also noticed the story mentions using --login_id in the users commands, shouldn’t that be --id? (since that’s what we have already for users get --id me)