Skip to content

Commit

Permalink
feat: add postman-cli plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
ericflores108 committed Mar 31, 2024
1 parent 39ed88f commit e04f49c
Show file tree
Hide file tree
Showing 5 changed files with 203 additions and 0 deletions.
87 changes: 87 additions & 0 deletions plugins/postman/api_key.go
Original file line number Diff line number Diff line change
@@ -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"`
}
53 changes: 53 additions & 0 deletions plugins/postman/api_key_test.go
Original file line number Diff line number Diff line change
@@ -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",
},
},
},
},
})
}
22 changes: 22 additions & 0 deletions plugins/postman/plugin.go
Original file line number Diff line number Diff line change
@@ -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/"),

Check failure on line 13 in plugins/postman/plugin.go

View workflow job for this annotation

GitHub Actions / Lint

File is not `gofmt`-ed with `-s` (gofmt)
},
Credentials: []schema.CredentialType{
APIKey(),
},
Executables: []schema.Executable{
postmanCLI(),
},
}
}
27 changes: 27 additions & 0 deletions plugins/postman/postman.go
Original file line number Diff line number Diff line change
@@ -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,
},
},
}
}
14 changes: 14 additions & 0 deletions plugins/postman/test-fixtures/postmanrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"login": {
"_profiles": [
{
"alias": "default",
"postmanApiKey": "jNMdtxuUHqiSMNmwYu3OXyhOgYKse6H82uhghe0Zw3K92ZEfXhL8wvLzX",
"username": "example@example.com"
}
]
},
"updates": {
"updateCheckedTimestamp": 1623456789
}
}

0 comments on commit e04f49c

Please sign in to comment.