From b49763fbb1e39d8c5fccdb7570bdaa90b785f99c Mon Sep 17 00:00:00 2001 From: "Daniel G. Taylor" Date: Fri, 15 Dec 2023 15:31:29 -0800 Subject: [PATCH 1/2] feat: add command to clear auth token cache --- cli/apiconfig.go | 21 +++++++++++++++++++++ cli/apiconfig_test.go | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/cli/apiconfig.go b/cli/apiconfig.go index 30cfae4..e9ecfdc 100644 --- a/cli/apiconfig.go +++ b/cli/apiconfig.go @@ -170,6 +170,27 @@ func initAPIConfig() { Run: func(cmd *cobra.Command, args []string) { editAPIs(os.Exit) }, }) + apiCommand.AddCommand(&cobra.Command{ + Use: "clear-auth-cache short-name", + Short: "Clear API auth token cache", + Long: "Clear the API auth token cache for the current profile. This will force a re-authentication the next time you make a request.", + Args: cobra.ExactArgs(1), + Run: func(cmd *cobra.Command, args []string) { + apiName := args[0] + api := configs[apiName] + if api == nil { + panic("API " + apiName + " not found") + } + + // Remove the cache entry. + Cache.Set(apiName+":"+viper.GetString("rsh-profile"), "") + + if err := Cache.WriteConfig(); err != nil { + panic(fmt.Errorf("Unable to write cache file: %w", err)) + } + }, + }) + apiCommand.AddCommand(&cobra.Command{ Use: "show short-name", Short: "Show API config", diff --git a/cli/apiconfig_test.go b/cli/apiconfig_test.go index be1b0c6..ba22ff9 100644 --- a/cli/apiconfig_test.go +++ b/cli/apiconfig_test.go @@ -24,6 +24,43 @@ func TestAPIShow(t *testing.T) { assert.Equal(t, captured, "\x1b[38;5;247m{\x1b[0m\n \x1b[38;5;74m\"base\"\x1b[0m\x1b[38;5;247m:\x1b[0m \x1b[38;5;150m\"https://api.example.com\"\x1b[0m\n\x1b[38;5;247m}\x1b[0m\n") } +func TestAPIClearCache(t *testing.T) { + reset(false) + + configs["test"] = &APIConfig{ + name: "test", + Base: "https://api.example.com", + } + Cache.Set("test:default.token", "abc123") + + runNoReset("api clear-auth-cache test") + + assert.Equal(t, "", Cache.GetString("test:default.token")) +} + +func TestAPIClearCacheProfile(t *testing.T) { + reset(false) + + configs["test"] = &APIConfig{ + name: "test", + Base: "https://api.example.com", + } + Cache.Set("test:default.token", "abc123") + Cache.Set("test:other.token", "def456") + + runNoReset("api clear-auth-cache test -p other") + + assert.Equal(t, "abc123", Cache.GetString("test:default.token")) + assert.Equal(t, "", Cache.GetString("test:other.token")) +} + +func TestAPIClearCacheMissing(t *testing.T) { + reset(false) + + captured := runNoReset("api clear-auth-cache missing-api") + assert.Contains(t, captured, "API missing-api not found") +} + func TestEditAPIsMissingEditor(t *testing.T) { os.Setenv("EDITOR", "") os.Setenv("VISUAL", "") From 48405292a196c70cbce22453332caff2c43977e2 Mon Sep 17 00:00:00 2001 From: Felipe Flores Date: Mon, 20 May 2024 07:53:29 -0400 Subject: [PATCH 2/2] Added examples to external-tool auth --- docs/configuration.md | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index 6a982c7..84ddea7 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -333,19 +333,36 @@ helper commandline: "method": "GET", "uri": "http://...", "headers": { - "content-type": ["…"] + "content-type": ["…"], + "authorization": ["Bearer "] // … }, "body": "…" } ``` - -The same shape is expected on the program's standard output. Two +The same shape is expected on the program's standard output. Please note that the fields inside `headers` must be in an array. Two parameters only will be considered: - `headers`: Values present will be added to the outbound payload. -- `uri`: Will replace the destination URL entirely (allowing the - addition of query arguments if needed). +- `uri`: Will replace the destination URL entirely (allowing the addition of query arguments if needed). + +Here is a good example of how to use this versatile option. Suppose you've written a script in your favorite language that connects to an Auth server and writes a relatively standard OAuth 2.0 JSON in the following shape: + +```json +{ + "expires_in": 3600, + "access_token": "", + "refresh_token": "", + "scope": "" +} +``` +You might find yourself doing this with a lot of APIs because not everyone follows the same OAuth 2.0 conventions (maybe you used `restish` to get this token manually in the first place!). Then, when you need to use this file, you could write a quick one-liner with `jq` to convert this to the appropriate format and feed it into `restish` with a line like this in your `commandline`: + +```bash +jq '{headers: {authorization: ["Bearer " + .access_token]}}' /path/to/auth_token.json +``` + +As long as your input writes the appropriate format to the standard output (**very important**), `restish` will modify the outgoing request accordingly. ### Loading from files or URLs