Skip to content

Commit

Permalink
Add basic authorization (#369)
Browse files Browse the repository at this point in the history
* Add basic authorization

* Add basic authorization

* update CHANGELOG and version, small refactor

* update comments

* refactor to accept username and password
  • Loading branch information
mikaelkrief authored and jhendrixMSFT committed Mar 25, 2019
1 parent 808755d commit 36c85df
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 1 deletion.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# CHANGELOG

## v11.6.0

### New Features

- Added type `autorest.BasicAuthorizer` to support Basic authentication.

## v11.5.2

### Bug Fixes
Expand Down
27 changes: 27 additions & 0 deletions autorest/authorization.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ package autorest
// limitations under the License.

import (
"encoding/base64"
"fmt"
"net/http"
"net/url"
Expand All @@ -31,6 +32,8 @@ const (
apiKeyAuthorizerHeader = "Ocp-Apim-Subscription-Key"
bingAPISdkHeader = "X-BingApis-SDK-Client"
golangBingAPISdkHeaderValue = "Go-SDK"
authorization = "Authorization"
basic = "Basic"
)

// Authorizer is the interface that provides a PrepareDecorator used to supply request
Expand Down Expand Up @@ -258,3 +261,27 @@ func (egta EventGridKeyAuthorizer) WithAuthorization() PrepareDecorator {
}
return NewAPIKeyAuthorizerWithHeaders(headers).WithAuthorization()
}

// BasicAuthorizer implements basic HTTP authorization by adding the Authorization HTTP header
// with the value "Basic <TOKEN>" where <TOKEN> is a base64-encoded username:password tuple.
type BasicAuthorizer struct {
userName string
password string
}

// NewBasicAuthorizer creates a new BasicAuthorizer with the specified username and password.
func NewBasicAuthorizer(userName, password string) *BasicAuthorizer {
return &BasicAuthorizer{
userName: userName,
password: password,
}
}

// WithAuthorization returns a PrepareDecorator that adds an HTTP Authorization header whose
// value is "Basic " followed by the base64-encoded username:password tuple.
func (ba *BasicAuthorizer) WithAuthorization() PrepareDecorator {
headers := make(map[string]interface{})
headers[authorization] = basic + " " + base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", ba.userName, ba.password)))

return NewAPIKeyAuthorizerWithHeaders(headers).WithAuthorization()
}
22 changes: 22 additions & 0 deletions autorest/authorization_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -228,3 +228,25 @@ func TestCognitivesServicesAuthorization(t *testing.T) {
t.Fatalf("azure: CognitiveServicesAuthorizer#WithAuthorization failed to set %s header", apiKeyAuthorizerHeader)
}
}

func TestBasicAuthorization(t *testing.T) {
ba := NewBasicAuthorizer("Aladdin", "open sesame")
req, err := Prepare(mocks.NewRequest(), ba.WithAuthorization())

if err != nil {
t.Fatalf("BasicAuthorizer#WithAuthorization returned an error (%v)", err)
} else if req.Header.Get(http.CanonicalHeaderKey(authorization)) != basic+" QWxhZGRpbjpvcGVuIHNlc2FtZQ==" {
t.Fatalf("BasicAuthorizer#WithAuthorization failed to set %s header", authorization)
}
}

func TestBasicAuthorizationPasswordOnly(t *testing.T) {
ba := NewBasicAuthorizer("", "dummyKey")
req, err := Prepare(mocks.NewRequest(), ba.WithAuthorization())

if err != nil {
t.Fatalf("BasicAuthorizer#WithAuthorization returned an error (%v)", err)
} else if req.Header.Get(http.CanonicalHeaderKey(authorization)) != basic+" OmR1bW15S2V5" {
t.Fatalf("BasicAuthorizer#WithAuthorization failed to set %s header", authorization)
}
}
2 changes: 1 addition & 1 deletion autorest/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import (
"runtime"
)

const number = "v11.5.2"
const number = "v11.6.0"

var (
userAgent = fmt.Sprintf("Go/%s (%s-%s) go-autorest/%s",
Expand Down

0 comments on commit 36c85df

Please sign in to comment.