From bf017d28d15eb284c32aa48220eb99f8741b9004 Mon Sep 17 00:00:00 2001 From: vishalnayak Date: Fri, 2 Oct 2015 13:33:19 -0400 Subject: [PATCH] Github backend: enable auth renewals --- builtin/credential/github/backend.go | 4 ++- builtin/credential/github/path_config.go | 41 ++++++++++++++++++------ builtin/credential/github/path_login.go | 14 ++++++++ command/auth.go | 10 +++--- vault/token_store.go | 2 +- 5 files changed, 54 insertions(+), 17 deletions(-) diff --git a/builtin/credential/github/backend.go b/builtin/credential/github/backend.go index c8b6f97a11..ea5c9f41ec 100644 --- a/builtin/credential/github/backend.go +++ b/builtin/credential/github/backend.go @@ -35,9 +35,11 @@ func Backend() *framework.Backend { }, Paths: append([]*framework.Path{ - pathConfig(), + pathConfig(&b), pathLogin(&b), }, b.Map.Paths()...), + + AuthRenew: b.pathLoginRenew, } return b.Backend diff --git a/builtin/credential/github/path_config.go b/builtin/credential/github/path_config.go index b923e57a9d..cc32a5dcb1 100644 --- a/builtin/credential/github/path_config.go +++ b/builtin/credential/github/path_config.go @@ -3,12 +3,13 @@ package github import ( "fmt" "net/url" + "time" "github.com/hashicorp/vault/logical" "github.com/hashicorp/vault/logical/framework" ) -func pathConfig() *framework.Path { +func pathConfig(b *backend) *framework.Path { return &framework.Path{ Pattern: "config", Fields: map[string]*framework.FieldSchema{ @@ -23,29 +24,47 @@ func pathConfig() *framework.Path { are running GitHub Enterprise or an API-compatible authentication server.`, }, + "ttl": &framework.FieldSchema{ + Type: framework.TypeString, + Description: `Duration after which authentication will be expired`, + }, + "max_ttl": &framework.FieldSchema{ + Type: framework.TypeString, + Description: `Maximum duration after which authentication will be expired`, + }, }, Callbacks: map[logical.Operation]framework.OperationFunc{ - logical.WriteOperation: pathConfigWrite, + logical.WriteOperation: b.pathConfigWrite, }, } } -func pathConfigWrite( +func (b *backend) pathConfigWrite( req *logical.Request, data *framework.FieldData) (*logical.Response, error) { - conf := config{ - Org: data.Get("organization").(string), - } + organization := data.Get("organization").(string) baseURL := data.Get("base_url").(string) if len(baseURL) != 0 { _, err := url.Parse(baseURL) if err != nil { return logical.ErrorResponse(fmt.Sprintf("Error parsing given base_url: %s", err)), nil } - conf.BaseURL = baseURL } - entry, err := logical.StorageEntryJSON("config", conf) + ttlStr := data.Get("ttl").(string) + maxTTLStr := data.Get("max_ttl").(string) + ttl, maxTTL, err := b.SanitizeTTL(ttlStr, maxTTLStr) + if err != nil { + return logical.ErrorResponse(fmt.Sprintf("err: %s", err)), nil + } + + entry, err := logical.StorageEntryJSON("config", config{ + Org: organization, + BaseURL: baseURL, + TTL: ttl, + MaxTTL: maxTTL, + }) + if err != nil { return nil, err } @@ -75,6 +94,8 @@ func (b *backend) Config(s logical.Storage) (*config, error) { } type config struct { - Org string `json:"organization"` - BaseURL string `json:"base_url"` + Org string `json:"organization"` + BaseURL string `json:"base_url"` + TTL time.Duration `json:"ttl"` + MaxTTL time.Duration `json:"max_ttl"` } diff --git a/builtin/credential/github/path_login.go b/builtin/credential/github/path_login.go index 854fa3cd81..bc858de4a5 100644 --- a/builtin/credential/github/path_login.go +++ b/builtin/credential/github/path_login.go @@ -132,6 +132,20 @@ func (b *backend) pathLogin( "org": *org.Login, }, DisplayName: *user.Login, + LeaseOptions: logical.LeaseOptions{ + TTL: config.TTL, + GracePeriod: config.TTL / 10, + Renewable: config.TTL > 0, + }, }, }, nil } + +func (b *backend) pathLoginRenew( + req *logical.Request, d *framework.FieldData) (*logical.Response, error) { + config, err := b.Config(req.Storage) + if err != nil { + return nil, err + } + return framework.LeaseExtend(config.MaxTTL, 0, false)(req, d) +} diff --git a/command/auth.go b/command/auth.go index dd604e96c2..99cfcc3fc5 100644 --- a/command/auth.go +++ b/command/auth.go @@ -33,6 +33,7 @@ type AuthCommand struct { } func (c *AuthCommand) Run(args []string) int { + var format string var method string var methods, methodHelp, noVerify bool flags := c.Meta.FlagSet("auth", FlagSetDefault) @@ -40,6 +41,7 @@ func (c *AuthCommand) Run(args []string) int { flags.BoolVar(&methodHelp, "method-help", false, "") flags.BoolVar(&noVerify, "no-verify", false, "") flags.StringVar(&method, "method", "", "method") + flags.StringVar(&format, "format", "table", "") flags.Usage = func() { c.Ui.Error(c.Help()) } if err := flags.Parse(args); err != nil { return 1 @@ -202,12 +204,10 @@ func (c *AuthCommand) Run(args []string) int { } output := "Successfully authenticated!" - if secret.LeaseDuration > 0 { - output += fmt.Sprintf("\nThe token's lifetime is %d seconds.", secret.LeaseDuration) - } - + output += fmt.Sprintf("\ntoken: %s", secret.Data["id"]) + output += fmt.Sprintf("\ntoken_duration: %d", int(secret.Data["ttl"].(float64))) if len(policies) > 0 { - output += fmt.Sprintf("\nThe policies that are associated with this token\narelisted below:\n\n%s", strings.Join(policies, ", ")) + output += fmt.Sprintf("\ntoken_policies: [%s]", strings.Join(policies, ", ")) } c.Ui.Output(output) diff --git a/vault/token_store.go b/vault/token_store.go index 8de20b588d..e918e2a5b8 100644 --- a/vault/token_store.go +++ b/vault/token_store.go @@ -721,7 +721,7 @@ func (ts *TokenStore) handleLookup( } // Generate a response. We purposely omit the parent reference otherwise - // you could escalade your privileges. + // you could escalate your privileges. resp := &logical.Response{ Data: map[string]interface{}{ "id": out.ID,