diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml new file mode 100644 index 0000000..981c054 --- /dev/null +++ b/.github/workflows/test.yaml @@ -0,0 +1,25 @@ +name: test +on: + push: + branches: + - main + pull_request: +jobs: + build: + name: go + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + go: ['1.16'] + steps: + - name: setup + uses: actions/setup-go@v3 + with: + go-version: ${{matrix.go}} + + - name: checkout + uses: actions/checkout@v3 + + - name: test + run: make \ No newline at end of file diff --git a/Makefile b/Makefile index 6b1d6fe..b15ba92 100644 --- a/Makefile +++ b/Makefile @@ -1,17 +1,17 @@ .PHONY: all -all: test vet lint fmt +all: test vet fmt .PHONY: test test: - @go test $$(go list ./... | grep -v examples) -cover + @go test . -cover .PHONY: vet vet: - @go vet -all $$(go list ./... | grep -v examples) + @go vet -all . .PHONY: lint lint: - @golint -set_exit_status ./... + @golint -set_exit_status . .PHONY: fmt fmt: diff --git a/auther.go b/auther.go index 0aabc0f..746b2cb 100644 --- a/auther.go +++ b/auther.go @@ -62,17 +62,11 @@ func newAuther(config *Config) *auther { // request (temporary credential) according to RFC 5849 2.1. func (a *auther) setRequestTokenAuthHeader(req *http.Request) error { oauthParams := a.commonOAuthParams() - - params, err := collectParameters(req, oauthParams) + oauthParams[oauthCallbackParam] = a.config.CallbackURL + params, err := collectParameters(req, oauthParams, true) if err != nil { return err } - - oauthParams[oauthCallbackParam] = a.config.CallbackURL - if bodyHash, ok := params[oauthBodyHash]; ok { - oauthParams[oauthBodyHash] = bodyHash - } - signatureBase := SignatureBase(req, params) signature, err := a.signer().Sign("", signatureBase) if err != nil { @@ -90,18 +84,12 @@ func (a *auther) setRequestTokenAuthHeader(req *http.Request) error { // (token credential) according to RFC 5849 2.3. func (a *auther) setAccessTokenAuthHeader(req *http.Request, requestToken, requestSecret, verifier string) error { oauthParams := a.commonOAuthParams() - - params, err := collectParameters(req, oauthParams) - if err != nil { - return err - } - oauthParams[oauthTokenParam] = requestToken oauthParams[oauthVerifierParam] = verifier - if bodyHash, ok := params[oauthBodyHash]; ok { - oauthParams[oauthBodyHash] = bodyHash + params, err := collectParameters(req, oauthParams, true) + if err != nil { + return err } - signatureBase := SignatureBase(req, params) signature, err := a.signer().Sign(requestSecret, signatureBase) if err != nil { @@ -134,7 +122,7 @@ func (a *auther) buildOauthParams(req *http.Request, accessToken *Token) (map[st tokenSecret = accessToken.TokenSecret } - params, err := collectParameters(req, oauthParams) + params, err := collectParameters(req, oauthParams, false) if err != nil { return nil, err } @@ -240,7 +228,7 @@ func sortParameters(params map[string]string, format string) []string { // provided the body is single part, form encoded, and the form content type // header is set. The returned map of collected parameter keys and values // follow RFC 5849 3.4.1.3, except duplicate parameters are not supported. -func collectParameters(req *http.Request, oauthParams map[string]string) (map[string]string, error) { +func collectParameters(req *http.Request, oauthParams map[string]string, isTokenRequest bool) (map[string]string, error) { // add oauth, query, and body parameters into params params := map[string]string{} for key, value := range req.URL.Query() { @@ -263,8 +251,8 @@ func collectParameters(req *http.Request, oauthParams map[string]string) (map[st // not supporting params with duplicate keys params[key] = value[0] } - } else { - // providing body hash for requests other than x-www-form-urlencoded + } else if !isTokenRequest { + // providing body hash for requests other than x-www-form-urlencoded, access token, or request token // as described in https://tools.ietf.org/html/draft-eaton-oauth-bodyhash-00#section-4.1.1 hash := sha1.Sum(b) hash64 := base64.StdEncoding.EncodeToString(hash[:]) diff --git a/auther_test.go b/auther_test.go index 08edb94..a8c9876 100644 --- a/auther_test.go +++ b/auther_test.go @@ -174,7 +174,7 @@ func TestCollectParameters(t *testing.T) { req, err := http.NewRequest("POST", "/request?b5=%3D%253D&a3=a&c%40=&a2=r%20b", strings.NewReader(values.Encode())) assert.Nil(t, err) req.Header.Set(contentType, formContentType) - params, err := collectParameters(req, oauthParams) + params, err := collectParameters(req, oauthParams, false) // assert parameters were collected from oauthParams, the query, and form body // excluding the realm parameter expected := map[string]string{ @@ -216,7 +216,7 @@ func TestCollectParametersNonWwwFormUrlencoded(t *testing.T) { req, err := http.NewRequest("POST", "/request?b5=%3D%253D&a3=a&c%40=&a2=r%20b", strings.NewReader(jsonBody)) assert.Nil(t, err) req.Header.Set(contentType, "application/json") - params, err := collectParameters(req, oauthParams) + params, err := collectParameters(req, oauthParams, false) // assert parameters were collected from oauthParams, the query, and form body // excluding the realm parameter expected := map[string]string{ diff --git a/cloudbuild.yaml b/cloudbuild.yaml new file mode 100644 index 0000000..e00bcbc --- /dev/null +++ b/cloudbuild.yaml @@ -0,0 +1,3 @@ +steps: +- name: 'golang:1.16' + args: ['go', 'test', '.'] diff --git a/go.mod b/go.mod index a0ea0da..f988236 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,8 @@ module github.com/derivita/oauth1 +go 1.16 + require ( - github.com/stretchr/testify v1.4.0 - gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect + github.com/stretchr/testify v1.8.1 + gopkg.in/yaml.v2 v2.2.2 // indirect ) diff --git a/go.sum b/go.sum index c848444..27da721 100644 --- a/go.sum +++ b/go.sum @@ -1,15 +1,19 @@ -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/reference_test.go b/reference_test.go index a0f7994..ff76ec4 100644 --- a/reference_test.go +++ b/reference_test.go @@ -117,7 +117,7 @@ func TestTwitterParameterString(t *testing.T) { req.Header.Set(contentType, formContentType) oauthParams := auther.commonOAuthParams() oauthParams[oauthTokenParam] = expectedTwitterOAuthToken - params, err := collectParameters(req, oauthParams) + params, err := collectParameters(req, oauthParams, false) // assert that the parameter string matches the reference expectedParameterString := "include_entities=true&oauth_consumer_key=xvz1evFS4wEEPTGEFPHBog&oauth_nonce=kYjzVBB8Y0ZFabxSWbWovY3uYSQ2pTgmZeNu2VS4cg&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1318622958&oauth_token=370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb&oauth_version=1.0&status=Hello%20Ladies%20%2B%20Gentlemen%2C%20a%20signed%20OAuth%20request%21" assert.Nil(t, err) @@ -134,7 +134,7 @@ func TestTwitterSignatureBase(t *testing.T) { req.Header.Set(contentType, formContentType) oauthParams := auther.commonOAuthParams() oauthParams[oauthTokenParam] = expectedTwitterOAuthToken - params, err := collectParameters(req, oauthParams) + params, err := collectParameters(req, oauthParams, false) signatureBase := SignatureBase(req, params) // assert that the signature base string matches the reference // checks that method is uppercased, url is encoded, parameter string is added, all joined by & diff --git a/transport_test.go b/transport_test.go index a64a3d7..80ed85e 100644 --- a/transport_test.go +++ b/transport_test.go @@ -78,7 +78,7 @@ func TestTransport_nilSource(t *testing.T) { resp, err := client.Get("http://example.com") assert.Nil(t, resp) if assert.Error(t, err) { - assert.Equal(t, "Get http://example.com: oauth1: Transport's source is nil", err.Error()) + assert.Equal(t, "Get \"http://example.com\": oauth1: Transport's source is nil", err.Error()) } } @@ -105,7 +105,7 @@ func TestTransport_nilAuther(t *testing.T) { resp, err := client.Get("http://example.com") assert.Nil(t, resp) if assert.Error(t, err) { - assert.Equal(t, "Get http://example.com: oauth1: Transport's auther is nil", err.Error()) + assert.Equal(t, "Get \"http://example.com\": oauth1: Transport's auther is nil", err.Error()) } } diff --git a/validator.go b/validator.go index 7177a67..36c1487 100644 --- a/validator.go +++ b/validator.go @@ -70,7 +70,7 @@ func newProviderRequest(req *http.Request) (*providerRequest, error) { } } } - allParams, err := collectParameters(req, authParams) + allParams, err := collectParameters(req, authParams, false) if err != nil { return nil, err }