From e04f49cd9a52862f95ed0b7945bbaccb0c0548e1 Mon Sep 17 00:00:00 2001 From: eric <95382086+ericflores108@users.noreply.github.com> Date: Sun, 31 Mar 2024 12:36:31 -0700 Subject: [PATCH 1/2] feat: add postman-cli plugin --- plugins/postman/api_key.go | 87 +++++++++++++++++++++++++ plugins/postman/api_key_test.go | 53 +++++++++++++++ plugins/postman/plugin.go | 22 +++++++ plugins/postman/postman.go | 27 ++++++++ plugins/postman/test-fixtures/postmanrc | 14 ++++ 5 files changed, 203 insertions(+) create mode 100644 plugins/postman/api_key.go create mode 100644 plugins/postman/api_key_test.go create mode 100644 plugins/postman/plugin.go create mode 100644 plugins/postman/postman.go create mode 100644 plugins/postman/test-fixtures/postmanrc diff --git a/plugins/postman/api_key.go b/plugins/postman/api_key.go new file mode 100644 index 000000000..6e94c5340 --- /dev/null +++ b/plugins/postman/api_key.go @@ -0,0 +1,87 @@ +package postman + +import ( + "context" + + "github.com/1Password/shell-plugins/sdk" + "github.com/1Password/shell-plugins/sdk/importer" + "github.com/1Password/shell-plugins/sdk/provision" + "github.com/1Password/shell-plugins/sdk/schema" + "github.com/1Password/shell-plugins/sdk/schema/credname" + "github.com/1Password/shell-plugins/sdk/schema/fieldname" +) + +func APIKey() schema.CredentialType { + return schema.CredentialType{ + Name: credname.APIKey, + DocsURL: sdk.URL("https://learning.postman.com/docs/developer/postman-api/intro-api/#generating-a-postman-api-key"), + ManagementURL: sdk.URL("https://web.postman.co/settings/me/api-keys"), + Fields: []schema.CredentialField{ + { + Name: fieldname.APIKey, + MarkdownDescription: "API Key used to authenticate to postman.", + Secret: true, + Composition: &schema.ValueComposition{ + Length: 64, + Charset: schema.Charset{ + Uppercase: true, + Lowercase: true, + Digits: true, + }, + }, + }, + }, + DefaultProvisioner: provision.EnvVars(defaultEnvVarMapping), + Importer: importer.TryAll( + importer.TryEnvVarPair(defaultEnvVarMapping), + TryPostmanConfigFile(), + )} +} + +var defaultEnvVarMapping = map[string]sdk.FieldName{ + "POSTMAN_API_KEY": fieldname.APIKey, +} + +func TryPostmanConfigFile() sdk.Importer { + return importer.TryFile("~/.postman/postmanrc", func(ctx context.Context, contents importer.FileContents, in sdk.ImportInput, out *sdk.ImportAttempt) { + var config Config + if err := contents.ToJSON(&config); err != nil { + out.AddError(err) + return + } + + var defaultProfile *PostmanProfile + + for _, profile := range config.Login.Profiles { + if profile.Alias == "default" { + defaultProfile = &profile + break + } + } + + if defaultProfile == nil || defaultProfile.PostmanAPIKey == "" { + return + } + + out.AddCandidate(sdk.ImportCandidate{ + Fields: map[sdk.FieldName]string{ + fieldname.APIKey: defaultProfile.PostmanAPIKey, + }, + }) + }) +} + +type PostmanProfile struct { + Alias string `json:"alias"` + PostmanAPIKey string `json:"postmanApiKey"` + Username string `json:"username"` +} + +type Config struct { + Login struct { + Profiles []PostmanProfile `json:"_profiles"` + } `json:"login"` + Updates struct { + UpdateCheckedTimestamp int64 `json:"updateCheckedTimestamp"` + } `json:"updates"` +} diff --git a/plugins/postman/api_key_test.go b/plugins/postman/api_key_test.go new file mode 100644 index 000000000..ef7a06a69 --- /dev/null +++ b/plugins/postman/api_key_test.go @@ -0,0 +1,53 @@ +package postman + +import ( + "testing" + + "github.com/1Password/shell-plugins/sdk" + "github.com/1Password/shell-plugins/sdk/plugintest" + "github.com/1Password/shell-plugins/sdk/schema/fieldname" +) + +func TestAPIKeyProvisioner(t *testing.T) { + plugintest.TestProvisioner(t, APIKey().DefaultProvisioner, map[string]plugintest.ProvisionCase{ + "default": { + ItemFields: map[sdk.FieldName]string{ + fieldname.APIKey: "jNMdtxuUHqiSMNmwYu3OXyhOgYKse6H82uhghe0Zw3K92ZEfXhL8wvLzX", + }, + ExpectedOutput: sdk.ProvisionOutput{ + Environment: map[string]string{ + "POSTMAN_API_KEY": "jNMdtxuUHqiSMNmwYu3OXyhOgYKse6H82uhghe0Zw3K92ZEfXhL8wvLzX", + }, + }, + }, + }) +} + +func TestAPIKeyImporter(t *testing.T) { + plugintest.TestImporter(t, APIKey().Importer, map[string]plugintest.ImportCase{ + "environment": { + Environment: map[string]string{ + "POSTMAN_API_KEY": "jNMdtxuUHqiSMNmwYu3OXyhOgYKse6H82uhghe0Zw3K92ZEfXhL8wvLzX", + }, + ExpectedCandidates: []sdk.ImportCandidate{ + { + Fields: map[sdk.FieldName]string{ + fieldname.APIKey: "jNMdtxuUHqiSMNmwYu3OXyhOgYKse6H82uhghe0Zw3K92ZEfXhL8wvLzX", + }, + }, + }, + }, + "config file": { + Files: map[string]string{ + "~/.postman/postmanrc": plugintest.LoadFixture(t, "postmanrc"), + }, + ExpectedCandidates: []sdk.ImportCandidate{ + { + Fields: map[sdk.FieldName]string{ + fieldname.APIKey: "jNMdtxuUHqiSMNmwYu3OXyhOgYKse6H82uhghe0Zw3K92ZEfXhL8wvLzX", + }, + }, + }, + }, + }) +} diff --git a/plugins/postman/plugin.go b/plugins/postman/plugin.go new file mode 100644 index 000000000..6aa52a1c7 --- /dev/null +++ b/plugins/postman/plugin.go @@ -0,0 +1,22 @@ +package postman + +import ( + "github.com/1Password/shell-plugins/sdk" + "github.com/1Password/shell-plugins/sdk/schema" +) + +func New() schema.Plugin { + return schema.Plugin{ + Name: "postman", + Platform: schema.PlatformInfo{ + Name: "postman", + Homepage: sdk.URL("https://identity.getpostman.com/"), + }, + Credentials: []schema.CredentialType{ + APIKey(), + }, + Executables: []schema.Executable{ + postmanCLI(), + }, + } +} diff --git a/plugins/postman/postman.go b/plugins/postman/postman.go new file mode 100644 index 000000000..557a1a950 --- /dev/null +++ b/plugins/postman/postman.go @@ -0,0 +1,27 @@ +package postman + +import ( + "github.com/1Password/shell-plugins/sdk" + "github.com/1Password/shell-plugins/sdk/needsauth" + "github.com/1Password/shell-plugins/sdk/schema" + "github.com/1Password/shell-plugins/sdk/schema/credname" +) + +func postmanCLI() schema.Executable { + return schema.Executable{ + Name: "postman", + Runs: []string{"postman"}, + DocsURL: sdk.URL("https://learning.postman.com/docs/postman-cli/postman-cli-overview/"), + NeedsAuth: needsauth.IfAll( + needsauth.NotForHelpOrVersion(), + needsauth.NotWithoutArgs(), + needsauth.NotWhenContainsArgs("login"), + needsauth.NotWhenContainsArgs("-with-api-key"), + ), + Uses: []schema.CredentialUsage{ + { + Name: credname.APIKey, + }, + }, + } +} diff --git a/plugins/postman/test-fixtures/postmanrc b/plugins/postman/test-fixtures/postmanrc new file mode 100644 index 000000000..283fd89bc --- /dev/null +++ b/plugins/postman/test-fixtures/postmanrc @@ -0,0 +1,14 @@ +{ + "login": { + "_profiles": [ + { + "alias": "default", + "postmanApiKey": "jNMdtxuUHqiSMNmwYu3OXyhOgYKse6H82uhghe0Zw3K92ZEfXhL8wvLzX", + "username": "example@example.com" + } + ] + }, + "updates": { + "updateCheckedTimestamp": 1623456789 + } +} \ No newline at end of file From 1b0894d1353f81a97f5e29a094453aa47c0bf34e Mon Sep 17 00:00:00 2001 From: Eric Flores Date: Thu, 6 Jun 2024 16:19:23 -0700 Subject: [PATCH 2/2] Update plugins/postman/plugin.go Co-authored-by: Simon Barendse --- plugins/postman/plugin.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/postman/plugin.go b/plugins/postman/plugin.go index 6aa52a1c7..056be6c29 100644 --- a/plugins/postman/plugin.go +++ b/plugins/postman/plugin.go @@ -10,7 +10,7 @@ func New() schema.Plugin { Name: "postman", Platform: schema.PlatformInfo{ Name: "postman", - Homepage: sdk.URL("https://identity.getpostman.com/"), + Homepage: sdk.URL("https://www.postman.com/"), }, Credentials: []schema.CredentialType{ APIKey(),