Auth: Update unified storage to depend on AuthInfo rather than Requester (#91783)

depend on authlib user info
pull/91682/head
Ryan McKinley 11 months ago committed by GitHub
parent 21d4a4f49e
commit e106df6d0b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 10
      pkg/storage/unified/resource/hooks.go
  2. 22
      pkg/storage/unified/resource/server.go
  3. 9
      pkg/storage/unified/resource/server_test.go

@ -4,16 +4,16 @@ import (
context "context"
"fmt"
"github.com/grafana/grafana/pkg/apimachinery/identity"
"github.com/grafana/authlib/claims"
)
type WriteAccessHooks struct {
// Check if a user has access to write folders
// When this is nil, no resources can have folders configured
Folder func(ctx context.Context, user identity.Requester, uid string) bool
Folder func(ctx context.Context, user claims.AuthInfo, uid string) bool
// When configured, this will make sure a user is allowed to save to a given origin
Origin func(ctx context.Context, user identity.Requester, origin string) bool
Origin func(ctx context.Context, user claims.AuthInfo, origin string) bool
}
type LifecycleHooks interface {
@ -24,7 +24,7 @@ type LifecycleHooks interface {
Stop(context.Context) error
}
func (a *WriteAccessHooks) CanWriteFolder(ctx context.Context, user identity.Requester, uid string) error {
func (a *WriteAccessHooks) CanWriteFolder(ctx context.Context, user claims.AuthInfo, uid string) error {
if a.Folder == nil {
return fmt.Errorf("writing folders is not supported")
}
@ -34,7 +34,7 @@ func (a *WriteAccessHooks) CanWriteFolder(ctx context.Context, user identity.Req
return nil
}
func (a *WriteAccessHooks) CanWriteOrigin(ctx context.Context, user identity.Requester, uid string) error {
func (a *WriteAccessHooks) CanWriteOrigin(ctx context.Context, user claims.AuthInfo, uid string) error {
if a.Origin == nil || uid == "UI" {
return nil // default to OK
}

@ -121,7 +121,7 @@ func NewResourceServer(opts ResourceServerOptions) (ResourceServer, error) {
}
// Make this cancelable
ctx, cancel := context.WithCancel(identity.WithRequester(context.Background(),
ctx, cancel := context.WithCancel(claims.WithClaims(context.Background(),
&identity.StaticRequester{
Type: claims.TypeServiceAccount,
Login: "watcher", // admin user for watch
@ -212,7 +212,7 @@ func (s *server) Stop(ctx context.Context) error {
}
// Old value indicates an update -- otherwise a create
func (s *server) newEvent(ctx context.Context, user identity.Requester, key *ResourceKey, value, oldValue []byte) (*WriteEvent, *ErrorResult) {
func (s *server) newEvent(ctx context.Context, user claims.AuthInfo, key *ResourceKey, value, oldValue []byte) (*WriteEvent, *ErrorResult) {
tmp := &unstructured.Unstructured{}
err := tmp.UnmarshalJSON(value)
if err != nil {
@ -304,8 +304,8 @@ func (s *server) Create(ctx context.Context, req *CreateRequest) (*CreateRespons
}
rsp := &CreateResponse{}
user, err := identity.GetRequester(ctx)
if err != nil || user == nil {
user, ok := claims.From(ctx)
if !ok || user == nil {
rsp.Error = &ErrorResult{
Message: "no user found in context",
Code: http.StatusUnauthorized,
@ -328,6 +328,7 @@ func (s *server) Create(ctx context.Context, req *CreateRequest) (*CreateRespons
return rsp, nil
}
var err error
rsp.ResourceVersion, err = s.backend.WriteEvent(ctx, *event)
if err != nil {
rsp.Error = AsErrorResult(err)
@ -344,8 +345,8 @@ func (s *server) Update(ctx context.Context, req *UpdateRequest) (*UpdateRespons
}
rsp := &UpdateResponse{}
user, err := identity.GetRequester(ctx)
if err != nil || user == nil {
user, ok := claims.From(ctx)
if !ok || user == nil {
rsp.Error = &ErrorResult{
Message: "no user found in context",
Code: http.StatusUnauthorized,
@ -375,12 +376,13 @@ func (s *server) Update(ctx context.Context, req *UpdateRequest) (*UpdateRespons
event, e := s.newEvent(ctx, user, req.Key, req.Value, latest.Value)
if e != nil {
rsp.Error = e
return rsp, err
return rsp, nil
}
event.Type = WatchEvent_MODIFIED
event.PreviousRV = latest.ResourceVersion
var err error
rsp.ResourceVersion, err = s.backend.WriteEvent(ctx, *event)
if err != nil {
rsp.Error = AsErrorResult(err)
@ -419,12 +421,12 @@ func (s *server) Delete(ctx context.Context, req *DeleteRequest) (*DeleteRespons
Type: WatchEvent_DELETED,
PreviousRV: latest.ResourceVersion,
}
requester, err := identity.GetRequester(ctx)
if err != nil {
requester, ok := claims.From(ctx)
if !ok {
return nil, apierrors.NewBadRequest("unable to get user")
}
marker := &DeletedMarker{}
err = json.Unmarshal(latest.Value, marker)
err := json.Unmarshal(latest.Value, marker)
if err != nil {
return nil, apierrors.NewBadRequest(
fmt.Sprintf("unable to read previous object, %v", err))

@ -8,14 +8,13 @@ import (
"testing"
"time"
"github.com/grafana/authlib/claims"
"github.com/grafana/grafana/pkg/apimachinery/identity"
"github.com/grafana/grafana/pkg/apimachinery/utils"
"github.com/stretchr/testify/require"
"gocloud.dev/blob/fileblob"
"gocloud.dev/blob/memblob"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"github.com/grafana/authlib/claims"
"github.com/grafana/grafana/pkg/apimachinery/identity"
"github.com/grafana/grafana/pkg/apimachinery/utils"
)
func TestSimpleServer(t *testing.T) {
@ -27,7 +26,7 @@ func TestSimpleServer(t *testing.T) {
OrgRole: identity.RoleAdmin,
IsGrafanaAdmin: true, // can do anything
}
ctx := identity.WithRequester(context.Background(), testUserA)
ctx := claims.WithClaims(context.Background(), testUserA)
bucket := memblob.OpenBucket(nil)
if false {

Loading…
Cancel
Save