K8s: Improve identity mapping setup (#89450)
This commit is contained in:
@@ -8,8 +8,8 @@ import (
|
|||||||
|
|
||||||
"github.com/grafana/grafana/pkg/api/dtos"
|
"github.com/grafana/grafana/pkg/api/dtos"
|
||||||
"github.com/grafana/grafana/pkg/api/response"
|
"github.com/grafana/grafana/pkg/api/response"
|
||||||
|
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||||
dashboardsnapshot "github.com/grafana/grafana/pkg/apis/dashboardsnapshot/v0alpha1"
|
dashboardsnapshot "github.com/grafana/grafana/pkg/apis/dashboardsnapshot/v0alpha1"
|
||||||
"github.com/grafana/grafana/pkg/infra/appcontext"
|
|
||||||
"github.com/grafana/grafana/pkg/infra/metrics"
|
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||||
ac "github.com/grafana/grafana/pkg/services/accesscontrol"
|
ac "github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||||
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
|
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
|
||||||
@@ -28,13 +28,13 @@ func (hs *HTTPServer) getCreatedSnapshotHandler() web.Handler {
|
|||||||
if hs.Features.IsEnabledGlobally(featuremgmt.FlagKubernetesSnapshots) {
|
if hs.Features.IsEnabledGlobally(featuremgmt.FlagKubernetesSnapshots) {
|
||||||
namespaceMapper := request.GetNamespaceMapper(hs.Cfg)
|
namespaceMapper := request.GetNamespaceMapper(hs.Cfg)
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
user, err := appcontext.User(r.Context())
|
user, err := identity.GetRequester(r.Context())
|
||||||
if err != nil || user == nil {
|
if err != nil || user == nil {
|
||||||
errhttp.Write(r.Context(), fmt.Errorf("no user"), w)
|
errhttp.Write(r.Context(), fmt.Errorf("no user"), w)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
r.URL.Path = "/apis/dashboardsnapshot.grafana.app/v0alpha1/namespaces/" +
|
r.URL.Path = "/apis/dashboardsnapshot.grafana.app/v0alpha1/namespaces/" +
|
||||||
namespaceMapper(user.OrgID) + "/dashboardsnapshots/create"
|
namespaceMapper(user.GetOrgID()) + "/dashboardsnapshots/create"
|
||||||
hs.clientConfigProvider.DirectlyServeHTTP(w, r)
|
hs.clientConfigProvider.DirectlyServeHTTP(w, r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -11,7 +11,7 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/api/dtos"
|
"github.com/grafana/grafana/pkg/api/dtos"
|
||||||
"github.com/grafana/grafana/pkg/api/response"
|
"github.com/grafana/grafana/pkg/api/response"
|
||||||
"github.com/grafana/grafana/pkg/api/routing"
|
"github.com/grafana/grafana/pkg/api/routing"
|
||||||
"github.com/grafana/grafana/pkg/infra/appcontext"
|
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||||
"github.com/grafana/grafana/pkg/middleware/requestmeta"
|
"github.com/grafana/grafana/pkg/middleware/requestmeta"
|
||||||
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
|
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
|
||||||
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
|
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
|
||||||
@@ -43,12 +43,12 @@ func (hs *HTTPServer) getDSQueryEndpoint() web.Handler {
|
|||||||
// rewrite requests from /ds/query to the new query service
|
// rewrite requests from /ds/query to the new query service
|
||||||
namespaceMapper := request.GetNamespaceMapper(hs.Cfg)
|
namespaceMapper := request.GetNamespaceMapper(hs.Cfg)
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
user, err := appcontext.User(r.Context())
|
user, err := identity.GetRequester(r.Context())
|
||||||
if err != nil || user == nil {
|
if err != nil || user == nil {
|
||||||
errhttp.Write(r.Context(), fmt.Errorf("no user"), w)
|
errhttp.Write(r.Context(), fmt.Errorf("no user"), w)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
r.URL.Path = "/apis/query.grafana.app/v0alpha1/namespaces/" + namespaceMapper(user.OrgID) + "/query"
|
r.URL.Path = "/apis/query.grafana.app/v0alpha1/namespaces/" + namespaceMapper(user.GetOrgID()) + "/query"
|
||||||
hs.clientConfigProvider.DirectlyServeHTTP(w, r)
|
hs.clientConfigProvider.DirectlyServeHTTP(w, r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
"golang.org/x/mod/semver"
|
"golang.org/x/mod/semver"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
@@ -26,7 +27,6 @@ import (
|
|||||||
|
|
||||||
"github.com/grafana/grafana/pkg/apiserver/endpoints/filters"
|
"github.com/grafana/grafana/pkg/apiserver/endpoints/filters"
|
||||||
"github.com/grafana/grafana/pkg/services/apiserver/options"
|
"github.com/grafana/grafana/pkg/services/apiserver/options"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: this is a temporary hack to make rest.Connecter work with resource level routes
|
// TODO: this is a temporary hack to make rest.Connecter work with resource level routes
|
||||||
@@ -96,6 +96,7 @@ func SetupConfig(
|
|||||||
|
|
||||||
// Needs to run last in request chain to function as expected, hence we register it first.
|
// Needs to run last in request chain to function as expected, hence we register it first.
|
||||||
handler := filters.WithTracingHTTPLoggingAttributes(requestHandler)
|
handler := filters.WithTracingHTTPLoggingAttributes(requestHandler)
|
||||||
|
handler = filters.WithRequester(handler)
|
||||||
handler = genericapiserver.DefaultBuildHandlerChain(handler, c)
|
handler = genericapiserver.DefaultBuildHandlerChain(handler, c)
|
||||||
handler = filters.WithAcceptHeader(handler)
|
handler = filters.WithAcceptHeader(handler)
|
||||||
handler = filters.WithPathRewriters(handler, pathRewriters)
|
handler = filters.WithPathRewriters(handler, pathRewriters)
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
package filters
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"slices"
|
||||||
|
|
||||||
|
"k8s.io/apiserver/pkg/authentication/user"
|
||||||
|
"k8s.io/apiserver/pkg/endpoints/request"
|
||||||
|
"k8s.io/klog"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||||
|
)
|
||||||
|
|
||||||
|
// WithRequester makes sure there is an identity.Requester in context
|
||||||
|
func WithRequester(handler http.Handler) http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||||
|
ctx := req.Context()
|
||||||
|
requester, err := identity.GetRequester(ctx)
|
||||||
|
if err != nil {
|
||||||
|
// Find the kubernetes user info
|
||||||
|
info, ok := request.UserFrom(ctx)
|
||||||
|
if ok {
|
||||||
|
if info.GetName() == user.Anonymous {
|
||||||
|
requester = &identity.StaticRequester{
|
||||||
|
Namespace: identity.NamespaceAnonymous,
|
||||||
|
Name: info.GetName(),
|
||||||
|
Login: info.GetName(),
|
||||||
|
Permissions: map[int64]map[string][]string{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if info.GetName() == user.APIServerUser ||
|
||||||
|
slices.Contains(info.GetGroups(), user.SystemPrivilegedGroup) {
|
||||||
|
orgId := int64(1)
|
||||||
|
requester = &identity.StaticRequester{
|
||||||
|
UserID: 1,
|
||||||
|
OrgID: orgId,
|
||||||
|
Name: info.GetName(),
|
||||||
|
Login: info.GetName(),
|
||||||
|
OrgRole: identity.RoleAdmin,
|
||||||
|
IsGrafanaAdmin: true,
|
||||||
|
Permissions: map[int64]map[string][]string{
|
||||||
|
orgId: {
|
||||||
|
"*": {"*"}, // all resources, all scopes
|
||||||
|
|
||||||
|
// Dashboards do not support wildcard action
|
||||||
|
// dashboards.ActionDashboardsRead: {"*"},
|
||||||
|
// dashboards.ActionDashboardsCreate: {"*"},
|
||||||
|
// dashboards.ActionDashboardsWrite: {"*"},
|
||||||
|
// dashboards.ActionDashboardsDelete: {"*"},
|
||||||
|
// dashboards.ActionFoldersCreate: {"*"},
|
||||||
|
// dashboards.ActionFoldersRead: {dashboards.ScopeFoldersAll}, // access to read all folders
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if requester != nil {
|
||||||
|
req = req.WithContext(identity.WithRequester(ctx, requester))
|
||||||
|
} else {
|
||||||
|
klog.V(5).Info("unable to map the k8s user to grafana requester", "user", info)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
handler.ServeHTTP(w, req)
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -4,13 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
k8suser "k8s.io/apiserver/pkg/authentication/user"
|
|
||||||
"k8s.io/apiserver/pkg/endpoints/request"
|
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||||
"github.com/grafana/grafana/pkg/services/contexthandler/ctxkey"
|
|
||||||
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
|
|
||||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
|
||||||
grpccontext "github.com/grafana/grafana/pkg/services/grpcserver/context"
|
grpccontext "github.com/grafana/grafana/pkg/services/grpcserver/context"
|
||||||
"github.com/grafana/grafana/pkg/services/user"
|
"github.com/grafana/grafana/pkg/services/user"
|
||||||
)
|
)
|
||||||
@@ -20,11 +14,16 @@ type ctxUserKey struct{}
|
|||||||
// WithUser adds the supplied SignedInUser to the context.
|
// WithUser adds the supplied SignedInUser to the context.
|
||||||
func WithUser(ctx context.Context, usr *user.SignedInUser) context.Context {
|
func WithUser(ctx context.Context, usr *user.SignedInUser) context.Context {
|
||||||
ctx = context.WithValue(ctx, ctxUserKey{}, usr)
|
ctx = context.WithValue(ctx, ctxUserKey{}, usr)
|
||||||
|
// make sure it is also in the simplified version
|
||||||
|
if usr == nil || usr.IsNil() {
|
||||||
|
return identity.WithRequester(ctx, nil)
|
||||||
|
}
|
||||||
return identity.WithRequester(ctx, usr)
|
return identity.WithRequester(ctx, usr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// User extracts the SignedInUser from the supplied context.
|
// User extracts the SignedInUser from the supplied context.
|
||||||
// Supports context set by appcontext.WithUser, gRPC server context, and HTTP ReqContext.
|
// Supports context set by appcontext.WithUser, gRPC server context, and HTTP ReqContext.
|
||||||
|
// Deprecated: use identity.GetRequester(ctx) when possible
|
||||||
func User(ctx context.Context) (*user.SignedInUser, error) {
|
func User(ctx context.Context) (*user.SignedInUser, error) {
|
||||||
// Set by appcontext.WithUser
|
// Set by appcontext.WithUser
|
||||||
u, ok := ctx.Value(ctxUserKey{}).(*user.SignedInUser)
|
u, ok := ctx.Value(ctxUserKey{}).(*user.SignedInUser)
|
||||||
@@ -38,44 +37,32 @@ func User(ctx context.Context) (*user.SignedInUser, error) {
|
|||||||
return grpcCtx.SignedInUser, nil
|
return grpcCtx.SignedInUser, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set by incoming HTTP request
|
// If the identity was set via requester, but not appcontext, we can map values
|
||||||
c, ok := ctxkey.Get(ctx).(*contextmodel.ReqContext)
|
// NOTE: this path
|
||||||
if ok && c.SignedInUser != nil {
|
requester, _ := identity.GetRequester(ctx)
|
||||||
return c.SignedInUser, nil
|
if requester != nil {
|
||||||
}
|
id := requester.GetID()
|
||||||
|
userId, _ := id.UserID()
|
||||||
// Find the kubernetes user info
|
orgId := requester.GetOrgID()
|
||||||
k8sUserInfo, ok := request.UserFrom(ctx)
|
return &user.SignedInUser{
|
||||||
if ok {
|
NamespacedID: id,
|
||||||
for _, group := range k8sUserInfo.GetGroups() {
|
UserID: userId,
|
||||||
switch group {
|
UserUID: requester.GetUID().ID(),
|
||||||
case k8suser.APIServerUser:
|
OrgID: orgId,
|
||||||
fallthrough
|
OrgName: requester.GetOrgName(),
|
||||||
case k8suser.SystemPrivilegedGroup:
|
OrgRole: requester.GetOrgRole(),
|
||||||
orgId := int64(1)
|
Login: requester.GetLogin(),
|
||||||
return &user.SignedInUser{
|
Email: requester.GetEmail(),
|
||||||
UserID: 1,
|
IsGrafanaAdmin: requester.GetIsGrafanaAdmin(),
|
||||||
OrgID: orgId,
|
Teams: requester.GetTeams(),
|
||||||
Name: k8sUserInfo.GetName(),
|
AuthID: requester.GetAuthID(),
|
||||||
Login: k8sUserInfo.GetName(),
|
AuthenticatedBy: requester.GetAuthenticatedBy(),
|
||||||
OrgRole: identity.RoleAdmin,
|
IDToken: requester.GetIDToken(),
|
||||||
IsGrafanaAdmin: true,
|
Permissions: map[int64]map[string][]string{
|
||||||
Permissions: map[int64]map[string][]string{
|
0: requester.GetGlobalPermissions(),
|
||||||
orgId: {
|
orgId: requester.GetPermissions(),
|
||||||
"*": {"*"}, // all resources, all scopes
|
},
|
||||||
|
}, nil
|
||||||
// Dashboards do not support wildcard action
|
|
||||||
dashboards.ActionDashboardsRead: {"*"},
|
|
||||||
dashboards.ActionDashboardsCreate: {"*"},
|
|
||||||
dashboards.ActionDashboardsWrite: {"*"},
|
|
||||||
dashboards.ActionDashboardsDelete: {"*"},
|
|
||||||
dashboards.ActionFoldersCreate: {"*"},
|
|
||||||
dashboards.ActionFoldersRead: {dashboards.ScopeFoldersAll}, // access to read all folders
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, fmt.Errorf("a SignedInUser was not found in the context")
|
return nil, fmt.Errorf("a SignedInUser was not found in the context")
|
||||||
|
|||||||
@@ -11,8 +11,6 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||||
"github.com/grafana/grafana/pkg/infra/appcontext"
|
"github.com/grafana/grafana/pkg/infra/appcontext"
|
||||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||||
"github.com/grafana/grafana/pkg/services/contexthandler/ctxkey"
|
|
||||||
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
|
|
||||||
grpccontext "github.com/grafana/grafana/pkg/services/grpcserver/context"
|
grpccontext "github.com/grafana/grafana/pkg/services/grpcserver/context"
|
||||||
"github.com/grafana/grafana/pkg/services/user"
|
"github.com/grafana/grafana/pkg/services/user"
|
||||||
)
|
)
|
||||||
@@ -52,11 +50,9 @@ func TestUserFromContext(t *testing.T) {
|
|||||||
require.Equal(t, expected.UserID, actual.UserID)
|
require.Equal(t, expected.UserID, actual.UserID)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("should return user set by HTTP ReqContext", func(t *testing.T) {
|
t.Run("should return user set as a requester", func(t *testing.T) {
|
||||||
expected := testUser()
|
expected := testUser()
|
||||||
ctx := ctxkey.Set(context.Background(), &contextmodel.ReqContext{
|
ctx := identity.WithRequester(context.Background(), expected)
|
||||||
SignedInUser: expected,
|
|
||||||
})
|
|
||||||
actual, err := appcontext.User(ctx)
|
actual, err := appcontext.User(ctx)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, expected.UserID, actual.UserID)
|
require.Equal(t, expected.UserID, actual.UserID)
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ import (
|
|||||||
|
|
||||||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1"
|
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1"
|
||||||
"github.com/grafana/grafana/pkg/infra/appcontext"
|
|
||||||
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
|
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
|
||||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||||
"github.com/grafana/grafana/pkg/services/guardian"
|
"github.com/grafana/grafana/pkg/services/guardian"
|
||||||
@@ -19,7 +19,7 @@ func (b *DashboardsAPIBuilder) GetAuthorizer() authorizer.Authorizer {
|
|||||||
return authorizer.DecisionNoOpinion, "", nil
|
return authorizer.DecisionNoOpinion, "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
user, err := appcontext.User(ctx)
|
user, err := identity.GetRequester(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return authorizer.DecisionDeny, "", err
|
return authorizer.DecisionDeny, "", err
|
||||||
}
|
}
|
||||||
@@ -27,7 +27,7 @@ func (b *DashboardsAPIBuilder) GetAuthorizer() authorizer.Authorizer {
|
|||||||
if attr.GetName() == "" {
|
if attr.GetName() == "" {
|
||||||
// Discourage use of the "list" command for non super admin users
|
// Discourage use of the "list" command for non super admin users
|
||||||
if attr.GetVerb() == "list" && attr.GetResource() == v0alpha1.DashboardResourceInfo.GroupResource().Resource {
|
if attr.GetVerb() == "list" && attr.GetResource() == v0alpha1.DashboardResourceInfo.GroupResource().Resource {
|
||||||
if !user.IsGrafanaAdmin {
|
if !user.GetIsGrafanaAdmin() {
|
||||||
return authorizer.DecisionDeny, "list summary objects (or connect as GrafanaAdmin)", err
|
return authorizer.DecisionDeny, "list summary objects (or connect as GrafanaAdmin)", err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apiserver/pkg/registry/rest"
|
"k8s.io/apiserver/pkg/registry/rest"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||||
dashboardsnapshot "github.com/grafana/grafana/pkg/apis/dashboardsnapshot/v0alpha1"
|
dashboardsnapshot "github.com/grafana/grafana/pkg/apis/dashboardsnapshot/v0alpha1"
|
||||||
"github.com/grafana/grafana/pkg/infra/appcontext"
|
|
||||||
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
|
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
|
||||||
"github.com/grafana/grafana/pkg/services/dashboardsnapshots"
|
"github.com/grafana/grafana/pkg/services/dashboardsnapshots"
|
||||||
)
|
)
|
||||||
@@ -73,7 +73,7 @@ func (s *legacyStorage) List(ctx context.Context, options *internalversion.ListO
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
user, err := appcontext.User(ctx)
|
user, err := identity.GetRequester(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import (
|
|||||||
|
|
||||||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/infra/appcontext"
|
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||||
ac "github.com/grafana/grafana/pkg/services/accesscontrol"
|
ac "github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||||
"github.com/grafana/grafana/pkg/services/datasources"
|
"github.com/grafana/grafana/pkg/services/datasources"
|
||||||
)
|
)
|
||||||
@@ -17,7 +17,7 @@ func (b *DataSourceAPIBuilder) GetAuthorizer() authorizer.Authorizer {
|
|||||||
if !attr.IsResourceRequest() {
|
if !attr.IsResourceRequest() {
|
||||||
return authorizer.DecisionNoOpinion, "", nil
|
return authorizer.DecisionNoOpinion, "", nil
|
||||||
}
|
}
|
||||||
user, err := appcontext.User(ctx)
|
user, err := identity.GetRequester(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return authorizer.DecisionDeny, "valid user is required", err
|
return authorizer.DecisionDeny, "valid user is required", err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ import (
|
|||||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||||
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
||||||
"github.com/grafana/grafana/pkg/apis/datasource/v0alpha1"
|
"github.com/grafana/grafana/pkg/apis/datasource/v0alpha1"
|
||||||
"github.com/grafana/grafana/pkg/infra/appcontext"
|
|
||||||
"github.com/grafana/grafana/pkg/plugins"
|
"github.com/grafana/grafana/pkg/plugins"
|
||||||
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
|
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
|
||||||
gapiutil "github.com/grafana/grafana/pkg/services/apiserver/utils"
|
gapiutil "github.com/grafana/grafana/pkg/services/apiserver/utils"
|
||||||
@@ -84,7 +84,7 @@ func (q *scopedDatasourceProvider) Get(ctx context.Context, uid string) (*v0alph
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
user, err := appcontext.User(ctx)
|
user, err := identity.GetRequester(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ import (
|
|||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
|
||||||
common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1"
|
common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1"
|
||||||
|
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||||
"github.com/grafana/grafana/pkg/apis/datasource/v0alpha1"
|
"github.com/grafana/grafana/pkg/apis/datasource/v0alpha1"
|
||||||
"github.com/grafana/grafana/pkg/infra/appcontext"
|
|
||||||
"github.com/grafana/grafana/pkg/plugins"
|
"github.com/grafana/grafana/pkg/plugins"
|
||||||
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
|
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
|
||||||
"github.com/grafana/grafana/pkg/services/datasources"
|
"github.com/grafana/grafana/pkg/services/datasources"
|
||||||
@@ -108,7 +108,7 @@ func (q *DefaultQuerier) Datasource(ctx context.Context, name string) (*v0alpha1
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
user, err := appcontext.User(ctx)
|
user, err := identity.GetRequester(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
@@ -20,12 +21,11 @@ import (
|
|||||||
"k8s.io/kube-openapi/pkg/spec3"
|
"k8s.io/kube-openapi/pkg/spec3"
|
||||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||||
example "github.com/grafana/grafana/pkg/apis/example/v0alpha1"
|
example "github.com/grafana/grafana/pkg/apis/example/v0alpha1"
|
||||||
"github.com/grafana/grafana/pkg/apiserver/builder"
|
"github.com/grafana/grafana/pkg/apiserver/builder"
|
||||||
grafanarest "github.com/grafana/grafana/pkg/apiserver/rest"
|
grafanarest "github.com/grafana/grafana/pkg/apiserver/rest"
|
||||||
"github.com/grafana/grafana/pkg/infra/appcontext"
|
|
||||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ builder.APIGroupBuilder = (*TestingAPIBuilder)(nil)
|
var _ builder.APIGroupBuilder = (*TestingAPIBuilder)(nil)
|
||||||
@@ -216,7 +216,7 @@ func (b *TestingAPIBuilder) GetAuthorizer() authorizer.Authorizer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// require a user
|
// require a user
|
||||||
_, err = appcontext.User(ctx)
|
_, err = identity.GetRequester(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return authorizer.DecisionDeny, "valid user is required", err
|
return authorizer.DecisionDeny, "valid user is required", err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apiserver/pkg/registry/rest"
|
"k8s.io/apiserver/pkg/registry/rest"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||||
example "github.com/grafana/grafana/pkg/apis/example/v0alpha1"
|
example "github.com/grafana/grafana/pkg/apis/example/v0alpha1"
|
||||||
"github.com/grafana/grafana/pkg/infra/appcontext"
|
|
||||||
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
|
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -38,14 +38,14 @@ func (r *dummySubresourceREST) Connect(ctx context.Context, name string, opts ru
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
user, err := appcontext.User(ctx)
|
user, err := identity.GetRequester(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// This response object format is negotiated by k8s
|
// This response object format is negotiated by k8s
|
||||||
dummy := &example.DummySubresource{
|
dummy := &example.DummySubresource{
|
||||||
Info: fmt.Sprintf("%s/%s", info.Value, user.Login),
|
Info: fmt.Sprintf("%s/%s", info.Value, user.GetLogin()),
|
||||||
}
|
}
|
||||||
|
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||||
|
|||||||
@@ -11,9 +11,9 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apiserver/pkg/registry/rest"
|
"k8s.io/apiserver/pkg/registry/rest"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||||
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
||||||
"github.com/grafana/grafana/pkg/apis/folder/v0alpha1"
|
"github.com/grafana/grafana/pkg/apis/folder/v0alpha1"
|
||||||
"github.com/grafana/grafana/pkg/infra/appcontext"
|
|
||||||
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
|
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
|
||||||
"github.com/grafana/grafana/pkg/services/apiserver/storage/entity"
|
"github.com/grafana/grafana/pkg/services/apiserver/storage/entity"
|
||||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||||
@@ -83,7 +83,7 @@ func (s *legacyStorage) List(ctx context.Context, options *internalversion.ListO
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
user, err := appcontext.User(ctx)
|
user, err := identity.GetRequester(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -116,7 +116,7 @@ func (s *legacyStorage) Get(ctx context.Context, name string, options *metav1.Ge
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
user, err := appcontext.User(ctx)
|
user, err := identity.GetRequester(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -146,7 +146,7 @@ func (s *legacyStorage) Create(ctx context.Context,
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
user, err := appcontext.User(ctx)
|
user, err := identity.GetRequester(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -195,7 +195,7 @@ func (s *legacyStorage) Update(ctx context.Context,
|
|||||||
return nil, false, err
|
return nil, false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
user, err := appcontext.User(ctx)
|
user, err := identity.GetRequester(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, false, err
|
return nil, false, err
|
||||||
}
|
}
|
||||||
@@ -267,7 +267,7 @@ func (s *legacyStorage) Delete(ctx context.Context, name string, deleteValidatio
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return v, false, err // includes the not-found error
|
return v, false, err // includes the not-found error
|
||||||
}
|
}
|
||||||
user, err := appcontext.User(ctx)
|
user, err := identity.GetRequester(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, false, err
|
return nil, false, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
@@ -15,11 +16,11 @@ import (
|
|||||||
common "k8s.io/kube-openapi/pkg/common"
|
common "k8s.io/kube-openapi/pkg/common"
|
||||||
"k8s.io/kube-openapi/pkg/spec3"
|
"k8s.io/kube-openapi/pkg/spec3"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||||
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
||||||
"github.com/grafana/grafana/pkg/apis/folder/v0alpha1"
|
"github.com/grafana/grafana/pkg/apis/folder/v0alpha1"
|
||||||
"github.com/grafana/grafana/pkg/apiserver/builder"
|
"github.com/grafana/grafana/pkg/apiserver/builder"
|
||||||
grafanarest "github.com/grafana/grafana/pkg/apiserver/rest"
|
grafanarest "github.com/grafana/grafana/pkg/apiserver/rest"
|
||||||
"github.com/grafana/grafana/pkg/infra/appcontext"
|
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||||
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
|
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
|
||||||
gapiutil "github.com/grafana/grafana/pkg/services/apiserver/utils"
|
gapiutil "github.com/grafana/grafana/pkg/services/apiserver/utils"
|
||||||
@@ -27,7 +28,6 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||||
"github.com/grafana/grafana/pkg/services/folder"
|
"github.com/grafana/grafana/pkg/services/folder"
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ builder.APIGroupBuilder = (*FolderAPIBuilder)(nil)
|
var _ builder.APIGroupBuilder = (*FolderAPIBuilder)(nil)
|
||||||
@@ -190,7 +190,7 @@ func (b *FolderAPIBuilder) GetAuthorizer() authorizer.Authorizer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// require a user
|
// require a user
|
||||||
user, err := appcontext.User(ctx)
|
user, err := identity.GetRequester(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return authorizer.DecisionDeny, "valid user is required", err
|
return authorizer.DecisionDeny, "valid user is required", err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apiserver/pkg/registry/rest"
|
"k8s.io/apiserver/pkg/registry/rest"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||||
"github.com/grafana/grafana/pkg/apis/folder/v0alpha1"
|
"github.com/grafana/grafana/pkg/apis/folder/v0alpha1"
|
||||||
"github.com/grafana/grafana/pkg/infra/appcontext"
|
|
||||||
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
|
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
|
||||||
"github.com/grafana/grafana/pkg/services/folder"
|
"github.com/grafana/grafana/pkg/services/folder"
|
||||||
"github.com/grafana/grafana/pkg/services/guardian"
|
"github.com/grafana/grafana/pkg/services/guardian"
|
||||||
@@ -49,7 +49,7 @@ func (r *subAccessREST) Connect(ctx context.Context, name string, opts runtime.O
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
user, err := appcontext.User(ctx)
|
user, err := identity.GetRequester(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apiserver/pkg/registry/rest"
|
"k8s.io/apiserver/pkg/registry/rest"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||||
"github.com/grafana/grafana/pkg/apis/folder/v0alpha1"
|
"github.com/grafana/grafana/pkg/apis/folder/v0alpha1"
|
||||||
"github.com/grafana/grafana/pkg/infra/appcontext"
|
|
||||||
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
|
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
|
||||||
"github.com/grafana/grafana/pkg/services/folder"
|
"github.com/grafana/grafana/pkg/services/folder"
|
||||||
)
|
)
|
||||||
@@ -46,7 +46,7 @@ func (r *subCountREST) NewConnectOptions() (runtime.Object, bool, string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *subCountREST) Connect(ctx context.Context, name string, opts runtime.Object, responder rest.Responder) (http.Handler, error) {
|
func (r *subCountREST) Connect(ctx context.Context, name string, opts runtime.Object, responder rest.Responder) (http.Handler, error) {
|
||||||
user, err := appcontext.User(ctx)
|
user, err := identity.GetRequester(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,38 +8,38 @@ import (
|
|||||||
k8suser "k8s.io/apiserver/pkg/authentication/user"
|
k8suser "k8s.io/apiserver/pkg/authentication/user"
|
||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/infra/appcontext"
|
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ authenticator.RequestFunc = signedInUserAuthenticator
|
var _ authenticator.RequestFunc = signedInUserAuthenticator
|
||||||
|
|
||||||
func signedInUserAuthenticator(req *http.Request) (*authenticator.Response, bool, error) {
|
func signedInUserAuthenticator(req *http.Request) (*authenticator.Response, bool, error) {
|
||||||
ctx := req.Context()
|
ctx := req.Context()
|
||||||
signedInUser, err := appcontext.User(ctx)
|
signedInUser, err := identity.GetRequester(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
klog.V(5).Info("failed to get signed in user", "err", err)
|
klog.V(5).Info("failed to get signed in user", "err", err)
|
||||||
return nil, false, nil
|
return nil, false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
userInfo := &k8suser.DefaultInfo{
|
userInfo := &k8suser.DefaultInfo{
|
||||||
Name: signedInUser.Login,
|
Name: signedInUser.GetLogin(),
|
||||||
UID: signedInUser.UserUID,
|
UID: signedInUser.GetUID().ID(),
|
||||||
Groups: []string{},
|
Groups: []string{},
|
||||||
// In order to faithfully round-trip through an impersonation flow, Extra keys MUST be lowercase.
|
// In order to faithfully round-trip through an impersonation flow, Extra keys MUST be lowercase.
|
||||||
// see: https://pkg.go.dev/k8s.io/apiserver@v0.27.1/pkg/authentication/user#Info
|
// see: https://pkg.go.dev/k8s.io/apiserver@v0.27.1/pkg/authentication/user#Info
|
||||||
Extra: map[string][]string{},
|
Extra: map[string][]string{},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, v := range signedInUser.Teams {
|
for _, v := range signedInUser.GetTeams() {
|
||||||
userInfo.Groups = append(userInfo.Groups, strconv.FormatInt(v, 10))
|
userInfo.Groups = append(userInfo.Groups, strconv.FormatInt(v, 10))
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
if signedInUser.IDToken != "" {
|
if signedInUser.GetIDToken() != "" {
|
||||||
userInfo.Extra["id-token"] = []string{signedInUser.IDToken}
|
userInfo.Extra["id-token"] = []string{signedInUser.GetIDToken()}
|
||||||
}
|
}
|
||||||
if signedInUser.OrgRole.IsValid() {
|
if signedInUser.GetOrgRole().IsValid() {
|
||||||
userInfo.Extra["user-instance-role"] = []string{string(signedInUser.OrgRole)}
|
userInfo.Extra["user-instance-role"] = []string{string(signedInUser.GetOrgRole())}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &authenticator.Response{
|
return &authenticator.Response{
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import (
|
|||||||
|
|
||||||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/infra/appcontext"
|
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
grafanarequest "github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
|
grafanarequest "github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
|
||||||
"github.com/grafana/grafana/pkg/services/org"
|
"github.com/grafana/grafana/pkg/services/org"
|
||||||
@@ -27,7 +27,7 @@ func newOrgIDAuthorizer(orgService org.Service) *orgIDAuthorizer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (auth orgIDAuthorizer) Authorize(ctx context.Context, a authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) {
|
func (auth orgIDAuthorizer) Authorize(ctx context.Context, a authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) {
|
||||||
signedInUser, err := appcontext.User(ctx)
|
signedInUser, err := identity.GetRequester(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return authorizer.DecisionDeny, fmt.Sprintf("error getting signed in user: %v", err), nil
|
return authorizer.DecisionDeny, fmt.Sprintf("error getting signed in user: %v", err), nil
|
||||||
}
|
}
|
||||||
@@ -51,12 +51,16 @@ func (auth orgIDAuthorizer) Authorize(ctx context.Context, a authorizer.Attribut
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Quick check that the same org is used
|
// Quick check that the same org is used
|
||||||
if signedInUser.OrgID == info.OrgID {
|
if signedInUser.GetOrgID() == info.OrgID {
|
||||||
return authorizer.DecisionNoOpinion, "", nil
|
return authorizer.DecisionNoOpinion, "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the user has access to the specified org
|
// Check if the user has access to the specified org
|
||||||
query := org.GetUserOrgListQuery{UserID: signedInUser.UserID}
|
userId, err := signedInUser.GetID().UserID()
|
||||||
|
if err != nil {
|
||||||
|
return authorizer.DecisionDeny, "unable to get userId", err
|
||||||
|
}
|
||||||
|
query := org.GetUserOrgListQuery{UserID: userId}
|
||||||
result, err := auth.org.GetUserOrgList(ctx, &query)
|
result, err := auth.org.GetUserOrgList(ctx, &query)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return authorizer.DecisionDeny, "error getting user org list", err
|
return authorizer.DecisionDeny, "error getting user org list", err
|
||||||
@@ -68,5 +72,5 @@ func (auth orgIDAuthorizer) Authorize(ctx context.Context, a authorizer.Attribut
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return authorizer.DecisionDeny, fmt.Sprintf("user %d is not a member of org %d", signedInUser.UserID, info.OrgID), nil
|
return authorizer.DecisionDeny, fmt.Sprintf("user %d is not a member of org %d", userId, info.OrgID), nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import (
|
|||||||
|
|
||||||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/infra/appcontext"
|
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
"github.com/grafana/grafana/pkg/services/org"
|
"github.com/grafana/grafana/pkg/services/org"
|
||||||
)
|
)
|
||||||
@@ -22,12 +22,13 @@ func newOrgRoleAuthorizer(orgService org.Service) *orgRoleAuthorizer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (auth orgRoleAuthorizer) Authorize(ctx context.Context, a authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) {
|
func (auth orgRoleAuthorizer) Authorize(ctx context.Context, a authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) {
|
||||||
signedInUser, err := appcontext.User(ctx)
|
signedInUser, err := identity.GetRequester(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return authorizer.DecisionDeny, fmt.Sprintf("error getting signed in user: %v", err), nil
|
return authorizer.DecisionDeny, fmt.Sprintf("error getting signed in user: %v", err), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
switch signedInUser.OrgRole {
|
orgRole := signedInUser.GetOrgRole()
|
||||||
|
switch orgRole {
|
||||||
case org.RoleAdmin:
|
case org.RoleAdmin:
|
||||||
return authorizer.DecisionAllow, "", nil
|
return authorizer.DecisionAllow, "", nil
|
||||||
case org.RoleEditor:
|
case org.RoleEditor:
|
||||||
@@ -35,21 +36,21 @@ func (auth orgRoleAuthorizer) Authorize(ctx context.Context, a authorizer.Attrib
|
|||||||
case "get", "list", "watch", "create", "update", "patch", "delete", "put", "post":
|
case "get", "list", "watch", "create", "update", "patch", "delete", "put", "post":
|
||||||
return authorizer.DecisionAllow, "", nil
|
return authorizer.DecisionAllow, "", nil
|
||||||
default:
|
default:
|
||||||
return authorizer.DecisionDeny, errorMessageForGrafanaOrgRole(string(signedInUser.OrgRole), a), nil
|
return authorizer.DecisionDeny, errorMessageForGrafanaOrgRole(orgRole, a), nil
|
||||||
}
|
}
|
||||||
case org.RoleViewer:
|
case org.RoleViewer:
|
||||||
switch a.GetVerb() {
|
switch a.GetVerb() {
|
||||||
case "get", "list", "watch":
|
case "get", "list", "watch":
|
||||||
return authorizer.DecisionAllow, "", nil
|
return authorizer.DecisionAllow, "", nil
|
||||||
default:
|
default:
|
||||||
return authorizer.DecisionDeny, errorMessageForGrafanaOrgRole(string(signedInUser.OrgRole), a), nil
|
return authorizer.DecisionDeny, errorMessageForGrafanaOrgRole(orgRole, a), nil
|
||||||
}
|
}
|
||||||
case org.RoleNone:
|
case org.RoleNone:
|
||||||
return authorizer.DecisionDeny, errorMessageForGrafanaOrgRole(string(signedInUser.OrgRole), a), nil
|
return authorizer.DecisionDeny, errorMessageForGrafanaOrgRole(orgRole, a), nil
|
||||||
}
|
}
|
||||||
return authorizer.DecisionDeny, "", nil
|
return authorizer.DecisionDeny, "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func errorMessageForGrafanaOrgRole(grafanaOrgRole string, a authorizer.Attributes) string {
|
func errorMessageForGrafanaOrgRole(orgRole identity.RoleType, a authorizer.Attributes) string {
|
||||||
return fmt.Sprintf("Grafana org role (%s) didn't allow %s access on requested resource=%s, path=%s", grafanaOrgRole, a.GetVerb(), a.GetResource(), a.GetPath())
|
return fmt.Sprintf("Grafana org role (%s) didn't allow %s access on requested resource=%s, path=%s", orgRole, a.GetVerb(), a.GetResource(), a.GetPath())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import (
|
|||||||
|
|
||||||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/infra/appcontext"
|
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
grafanarequest "github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
|
grafanarequest "github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
@@ -27,7 +27,7 @@ func newStackIDAuthorizer(cfg *setting.Cfg) *stackIDAuthorizer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (auth stackIDAuthorizer) Authorize(ctx context.Context, a authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) {
|
func (auth stackIDAuthorizer) Authorize(ctx context.Context, a authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) {
|
||||||
signedInUser, err := appcontext.User(ctx)
|
signedInUser, err := identity.GetRequester(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return authorizer.DecisionDeny, fmt.Sprintf("error getting signed in user: %v", err), nil
|
return authorizer.DecisionDeny, fmt.Sprintf("error getting signed in user: %v", err), nil
|
||||||
}
|
}
|
||||||
@@ -48,7 +48,7 @@ func (auth stackIDAuthorizer) Authorize(ctx context.Context, a authorizer.Attrib
|
|||||||
if info.OrgID != 1 {
|
if info.OrgID != 1 {
|
||||||
return authorizer.DecisionDeny, "cloud instance requires org 1", nil
|
return authorizer.DecisionDeny, "cloud instance requires org 1", nil
|
||||||
}
|
}
|
||||||
if signedInUser.OrgID != 1 {
|
if signedInUser.GetOrgID() != 1 {
|
||||||
return authorizer.DecisionDeny, "user must be in org 1", nil
|
return authorizer.DecisionDeny, "user must be in org 1", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
|
|
||||||
"k8s.io/apiserver/pkg/endpoints/request"
|
"k8s.io/apiserver/pkg/endpoints/request"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/infra/appcontext"
|
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -82,9 +82,9 @@ func ParseNamespace(ns string) (NamespaceInfo, error) {
|
|||||||
func OrgIDForList(ctx context.Context) (int64, error) {
|
func OrgIDForList(ctx context.Context) (int64, error) {
|
||||||
ns := request.NamespaceValue(ctx)
|
ns := request.NamespaceValue(ctx)
|
||||||
if ns == "" {
|
if ns == "" {
|
||||||
user, err := appcontext.User(ctx)
|
user, err := identity.GetRequester(ctx)
|
||||||
if user != nil {
|
if user != nil {
|
||||||
return user.OrgID, err
|
return user.GetOrgID(), err
|
||||||
}
|
}
|
||||||
return -1, err
|
return -1, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -157,6 +157,11 @@ func ProvideService(
|
|||||||
req.URL.Path = "/"
|
req.URL.Path = "/"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if c.SignedInUser != nil {
|
||||||
|
ctx := appcontext.WithUser(req.Context(), c.SignedInUser)
|
||||||
|
req = req.WithContext(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
resp := responsewriter.WrapForHTTP1Or2(c.Resp)
|
resp := responsewriter.WrapForHTTP1Or2(c.Resp)
|
||||||
s.handler.ServeHTTP(resp, req)
|
s.handler.ServeHTTP(resp, req)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
|
|
||||||
data "github.com/grafana/grafana-plugin-sdk-go/experimental/apis/data/v0alpha1"
|
data "github.com/grafana/grafana-plugin-sdk-go/experimental/apis/data/v0alpha1"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/infra/appcontext"
|
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||||
"github.com/grafana/grafana/pkg/services/datasources"
|
"github.com/grafana/grafana/pkg/services/datasources"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -56,11 +56,11 @@ func (s *cachingLegacyDataSourceLookup) GetDataSourceFromDeprecatedFields(ctx co
|
|||||||
if id == 0 && name == "" {
|
if id == 0 && name == "" {
|
||||||
return nil, fmt.Errorf("either name or ID must be set")
|
return nil, fmt.Errorf("either name or ID must be set")
|
||||||
}
|
}
|
||||||
user, err := appcontext.User(ctx)
|
user, err := identity.GetRequester(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
key := fmt.Sprintf("%d/%s/%d", user.OrgID, name, id)
|
key := fmt.Sprintf("%d/%s/%d", user.GetOrgID(), name, id)
|
||||||
s.cacheMu.Lock()
|
s.cacheMu.Lock()
|
||||||
defer s.cacheMu.Unlock()
|
defer s.cacheMu.Unlock()
|
||||||
|
|
||||||
@@ -70,13 +70,13 @@ func (s *cachingLegacyDataSourceLookup) GetDataSourceFromDeprecatedFields(ctx co
|
|||||||
}
|
}
|
||||||
|
|
||||||
ds, err := s.retriever.GetDataSource(ctx, &datasources.GetDataSourceQuery{
|
ds, err := s.retriever.GetDataSource(ctx, &datasources.GetDataSourceQuery{
|
||||||
OrgID: user.OrgID,
|
OrgID: user.GetOrgID(),
|
||||||
Name: name,
|
Name: name,
|
||||||
ID: id,
|
ID: id,
|
||||||
})
|
})
|
||||||
if errors.Is(err, datasources.ErrDataSourceNotFound) && name != "" {
|
if errors.Is(err, datasources.ErrDataSourceNotFound) && name != "" {
|
||||||
ds, err = s.retriever.GetDataSource(ctx, &datasources.GetDataSourceQuery{
|
ds, err = s.retriever.GetDataSource(ctx, &datasources.GetDataSourceQuery{
|
||||||
OrgID: user.OrgID,
|
OrgID: user.GetOrgID(),
|
||||||
UID: name, // Sometimes name is actually the UID :(
|
UID: name, // Sometimes name is actually the UID :(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/infra/appcontext"
|
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||||
ac "github.com/grafana/grafana/pkg/services/accesscontrol"
|
ac "github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||||
"github.com/grafana/grafana/pkg/services/folder"
|
"github.com/grafana/grafana/pkg/services/folder"
|
||||||
@@ -47,7 +47,7 @@ func LibraryPanelUIDScopeResolver(l *LibraryElementService, folderSvc folder.Ser
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
user, err := appcontext.User(ctx)
|
user, err := identity.GetRequester(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import (
|
|||||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||||
"github.com/grafana/grafana/pkg/infra/appcontext"
|
|
||||||
"github.com/grafana/grafana/pkg/infra/localcache"
|
"github.com/grafana/grafana/pkg/infra/localcache"
|
||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
"github.com/grafana/grafana/pkg/plugins"
|
"github.com/grafana/grafana/pkg/plugins"
|
||||||
@@ -95,7 +94,7 @@ func (p *Provider) GetWithDataSource(ctx context.Context, pluginID string, user
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *Provider) GetDataSourceInstanceSettings(ctx context.Context, uid string) (*backend.DataSourceInstanceSettings, error) {
|
func (p *Provider) GetDataSourceInstanceSettings(ctx context.Context, uid string) (*backend.DataSourceInstanceSettings, error) {
|
||||||
user, err := appcontext.User(ctx)
|
user, err := identity.GetRequester(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -115,7 +114,7 @@ func (p *Provider) PluginContextForDataSource(ctx context.Context, datasourceSet
|
|||||||
return backend.PluginContext{}, plugins.ErrPluginNotRegistered
|
return backend.PluginContext{}, plugins.ErrPluginNotRegistered
|
||||||
}
|
}
|
||||||
|
|
||||||
user, err := appcontext.User(ctx)
|
user, err := identity.GetRequester(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return backend.PluginContext{}, err
|
return backend.PluginContext{}, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,11 +5,13 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
"google.golang.org/grpc/metadata"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||||
"github.com/grafana/grafana/pkg/infra/appcontext"
|
"github.com/grafana/grafana/pkg/infra/appcontext"
|
||||||
"github.com/grafana/grafana/pkg/services/grpcserver/interceptors"
|
"github.com/grafana/grafana/pkg/services/grpcserver/interceptors"
|
||||||
"github.com/grafana/grafana/pkg/services/user"
|
"github.com/grafana/grafana/pkg/services/user"
|
||||||
"google.golang.org/grpc"
|
|
||||||
"google.golang.org/grpc/metadata"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Authenticator struct{}
|
type Authenticator struct{}
|
||||||
@@ -82,16 +84,17 @@ func StreamClientInterceptor(ctx context.Context, desc *grpc.StreamDesc, cc *grp
|
|||||||
var _ grpc.StreamClientInterceptor = StreamClientInterceptor
|
var _ grpc.StreamClientInterceptor = StreamClientInterceptor
|
||||||
|
|
||||||
func WrapContext(ctx context.Context) (context.Context, error) {
|
func WrapContext(ctx context.Context) (context.Context, error) {
|
||||||
user, err := appcontext.User(ctx)
|
user, err := identity.GetRequester(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ctx, err
|
return ctx, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// set grpc metadata into the context to pass to the grpc server
|
// set grpc metadata into the context to pass to the grpc server
|
||||||
return metadata.NewOutgoingContext(ctx, metadata.Pairs(
|
return metadata.NewOutgoingContext(ctx, metadata.Pairs(
|
||||||
"grafana-idtoken", user.IDToken,
|
"grafana-idtoken", user.GetIDToken(),
|
||||||
"grafana-userid", strconv.FormatInt(user.UserID, 10),
|
"grafana-userid", user.GetID().ID(),
|
||||||
"grafana-orgid", strconv.FormatInt(user.OrgID, 10),
|
"grafana-useruid", user.GetUID().ID(),
|
||||||
"grafana-login", user.Login,
|
"grafana-orgid", strconv.FormatInt(user.GetOrgID(), 10),
|
||||||
|
"grafana-login", user.GetLogin(),
|
||||||
)), nil
|
)), nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import (
|
|||||||
"go.opentelemetry.io/otel/attribute"
|
"go.opentelemetry.io/otel/attribute"
|
||||||
"go.opentelemetry.io/otel/trace"
|
"go.opentelemetry.io/otel/trace"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/infra/appcontext"
|
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||||
"github.com/grafana/grafana/pkg/services/sqlstore/migrator"
|
"github.com/grafana/grafana/pkg/services/sqlstore/migrator"
|
||||||
@@ -358,7 +358,7 @@ func (s *sqlEntityServer) History(ctx context.Context, r *entity.EntityHistoryRe
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
user, err := appcontext.User(ctx)
|
user, err := identity.GetRequester(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctxLogger.Error("error getting user from ctx", "error", err)
|
ctxLogger.Error("error getting user from ctx", "error", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -573,7 +573,7 @@ func (s *sqlEntityServer) List(ctx context.Context, r *entity.EntityListRequest)
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
user, err := appcontext.User(ctx)
|
user, err := identity.GetRequester(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctxLogger.Error("error getting user from ctx", "error", err)
|
ctxLogger.Error("error getting user from ctx", "error", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -803,7 +803,7 @@ func (s *sqlEntityServer) Watch(w entity.EntityStore_WatchServer) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
user, err := appcontext.User(w.Context())
|
user, err := identity.GetRequester(w.Context())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctxLogger.Error("error getting user from ctx", "error", err)
|
ctxLogger.Error("error getting user from ctx", "error", err)
|
||||||
return err
|
return err
|
||||||
@@ -1289,7 +1289,7 @@ func (s *sqlEntityServer) FindReferences(ctx context.Context, r *entity.Referenc
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
user, err := appcontext.User(ctx)
|
user, err := identity.GetRequester(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctxLogger.Error("error getting user from ctx", "error", err)
|
ctxLogger.Error("error getting user from ctx", "error", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/infra/appcontext"
|
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||||
"github.com/grafana/grafana/pkg/services/store/entity/db"
|
"github.com/grafana/grafana/pkg/services/store/entity/db"
|
||||||
"github.com/grafana/grafana/pkg/services/store/entity/sqlstash/sqltemplate"
|
"github.com/grafana/grafana/pkg/services/store/entity/sqlstash/sqltemplate"
|
||||||
)
|
)
|
||||||
@@ -27,7 +27,7 @@ func createETag(body []byte, meta []byte, status []byte) string {
|
|||||||
// getCurrentUser returns a string identifying the user making a request with
|
// getCurrentUser returns a string identifying the user making a request with
|
||||||
// the given context.
|
// the given context.
|
||||||
func getCurrentUser(ctx context.Context) (string, error) {
|
func getCurrentUser(ctx context.Context) (string, error) {
|
||||||
user, err := appcontext.User(ctx)
|
user, err := identity.GetRequester(ctx)
|
||||||
if err != nil || user == nil {
|
if err != nil || user == nil {
|
||||||
return "", fmt.Errorf("%w: %w", ErrUserNotFoundInContext, err)
|
return "", fmt.Errorf("%w: %w", ErrUserNotFoundInContext, err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/infra/appcontext"
|
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||||
"github.com/grafana/grafana/pkg/services/datasources"
|
"github.com/grafana/grafana/pkg/services/datasources"
|
||||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
|
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
|
||||||
"github.com/grafana/grafana/pkg/tsdb/grafanads"
|
"github.com/grafana/grafana/pkg/tsdb/grafanads"
|
||||||
@@ -122,12 +122,12 @@ func (c *dsCache) getDS(ctx context.Context, uid string) (*dsVal, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
usr, err := appcontext.User(ctx)
|
usr, err := identity.GetRequester(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil // no user
|
return nil, nil // no user
|
||||||
}
|
}
|
||||||
|
|
||||||
v, ok := c.cache[usr.OrgID]
|
v, ok := c.cache[usr.GetOrgID()]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, nil // org not found
|
return nil, nil // org not found
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user