mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Access Control: Get org from request data for authorization (#84359)
* Access Control: Get org from request data for authorization * move type to models * Update pkg/services/accesscontrol/middleware.go Co-authored-by: Ieva <ieva.vasiljeva@grafana.com> * refactor * refactor * Fix linter --------- Co-authored-by: Ieva <ieva.vasiljeva@grafana.com>
This commit is contained in:
parent
d480d3296c
commit
fd9031ca37
pkg/services/accesscontrol
@ -5,6 +5,7 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"regexp"
|
||||
@ -320,6 +321,83 @@ func UseGlobalOrSingleOrg(cfg *setting.Cfg) OrgIDGetter {
|
||||
}
|
||||
}
|
||||
|
||||
// UseOrgFromRequestData returns the organization from the request data.
|
||||
// If no org is specified, then the org where user is logged in is returned.
|
||||
func UseOrgFromRequestData(c *contextmodel.ReqContext) (int64, error) {
|
||||
query, err := getOrgQueryFromRequest(c)
|
||||
if err != nil {
|
||||
// Special case of macaron handling invalid params
|
||||
return NoOrgID, org.ErrOrgNotFound.Errorf("failed to get organization from context: %w", err)
|
||||
}
|
||||
|
||||
if query.OrgId == nil {
|
||||
return c.SignedInUser.GetOrgID(), nil
|
||||
}
|
||||
|
||||
return *query.OrgId, nil
|
||||
}
|
||||
|
||||
// UseGlobalOrgFromRequestData returns global org if `global` flag is set or the org where user is logged in.
|
||||
func UseGlobalOrgFromRequestData(c *contextmodel.ReqContext) (int64, error) {
|
||||
query, err := getOrgQueryFromRequest(c)
|
||||
if err != nil {
|
||||
// Special case of macaron handling invalid params
|
||||
return NoOrgID, org.ErrOrgNotFound.Errorf("failed to get organization from context: %w", err)
|
||||
}
|
||||
|
||||
if query.Global {
|
||||
return GlobalOrgID, nil
|
||||
}
|
||||
|
||||
return c.SignedInUser.GetOrgID(), nil
|
||||
}
|
||||
|
||||
func getOrgQueryFromRequest(c *contextmodel.ReqContext) (*QueryWithOrg, error) {
|
||||
query := &QueryWithOrg{}
|
||||
|
||||
req, err := CloneRequest(c.Req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := web.Bind(req, query); err != nil {
|
||||
// Special case of macaron handling invalid params
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return query, nil
|
||||
}
|
||||
|
||||
// CloneRequest creates request copy including request body
|
||||
func CloneRequest(req *http.Request) (*http.Request, error) {
|
||||
// Get copy of body to prevent error when reading closed body in request handler
|
||||
bodyCopy, err := CopyRequestBody(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
reqCopy := req.Clone(req.Context())
|
||||
reqCopy.Body = bodyCopy
|
||||
return reqCopy, nil
|
||||
}
|
||||
|
||||
// CopyRequestBody returns copy of request body and keeps the original one to prevent error when reading closed body
|
||||
func CopyRequestBody(req *http.Request) (io.ReadCloser, error) {
|
||||
if req.Body == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
body := req.Body
|
||||
var buf bytes.Buffer
|
||||
if _, err := buf.ReadFrom(body); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := body.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Body = io.NopCloser(&buf)
|
||||
return io.NopCloser(bytes.NewReader(buf.Bytes())), nil
|
||||
}
|
||||
|
||||
// scopeParams holds the parameters used to fill in scope templates
|
||||
type scopeParams struct {
|
||||
OrgID int64
|
||||
|
@ -562,3 +562,8 @@ var OrgsCreateAccessEvaluator = EvalAll(
|
||||
|
||||
// ApiKeyAccessEvaluator is used to protect the "Configuration > API keys" page access
|
||||
var ApiKeyAccessEvaluator = EvalPermission(ActionAPIKeyRead)
|
||||
|
||||
type QueryWithOrg struct {
|
||||
OrgId *int64 `json:"orgId"`
|
||||
Global bool `json:"global"`
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user