grafana/pkg/infra/appcontext/user.go
2024-06-20 17:53:07 +03:00

80 lines
2.5 KiB
Go

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
}