Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

provider: Add insecure mode #48

Merged
merged 3 commits into from
Aug 7, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion github/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package github

import (
"context"
"crypto/tls"
"net/http"
"net/url"

"github.com/google/go-github/github"
Expand All @@ -13,6 +15,7 @@ type Config struct {
Token string
Organization string
BaseURL string
Insecure bool
}

type Organization struct {
Expand All @@ -28,7 +31,15 @@ func (c *Config) Client() (interface{}, error) {
ts := oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: c.Token},
)
tc := oauth2.NewClient(oauth2.NoContext, ts)

ctx := context.Background()

if c.Insecure {
httpClient := insecureHttpClient()
ctx = context.WithValue(ctx, oauth2.HTTPClient, httpClient)
}

tc := oauth2.NewClient(ctx, ts)

tc.Transport = logging.NewTransport("Github", tc.Transport)

Expand All @@ -43,3 +54,13 @@ func (c *Config) Client() (interface{}, error) {

return &org, nil
}

func insecureHttpClient() *http.Client {
return &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
},
}
}
10 changes: 10 additions & 0 deletions github/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ func Provider() terraform.ResourceProvider {
DefaultFunc: schema.EnvDefaultFunc("GITHUB_BASE_URL", ""),
Description: descriptions["base_url"],
},
"insecure": &schema.Schema{
Type: schema.TypeBool,
Optional: true,
Default: false,
Description: descriptions["insecure"],
},
},

ResourcesMap: map[string]*schema.Resource{
Expand Down Expand Up @@ -67,6 +73,9 @@ func init() {
"organization": "The GitHub organization name to manage.",

"base_url": "The GitHub Base API URL",

"insecure": "Whether server should be accessed " +
"without verifying the TLS certificate.",
}
}

Expand All @@ -76,6 +85,7 @@ func providerConfigure(p *schema.Provider) schema.ConfigureFunc {
Token: d.Get("token").(string),
Organization: d.Get("organization").(string),
BaseURL: d.Get("base_url").(string),
Insecure: d.Get("insecure").(bool),
}

meta, err := config.Client()
Expand Down
154 changes: 154 additions & 0 deletions github/provider_test.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
package github

import (
"fmt"
"math/rand"
"net/http"
"os"
"path/filepath"
"regexp"
"testing"

"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/terraform"
)
Expand Down Expand Up @@ -45,3 +51,151 @@ func testAccPreCheck(t *testing.T) {
t.Fatal("GITHUB_TEST_COLLABORATOR must be set for acceptance tests")
}
}

func TestProvider_insecure(t *testing.T) {
// Use ephemeral port range (49152–65535)
port := fmt.Sprintf("%d", 49152+rand.Intn(16382))

// Use self-signed certificate
certFile := filepath.Join("test-fixtures", "cert.pem")
keyFile := filepath.Join("test-fixtures", "key.pem")

url, closeFunc := githubApiMock(port, certFile, keyFile, t)
defer closeFunc()

oldBaseUrl := os.Getenv("GITHUB_BASE_URL")
defer os.Setenv("GITHUB_BASE_URL", oldBaseUrl)

// Point provider to mock API with self-signed cert
os.Setenv("GITHUB_BASE_URL", url)

insecureProviderConfig := `provider "github" {
insecure = true
}
`

username := "hashibot"
resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccCheckGithubUserDataSourceConfig(username),
ExpectError: regexp.MustCompile("x509: certificate is valid for untrusted, not localhost"),
},
{
Config: insecureProviderConfig + testAccCheckGithubUserDataSourceConfig(username),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttrSet("data.github_user.test", "name"),
resource.TestCheckResourceAttr("data.github_user.test", "id", "1"),
resource.TestCheckResourceAttr("data.github_user.test", "name", "HashiBot"),
),
},
},
})
}

func githubApiMock(port, certFile, keyFile string, t *testing.T) (string, func() error) {
mux := http.NewServeMux()
mux.HandleFunc("/users/hashibot", testRespondJson(userResponseBody))
mux.HandleFunc("/users/hashibot/gpg_keys", testRespondJson(gpgKeysResponseBody))
mux.HandleFunc("/users/hashibot/keys", testRespondJson(keysResponseBody))

server := &http.Server{
Addr: ":" + port,
Handler: mux,
}

go server.ListenAndServeTLS(certFile, keyFile)

return "https://localhost:" + port + "/", server.Close
}

func testRespondJson(responseBody string) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(responseBody))
}
}

const userResponseBody = `{
"login": "hashibot",
"id": 1,
"node_id": "MDQ6VXNlcjE=",
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
"gravatar_id": "",
"url": "https://api.github.com/users/octocat",
"html_url": "https://github.com/octocat",
"followers_url": "https://api.github.com/users/octocat/followers",
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
"organizations_url": "https://api.github.com/users/octocat/orgs",
"repos_url": "https://api.github.com/users/octocat/repos",
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
"received_events_url": "https://api.github.com/users/octocat/received_events",
"type": "User",
"site_admin": false,
"name": "HashiBot",
"company": "GitHub",
"blog": "https://github.com/blog",
"location": "San Francisco",
"email": "[email protected]",
"hireable": false,
"bio": "There once was...",
"public_repos": 2,
"public_gists": 1,
"followers": 20,
"following": 0,
"created_at": "2008-01-14T04:33:35Z",
"updated_at": "2008-01-14T04:33:35Z"
}`

const gpgKeysResponseBody = `[
{
"id": 3,
"primary_key_id": null,
"key_id": "3262EFF25BA0D270",
"public_key": "xsBNBFayYZ...",
"emails": [
{
"email": "[email protected]",
"verified": true
}
],
"subkeys": [
{
"id": 4,
"primary_key_id": 3,
"key_id": "4A595D4C72EE49C7",
"public_key": "zsBNBFayYZ...",
"emails": [
],
"subkeys": [
],
"can_sign": false,
"can_encrypt_comms": true,
"can_encrypt_storage": true,
"can_certify": false,
"created_at": "2016-03-24T11:31:04-06:00",
"expires_at": null
}
],
"can_sign": true,
"can_encrypt_comms": false,
"can_encrypt_storage": false,
"can_certify": true,
"created_at": "2016-03-24T11:31:04-06:00",
"expires_at": null
}
]`

const keysResponseBody = `[
{
"id": 1,
"key": "ssh-rsa AAA..."
}
]`
15 changes: 15 additions & 0 deletions github/test-fixtures/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Hi fellow bots and humans :wave:

If you're about to panic about leaked private key, then please don't.
This is purposefully exposed self-signed cert & key used in
acceptance tests of the GitHub provider.

Thanks for understanding :heart:

-----

Generated via

```
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes
```
33 changes: 33 additions & 0 deletions github/test-fixtures/cert.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
-----BEGIN CERTIFICATE-----
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
-----END CERTIFICATE-----
52 changes: 52 additions & 0 deletions github/test-fixtures/key.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
-----BEGIN PRIVATE KEY-----
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
OtnwcUdVQi5gB9VoHaQOp10Ugs7btA==
-----END PRIVATE KEY-----
7 changes: 7 additions & 0 deletions website/docs/index.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,10 @@ The following arguments are supported in the `provider` block:
* `base_url` - (Optional) This is the target GitHub base API endpoint. Providing a value is a
requirement when working with GitHub Enterprise. It is optional to provide this value and
it can also be sourced from the `GITHUB_BASE_URL` environment variable. The value must end with a slash.

* `insecure` - (Optional) Whether server should be accessed without verifying the TLS certificate.
As the name suggests **this is insecure** and should not be used beyond experiments,
accessing local (non-production) GHE instance etc.
There is a number of ways to obtain trusted certificate for free, e.g. from [Let's Encrypt](https://letsencrypt.org/).
Such trusted certificate *does not require* this option to be enabled.
Defaults to `false`.