open-vault/builtin/credential/github/path_config.go

172 lines
4.4 KiB
Go

package github
import (
"context"
"fmt"
"net/url"
"strings"
"time"
"github.com/hashicorp/errwrap"
"github.com/hashicorp/vault/sdk/framework"
"github.com/hashicorp/vault/sdk/helper/tokenutil"
"github.com/hashicorp/vault/sdk/logical"
)
func pathConfig(b *backend) *framework.Path {
p := &framework.Path{
Pattern: "config",
Fields: map[string]*framework.FieldSchema{
"organization": &framework.FieldSchema{
Type: framework.TypeString,
Description: "The organization users must be part of",
},
"base_url": &framework.FieldSchema{
Type: framework.TypeString,
Description: `The API endpoint to use. Useful if you
are running GitHub Enterprise or an
API-compatible authentication server.`,
DisplayAttrs: &framework.DisplayAttributes{
Name: "Base URL",
Group: "GitHub Options",
},
},
"ttl": &framework.FieldSchema{
Type: framework.TypeDurationSecond,
Description: tokenutil.DeprecationText("token_ttl"),
Deprecated: true,
},
"max_ttl": &framework.FieldSchema{
Type: framework.TypeDurationSecond,
Description: tokenutil.DeprecationText("token_max_ttl"),
Deprecated: true,
},
},
Callbacks: map[logical.Operation]framework.OperationFunc{
logical.UpdateOperation: b.pathConfigWrite,
logical.ReadOperation: b.pathConfigRead,
},
}
tokenutil.AddTokenFields(p.Fields)
p.Fields["token_policies"].Description += ". This will apply to all tokens generated by this auth method, in addition to any policies configured for specific users/groups."
return p
}
func (b *backend) pathConfigWrite(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
c, err := b.Config(ctx, req.Storage)
if err != nil {
return nil, err
}
if c == nil {
c = &config{}
}
if organizationRaw, ok := data.GetOk("organization"); ok {
c.Organization = organizationRaw.(string)
}
if baseURLRaw, ok := data.GetOk("base_url"); ok {
baseURL := baseURLRaw.(string)
_, err := url.Parse(baseURL)
if err != nil {
return logical.ErrorResponse(fmt.Sprintf("Error parsing given base_url: %s", err)), nil
}
if !strings.HasSuffix(baseURL, "/") {
baseURL += "/"
}
c.BaseURL = baseURL
}
if err := c.ParseTokenFields(req, data); err != nil {
return logical.ErrorResponse(err.Error()), logical.ErrInvalidRequest
}
// Handle upgrade cases
{
if err := tokenutil.UpgradeValue(data, "ttl", "token_ttl", &c.TTL, &c.TokenTTL); err != nil {
return logical.ErrorResponse(err.Error()), nil
}
if err := tokenutil.UpgradeValue(data, "max_ttl", "token_max_ttl", &c.MaxTTL, &c.TokenMaxTTL); err != nil {
return logical.ErrorResponse(err.Error()), nil
}
}
entry, err := logical.StorageEntryJSON("config", c)
if err != nil {
return nil, err
}
if err := req.Storage.Put(ctx, entry); err != nil {
return nil, err
}
return nil, nil
}
func (b *backend) pathConfigRead(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
config, err := b.Config(ctx, req.Storage)
if err != nil {
return nil, err
}
if config == nil {
return nil, nil
}
d := map[string]interface{}{
"organization": config.Organization,
"base_url": config.BaseURL,
}
config.PopulateTokenData(d)
if config.TTL > 0 {
d["ttl"] = int64(config.TTL.Seconds())
}
if config.MaxTTL > 0 {
d["max_ttl"] = int64(config.MaxTTL.Seconds())
}
return &logical.Response{
Data: d,
}, nil
}
// Config returns the configuration for this backend.
func (b *backend) Config(ctx context.Context, s logical.Storage) (*config, error) {
entry, err := s.Get(ctx, "config")
if err != nil {
return nil, err
}
if entry == nil {
return nil, nil
}
var result config
if entry != nil {
if err := entry.DecodeJSON(&result); err != nil {
return nil, errwrap.Wrapf("error reading configuration: {{err}}", err)
}
}
if result.TokenTTL == 0 && result.TTL > 0 {
result.TokenTTL = result.TTL
}
if result.TokenMaxTTL == 0 && result.MaxTTL > 0 {
result.TokenMaxTTL = result.MaxTTL
}
return &result, nil
}
type config struct {
tokenutil.TokenParams
Organization string `json:"organization" structs:"organization" mapstructure:"organization"`
BaseURL string `json:"base_url" structs:"base_url" mapstructure:"base_url"`
TTL time.Duration `json:"ttl" structs:"ttl" mapstructure:"ttl"`
MaxTTL time.Duration `json:"max_ttl" structs:"max_ttl" mapstructure:"max_ttl"`
}