mirror of
https://github.com/grafana/grafana.git
synced 2024-11-25 18:30:41 -06:00
Access control: allow using targetOrgId parameter to set organization ID for a request (#41761)
* read target org ID in context handler * simplify test * add test for request body not being read in ctx handler * linting fix
This commit is contained in:
parent
d623285fcc
commit
c426f5673b
@ -4,10 +4,12 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@ -497,6 +499,58 @@ func TestMiddlewareContext(t *testing.T) {
|
||||
cfg.AuthProxyAutoSignUp = true
|
||||
})
|
||||
|
||||
middlewareScenario(t, "Should use organisation specified by targetOrgId parameter", func(t *testing.T, sc *scenarioContext) {
|
||||
bus.AddHandlerCtx("test", func(ctx context.Context, query *models.GetSignedInUserQuery) error {
|
||||
if query.UserId > 0 {
|
||||
query.Result = &models.SignedInUser{OrgId: query.OrgId, UserId: userID}
|
||||
return nil
|
||||
}
|
||||
return models.ErrUserNotFound
|
||||
})
|
||||
|
||||
bus.AddHandler("test", func(cmd *models.UpsertUserCommand) error {
|
||||
cmd.Result = &models.User{Id: userID}
|
||||
return nil
|
||||
})
|
||||
|
||||
targetOrgID := 123
|
||||
sc.fakeReq("GET", fmt.Sprintf("/?targetOrgId=%d", targetOrgID))
|
||||
sc.req.Header.Set(sc.cfg.AuthProxyHeaderName, hdrName)
|
||||
sc.exec()
|
||||
|
||||
assert.True(t, sc.context.IsSignedIn)
|
||||
assert.Equal(t, userID, sc.context.UserId)
|
||||
assert.Equal(t, int64(targetOrgID), sc.context.OrgId)
|
||||
}, func(cfg *setting.Cfg) {
|
||||
configure(cfg)
|
||||
cfg.LDAPEnabled = false
|
||||
cfg.AuthProxyAutoSignUp = true
|
||||
})
|
||||
|
||||
middlewareScenario(t, "Request body should not be read in default context handler", func(t *testing.T, sc *scenarioContext) {
|
||||
sc.fakeReq("POST", "/?targetOrgId=123")
|
||||
body := "key=value"
|
||||
sc.req.Body = io.NopCloser(strings.NewReader(body))
|
||||
|
||||
sc.handlerFunc = func(c *models.ReqContext) {
|
||||
t.Log("Handler called")
|
||||
defer func() {
|
||||
err := c.Req.Body.Close()
|
||||
require.NoError(t, err)
|
||||
}()
|
||||
|
||||
bodyAfterHandler, e := io.ReadAll(c.Req.Body)
|
||||
require.NoError(t, e)
|
||||
require.Equal(t, body, string(bodyAfterHandler))
|
||||
}
|
||||
|
||||
sc.req.Header.Set(sc.cfg.AuthProxyHeaderName, hdrName)
|
||||
sc.req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
sc.req.Header.Set("Content-Length", strconv.Itoa(len(body)))
|
||||
sc.m.Post("/", sc.defaultHandler)
|
||||
sc.exec()
|
||||
})
|
||||
|
||||
middlewareScenario(t, "Should get an existing user from header", func(t *testing.T, sc *scenarioContext) {
|
||||
const userID int64 = 12
|
||||
const orgID int64 = 2
|
||||
|
@ -4,6 +4,7 @@ package contexthandler
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@ -105,6 +106,19 @@ func (h *ContextHandler) Middleware(mContext *web.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
queryParameters, err := url.ParseQuery(reqContext.Req.URL.RawQuery)
|
||||
if err != nil {
|
||||
reqContext.Logger.Error("Failed to parse query parameters", "error", err)
|
||||
}
|
||||
if queryParameters.Has("targetOrgId") {
|
||||
targetOrg, err := strconv.ParseInt(queryParameters.Get("targetOrgId"), 10, 64)
|
||||
if err == nil {
|
||||
orgID = targetOrg
|
||||
} else {
|
||||
reqContext.Logger.Error("Invalid target organization ID", "error", err)
|
||||
}
|
||||
}
|
||||
|
||||
// the order in which these are tested are important
|
||||
// look for api key in Authorization header first
|
||||
// then init session and look for userId in session
|
||||
|
Loading…
Reference in New Issue
Block a user