Merge remote-tracking branch 'origin/main' into resource-store
This commit is contained in:
@@ -8,38 +8,38 @@ import (
|
||||
k8suser "k8s.io/apiserver/pkg/authentication/user"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/appcontext"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
)
|
||||
|
||||
var _ authenticator.RequestFunc = signedInUserAuthenticator
|
||||
|
||||
func signedInUserAuthenticator(req *http.Request) (*authenticator.Response, bool, error) {
|
||||
ctx := req.Context()
|
||||
signedInUser, err := appcontext.User(ctx)
|
||||
signedInUser, err := identity.GetRequester(ctx)
|
||||
if err != nil {
|
||||
klog.V(5).Info("failed to get signed in user", "err", err)
|
||||
return nil, false, nil
|
||||
}
|
||||
|
||||
userInfo := &k8suser.DefaultInfo{
|
||||
Name: signedInUser.Login,
|
||||
UID: signedInUser.UserUID,
|
||||
Name: signedInUser.GetLogin(),
|
||||
UID: signedInUser.GetUID().ID(),
|
||||
Groups: []string{},
|
||||
// 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
|
||||
Extra: map[string][]string{},
|
||||
}
|
||||
|
||||
for _, v := range signedInUser.Teams {
|
||||
for _, v := range signedInUser.GetTeams() {
|
||||
userInfo.Groups = append(userInfo.Groups, strconv.FormatInt(v, 10))
|
||||
}
|
||||
|
||||
//
|
||||
if signedInUser.IDToken != "" {
|
||||
userInfo.Extra["id-token"] = []string{signedInUser.IDToken}
|
||||
if signedInUser.GetIDToken() != "" {
|
||||
userInfo.Extra["id-token"] = []string{signedInUser.GetIDToken()}
|
||||
}
|
||||
if signedInUser.OrgRole.IsValid() {
|
||||
userInfo.Extra["user-instance-role"] = []string{string(signedInUser.OrgRole)}
|
||||
if signedInUser.GetOrgRole().IsValid() {
|
||||
userInfo.Extra["user-instance-role"] = []string{string(signedInUser.GetOrgRole())}
|
||||
}
|
||||
|
||||
return &authenticator.Response{
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
|
||||
"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"
|
||||
grafanarequest "github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
|
||||
"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) {
|
||||
signedInUser, err := appcontext.User(ctx)
|
||||
signedInUser, err := identity.GetRequester(ctx)
|
||||
if 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
|
||||
if signedInUser.OrgID == info.OrgID {
|
||||
if signedInUser.GetOrgID() == info.OrgID {
|
||||
return authorizer.DecisionNoOpinion, "", nil
|
||||
}
|
||||
|
||||
// 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)
|
||||
if err != nil {
|
||||
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"
|
||||
|
||||
"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/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) {
|
||||
signedInUser, err := appcontext.User(ctx)
|
||||
signedInUser, err := identity.GetRequester(ctx)
|
||||
if 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:
|
||||
return authorizer.DecisionAllow, "", nil
|
||||
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":
|
||||
return authorizer.DecisionAllow, "", nil
|
||||
default:
|
||||
return authorizer.DecisionDeny, errorMessageForGrafanaOrgRole(string(signedInUser.OrgRole), a), nil
|
||||
return authorizer.DecisionDeny, errorMessageForGrafanaOrgRole(orgRole, a), nil
|
||||
}
|
||||
case org.RoleViewer:
|
||||
switch a.GetVerb() {
|
||||
case "get", "list", "watch":
|
||||
return authorizer.DecisionAllow, "", nil
|
||||
default:
|
||||
return authorizer.DecisionDeny, errorMessageForGrafanaOrgRole(string(signedInUser.OrgRole), a), nil
|
||||
return authorizer.DecisionDeny, errorMessageForGrafanaOrgRole(orgRole, a), nil
|
||||
}
|
||||
case org.RoleNone:
|
||||
return authorizer.DecisionDeny, errorMessageForGrafanaOrgRole(string(signedInUser.OrgRole), a), nil
|
||||
return authorizer.DecisionDeny, errorMessageForGrafanaOrgRole(orgRole, a), nil
|
||||
}
|
||||
return authorizer.DecisionDeny, "", nil
|
||||
}
|
||||
|
||||
func errorMessageForGrafanaOrgRole(grafanaOrgRole string, 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())
|
||||
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", orgRole, a.GetVerb(), a.GetResource(), a.GetPath())
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
|
||||
"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"
|
||||
grafanarequest "github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
|
||||
"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) {
|
||||
signedInUser, err := appcontext.User(ctx)
|
||||
signedInUser, err := identity.GetRequester(ctx)
|
||||
if 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 {
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
|
||||
"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"
|
||||
)
|
||||
|
||||
@@ -82,9 +82,9 @@ func ParseNamespace(ns string) (NamespaceInfo, error) {
|
||||
func OrgIDForList(ctx context.Context) (int64, error) {
|
||||
ns := request.NamespaceValue(ctx)
|
||||
if ns == "" {
|
||||
user, err := appcontext.User(ctx)
|
||||
user, err := identity.GetRequester(ctx)
|
||||
if user != nil {
|
||||
return user.OrgID, err
|
||||
return user.GetOrgID(), err
|
||||
}
|
||||
return -1, err
|
||||
}
|
||||
|
||||
@@ -160,6 +160,11 @@ func ProvideService(
|
||||
req.URL.Path = "/"
|
||||
}
|
||||
|
||||
if c.SignedInUser != nil {
|
||||
ctx := appcontext.WithUser(req.Context(), c.SignedInUser)
|
||||
req = req.WithContext(ctx)
|
||||
}
|
||||
|
||||
resp := responsewriter.WrapForHTTP1Or2(c.Resp)
|
||||
s.handler.ServeHTTP(resp, req)
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
|
||||
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"
|
||||
)
|
||||
|
||||
@@ -56,11 +56,11 @@ func (s *cachingLegacyDataSourceLookup) GetDataSourceFromDeprecatedFields(ctx co
|
||||
if id == 0 && name == "" {
|
||||
return nil, fmt.Errorf("either name or ID must be set")
|
||||
}
|
||||
user, err := appcontext.User(ctx)
|
||||
user, err := identity.GetRequester(ctx)
|
||||
if err != nil {
|
||||
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()
|
||||
defer s.cacheMu.Unlock()
|
||||
|
||||
@@ -70,13 +70,13 @@ func (s *cachingLegacyDataSourceLookup) GetDataSourceFromDeprecatedFields(ctx co
|
||||
}
|
||||
|
||||
ds, err := s.retriever.GetDataSource(ctx, &datasources.GetDataSourceQuery{
|
||||
OrgID: user.OrgID,
|
||||
OrgID: user.GetOrgID(),
|
||||
Name: name,
|
||||
ID: id,
|
||||
})
|
||||
if errors.Is(err, datasources.ErrDataSourceNotFound) && name != "" {
|
||||
ds, err = s.retriever.GetDataSource(ctx, &datasources.GetDataSourceQuery{
|
||||
OrgID: user.OrgID,
|
||||
OrgID: user.GetOrgID(),
|
||||
UID: name, // Sometimes name is actually the UID :(
|
||||
})
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/appcontext"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
ac "github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
"github.com/grafana/grafana/pkg/services/folder"
|
||||
@@ -47,7 +47,7 @@ func LibraryPanelUIDScopeResolver(l *LibraryElementService, folderSvc folder.Ser
|
||||
return nil, err
|
||||
}
|
||||
|
||||
user, err := appcontext.User(ctx)
|
||||
user, err := identity.GetRequester(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
|
||||
"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/log"
|
||||
"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) {
|
||||
user, err := appcontext.User(ctx)
|
||||
user, err := identity.GetRequester(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -115,7 +114,7 @@ func (p *Provider) PluginContextForDataSource(ctx context.Context, datasourceSet
|
||||
return backend.PluginContext{}, plugins.ErrPluginNotRegistered
|
||||
}
|
||||
|
||||
user, err := appcontext.User(ctx)
|
||||
user, err := identity.GetRequester(ctx)
|
||||
if err != nil {
|
||||
return backend.PluginContext{}, err
|
||||
}
|
||||
|
||||
@@ -5,11 +5,13 @@ import (
|
||||
"fmt"
|
||||
"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/services/grpcserver/interceptors"
|
||||
"github.com/grafana/grafana/pkg/services/user"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/metadata"
|
||||
)
|
||||
|
||||
type Authenticator struct{}
|
||||
@@ -82,16 +84,17 @@ func StreamClientInterceptor(ctx context.Context, desc *grpc.StreamDesc, cc *grp
|
||||
var _ grpc.StreamClientInterceptor = StreamClientInterceptor
|
||||
|
||||
func WrapContext(ctx context.Context) (context.Context, error) {
|
||||
user, err := appcontext.User(ctx)
|
||||
user, err := identity.GetRequester(ctx)
|
||||
if err != nil {
|
||||
return ctx, err
|
||||
}
|
||||
|
||||
// set grpc metadata into the context to pass to the grpc server
|
||||
return metadata.NewOutgoingContext(ctx, metadata.Pairs(
|
||||
"grafana-idtoken", user.IDToken,
|
||||
"grafana-userid", strconv.FormatInt(user.UserID, 10),
|
||||
"grafana-orgid", strconv.FormatInt(user.OrgID, 10),
|
||||
"grafana-login", user.Login,
|
||||
"grafana-idtoken", user.GetIDToken(),
|
||||
"grafana-userid", user.GetID().ID(),
|
||||
"grafana-useruid", user.GetUID().ID(),
|
||||
"grafana-orgid", strconv.FormatInt(user.GetOrgID(), 10),
|
||||
"grafana-login", user.GetLogin(),
|
||||
)), nil
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ import (
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"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/tracing"
|
||||
"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
|
||||
}
|
||||
|
||||
user, err := appcontext.User(ctx)
|
||||
user, err := identity.GetRequester(ctx)
|
||||
if err != nil {
|
||||
ctxLogger.Error("error getting user from ctx", "error", err)
|
||||
return nil, err
|
||||
@@ -573,7 +573,7 @@ func (s *sqlEntityServer) List(ctx context.Context, r *entity.EntityListRequest)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
user, err := appcontext.User(ctx)
|
||||
user, err := identity.GetRequester(ctx)
|
||||
if err != nil {
|
||||
ctxLogger.Error("error getting user from ctx", "error", err)
|
||||
return nil, err
|
||||
@@ -803,7 +803,7 @@ func (s *sqlEntityServer) Watch(w entity.EntityStore_WatchServer) error {
|
||||
return err
|
||||
}
|
||||
|
||||
user, err := appcontext.User(w.Context())
|
||||
user, err := identity.GetRequester(w.Context())
|
||||
if err != nil {
|
||||
ctxLogger.Error("error getting user from ctx", "error", err)
|
||||
return err
|
||||
@@ -1289,7 +1289,7 @@ func (s *sqlEntityServer) FindReferences(ctx context.Context, r *entity.Referenc
|
||||
return nil, err
|
||||
}
|
||||
|
||||
user, err := appcontext.User(ctx)
|
||||
user, err := identity.GetRequester(ctx)
|
||||
if err != nil {
|
||||
ctxLogger.Error("error getting user from ctx", "error", err)
|
||||
return nil, err
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"fmt"
|
||||
"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/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
|
||||
// the given context.
|
||||
func getCurrentUser(ctx context.Context) (string, error) {
|
||||
user, err := appcontext.User(ctx)
|
||||
user, err := identity.GetRequester(ctx)
|
||||
if err != nil || user == nil {
|
||||
return "", fmt.Errorf("%w: %w", ErrUserNotFoundInContext, err)
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"sync"
|
||||
"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/pluginsintegration/pluginstore"
|
||||
"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 {
|
||||
return nil, nil // no user
|
||||
}
|
||||
|
||||
v, ok := c.cache[usr.OrgID]
|
||||
v, ok := c.cache[usr.GetOrgID()]
|
||||
if !ok {
|
||||
return nil, nil // org not found
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user