From be7b1ce2df46f593b43ac8d2d00adf5304b27f51 Mon Sep 17 00:00:00 2001 From: Ryan McKinley Date: Fri, 26 Jul 2024 16:39:23 +0300 Subject: [PATCH] Chore: Replace appcontext.User(ctx) with identity.GetRequester(ctx) (#91030) --- .github/CODEOWNERS | 1 - pkg/infra/appcontext/user.go | 79 ------------------- pkg/infra/appcontext/user_test.go | 71 ----------------- .../notifications/receiver/authorize.go | 4 +- .../notifications/timeinterval/authorize.go | 7 +- .../apis/dashboard/legacy/sql_dashboards.go | 10 ++- pkg/registry/apis/dashboard/sub_dto.go | 5 +- .../apis/dashboardsnapshot/register.go | 10 +-- pkg/registry/apis/featuretoggle/current.go | 21 +++-- .../apis/featuretoggle/current_test.go | 11 ++- .../auth/authenticator/signedinuser_test.go | 6 +- pkg/services/apiserver/service.go | 6 +- .../service/dashboard_service_test.go | 4 +- pkg/services/dashboardsnapshots/service.go | 11 ++- .../libraryelements/libraryelements_test.go | 6 +- .../librarypanels/librarypanels_test.go | 11 ++- pkg/services/ngalert/tests/util.go | 4 +- .../store/entity/tests/common_test.go | 4 +- .../entity/tests/server_integration_test.go | 4 +- pkg/services/store/resolver/service_test.go | 4 +- pkg/util/testutil/context.go | 4 +- 21 files changed, 68 insertions(+), 215 deletions(-) delete mode 100644 pkg/infra/appcontext/user.go delete mode 100644 pkg/infra/appcontext/user_test.go diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index d340ca7bb0d..3a65bdc656f 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -87,7 +87,6 @@ /pkg/events/ @grafana/grafana-backend-group /pkg/extensions/ @grafana/grafana-backend-group /pkg/ifaces/ @grafana/grafana-backend-group -/pkg/infra/appcontext/ @grafana/grafana-backend-group /pkg/infra/db/ @grafana/grafana-backend-group /pkg/infra/localcache/ @grafana/grafana-backend-group /pkg/infra/log/ @grafana/grafana-backend-group diff --git a/pkg/infra/appcontext/user.go b/pkg/infra/appcontext/user.go deleted file mode 100644 index d50eaacd8b9..00000000000 --- a/pkg/infra/appcontext/user.go +++ /dev/null @@ -1,79 +0,0 @@ -package appcontext - -import ( - "context" - "fmt" - - "github.com/grafana/grafana/pkg/apimachinery/identity" - grpccontext "github.com/grafana/grafana/pkg/services/grpcserver/context" - "github.com/grafana/grafana/pkg/services/user" -) - -type ctxUserKey struct{} - -// WithUser adds the supplied SignedInUser to the context. -func WithUser(ctx context.Context, usr *user.SignedInUser) context.Context { - 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) -} - -// User extracts the SignedInUser from the supplied context. -// 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) { - // Set by appcontext.WithUser - u, ok := ctx.Value(ctxUserKey{}).(*user.SignedInUser) - if ok && u != nil { - return u, nil - } - - // Set by incoming gRPC server request - grpcCtx := grpccontext.FromContext(ctx) - if grpcCtx != nil && grpcCtx.SignedInUser != nil { - return grpcCtx.SignedInUser, nil - } - - // If the identity was set via requester, but not appcontext, we can map values - // NOTE: this path - requester, _ := identity.GetRequester(ctx) - if requester != nil { - id := requester.GetID() - userId, _ := id.UserID() - orgId := requester.GetOrgID() - return &user.SignedInUser{ - NamespacedID: id, - UserID: userId, - UserUID: requester.GetUID().ID(), - OrgID: orgId, - OrgName: requester.GetOrgName(), - OrgRole: requester.GetOrgRole(), - Login: requester.GetLogin(), - Email: requester.GetEmail(), - IsGrafanaAdmin: requester.GetIsGrafanaAdmin(), - Teams: requester.GetTeams(), - AuthID: requester.GetAuthID(), - AuthenticatedBy: requester.GetAuthenticatedBy(), - IDToken: requester.GetIDToken(), - Permissions: map[int64]map[string][]string{ - 0: requester.GetGlobalPermissions(), - orgId: requester.GetPermissions(), - }, - }, nil - } - - return nil, fmt.Errorf("a SignedInUser was not found in the context") -} - -// MustUser extracts the SignedInUser from the supplied context, and panics if a user is not found. -// Supports context set by appcontext.WithUser, gRPC server context, and HTTP ReqContext. -func MustUser(ctx context.Context) *user.SignedInUser { - usr, err := User(ctx) - if err != nil { - panic(err) - } - return usr -} diff --git a/pkg/infra/appcontext/user_test.go b/pkg/infra/appcontext/user_test.go deleted file mode 100644 index 55c9e0ac9a8..00000000000 --- a/pkg/infra/appcontext/user_test.go +++ /dev/null @@ -1,71 +0,0 @@ -package appcontext_test - -import ( - "context" - "crypto/rand" - "math/big" - "testing" - - "github.com/stretchr/testify/require" - - "github.com/grafana/grafana/pkg/apimachinery/identity" - "github.com/grafana/grafana/pkg/infra/appcontext" - "github.com/grafana/grafana/pkg/infra/tracing" - grpccontext "github.com/grafana/grafana/pkg/services/grpcserver/context" - "github.com/grafana/grafana/pkg/services/user" -) - -func TestUserFromContext(t *testing.T) { - t.Run("User should error when context is missing user", func(t *testing.T) { - usr, err := appcontext.User(context.Background()) - require.Nil(t, usr) - require.Error(t, err) - }) - - t.Run("MustUser should panic when context is missing user", func(t *testing.T) { - require.Panics(t, func() { - _ = appcontext.MustUser(context.Background()) - }) - }) - - t.Run("should return user set by ContextWithUser", func(t *testing.T) { - expected := testUser() - ctx := appcontext.WithUser(context.Background(), expected) - actual, err := appcontext.User(ctx) - require.NoError(t, err) - require.Equal(t, expected.UserID, actual.UserID) - - // The requester is also in context - requester, err := identity.GetRequester(ctx) - require.NoError(t, err) - require.Equal(t, expected.GetUID(), requester.GetUID()) - }) - - t.Run("should return user set by gRPC context", func(t *testing.T) { - expected := testUser() - handler := grpccontext.ProvideContextHandler(tracing.InitializeTracerForTest()) - ctx := handler.SetUser(context.Background(), expected) - actual, err := appcontext.User(ctx) - require.NoError(t, err) - require.Equal(t, expected.UserID, actual.UserID) - }) - - t.Run("should return user set as a requester", func(t *testing.T) { - expected := testUser() - ctx := identity.WithRequester(context.Background(), expected) - actual, err := appcontext.User(ctx) - require.NoError(t, err) - require.Equal(t, expected.UserID, actual.UserID) - }) -} - -func testUser() *user.SignedInUser { - i, err := rand.Int(rand.Reader, big.NewInt(100000)) - if err != nil { - panic(err) - } - return &user.SignedInUser{ - UserID: i.Int64(), - OrgID: 1, - } -} diff --git a/pkg/registry/apis/alerting/notifications/receiver/authorize.go b/pkg/registry/apis/alerting/notifications/receiver/authorize.go index f06c6862c17..972ca506dfd 100644 --- a/pkg/registry/apis/alerting/notifications/receiver/authorize.go +++ b/pkg/registry/apis/alerting/notifications/receiver/authorize.go @@ -5,7 +5,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/services/accesscontrol" ) @@ -13,7 +13,7 @@ func Authorize(ctx context.Context, ac accesscontrol.AccessControl, attr authori if attr.GetResource() != resourceInfo.GroupResource().Resource { return authorizer.DecisionNoOpinion, "", nil } - user, err := appcontext.User(ctx) + user, err := identity.GetRequester(ctx) if err != nil { return authorizer.DecisionDeny, "valid user is required", err } diff --git a/pkg/registry/apis/alerting/notifications/timeinterval/authorize.go b/pkg/registry/apis/alerting/notifications/timeinterval/authorize.go index b5ccd9d9812..2966cbe8434 100644 --- a/pkg/registry/apis/alerting/notifications/timeinterval/authorize.go +++ b/pkg/registry/apis/alerting/notifications/timeinterval/authorize.go @@ -3,17 +3,16 @@ package timeinterval import ( "context" - "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/services/accesscontrol" + "k8s.io/apiserver/pkg/authorization/authorizer" ) func Authorize(ctx context.Context, ac accesscontrol.AccessControl, attr authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) { if attr.GetResource() != resourceInfo.GroupResource().Resource { return authorizer.DecisionNoOpinion, "", nil } - user, err := appcontext.User(ctx) + user, err := identity.GetRequester(ctx) if err != nil { return authorizer.DecisionDeny, "valid user is required", err } diff --git a/pkg/registry/apis/dashboard/legacy/sql_dashboards.go b/pkg/registry/apis/dashboard/legacy/sql_dashboards.go index 35032b5d956..e6174dc679b 100644 --- a/pkg/registry/apis/dashboard/legacy/sql_dashboards.go +++ b/pkg/registry/apis/dashboard/legacy/sql_dashboards.go @@ -15,7 +15,6 @@ import ( "github.com/grafana/grafana/pkg/apimachinery/utils" dashboardsV0 "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1" "github.com/grafana/grafana/pkg/components/simplejson" - "github.com/grafana/grafana/pkg/infra/appcontext" "github.com/grafana/grafana/pkg/infra/db" "github.com/grafana/grafana/pkg/services/apiserver/endpoints/request" gapiutil "github.com/grafana/grafana/pkg/services/apiserver/utils" @@ -363,7 +362,7 @@ func (a *dashboardSqlAccess) DeleteDashboard(ctx context.Context, orgId int64, u // SaveDashboard implements DashboardAccess. func (a *dashboardSqlAccess) SaveDashboard(ctx context.Context, orgId int64, dash *dashboardsV0.Dashboard) (*dashboardsV0.Dashboard, bool, error) { created := false - user, err := appcontext.User(ctx) + user, err := identity.GetRequester(ctx) if err != nil { return nil, created, err } @@ -386,6 +385,11 @@ func (a *dashboardSqlAccess) SaveDashboard(ctx context.Context, orgId int64, das dash.Spec.Remove("uid") } + userID, err := user.GetID().UserID() + if err != nil { + return nil, false, err + } + meta, err := utils.MetaAccessor(dash) if err != nil { return nil, false, err @@ -395,7 +399,7 @@ func (a *dashboardSqlAccess) SaveDashboard(ctx context.Context, orgId int64, das Dashboard: simplejson.NewFromAny(dash.Spec.UnstructuredContent()), FolderUID: meta.GetFolder(), Overwrite: true, // already passed the revisionVersion checks! - UserID: user.UserID, + UserID: userID, }) if err != nil { return nil, false, err diff --git a/pkg/registry/apis/dashboard/sub_dto.go b/pkg/registry/apis/dashboard/sub_dto.go index 7bc53b23724..0b3a18c1e28 100644 --- a/pkg/registry/apis/dashboard/sub_dto.go +++ b/pkg/registry/apis/dashboard/sub_dto.go @@ -12,7 +12,6 @@ import ( "github.com/grafana/grafana/pkg/apimachinery/identity" "github.com/grafana/grafana/pkg/apimachinery/utils" dashboard "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1" - "github.com/grafana/grafana/pkg/infra/appcontext" "github.com/grafana/grafana/pkg/infra/slugify" "github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/apiserver/endpoints/request" @@ -60,7 +59,7 @@ func (r *DTOConnector) Connect(ctx context.Context, name string, opts runtime.Ob return nil, err } - user, err := appcontext.User(ctx) + user, err := identity.GetRequester(ctx) if err != nil { return nil, err } @@ -87,7 +86,7 @@ func (r *DTOConnector) Connect(ctx context.Context, name string, opts runtime.Ob access.CanSave, _ = guardian.CanSave() access.CanAdmin, _ = guardian.CanAdmin() access.CanDelete, _ = guardian.CanDelete() - access.CanStar = user.IsRealUser() && !user.IsAnonymous + access.CanStar = user.GetID().Type() == identity.TypeUser // not anon access.AnnotationsPermissions = &dashboard.AnnotationPermission{} r.getAnnotationPermissionsByScope(ctx, user, &access.AnnotationsPermissions.Dashboard, accesscontrol.ScopeAnnotationsTypeDashboard) diff --git a/pkg/registry/apis/dashboardsnapshot/register.go b/pkg/registry/apis/dashboardsnapshot/register.go index 184da3fac6b..58ff6367713 100644 --- a/pkg/registry/apis/dashboardsnapshot/register.go +++ b/pkg/registry/apis/dashboardsnapshot/register.go @@ -21,9 +21,9 @@ import ( "k8s.io/kube-openapi/pkg/spec3" "k8s.io/kube-openapi/pkg/validation/spec" + "github.com/grafana/grafana/pkg/apimachinery/identity" dashboardsnapshot "github.com/grafana/grafana/pkg/apis/dashboardsnapshot/v0alpha1" grafanarest "github.com/grafana/grafana/pkg/apiserver/rest" - "github.com/grafana/grafana/pkg/infra/appcontext" "github.com/grafana/grafana/pkg/infra/db" "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/services/apiserver/builder" @@ -247,7 +247,7 @@ func (b *SnapshotsAPIBuilder) GetAPIRoutes() *builder.APIRoutes { }, }, Handler: func(w http.ResponseWriter, r *http.Request) { - user, err := appcontext.User(r.Context()) + user, err := identity.GetRequester(r.Context()) if err != nil { errhttp.Write(r.Context(), err, w) return @@ -258,7 +258,7 @@ func (b *SnapshotsAPIBuilder) GetAPIRoutes() *builder.APIRoutes { Req: r, Resp: web.NewResponseWriter(r.Method, w), }, - SignedInUser: user, + // SignedInUser: user, ???????????? } vars := mux.Vars(r) @@ -267,9 +267,9 @@ func (b *SnapshotsAPIBuilder) GetAPIRoutes() *builder.APIRoutes { wrap.JsonApiErr(http.StatusBadRequest, "expected namespace", nil) return } - if info.OrgID != user.OrgID { + if info.OrgID != user.GetOrgID() { wrap.JsonApiErr(http.StatusBadRequest, - fmt.Sprintf("user orgId does not match namespace (%d != %d)", info.OrgID, user.OrgID), nil) + fmt.Sprintf("user orgId does not match namespace (%d != %d)", info.OrgID, user.GetOrgID()), nil) return } diff --git a/pkg/registry/apis/featuretoggle/current.go b/pkg/registry/apis/featuretoggle/current.go index a05fb62f4c2..f7602584a85 100644 --- a/pkg/registry/apis/featuretoggle/current.go +++ b/pkg/registry/apis/featuretoggle/current.go @@ -13,12 +13,11 @@ import ( common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1" "github.com/grafana/grafana/pkg/apimachinery/errutil" + "github.com/grafana/grafana/pkg/apimachinery/identity" "github.com/grafana/grafana/pkg/apis/featuretoggle/v0alpha1" "github.com/grafana/grafana/pkg/cmd/grafana-cli/logger" - "github.com/grafana/grafana/pkg/infra/appcontext" ac "github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/featuremgmt" - "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/util/errhttp" "github.com/grafana/grafana/pkg/web" @@ -77,9 +76,9 @@ func (b *FeatureFlagAPIBuilder) getResolvedToggleState(ctx context.Context) v0al return state } -func (b *FeatureFlagAPIBuilder) userCanRead(ctx context.Context, u *user.SignedInUser) bool { +func (b *FeatureFlagAPIBuilder) userCanRead(ctx context.Context, u identity.Requester) bool { if u == nil { - u, _ = appcontext.User(ctx) + u, _ = identity.GetRequester(ctx) if u == nil { return false } @@ -88,9 +87,9 @@ func (b *FeatureFlagAPIBuilder) userCanRead(ctx context.Context, u *user.SignedI return ok && err == nil } -func (b *FeatureFlagAPIBuilder) userCanWrite(ctx context.Context, u *user.SignedInUser) bool { +func (b *FeatureFlagAPIBuilder) userCanWrite(ctx context.Context, u identity.Requester) bool { if u == nil { - u, _ = appcontext.User(ctx) + u, _ = identity.GetRequester(ctx) if u == nil { return false } @@ -107,7 +106,7 @@ func (b *FeatureFlagAPIBuilder) handleCurrentStatus(w http.ResponseWriter, r *ht // Check if the user can access toggle info ctx := r.Context() - user, err := appcontext.User(ctx) + user, err := identity.GetRequester(ctx) if err != nil { errhttp.Write(ctx, err, w) return @@ -115,7 +114,7 @@ func (b *FeatureFlagAPIBuilder) handleCurrentStatus(w http.ResponseWriter, r *ht if !b.userCanRead(ctx, user) { err = errutil.Unauthorized("featuretoggle.canNotRead", - errutil.WithPublicMessage("missing read permission")).Errorf("user %s does not have read permissions", user.Login) + errutil.WithPublicMessage("missing read permission")).Errorf("user %s does not have read permissions", user.GetLogin()) errhttp.Write(ctx, err, w) return } @@ -136,7 +135,7 @@ func (b *FeatureFlagAPIBuilder) handlePatchCurrent(w http.ResponseWriter, r *htt return } - user, err := appcontext.User(ctx) + user, err := identity.GetRequester(ctx) if err != nil { errhttp.Write(ctx, err, w) return @@ -144,7 +143,7 @@ func (b *FeatureFlagAPIBuilder) handlePatchCurrent(w http.ResponseWriter, r *htt if !b.userCanWrite(ctx, user) { err = errutil.Unauthorized("featuretoggle.canNotWrite", - errutil.WithPublicMessage("missing write permission")).Errorf("user %s does not have write permissions", user.Login) + errutil.WithPublicMessage("missing write permission")).Errorf("user %s does not have write permissions", user.GetLogin()) errhttp.Write(ctx, err, w) return } @@ -185,7 +184,7 @@ func (b *FeatureFlagAPIBuilder) handlePatchCurrent(w http.ResponseWriter, r *htt payload := featuremgmt.FeatureToggleWebhookPayload{ FeatureToggles: changes, - User: user.Email, + User: user.GetEmail(), } err = sendWebhookUpdate(b.features.Settings, payload) diff --git a/pkg/registry/apis/featuretoggle/current_test.go b/pkg/registry/apis/featuretoggle/current_test.go index 7b1b24c52bb..e37dff81cbc 100644 --- a/pkg/registry/apis/featuretoggle/current_test.go +++ b/pkg/registry/apis/featuretoggle/current_test.go @@ -8,16 +8,15 @@ import ( "net/http/httptest" "testing" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "github.com/grafana/grafana/pkg/api/response" + "github.com/grafana/grafana/pkg/apimachinery/identity" "github.com/grafana/grafana/pkg/apis/featuretoggle/v0alpha1" - "github.com/grafana/grafana/pkg/infra/appcontext" "github.com/grafana/grafana/pkg/services/accesscontrol/actest" "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/setting" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestGetFeatureToggles(t *testing.T) { @@ -397,7 +396,7 @@ func callGetWith(t *testing.T, b *FeatureFlagAPIBuilder, expectedCode int) v0alp Header: http.Header{}, } req.Header.Add("content-type", "application/json") - req = req.WithContext(appcontext.WithUser(req.Context(), &user.SignedInUser{})) + req = req.WithContext(identity.WithRequester(req.Context(), &user.SignedInUser{})) b.handleCurrentStatus(w, req) rts := v0alpha1.ResolvedToggleState{} @@ -426,7 +425,7 @@ func callPatchWith(t *testing.T, b *FeatureFlagAPIBuilder, update v0alpha1.Resol Header: http.Header{}, } req.Header.Add("content-type", "application/json") - req = req.WithContext(appcontext.WithUser(req.Context(), &user.SignedInUser{})) + req = req.WithContext(identity.WithRequester(req.Context(), &user.SignedInUser{})) b.handleCurrentStatus(w, req) require.NotNil(t, w.Body()) diff --git a/pkg/services/apiserver/auth/authenticator/signedinuser_test.go b/pkg/services/apiserver/auth/authenticator/signedinuser_test.go index a06abe06aaf..86490c61dc5 100644 --- a/pkg/services/apiserver/auth/authenticator/signedinuser_test.go +++ b/pkg/services/apiserver/auth/authenticator/signedinuser_test.go @@ -6,7 +6,7 @@ import ( "testing" "github.com/google/uuid" - "github.com/grafana/grafana/pkg/infra/appcontext" + "github.com/grafana/grafana/pkg/apimachinery/identity" "github.com/grafana/grafana/pkg/services/user" "github.com/stretchr/testify/require" "k8s.io/apiserver/pkg/authentication/authenticator" @@ -33,7 +33,7 @@ func TestSignedInUser(t *testing.T) { UserUID: uuid.New().String(), Teams: []int64{1, 2}, } - ctx := appcontext.WithUser(context.Background(), u) + ctx := identity.WithRequester(context.Background(), u) req, err := http.NewRequest("GET", "http://localhost:3000/apis", nil) require.NoError(t, err) req = req.WithContext(ctx) @@ -58,7 +58,7 @@ func TestSignedInUser(t *testing.T) { Teams: []int64{1, 2}, IDToken: "test-id-token", } - ctx := appcontext.WithUser(context.Background(), u) + ctx := identity.WithRequester(context.Background(), u) req, err := http.NewRequest("GET", "http://localhost:3000/apis", nil) require.NoError(t, err) req = req.WithContext(ctx) diff --git a/pkg/services/apiserver/service.go b/pkg/services/apiserver/service.go index 640e819bda6..0afa1621fc9 100644 --- a/pkg/services/apiserver/service.go +++ b/pkg/services/apiserver/service.go @@ -20,8 +20,8 @@ import ( "k8s.io/client-go/tools/clientcmd" "github.com/grafana/grafana/pkg/api/routing" + "github.com/grafana/grafana/pkg/apimachinery/identity" grafanaresponsewriter "github.com/grafana/grafana/pkg/apiserver/endpoints/responsewriter" - "github.com/grafana/grafana/pkg/infra/appcontext" "github.com/grafana/grafana/pkg/infra/db" "github.com/grafana/grafana/pkg/infra/kvstore" "github.com/grafana/grafana/pkg/infra/metrics" @@ -163,7 +163,7 @@ func ProvideService( } if c.SignedInUser != nil { - ctx := appcontext.WithUser(req.Context(), c.SignedInUser) + ctx := identity.WithRequester(req.Context(), c.SignedInUser) req = req.WithContext(ctx) } @@ -423,7 +423,7 @@ func (s *service) GetDirectRestConfig(c *contextmodel.ReqContext) *clientrest.Co Transport: &roundTripperFunc{ fn: func(req *http.Request) (*http.Response, error) { <-s.startedCh - ctx := appcontext.WithUser(req.Context(), c.SignedInUser) + ctx := identity.WithRequester(req.Context(), c.SignedInUser) wrapped := grafanaresponsewriter.WrapHandler(s.handler) return wrapped(req.WithContext(ctx)) }, diff --git a/pkg/services/dashboards/service/dashboard_service_test.go b/pkg/services/dashboards/service/dashboard_service_test.go index 78e81ce47f2..34c6c6c18dd 100644 --- a/pkg/services/dashboards/service/dashboard_service_test.go +++ b/pkg/services/dashboards/service/dashboard_service_test.go @@ -7,8 +7,8 @@ import ( "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + "github.com/grafana/grafana/pkg/apimachinery/identity" "github.com/grafana/grafana/pkg/components/simplejson" - "github.com/grafana/grafana/pkg/infra/appcontext" "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/services/dashboards" "github.com/grafana/grafana/pkg/services/featuremgmt" @@ -201,7 +201,7 @@ func TestDashboardService(t *testing.T) { folderSvc.ExpectedFolder = &folder.Folder{UID: "i am a folder"} // set up a ctx with signed in user usr := &user.SignedInUser{UserID: 1} - ctx := appcontext.WithUser(context.Background(), usr) + ctx := identity.WithRequester(context.Background(), usr) count, err := service.CountInFolders(ctx, 1, []string{"i am a folder"}, usr) require.NoError(t, err) diff --git a/pkg/services/dashboardsnapshots/service.go b/pkg/services/dashboardsnapshots/service.go index f3b83b355e4..bf0add3c4f6 100644 --- a/pkg/services/dashboardsnapshots/service.go +++ b/pkg/services/dashboardsnapshots/service.go @@ -43,8 +43,13 @@ func CreateDashboardSnapshot(c *contextmodel.ReqContext, cfg dashboardsnapshot.S } uid := cmd.DashboardCreateCommand.Dashboard.GetNestedString("uid") + user, err := identity.GetRequester(c.Req.Context()) + if err != nil { + c.JsonApiErr(http.StatusBadRequest, "missing user in context", nil) + return + } - err := svc.ValidateDashboardExists(c.Req.Context(), c.SignedInUser.GetOrgID(), uid) + err = svc.ValidateDashboardExists(c.Req.Context(), user.GetOrgID(), uid) if err != nil { if errors.Is(err, dashboards.ErrDashboardNotFound) { c.JsonApiErr(http.StatusBadRequest, "Dashboard not found", err) @@ -58,7 +63,7 @@ func CreateDashboardSnapshot(c *contextmodel.ReqContext, cfg dashboardsnapshot.S cmd.DashboardCreateCommand.Name = "Unnamed snapshot" } - userID, err := identity.UserIdentifier(c.SignedInUser.GetTypedID()) + userID, err := identity.UserIdentifier(user.GetTypedID()) if err != nil { c.JsonApiErr(http.StatusInternalServerError, "Failed to create external snapshot", err) @@ -67,7 +72,7 @@ func CreateDashboardSnapshot(c *contextmodel.ReqContext, cfg dashboardsnapshot.S var snapshotUrl string cmd.ExternalURL = "" - cmd.OrgID = c.SignedInUser.GetOrgID() + cmd.OrgID = user.GetOrgID() cmd.UserID = userID originalDashboardURL, err := createOriginalDashboardURL(&cmd) if err != nil { diff --git a/pkg/services/libraryelements/libraryelements_test.go b/pkg/services/libraryelements/libraryelements_test.go index 769742d380e..9517e9adf94 100644 --- a/pkg/services/libraryelements/libraryelements_test.go +++ b/pkg/services/libraryelements/libraryelements_test.go @@ -14,9 +14,9 @@ import ( "github.com/stretchr/testify/require" "github.com/grafana/grafana/pkg/api/response" + "github.com/grafana/grafana/pkg/apimachinery/identity" "github.com/grafana/grafana/pkg/bus" "github.com/grafana/grafana/pkg/components/simplejson" - "github.com/grafana/grafana/pkg/infra/appcontext" "github.com/grafana/grafana/pkg/infra/db" "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/infra/tracing" @@ -331,7 +331,7 @@ func createFolder(t *testing.T, sc scenarioContext, title string) *folder.Folder folderStore := folderimpl.ProvideDashboardFolderStore(sc.sqlStore) s := folderimpl.ProvideService(ac, bus.ProvideBus(tracing.InitializeTracerForTest()), dashboardStore, folderStore, sc.sqlStore, features, supportbundlestest.NewFakeBundleService(), nil) t.Logf("Creating folder with title and UID %q", title) - ctx := appcontext.WithUser(context.Background(), &sc.user) + ctx := identity.WithRequester(context.Background(), &sc.user) folder, err := s.Create(ctx, &folder.CreateFolderCommand{ OrgID: sc.user.OrgID, Title: title, UID: title, SignedInUser: &sc.user, }) @@ -436,7 +436,7 @@ func testScenario(t *testing.T, desc string, fn func(t *testing.T, sc scenarioCo "Content-Type": []string{"application/json"}, }, } - ctx := appcontext.WithUser(context.Background(), &usr) + ctx := identity.WithRequester(context.Background(), &usr) req = req.WithContext(ctx) webCtx := web.Context{Req: req} diff --git a/pkg/services/librarypanels/librarypanels_test.go b/pkg/services/librarypanels/librarypanels_test.go index 76cb8bac97c..3ff533995e6 100644 --- a/pkg/services/librarypanels/librarypanels_test.go +++ b/pkg/services/librarypanels/librarypanels_test.go @@ -7,13 +7,10 @@ import ( "time" "github.com/google/go-cmp/cmp" - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "github.com/grafana/grafana/pkg/api/routing" + "github.com/grafana/grafana/pkg/apimachinery/identity" "github.com/grafana/grafana/pkg/bus" "github.com/grafana/grafana/pkg/components/simplejson" - "github.com/grafana/grafana/pkg/infra/appcontext" "github.com/grafana/grafana/pkg/infra/db" "github.com/grafana/grafana/pkg/infra/slugify" "github.com/grafana/grafana/pkg/infra/tracing" @@ -40,6 +37,8 @@ import ( "github.com/grafana/grafana/pkg/services/user/userimpl" "github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/tests/testsuite" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" ) const userInDbName = "user_in_db" @@ -757,7 +756,7 @@ func createFolder(t *testing.T, sc scenarioContext, title string) *folder.Folder s := folderimpl.ProvideService(ac, bus.ProvideBus(tracing.InitializeTracerForTest()), dashboardStore, folderStore, sc.sqlStore, features, supportbundlestest.NewFakeBundleService(), nil) t.Logf("Creating folder with title and UID %q", title) - ctx := appcontext.WithUser(context.Background(), sc.user) + ctx := identity.WithRequester(context.Background(), sc.user) folder, err := s.Create(ctx, &folder.CreateFolderCommand{OrgID: sc.user.OrgID, Title: title, UID: title, SignedInUser: sc.user}) require.NoError(t, err) @@ -871,7 +870,7 @@ func testScenario(t *testing.T, desc string, fn func(t *testing.T, sc scenarioCo Name: "User In DB", Login: userInDbName, } - ctx := appcontext.WithUser(context.Background(), usr) + ctx := identity.WithRequester(context.Background(), usr) orgSvc, err := orgimpl.ProvideService(sqlStore, cfg, quotaService) require.NoError(t, err) usrSvc, err := userimpl.ProvideService( diff --git a/pkg/services/ngalert/tests/util.go b/pkg/services/ngalert/tests/util.go index 0a7f69409c8..5080e2e3d5d 100644 --- a/pkg/services/ngalert/tests/util.go +++ b/pkg/services/ngalert/tests/util.go @@ -12,8 +12,8 @@ import ( "github.com/stretchr/testify/require" "github.com/grafana/grafana/pkg/api/routing" + "github.com/grafana/grafana/pkg/apimachinery/identity" "github.com/grafana/grafana/pkg/bus" - "github.com/grafana/grafana/pkg/infra/appcontext" "github.com/grafana/grafana/pkg/infra/db" "github.com/grafana/grafana/pkg/infra/httpclient" "github.com/grafana/grafana/pkg/infra/kvstore" @@ -100,7 +100,7 @@ func CreateTestAlertRuleWithLabels(t testing.TB, ctx context.Context, dbstore *s IsGrafanaAdmin: true, } - ctx = appcontext.WithUser(ctx, user) + ctx = identity.WithRequester(ctx, user) _, err := dbstore.FolderService.Create(ctx, &folder.CreateFolderCommand{OrgID: orgID, Title: "FOLDER-" + util.GenerateShortUID(), UID: folderUID, SignedInUser: user}) // var foldr *folder.Folder if errors.Is(err, dashboards.ErrFolderWithSameUIDExists) || errors.Is(err, dashboards.ErrFolderVersionMismatch) { diff --git a/pkg/services/store/entity/tests/common_test.go b/pkg/services/store/entity/tests/common_test.go index ffdaa62a876..191baf7dfe8 100644 --- a/pkg/services/store/entity/tests/common_test.go +++ b/pkg/services/store/entity/tests/common_test.go @@ -4,11 +4,11 @@ import ( "context" "testing" + "github.com/grafana/grafana/pkg/apimachinery/identity" "github.com/grafana/grafana/pkg/infra/tracing" "github.com/stretchr/testify/require" "github.com/grafana/grafana/pkg/components/satokengen" - "github.com/grafana/grafana/pkg/infra/appcontext" "github.com/grafana/grafana/pkg/server" "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/org" @@ -99,6 +99,6 @@ func createTestContext(t *testing.T) testContext { authToken: authToken, client: client, user: serviceAccountUser, - ctx: appcontext.WithUser(context.Background(), serviceAccountUser), + ctx: identity.WithRequester(context.Background(), serviceAccountUser), } } diff --git a/pkg/services/store/entity/tests/server_integration_test.go b/pkg/services/store/entity/tests/server_integration_test.go index 6afe43b3173..1cb9d486dda 100644 --- a/pkg/services/store/entity/tests/server_integration_test.go +++ b/pkg/services/store/entity/tests/server_integration_test.go @@ -10,7 +10,7 @@ import ( "github.com/stretchr/testify/require" - "github.com/grafana/grafana/pkg/infra/appcontext" + "github.com/grafana/grafana/pkg/apimachinery/identity" "github.com/grafana/grafana/pkg/services/store/entity" ) @@ -119,7 +119,7 @@ func TestIntegrationEntityServer(t *testing.T) { } testCtx := createTestContext(t) - ctx := appcontext.WithUser(testCtx.ctx, testCtx.user) + ctx := identity.WithRequester(testCtx.ctx, testCtx.user) fakeUser := testCtx.user.GetUID().String() firstVersion := int64(0) diff --git a/pkg/services/store/resolver/service_test.go b/pkg/services/store/resolver/service_test.go index c62356b50f0..3bc23b5979f 100644 --- a/pkg/services/store/resolver/service_test.go +++ b/pkg/services/store/resolver/service_test.go @@ -6,7 +6,7 @@ import ( "github.com/stretchr/testify/require" - "github.com/grafana/grafana/pkg/infra/appcontext" + "github.com/grafana/grafana/pkg/apimachinery/identity" "github.com/grafana/grafana/pkg/services/datasources" fakeDatasources "github.com/grafana/grafana/pkg/services/datasources/fakes" "github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore" @@ -15,7 +15,7 @@ import ( ) func TestResolver(t *testing.T) { - ctxOrg1 := appcontext.WithUser(context.Background(), &user.SignedInUser{OrgID: 1}) + ctxOrg1 := identity.WithRequester(context.Background(), &user.SignedInUser{OrgID: 1}) ds := &fakeDatasources.FakeDataSourceService{ DataSources: []*datasources.DataSource{ diff --git a/pkg/util/testutil/context.go b/pkg/util/testutil/context.go index 74bec2b95b4..1f64326ff5a 100644 --- a/pkg/util/testutil/context.go +++ b/pkg/util/testutil/context.go @@ -6,7 +6,7 @@ import ( "github.com/stretchr/testify/require" - "github.com/grafana/grafana/pkg/infra/appcontext" + "github.com/grafana/grafana/pkg/apimachinery/identity" "github.com/grafana/grafana/pkg/services/user" ) @@ -105,7 +105,7 @@ func (f testContextFunc) CancelCause(err error) { } func (f testContextFunc) WithUser(usr *user.SignedInUser) TestContext { - ctx := appcontext.WithUser(f, usr) + ctx := identity.WithRequester(f, usr) return testContextFunc(func() (context.Context, context.CancelFunc, context.CancelCauseFunc) { return ctx, f.Cancel, f.CancelCause