From 3056d9a80eda8414539ff9c96ba2f32a219d2149 Mon Sep 17 00:00:00 2001 From: Dan Cech Date: Thu, 28 Jun 2018 12:08:32 +0200 Subject: [PATCH] support passing api token in Basic auth password (#12416) --- docs/sources/http_api/auth.md | 8 ++++++++ pkg/middleware/auth.go | 6 ++++++ pkg/middleware/middleware_test.go | 26 ++++++++++++++++++++++++-- 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/docs/sources/http_api/auth.md b/docs/sources/http_api/auth.md index 166a5a4fdb9..8ff40b5ef04 100644 --- a/docs/sources/http_api/auth.md +++ b/docs/sources/http_api/auth.md @@ -44,6 +44,14 @@ Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk The `Authorization` header value should be `Bearer `. +The API Token can also be passed as a Basic authorization password with the special username `api_key`: + +curl example: +```bash +?curl http://api_key:eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk@localhost:3000/api/org +{"id":1,"name":"Main Org."} +``` + # Auth HTTP resources / actions ## Api Keys diff --git a/pkg/middleware/auth.go b/pkg/middleware/auth.go index 37e79c01071..5faee1e3fa7 100644 --- a/pkg/middleware/auth.go +++ b/pkg/middleware/auth.go @@ -9,6 +9,7 @@ import ( m "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/session" "github.com/grafana/grafana/pkg/setting" + "github.com/grafana/grafana/pkg/util" ) type AuthOptions struct { @@ -34,6 +35,11 @@ func getApiKey(c *m.ReqContext) string { return key } + username, password, err := util.DecodeBasicAuthHeader(header) + if err == nil && username == "api_key" { + return password + } + return "" } diff --git a/pkg/middleware/middleware_test.go b/pkg/middleware/middleware_test.go index 0b50358ad73..d82b7313585 100644 --- a/pkg/middleware/middleware_test.go +++ b/pkg/middleware/middleware_test.go @@ -82,7 +82,7 @@ func TestMiddlewareContext(t *testing.T) { setting.BasicAuthEnabled = true authHeader := util.GetBasicAuthHeader("myUser", "myPass") - sc.fakeReq("GET", "/").withAuthoriziationHeader(authHeader).exec() + sc.fakeReq("GET", "/").withAuthorizationHeader(authHeader).exec() Convey("Should init middleware context with user", func() { So(sc.context.IsSignedIn, ShouldEqual, true) @@ -128,6 +128,28 @@ func TestMiddlewareContext(t *testing.T) { }) }) + middlewareScenario("Valid api key via Basic auth", func(sc *scenarioContext) { + keyhash := util.EncodePassword("v5nAwpMafFP6znaS4urhdWDLS5511M42", "asd") + + bus.AddHandler("test", func(query *m.GetApiKeyByNameQuery) error { + query.Result = &m.ApiKey{OrgId: 12, Role: m.ROLE_EDITOR, Key: keyhash} + return nil + }) + + authHeader := util.GetBasicAuthHeader("api_key", "eyJrIjoidjVuQXdwTWFmRlA2em5hUzR1cmhkV0RMUzU1MTFNNDIiLCJuIjoiYXNkIiwiaWQiOjF9") + sc.fakeReq("GET", "/").withAuthorizationHeader(authHeader).exec() + + Convey("Should return 200", func() { + So(sc.resp.Code, ShouldEqual, 200) + }) + + Convey("Should init middleware context", func() { + So(sc.context.IsSignedIn, ShouldEqual, true) + So(sc.context.OrgId, ShouldEqual, 12) + So(sc.context.OrgRole, ShouldEqual, m.ROLE_EDITOR) + }) + }) + middlewareScenario("UserId in session", func(sc *scenarioContext) { sc.fakeReq("GET", "/").handler(func(c *m.ReqContext) { @@ -473,7 +495,7 @@ func (sc *scenarioContext) withInvalidApiKey() *scenarioContext { return sc } -func (sc *scenarioContext) withAuthoriziationHeader(authHeader string) *scenarioContext { +func (sc *scenarioContext) withAuthorizationHeader(authHeader string) *scenarioContext { sc.authHeader = authHeader return sc }