diff --git a/builtin/credential/github/backend.go b/builtin/credential/github/backend.go deleted file mode 100644 index f560606e4..000000000 --- a/builtin/credential/github/backend.go +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package github - -import ( - "context" - "net/url" - - "github.com/google/go-github/github" - cleanhttp "github.com/hashicorp/go-cleanhttp" - "github.com/hashicorp/vault/sdk/framework" - "github.com/hashicorp/vault/sdk/logical" - "golang.org/x/oauth2" -) - -const operationPrefixGithub = "github" - -func Factory(ctx context.Context, conf *logical.BackendConfig) (logical.Backend, error) { - b := Backend() - if err := b.Setup(ctx, conf); err != nil { - return nil, err - } - return b, nil -} - -func Backend() *backend { - var b backend - b.TeamMap = &framework.PolicyMap{ - PathMap: framework.PathMap{ - Name: "teams", - }, - DefaultKey: "default", - } - - teamMapPaths := b.TeamMap.Paths() - - teamMapPaths[0].DisplayAttrs = &framework.DisplayAttributes{ - OperationPrefix: operationPrefixGithub, - OperationSuffix: "teams", - } - teamMapPaths[1].DisplayAttrs = &framework.DisplayAttributes{ - OperationPrefix: operationPrefixGithub, - OperationSuffix: "team-mapping", - } - - b.UserMap = &framework.PolicyMap{ - PathMap: framework.PathMap{ - Name: "users", - }, - DefaultKey: "default", - } - - userMapPaths := b.UserMap.Paths() - - userMapPaths[0].DisplayAttrs = &framework.DisplayAttributes{ - OperationPrefix: operationPrefixGithub, - OperationSuffix: "users", - } - userMapPaths[1].DisplayAttrs = &framework.DisplayAttributes{ - OperationPrefix: operationPrefixGithub, - OperationSuffix: "user-mapping", - } - - allPaths := append(teamMapPaths, userMapPaths...) - b.Backend = &framework.Backend{ - Help: backendHelp, - - PathsSpecial: &logical.Paths{ - Unauthenticated: []string{ - "login", - }, - }, - - Paths: append([]*framework.Path{pathConfig(&b), pathLogin(&b)}, allPaths...), - AuthRenew: b.pathLoginRenew, - BackendType: logical.TypeCredential, - } - - return &b -} - -type backend struct { - *framework.Backend - - TeamMap *framework.PolicyMap - - UserMap *framework.PolicyMap -} - -// Client returns the GitHub client to communicate to GitHub via the -// configured settings. -func (b *backend) Client(token string) (*github.Client, error) { - tc := cleanhttp.DefaultClient() - if token != "" { - ctx := context.WithValue(context.Background(), oauth2.HTTPClient, tc) - tc = oauth2.NewClient(ctx, &tokenSource{Value: token}) - } - - client := github.NewClient(tc) - emptyUrl, err := url.Parse("") - if err != nil { - return nil, err - } - client.UploadURL = emptyUrl - - return client, nil -} - -// tokenSource is an oauth2.TokenSource implementation. -type tokenSource struct { - Value string -} - -func (t *tokenSource) Token() (*oauth2.Token, error) { - return &oauth2.Token{AccessToken: t.Value}, nil -} - -const backendHelp = ` -The GitHub credential provider allows authentication via GitHub. - -Users provide a personal access token to log in, and the credential -provider verifies they're part of the correct organization and then -maps the user to a set of Vault policies according to the teams they're -part of. - -After enabling the credential provider, use the "config" route to -configure it. -` diff --git a/builtin/credential/github/backend_test.go b/builtin/credential/github/backend_test.go deleted file mode 100644 index 4f3dee078..000000000 --- a/builtin/credential/github/backend_test.go +++ /dev/null @@ -1,213 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package github - -import ( - "context" - "errors" - "fmt" - "os" - "strings" - "testing" - "time" - - logicaltest "github.com/hashicorp/vault/helper/testhelpers/logical" - "github.com/hashicorp/vault/sdk/logical" -) - -func TestBackend_Config(t *testing.T) { - defaultLeaseTTLVal := time.Hour * 24 - maxLeaseTTLVal := time.Hour * 24 * 2 - b, err := Factory(context.Background(), &logical.BackendConfig{ - Logger: nil, - System: &logical.StaticSystemView{ - DefaultLeaseTTLVal: defaultLeaseTTLVal, - MaxLeaseTTLVal: maxLeaseTTLVal, - }, - }) - if err != nil { - t.Fatalf("Unable to create backend: %s", err) - } - - login_data := map[string]interface{}{ - // This token has to be replaced with a working token for the test to work. - "token": os.Getenv("GITHUB_TOKEN"), - } - config_data1 := map[string]interface{}{ - "organization": os.Getenv("GITHUB_ORG"), - "ttl": "", - "max_ttl": "", - } - expectedTTL1 := 24 * time.Hour - config_data2 := map[string]interface{}{ - "organization": os.Getenv("GITHUB_ORG"), - "ttl": "1h", - "max_ttl": "2h", - } - expectedTTL2 := time.Hour - config_data3 := map[string]interface{}{ - "organization": os.Getenv("GITHUB_ORG"), - "ttl": "50h", - "max_ttl": "50h", - } - expectedTTL3 := 48 * time.Hour - - logicaltest.Test(t, logicaltest.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - CredentialBackend: b, - Steps: []logicaltest.TestStep{ - testConfigWrite(t, config_data1), - testLoginWrite(t, login_data, expectedTTL1, false), - testConfigWrite(t, config_data2), - testLoginWrite(t, login_data, expectedTTL2, false), - testConfigWrite(t, config_data3), - testLoginWrite(t, login_data, expectedTTL3, true), - }, - }) -} - -func testLoginWrite(t *testing.T, d map[string]interface{}, expectedTTL time.Duration, expectFail bool) logicaltest.TestStep { - return logicaltest.TestStep{ - Operation: logical.UpdateOperation, - Path: "login", - ErrorOk: true, - Data: d, - Check: func(resp *logical.Response) error { - if resp == nil { - return errors.New("expected a response but got nil") - } - if resp.IsError() && expectFail { - return nil - } - actualTTL := resp.Auth.LeaseOptions.TTL - if actualTTL != expectedTTL { - return fmt.Errorf("TTL mismatched. Expected: %d Actual: %d", expectedTTL, resp.Auth.LeaseOptions.TTL) - } - return nil - }, - } -} - -func testConfigWrite(t *testing.T, d map[string]interface{}) logicaltest.TestStep { - return logicaltest.TestStep{ - Operation: logical.UpdateOperation, - Path: "config", - Data: d, - } -} - -func TestBackend_basic(t *testing.T) { - defaultLeaseTTLVal := time.Hour * 24 - maxLeaseTTLVal := time.Hour * 24 * 32 - b, err := Factory(context.Background(), &logical.BackendConfig{ - Logger: nil, - System: &logical.StaticSystemView{ - DefaultLeaseTTLVal: defaultLeaseTTLVal, - MaxLeaseTTLVal: maxLeaseTTLVal, - }, - }) - if err != nil { - t.Fatalf("Unable to create backend: %s", err) - } - - logicaltest.Test(t, logicaltest.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - CredentialBackend: b, - Steps: []logicaltest.TestStep{ - testAccStepConfig(t, false), - testAccMap(t, "default", "fakepol"), - testAccMap(t, "oWnErs", "fakepol"), - testAccLogin(t, []string{"default", "abc", "fakepol"}), - testAccStepConfig(t, true), - testAccMap(t, "default", "fakepol"), - testAccMap(t, "oWnErs", "fakepol"), - testAccLogin(t, []string{"default", "abc", "fakepol"}), - testAccStepConfigWithBaseURL(t), - testAccMap(t, "default", "fakepol"), - testAccMap(t, "oWnErs", "fakepol"), - testAccLogin(t, []string{"default", "abc", "fakepol"}), - testAccMap(t, "default", "fakepol"), - testAccStepConfig(t, true), - mapUserToPolicy(t, os.Getenv("GITHUB_USER"), "userpolicy"), - testAccLogin(t, []string{"default", "abc", "fakepol", "userpolicy"}), - }, - }) -} - -func testAccPreCheck(t *testing.T) { - if v := os.Getenv("GITHUB_TOKEN"); v == "" { - t.Skip("GITHUB_TOKEN must be set for acceptance tests") - } - - if v := os.Getenv("GITHUB_USER"); v == "" { - t.Skip("GITHUB_USER must be set for acceptance tests") - } - - if v := os.Getenv("GITHUB_ORG"); v == "" { - t.Skip("GITHUB_ORG must be set for acceptance tests") - } - - if v := os.Getenv("GITHUB_BASEURL"); v == "" { - t.Skip("GITHUB_BASEURL must be set for acceptance tests (use 'https://api.github.com' if you don't know what you're doing)") - } -} - -func testAccStepConfig(t *testing.T, upper bool) logicaltest.TestStep { - ts := logicaltest.TestStep{ - Operation: logical.UpdateOperation, - Path: "config", - Data: map[string]interface{}{ - "organization": os.Getenv("GITHUB_ORG"), - "token_policies": []string{"abc"}, - }, - } - if upper { - ts.Data["organization"] = strings.ToUpper(os.Getenv("GITHUB_ORG")) - } - return ts -} - -func testAccStepConfigWithBaseURL(t *testing.T) logicaltest.TestStep { - return logicaltest.TestStep{ - Operation: logical.UpdateOperation, - Path: "config", - Data: map[string]interface{}{ - "organization": os.Getenv("GITHUB_ORG"), - "base_url": os.Getenv("GITHUB_BASEURL"), - }, - } -} - -func testAccMap(t *testing.T, k string, v string) logicaltest.TestStep { - return logicaltest.TestStep{ - Operation: logical.UpdateOperation, - Path: "map/teams/" + k, - Data: map[string]interface{}{ - "value": v, - }, - } -} - -func mapUserToPolicy(t *testing.T, k string, v string) logicaltest.TestStep { - return logicaltest.TestStep{ - Operation: logical.UpdateOperation, - Path: "map/users/" + k, - Data: map[string]interface{}{ - "value": v, - }, - } -} - -func testAccLogin(t *testing.T, policies []string) logicaltest.TestStep { - return logicaltest.TestStep{ - Operation: logical.UpdateOperation, - Path: "login", - Data: map[string]interface{}{ - "token": os.Getenv("GITHUB_TOKEN"), - }, - Unauthenticated: true, - - Check: logicaltest.TestCheckAuth(policies), - } -} diff --git a/builtin/credential/github/cli.go b/builtin/credential/github/cli.go deleted file mode 100644 index 177433bde..000000000 --- a/builtin/credential/github/cli.go +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package github - -import ( - "fmt" - "io" - "os" - "strings" - - "github.com/hashicorp/go-secure-stdlib/password" - "github.com/hashicorp/vault/api" -) - -type CLIHandler struct { - // for tests - testStdout io.Writer -} - -func (h *CLIHandler) Auth(c *api.Client, m map[string]string) (*api.Secret, error) { - mount, ok := m["mount"] - if !ok { - mount = "github" - } - - // Extract or prompt for token - token := m["token"] - if token == "" { - token = os.Getenv("VAULT_AUTH_GITHUB_TOKEN") - } - if token == "" { - // Override the output - stdout := h.testStdout - if stdout == nil { - stdout = os.Stderr - } - - var err error - fmt.Fprintf(stdout, "GitHub Personal Access Token (will be hidden): ") - token, err = password.Read(os.Stdin) - fmt.Fprintf(stdout, "\n") - if err != nil { - if err == password.ErrInterrupted { - return nil, fmt.Errorf("user interrupted") - } - - return nil, fmt.Errorf("An error occurred attempting to "+ - "ask for a token. The raw error message is shown below, but usually "+ - "this is because you attempted to pipe a value into the command or "+ - "you are executing outside of a terminal (tty). If you want to pipe "+ - "the value, pass \"-\" as the argument to read from stdin. The raw "+ - "error was: %w", err) - } - } - - path := fmt.Sprintf("auth/%s/login", mount) - secret, err := c.Logical().Write(path, map[string]interface{}{ - "token": strings.TrimSpace(token), - }) - if err != nil { - return nil, err - } - if secret == nil { - return nil, fmt.Errorf("empty response from credential provider") - } - - return secret, nil -} - -func (h *CLIHandler) Help() string { - help := ` -Usage: vault login -method=github [CONFIG K=V...] - - The GitHub auth method allows users to authenticate using a GitHub - personal access token. Users can generate a personal access token from the - settings page on their GitHub account. - - Authenticate using a GitHub token: - - $ vault login -method=github token=abcd1234 - -Configuration: - - mount= - Path where the GitHub credential method is mounted. This is usually - provided via the -path flag in the "vault login" command, but it can be - specified here as well. If specified here, it takes precedence over the - value for -path. The default value is "github". - - token= - GitHub personal access token to use for authentication. If not provided, - Vault will prompt for the value. -` - - return strings.TrimSpace(help) -} diff --git a/builtin/credential/github/cmd/github/main.go b/builtin/credential/github/cmd/github/main.go deleted file mode 100644 index 40a3a0002..000000000 --- a/builtin/credential/github/cmd/github/main.go +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package main - -import ( - "os" - - hclog "github.com/hashicorp/go-hclog" - "github.com/hashicorp/vault/api" - "github.com/hashicorp/vault/builtin/credential/github" - "github.com/hashicorp/vault/sdk/plugin" -) - -func main() { - apiClientMeta := &api.PluginAPIClientMeta{} - flags := apiClientMeta.FlagSet() - flags.Parse(os.Args[1:]) - - tlsConfig := apiClientMeta.GetTLSConfig() - tlsProviderFunc := api.VaultPluginTLSProvider(tlsConfig) - - if err := plugin.ServeMultiplex(&plugin.ServeOpts{ - BackendFactoryFunc: github.Factory, - // set the TLSProviderFunc so that the plugin maintains backwards - // compatibility with Vault versions that don’t support plugin AutoMTLS - TLSProviderFunc: tlsProviderFunc, - }); err != nil { - logger := hclog.New(&hclog.LoggerOptions{}) - - logger.Error("plugin shutting down", "error", err) - os.Exit(1) - } -} diff --git a/builtin/credential/github/path_config.go b/builtin/credential/github/path_config.go deleted file mode 100644 index abe78760f..000000000 --- a/builtin/credential/github/path_config.go +++ /dev/null @@ -1,247 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package github - -import ( - "context" - "fmt" - "net/url" - "os" - "strings" - "time" - - "github.com/google/go-github/github" - "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", - - DisplayAttrs: &framework.DisplayAttributes{ - OperationPrefix: operationPrefixGithub, - }, - - Fields: map[string]*framework.FieldSchema{ - "organization": { - Type: framework.TypeString, - Description: "The organization users must be part of", - Required: true, - }, - "organization_id": { - Type: framework.TypeInt64, - Description: "The ID of the organization users must be part of", - }, - "base_url": { - 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": { - Type: framework.TypeDurationSecond, - Description: tokenutil.DeprecationText("token_ttl"), - Deprecated: true, - }, - "max_ttl": { - Type: framework.TypeDurationSecond, - Description: tokenutil.DeprecationText("token_max_ttl"), - Deprecated: true, - }, - }, - - Operations: map[logical.Operation]framework.OperationHandler{ - logical.UpdateOperation: &framework.PathOperation{ - Callback: b.pathConfigWrite, - DisplayAttrs: &framework.DisplayAttributes{ - OperationPrefix: operationPrefixGithub, - OperationVerb: "configure", - }, - }, - logical.ReadOperation: &framework.PathOperation{ - Callback: b.pathConfigRead, - DisplayAttrs: &framework.DisplayAttributes{ - OperationSuffix: "configuration", - }, - }, - }, - } - - 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) { - var resp logical.Response - 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 c.Organization == "" { - return logical.ErrorResponse("organization is a required parameter"), nil - } - - if organizationRaw, ok := data.GetOk("organization_id"); ok { - c.OrganizationID = organizationRaw.(int64) - } - - var parsedURL *url.URL - if baseURLRaw, ok := data.GetOk("base_url"); ok { - baseURL := baseURLRaw.(string) - if !strings.HasSuffix(baseURL, "/") { - baseURL += "/" - } - parsedURL, err = url.Parse(baseURL) - if err != nil { - return logical.ErrorResponse(fmt.Sprintf("error parsing given base_url: %s", err)), nil - } - c.BaseURL = baseURL - } - - if c.OrganizationID == 0 { - githubToken := os.Getenv("VAULT_AUTH_CONFIG_GITHUB_TOKEN") - client, err := b.Client(githubToken) - if err != nil { - return nil, err - } - // ensure our client has the BaseURL if it was provided - if parsedURL != nil { - client.BaseURL = parsedURL - } - - // we want to set the Org ID in the config so we can use that to verify - // the credentials on login - err = c.setOrganizationID(ctx, client) - if err != nil { - errorMsg := fmt.Errorf("unable to fetch the organization_id, you must manually set it in the config: %s", err) - b.Logger().Error(errorMsg.Error()) - return nil, errorMsg - } - } - - 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 - } - - if len(resp.Warnings) == 0 { - return nil, nil - } - - return &resp, 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_id": config.OrganizationID, - "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, fmt.Errorf("error reading configuration: %w", 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 - - OrganizationID int64 `json:"organization_id" structs:"organization_id" mapstructure:"organization_id"` - 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"` -} - -func (c *config) setOrganizationID(ctx context.Context, client *github.Client) error { - org, _, err := client.Organizations.Get(ctx, c.Organization) - if err != nil { - return err - } - - orgID := org.GetID() - if orgID == 0 { - return fmt.Errorf("organization_id not found for %s", c.Organization) - } - - c.OrganizationID = orgID - - return nil -} diff --git a/builtin/credential/github/path_config_test.go b/builtin/credential/github/path_config_test.go deleted file mode 100644 index 19338ff44..000000000 --- a/builtin/credential/github/path_config_test.go +++ /dev/null @@ -1,255 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package github - -import ( - "context" - "errors" - "fmt" - "net/http" - "net/http/httptest" - "os" - "strings" - "testing" - - "github.com/hashicorp/vault/sdk/logical" - "github.com/stretchr/testify/assert" -) - -func createBackendWithStorage(t *testing.T) (*backend, logical.Storage) { - t.Helper() - config := logical.TestBackendConfig() - config.StorageView = &logical.InmemStorage{} - - b := Backend() - if b == nil { - t.Fatalf("failed to create backend") - } - err := b.Backend.Setup(context.Background(), config) - if err != nil { - t.Fatal(err) - } - return b, config.StorageView -} - -// setupTestServer configures httptest server to intercept and respond to the -// request to base_url -func setupTestServer(t *testing.T) *httptest.Server { - t.Helper() - return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - var resp string - if strings.Contains(r.URL.String(), "/user/orgs") { - resp = string(listOrgResponse) - } else if strings.Contains(r.URL.String(), "/user/teams") { - resp = string(listUserTeamsResponse) - } else if strings.Contains(r.URL.String(), "/user") { - resp = getUserResponse - } else if strings.Contains(r.URL.String(), "/orgs/") { - resp = getOrgResponse - } - - w.Header().Add("Content-Type", "application/json") - fmt.Fprintln(w, resp) - })) -} - -// TestGitHub_WriteReadConfig tests that we can successfully read and write -// the github auth config -func TestGitHub_WriteReadConfig(t *testing.T) { - b, s := createBackendWithStorage(t) - - // use a test server to return our mock GH org info - ts := setupTestServer(t) - defer ts.Close() - - // Write the config - resp, err := b.HandleRequest(context.Background(), &logical.Request{ - Path: "config", - Operation: logical.UpdateOperation, - Data: map[string]interface{}{ - "organization": "foo-org", - "base_url": ts.URL, // base_url will call the test server - }, - Storage: s, - }) - assert.NoError(t, err) - assert.Nil(t, resp) - assert.NoError(t, resp.Error()) - - // Read the config - resp, err = b.HandleRequest(context.Background(), &logical.Request{ - Path: "config", - Operation: logical.ReadOperation, - Storage: s, - }) - assert.NoError(t, err) - assert.NoError(t, resp.Error()) - - // the ID should be set, we grab it from the GET /orgs API - assert.Equal(t, int64(12345), resp.Data["organization_id"]) - assert.Equal(t, "foo-org", resp.Data["organization"]) -} - -// TestGitHub_WriteReadConfig_OrgID tests that we can successfully read and -// write the github auth config with an organization_id param -func TestGitHub_WriteReadConfig_OrgID(t *testing.T) { - b, s := createBackendWithStorage(t) - - // Write the config and pass in organization_id - resp, err := b.HandleRequest(context.Background(), &logical.Request{ - Path: "config", - Operation: logical.UpdateOperation, - Data: map[string]interface{}{ - "organization": "foo-org", - "organization_id": 98765, - }, - Storage: s, - }) - assert.NoError(t, err) - assert.Nil(t, resp) - assert.NoError(t, resp.Error()) - - // Read the config - resp, err = b.HandleRequest(context.Background(), &logical.Request{ - Path: "config", - Operation: logical.ReadOperation, - Storage: s, - }) - assert.NoError(t, err) - assert.NoError(t, resp.Error()) - - // the ID should be set to what was written in the config - assert.Equal(t, int64(98765), resp.Data["organization_id"]) - assert.Equal(t, "foo-org", resp.Data["organization"]) -} - -// TestGitHub_WriteReadConfig_Token tests that we can successfully read and -// write the github auth config with a token environment variable -func TestGitHub_WriteReadConfig_Token(t *testing.T) { - b, s := createBackendWithStorage(t) - // use a test server to return our mock GH org info - ts := setupTestServer(t) - defer ts.Close() - - err := os.Setenv("VAULT_AUTH_CONFIG_GITHUB_TOKEN", "foobar") - assert.NoError(t, err) - - resp, err := b.HandleRequest(context.Background(), &logical.Request{ - Path: "config", - Operation: logical.UpdateOperation, - Data: map[string]interface{}{ - "organization": "foo-org", - "base_url": ts.URL, // base_url will call the test server - }, - Storage: s, - }) - assert.NoError(t, err) - assert.Nil(t, resp) - assert.NoError(t, resp.Error()) - - // Read the config - resp, err = b.HandleRequest(context.Background(), &logical.Request{ - Path: "config", - Operation: logical.ReadOperation, - Storage: s, - }) - assert.NoError(t, err) - assert.NoError(t, resp.Error()) - - // the token should not be returned in the read config response. - assert.Nil(t, resp.Data["token"]) -} - -// TestGitHub_ErrorNoOrgID tests that an error is returned when we cannot fetch -// the org ID for the given org name -func TestGitHub_ErrorNoOrgID(t *testing.T) { - b, s := createBackendWithStorage(t) - // use a test server to return our mock GH org info - ts := func() *httptest.Server { - return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Header().Add("Content-Type", "application/json") - resp := `{ "id": 0 }` - fmt.Fprintln(w, resp) - })) - } - - defer ts().Close() - - // Write the config - resp, err := b.HandleRequest(context.Background(), &logical.Request{ - Path: "config", - Operation: logical.UpdateOperation, - Data: map[string]interface{}{ - "organization": "foo-org", - "base_url": ts().URL, // base_url will call the test server - }, - Storage: s, - }) - assert.Error(t, err) - assert.Nil(t, resp) - assert.Equal(t, errors.New( - "unable to fetch the organization_id, you must manually set it in the config: organization_id not found for foo-org", - ), err) -} - -// TestGitHub_WriteConfig_ErrorNoOrg tests that an error is returned when the -// required "organization" parameter is not provided -func TestGitHub_WriteConfig_ErrorNoOrg(t *testing.T) { - b, s := createBackendWithStorage(t) - - // Write the config - resp, err := b.HandleRequest(context.Background(), &logical.Request{ - Path: "config", - Operation: logical.UpdateOperation, - Data: map[string]interface{}{}, - Storage: s, - }) - - assert.NoError(t, err) - assert.Error(t, resp.Error()) - assert.Equal(t, errors.New("organization is a required parameter"), resp.Error()) -} - -// https://docs.github.com/en/rest/reference/users#get-the-authenticated-user -// Note: many of the fields have been omitted -var getUserResponse = ` -{ - "login": "user-foo", - "id": 6789, - "description": "A great user. The very best user.", - "name": "foo name", - "company": "foo-company", - "type": "User" -} -` - -// https://docs.github.com/en/rest/reference/orgs#get-an-organization -// Note: many of the fields have been omitted, we only care about 'login' and 'id' -var getOrgResponse = ` -{ - "login": "foo-org", - "id": 12345, - "description": "A great org. The very best org.", - "name": "foo-display-name", - "company": "foo-company", - "type": "Organization" -} -` - -// https://docs.github.com/en/rest/reference/orgs#list-organizations-for-the-authenticated-user -var listOrgResponse = []byte(fmt.Sprintf(`[%v]`, getOrgResponse)) - -// https://docs.github.com/en/rest/reference/teams#list-teams-for-the-authenticated-user -// Note: many of the fields have been omitted -var listUserTeamsResponse = []byte(fmt.Sprintf(`[ -{ - "id": 1, - "node_id": "MDQ6VGVhbTE=", - "name": "Foo team", - "slug": "foo-team", - "description": "A great team. The very best team.", - "permission": "admin", - "organization": %v - } -]`, getOrgResponse)) diff --git a/builtin/credential/github/path_login.go b/builtin/credential/github/path_login.go deleted file mode 100644 index 181076a65..000000000 --- a/builtin/credential/github/path_login.go +++ /dev/null @@ -1,312 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package github - -import ( - "context" - "errors" - "fmt" - "net/url" - - "github.com/google/go-github/github" - "github.com/hashicorp/vault/sdk/framework" - "github.com/hashicorp/vault/sdk/helper/cidrutil" - "github.com/hashicorp/vault/sdk/helper/policyutil" - "github.com/hashicorp/vault/sdk/logical" -) - -func pathLogin(b *backend) *framework.Path { - return &framework.Path{ - Pattern: "login", - - DisplayAttrs: &framework.DisplayAttributes{ - OperationPrefix: operationPrefixGithub, - OperationVerb: "login", - }, - - Fields: map[string]*framework.FieldSchema{ - "token": { - Type: framework.TypeString, - Description: "GitHub personal API token", - }, - }, - - Callbacks: map[logical.Operation]framework.OperationFunc{ - logical.UpdateOperation: b.pathLogin, - logical.AliasLookaheadOperation: b.pathLoginAliasLookahead, - }, - } -} - -func (b *backend) pathLoginAliasLookahead(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { - token := data.Get("token").(string) - - verifyResp, err := b.verifyCredentials(ctx, req, token) - if err != nil { - return nil, err - } - - return &logical.Response{ - Warnings: verifyResp.Warnings, - Auth: &logical.Auth{ - Alias: &logical.Alias{ - Name: *verifyResp.User.Login, - }, - }, - }, nil -} - -func (b *backend) pathLogin(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { - token := data.Get("token").(string) - - verifyResp, err := b.verifyCredentials(ctx, req, token) - if err != nil { - return nil, err - } - - auth := &logical.Auth{ - InternalData: map[string]interface{}{ - "token": token, - }, - Metadata: map[string]string{ - "username": *verifyResp.User.Login, - "org": *verifyResp.Org.Login, - }, - DisplayName: *verifyResp.User.Login, - Alias: &logical.Alias{ - Name: *verifyResp.User.Login, - }, - } - verifyResp.Config.PopulateTokenAuth(auth) - - // Add in configured policies from user/group mapping - if len(verifyResp.Policies) > 0 { - auth.Policies = append(auth.Policies, verifyResp.Policies...) - } - - resp := &logical.Response{ - Warnings: verifyResp.Warnings, - Auth: auth, - } - - for _, teamName := range verifyResp.TeamNames { - if teamName == "" { - continue - } - resp.Auth.GroupAliases = append(resp.Auth.GroupAliases, &logical.Alias{ - Name: teamName, - }) - } - - return resp, nil -} - -func (b *backend) pathLoginRenew(ctx context.Context, req *logical.Request, d *framework.FieldData) (*logical.Response, error) { - if req.Auth == nil { - return nil, fmt.Errorf("request auth was nil") - } - - tokenRaw, ok := req.Auth.InternalData["token"] - if !ok { - return nil, fmt.Errorf("token created in previous version of Vault cannot be validated properly at renewal time") - } - token := tokenRaw.(string) - - verifyResp, err := b.verifyCredentials(ctx, req, token) - if err != nil { - return nil, err - } - - if !policyutil.EquivalentPolicies(verifyResp.Policies, req.Auth.TokenPolicies) { - return nil, fmt.Errorf("policies do not match") - } - - resp := &logical.Response{Auth: req.Auth} - resp.Auth.Period = verifyResp.Config.TokenPeriod - resp.Auth.TTL = verifyResp.Config.TokenTTL - resp.Auth.MaxTTL = verifyResp.Config.TokenMaxTTL - resp.Warnings = verifyResp.Warnings - - // Remove old aliases - resp.Auth.GroupAliases = nil - - for _, teamName := range verifyResp.TeamNames { - resp.Auth.GroupAliases = append(resp.Auth.GroupAliases, &logical.Alias{ - Name: teamName, - }) - } - - return resp, nil -} - -func (b *backend) verifyCredentials(ctx context.Context, req *logical.Request, token string) (*verifyCredentialsResp, error) { - var warnings []string - config, err := b.Config(ctx, req.Storage) - if err != nil { - return nil, err - } - if config == nil { - return nil, errors.New("configuration has not been set") - } - - // Check for a CIDR match. - if len(config.TokenBoundCIDRs) > 0 { - if req.Connection == nil { - b.Logger().Error("token bound CIDRs found but no connection information available for validation") - return nil, logical.ErrPermissionDenied - } - if !cidrutil.RemoteAddrIsOk(req.Connection.RemoteAddr, config.TokenBoundCIDRs) { - return nil, logical.ErrPermissionDenied - } - } - - client, err := b.Client(token) - if err != nil { - return nil, err - } - - if config.BaseURL != "" { - parsedURL, err := url.Parse(config.BaseURL) - if err != nil { - return nil, fmt.Errorf("successfully parsed base_url when set but failing to parse now: %w", err) - } - client.BaseURL = parsedURL - } - - if config.OrganizationID == 0 { - // Previously we did not verify using the Org ID. So if the Org ID is - // not set, we will trust-on-first-use and set it now. - err = config.setOrganizationID(ctx, client) - if err != nil { - b.Logger().Error("failed to set the organization_id on login", "error", err) - return nil, err - } - entry, err := logical.StorageEntryJSON("config", config) - if err != nil { - return nil, err - } - - if err := req.Storage.Put(ctx, entry); err != nil { - return nil, err - } - - b.Logger().Info("set ID on a trust-on-first-use basis", "organization_id", config.OrganizationID) - } - - // Get the user - user, _, err := client.Users.Get(ctx, "") - if err != nil { - return nil, err - } - - // Verify that the user is part of the organization - var org *github.Organization - - orgOpt := &github.ListOptions{ - PerPage: 100, - } - - var allOrgs []*github.Organization - for { - orgs, resp, err := client.Organizations.List(ctx, "", orgOpt) - if err != nil { - return nil, err - } - allOrgs = append(allOrgs, orgs...) - if resp.NextPage == 0 { - break - } - orgOpt.Page = resp.NextPage - } - - orgLoginName := "" - for _, o := range allOrgs { - if o.GetID() == config.OrganizationID { - org = o - orgLoginName = *o.Login - break - } - } - if org == nil { - return nil, errors.New("user is not part of required org") - } - - if orgLoginName != config.Organization { - warningMsg := fmt.Sprintf( - "the organization name has changed to %q. It is recommended to verify and update the organization name in the config: %s=%d", - orgLoginName, - "organization_id", - config.OrganizationID, - ) - b.Logger().Warn(warningMsg) - warnings = append(warnings, warningMsg) - } - - // Get the teams that this user is part of to determine the policies - var teamNames []string - - teamOpt := &github.ListOptions{ - PerPage: 100, - } - - var allTeams []*github.Team - for { - teams, resp, err := client.Teams.ListUserTeams(ctx, teamOpt) - if err != nil { - return nil, err - } - allTeams = append(allTeams, teams...) - if resp.NextPage == 0 { - break - } - teamOpt.Page = resp.NextPage - } - - for _, t := range allTeams { - // We only care about teams that are part of the organization we use - if *t.Organization.ID != *org.ID { - continue - } - - // Append the names so we can get the policies - teamNames = append(teamNames, *t.Name) - if *t.Name != *t.Slug { - teamNames = append(teamNames, *t.Slug) - } - } - - groupPoliciesList, err := b.TeamMap.Policies(ctx, req.Storage, teamNames...) - if err != nil { - return nil, err - } - - userPoliciesList, err := b.UserMap.Policies(ctx, req.Storage, []string{*user.Login}...) - if err != nil { - return nil, err - } - - verifyResp := &verifyCredentialsResp{ - User: user, - Org: org, - Policies: append(groupPoliciesList, userPoliciesList...), - TeamNames: teamNames, - Config: config, - Warnings: warnings, - } - - return verifyResp, nil -} - -type verifyCredentialsResp struct { - User *github.User - Org *github.Organization - Policies []string - TeamNames []string - - // Warnings to send back to the caller - Warnings []string - - // This is just a cache to send back to the caller - Config *config -} diff --git a/builtin/credential/github/path_login_test.go b/builtin/credential/github/path_login_test.go deleted file mode 100644 index cfc47a984..000000000 --- a/builtin/credential/github/path_login_test.go +++ /dev/null @@ -1,189 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package github - -import ( - "context" - "errors" - "testing" - - "github.com/hashicorp/vault/helper/namespace" - "github.com/hashicorp/vault/sdk/logical" - "github.com/stretchr/testify/assert" -) - -// TestGitHub_Login tests that we can successfully login with the given config -func TestGitHub_Login(t *testing.T) { - b, s := createBackendWithStorage(t) - - // use a test server to return our mock GH org info - ts := setupTestServer(t) - defer ts.Close() - - // Write the config - resp, err := b.HandleRequest(context.Background(), &logical.Request{ - Path: "config", - Operation: logical.UpdateOperation, - Data: map[string]interface{}{ - "organization": "foo-org", - "base_url": ts.URL, // base_url will call the test server - }, - Storage: s, - }) - assert.NoError(t, err) - assert.NoError(t, resp.Error()) - - // Read the config - resp, err = b.HandleRequest(context.Background(), &logical.Request{ - Path: "config", - Operation: logical.ReadOperation, - Storage: s, - }) - assert.NoError(t, err) - assert.NoError(t, resp.Error()) - - // attempt a login - resp, err = b.HandleRequest(context.Background(), &logical.Request{ - Path: "login", - Operation: logical.UpdateOperation, - Storage: s, - }) - - expectedMetaData := map[string]string{ - "org": "foo-org", - "username": "user-foo", - } - assert.Equal(t, expectedMetaData, resp.Auth.Metadata) - assert.NoError(t, err) - assert.NoError(t, resp.Error()) -} - -// TestGitHub_Login_OrgInvalid tests that we cannot login with an ID other than -// what is set in the config -func TestGitHub_Login_OrgInvalid(t *testing.T) { - b, s := createBackendWithStorage(t) - ctx := namespace.RootContext(nil) - - // use a test server to return our mock GH org info - ts := setupTestServer(t) - defer ts.Close() - - // write and store config - config := config{ - Organization: "foo-org", - OrganizationID: 9999, - BaseURL: ts.URL + "/", // base_url will call the test server - } - entry, err := logical.StorageEntryJSON("config", config) - if err != nil { - t.Fatalf("failed creating storage entry") - } - if err := s.Put(ctx, entry); err != nil { - t.Fatalf("writing to in mem storage failed") - } - - // attempt a login - resp, err := b.HandleRequest(context.Background(), &logical.Request{ - Path: "login", - Operation: logical.UpdateOperation, - Storage: s, - }) - - assert.Nil(t, resp) - assert.Error(t, err) - assert.Equal(t, errors.New("user is not part of required org"), err) -} - -// TestGitHub_Login_OrgNameChanged tests that we can successfully login with the -// given config and emit a warning when the organization name has changed -func TestGitHub_Login_OrgNameChanged(t *testing.T) { - b, s := createBackendWithStorage(t) - ctx := namespace.RootContext(nil) - - // use a test server to return our mock GH org info - ts := setupTestServer(t) - defer ts.Close() - - // write and store config - // the name does not match what the API will return but the ID does - config := config{ - Organization: "old-name", - OrganizationID: 12345, - BaseURL: ts.URL + "/", // base_url will call the test server - } - entry, err := logical.StorageEntryJSON("config", config) - if err != nil { - t.Fatalf("failed creating storage entry") - } - if err := s.Put(ctx, entry); err != nil { - t.Fatalf("writing to in mem storage failed") - } - - // attempt a login - resp, err := b.HandleRequest(context.Background(), &logical.Request{ - Path: "login", - Operation: logical.UpdateOperation, - Storage: s, - }) - - assert.NoError(t, err) - assert.Nil(t, resp.Error()) - assert.Equal( - t, - []string{"the organization name has changed to \"foo-org\". It is recommended to verify and update the organization name in the config: organization_id=12345"}, - resp.Warnings, - ) -} - -// TestGitHub_Login_NoOrgID tests that we can successfully login with the given -// config when no organization ID is present and write the fetched ID to the -// config -func TestGitHub_Login_NoOrgID(t *testing.T) { - b, s := createBackendWithStorage(t) - ctx := namespace.RootContext(nil) - - // use a test server to return our mock GH org info - ts := setupTestServer(t) - defer ts.Close() - - // write and store config without Org ID - config := config{ - Organization: "foo-org", - BaseURL: ts.URL + "/", // base_url will call the test server - } - entry, err := logical.StorageEntryJSON("config", config) - if err != nil { - t.Fatalf("failed creating storage entry") - } - if err := s.Put(ctx, entry); err != nil { - t.Fatalf("writing to in mem storage failed") - } - - // attempt a login - resp, err := b.HandleRequest(context.Background(), &logical.Request{ - Path: "login", - Operation: logical.UpdateOperation, - Storage: s, - }) - - expectedMetaData := map[string]string{ - "org": "foo-org", - "username": "user-foo", - } - assert.Equal(t, expectedMetaData, resp.Auth.Metadata) - assert.NoError(t, err) - assert.NoError(t, resp.Error()) - - // Read the config - resp, err = b.HandleRequest(context.Background(), &logical.Request{ - Path: "config", - Operation: logical.ReadOperation, - Storage: s, - }) - assert.NoError(t, err) - assert.NoError(t, resp.Error()) - - // the ID should be set, we grab it from the GET /orgs API - assert.Equal(t, int64(12345), resp.Data["organization_id"]) -} diff --git a/command/base_predict.go b/command/base_predict.go index a64fbd7bc..368b37bb2 100644 --- a/command/base_predict.go +++ b/command/base_predict.go @@ -105,7 +105,6 @@ func (b *BaseCommand) PredictVaultAvailableAuths() complete.Predictor { "app-id", "approle", "cert", - "github", "ldap", "plugin", "radius", diff --git a/command/commands.go b/command/commands.go index 77ff401b5..5c088b878 100644 --- a/command/commands.go +++ b/command/commands.go @@ -29,7 +29,6 @@ import ( credOIDC "github.com/hashicorp/vault-plugin-auth-jwt" credKerb "github.com/hashicorp/vault-plugin-auth-kerberos" credCert "github.com/hashicorp/vault/builtin/credential/cert" - credGitHub "github.com/hashicorp/vault/builtin/credential/github" credLdap "github.com/hashicorp/vault/builtin/credential/ldap" credToken "github.com/hashicorp/vault/builtin/credential/token" credUserpass "github.com/hashicorp/vault/builtin/credential/userpass" @@ -178,7 +177,6 @@ var ( func initCommands(ui, serverCmdUi cli.Ui, runOpts *RunOptions) map[string]cli.CommandFactory { loginHandlers := map[string]LoginHandler{ "cert": &credCert.CLIHandler{}, - "github": &credGitHub.CLIHandler{}, "kerberos": &credKerb.CLIHandler{}, "ldap": &credLdap.CLIHandler{}, "oidc": &credOIDC.CLIHandler{}, diff --git a/go.mod b/go.mod index 8986228ff..641bca766 100644 --- a/go.mod +++ b/go.mod @@ -45,7 +45,6 @@ require ( github.com/gocql/gocql v1.0.0 github.com/golang/protobuf v1.5.3 github.com/google/go-cmp v0.6.0 - github.com/google/go-github v17.0.0+incompatible github.com/google/tink/go v1.7.0 github.com/hashicorp-forge/bbolt v1.3.8-hc3 github.com/hashicorp/cap v0.3.0 @@ -155,7 +154,6 @@ require ( golang.org/x/crypto v0.23.0 golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 golang.org/x/net v0.25.0 - golang.org/x/oauth2 v0.18.0 golang.org/x/sync v0.7.0 golang.org/x/sys v0.20.0 golang.org/x/term v0.20.0 @@ -341,6 +339,7 @@ require ( go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0 // indirect go.opentelemetry.io/otel/metric v1.22.0 // indirect golang.org/x/mod v0.15.0 // indirect + golang.org/x/oauth2 v0.18.0 // indirect golang.org/x/time v0.5.0 // indirect google.golang.org/api v0.163.0 // indirect google.golang.org/appengine v1.6.8 // indirect diff --git a/go.sum b/go.sum index 06aa19ebb..547772abd 100644 --- a/go.sum +++ b/go.sum @@ -1713,8 +1713,6 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-containerregistry v0.5.1/go.mod h1:Ct15B4yir3PLOP5jsy0GNeYVaIZs/MK/Jz5any1wFW0= github.com/google/go-containerregistry v0.14.0/go.mod h1:aiJ2fp/SXvkWgmYHioXnbMdlgB8eXiiYOY55gfN91Wk= -github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY= -github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= diff --git a/helper/builtinplugins/registry.go b/helper/builtinplugins/registry.go index 3d374b63e..8a37f24a1 100644 --- a/helper/builtinplugins/registry.go +++ b/helper/builtinplugins/registry.go @@ -16,7 +16,6 @@ import ( logicalTerraform "github.com/hashicorp/vault-plugin-secrets-terraform" credAppRole "github.com/hashicorp/vault/builtin/credential/approle" credCert "github.com/hashicorp/vault/builtin/credential/cert" - credGitHub "github.com/hashicorp/vault/builtin/credential/github" credLdap "github.com/hashicorp/vault/builtin/credential/ldap" credRadius "github.com/hashicorp/vault/builtin/credential/radius" credUserpass "github.com/hashicorp/vault/builtin/credential/userpass" @@ -80,7 +79,6 @@ func newRegistry() *registry { }, "approle": {Factory: credAppRole.Factory}, "cert": {Factory: credCert.Factory}, - "github": {Factory: credGitHub.Factory}, "jwt": {Factory: credJWT.Factory}, "kerberos": {Factory: credKerb.Factory}, "kubernetes": {Factory: credKube.Factory}, diff --git a/scripts/gen_openapi.sh b/scripts/gen_openapi.sh index b9a8ef314..9317b1672 100755 --- a/scripts/gen_openapi.sh +++ b/scripts/gen_openapi.sh @@ -52,7 +52,6 @@ echo "Mounting all builtin plugins ..." # Enable auth plugins vault auth enable "approle" vault auth enable "cert" -vault auth enable "github" vault auth enable "jwt" vault auth enable "kerberos" vault auth enable "kubernetes" diff --git a/ui/app/adapters/auth-config/github.js b/ui/app/adapters/auth-config/github.js deleted file mode 100644 index 1a1c1a672..000000000 --- a/ui/app/adapters/auth-config/github.js +++ /dev/null @@ -1,8 +0,0 @@ -/** - * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 - */ - -import AuthConfig from './_base'; - -export default AuthConfig.extend(); diff --git a/ui/app/helpers/mountable-auth-methods.js b/ui/app/helpers/mountable-auth-methods.js index a82310734..09c3d62a6 100644 --- a/ui/app/helpers/mountable-auth-methods.js +++ b/ui/app/helpers/mountable-auth-methods.js @@ -18,13 +18,6 @@ const MOUNTABLE_AUTH_METHODS = [ type: 'approle', category: 'generic', }, - { - displayName: 'GitHub', - value: 'github', - type: 'github', - category: 'cloud', - glyph: 'github-color', - }, { displayName: 'JWT', value: 'jwt', diff --git a/ui/app/helpers/supported-auth-backends.js b/ui/app/helpers/supported-auth-backends.js index 5778385c4..a4977fb07 100644 --- a/ui/app/helpers/supported-auth-backends.js +++ b/ui/app/helpers/supported-auth-backends.js @@ -60,14 +60,6 @@ const SUPPORTED_AUTH_BACKENDS = [ displayNamePath: 'metadata.username', formAttributes: ['username', 'password'], }, - { - type: 'github', - typeDisplay: 'GitHub', - description: 'GitHub authentication.', - tokenPath: 'client_token', - displayNamePath: ['metadata.org', 'metadata.username'], - formAttributes: ['token'], - }, ]; export function supportedAuthBackends() { diff --git a/ui/app/models/auth-config/github.js b/ui/app/models/auth-config/github.js deleted file mode 100644 index 675741c68..000000000 --- a/ui/app/models/auth-config/github.js +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 - */ - -import { attr } from '@ember-data/model'; -import { computed } from '@ember/object'; -import AuthConfig from '../auth-config'; -import fieldToAttrs from 'vault/utils/field-to-attrs'; -import { combineFieldGroups } from 'vault/utils/openapi-to-attrs'; - -export default AuthConfig.extend({ - useOpenAPI: true, - organization: attr('string'), - baseUrl: attr('string', { - label: 'Base URL', - }), - - fieldGroups: computed('newFields', function () { - let groups = [ - { default: ['organization'] }, - { - 'GitHub Options': ['baseUrl'], - }, - ]; - if (this.newFields) { - groups = combineFieldGroups(groups, this.newFields, []); - } - - return fieldToAttrs(this, groups); - }), -}); diff --git a/ui/app/routes/vault/cluster/settings/auth/configure/section.js b/ui/app/routes/vault/cluster/settings/auth/configure/section.js index 8473fdb5e..3b3e7ead7 100644 --- a/ui/app/routes/vault/cluster/settings/auth/configure/section.js +++ b/ui/app/routes/vault/cluster/settings/auth/configure/section.js @@ -17,7 +17,6 @@ export default Route.extend(UnloadModelRoute, { modelType(backendType, section) { const MODELS = { - 'github-configuration': 'auth-config/github', 'jwt-configuration': 'auth-config/jwt', 'oidc-configuration': 'auth-config/oidc', 'kubernetes-configuration': 'auth-config/kubernetes', diff --git a/ui/app/templates/components/auth-form.hbs b/ui/app/templates/components/auth-form.hbs index 23328c727..6a201316d 100644 --- a/ui/app/templates/components/auth-form.hbs +++ b/ui/app/templates/components/auth-form.hbs @@ -87,23 +87,7 @@ {{else}}
- {{#if (eq this.providerName "github")}} -
- -
- -
-
- {{else if (eq this.providerName "token")}} + {{if (eq this.providerName "token")}}
diff --git a/ui/app/templates/components/wizard/github-method.hbs b/ui/app/templates/components/wizard/github-method.hbs deleted file mode 100644 index 708eda451..000000000 --- a/ui/app/templates/components/wizard/github-method.hbs +++ /dev/null @@ -1,15 +0,0 @@ -{{! - Copyright (c) HashiCorp, Inc. - SPDX-License-Identifier: BUSL-1.1 -~}} - - -

- The Github Auth Method can be used to authenticate with Vault using a GitHub personal access token. -

-
\ No newline at end of file diff --git a/ui/lib/core/icon-mappings.js b/ui/lib/core/icon-mappings.js index 0f38d8029..99db8cbda 100644 --- a/ui/lib/core/icon-mappings.js +++ b/ui/lib/core/icon-mappings.js @@ -125,8 +125,6 @@ export const structureIconMap = { 'logo-bitbucket-monochrome': 'bitbucket', 'logo-f5-color': 'f5-color', 'logo-f5-monochrome': 'f5', - 'logo-github-color': 'github-color', - 'logo-github-monochrome': 'github', 'logo-gitlab-color': 'gitlab-color', 'logo-gitlab-monochrome': 'gitlab', 'logo-google-color': 'google-color', diff --git a/ui/public/eco/github.svg b/ui/public/eco/github.svg deleted file mode 100644 index fdd4893e5..000000000 --- a/ui/public/eco/github.svg +++ /dev/null @@ -1 +0,0 @@ -