Authlib: Use types package rather than claims (#99243)
This commit is contained in:
@@ -14,7 +14,7 @@ exclude k8s.io/client-go v12.0.0+incompatible
|
||||
require (
|
||||
github.com/bwmarrin/snowflake v0.3.0
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/grafana/authlib/claims v0.0.0-20241202085737-df90af04f335
|
||||
github.com/grafana/authlib/types v0.0.0-20250120145936-5f0e28e7a87c
|
||||
github.com/grafana/grafana v0.0.0-00010101000000-000000000000
|
||||
github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240821155123-6891eb1d35da
|
||||
github.com/grafana/grafana/pkg/apiserver v0.0.0-20240821155123-6891eb1d35da
|
||||
@@ -171,7 +171,7 @@ require (
|
||||
github.com/googleapis/gax-go/v2 v2.14.1 // indirect
|
||||
github.com/gorilla/mux v1.8.1 // indirect
|
||||
github.com/grafana/alerting v0.0.0-20250115195200-209e052dba64 // indirect
|
||||
github.com/grafana/authlib v0.0.0-20250108202437-7a039176d884 // indirect
|
||||
github.com/grafana/authlib v0.0.0-20250120145936-5f0e28e7a87c // indirect
|
||||
github.com/grafana/dataplane/sdata v0.0.9 // indirect
|
||||
github.com/grafana/dskit v0.0.0-20241105154643-a6b453a88040 // indirect
|
||||
github.com/grafana/grafana-app-sdk/logging v0.29.0 // indirect
|
||||
|
||||
@@ -547,10 +547,10 @@ github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aN
|
||||
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/grafana/alerting v0.0.0-20250115195200-209e052dba64 h1:OrFa8vDe7iFMasag7cbaqiTZQ+9Nhy3WRZUhGU8MJAw=
|
||||
github.com/grafana/alerting v0.0.0-20250115195200-209e052dba64/go.mod h1:QsnoKX/iYZxA4Cv+H+wC7uxutBD8qi8ZW5UJvD2TYmU=
|
||||
github.com/grafana/authlib v0.0.0-20250108202437-7a039176d884 h1:MSRBiQrSJZ+iowjU4Tgtq8+uC5/cs9XdtUdSWCNHrNE=
|
||||
github.com/grafana/authlib v0.0.0-20250108202437-7a039176d884/go.mod h1:x7df73G3xuSD35Xv9cjaMLyPJCgM9Z/Wj5ISouoAfiI=
|
||||
github.com/grafana/authlib/claims v0.0.0-20241202085737-df90af04f335 h1:3DHH81RJCi8Bcgn2MdBh7vgWUshmAFjZzBCVuxiQ0uk=
|
||||
github.com/grafana/authlib/claims v0.0.0-20241202085737-df90af04f335/go.mod h1:r+F8H6awwjNQt/KPZ2GNwjk8TvsJ7/gxzkXN26GlL/A=
|
||||
github.com/grafana/authlib v0.0.0-20250120145936-5f0e28e7a87c h1:duHQ8Bih3nt9p68aQdp+22a6mFBLpK4IOURhEq+Cvk8=
|
||||
github.com/grafana/authlib v0.0.0-20250120145936-5f0e28e7a87c/go.mod h1:/gYfphsNu9v1qYWXxpv1NSvMEMSwvdf8qb8YlgwIRl8=
|
||||
github.com/grafana/authlib/types v0.0.0-20250120145936-5f0e28e7a87c h1:b0sPDtt33uFdmvUJjSCld3kwE2E49dUvevuUDSJsEuo=
|
||||
github.com/grafana/authlib/types v0.0.0-20250120145936-5f0e28e7a87c/go.mod h1:qYjSd1tmJiuVoSICp7Py9/zD54O9uQQA3wuM6Gg4DFM=
|
||||
github.com/grafana/dataplane/examples v0.0.1 h1:K9M5glueWyLoL4//H+EtTQq16lXuHLmOhb6DjSCahzA=
|
||||
github.com/grafana/dataplane/examples v0.0.1/go.mod h1:h5YwY8s407/17XF5/dS8XrUtsTVV2RnuW8+m1Mp46mg=
|
||||
github.com/grafana/dataplane/sdata v0.0.9 h1:AGL1LZnCUG4MnQtnWpBPbQ8ZpptaZs14w6kE/MWfg7s=
|
||||
|
||||
@@ -20,7 +20,7 @@ import (
|
||||
examplev1 "k8s.io/apiserver/pkg/apis/example/v1"
|
||||
"k8s.io/apiserver/pkg/storage"
|
||||
|
||||
"github.com/grafana/authlib/claims"
|
||||
claims "github.com/grafana/authlib/types"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
storagetesting "github.com/grafana/grafana/pkg/apiserver/storage/testing"
|
||||
)
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
|
||||
authnlib "github.com/grafana/authlib/authn"
|
||||
"github.com/grafana/authlib/authz"
|
||||
"github.com/grafana/authlib/types"
|
||||
|
||||
infraDB "github.com/grafana/grafana/pkg/infra/db"
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
@@ -35,7 +35,7 @@ func ProvideUnifiedStorageClient(
|
||||
db infraDB.DB,
|
||||
tracer tracing.Tracer,
|
||||
reg prometheus.Registerer,
|
||||
authzc authz.AccessClient,
|
||||
authzc types.AccessClient,
|
||||
docs resource.DocumentBuilderSupplier,
|
||||
) (resource.ResourceClient, error) {
|
||||
// See: apiserver.ApplyGrafanaConfig(cfg, features, o)
|
||||
@@ -62,7 +62,7 @@ func newClient(opts options.StorageOptions,
|
||||
db infraDB.DB,
|
||||
tracer tracing.Tracer,
|
||||
reg prometheus.Registerer,
|
||||
authzc authz.AccessClient,
|
||||
authzc types.AccessClient,
|
||||
docs resource.DocumentBuilderSupplier,
|
||||
) (resource.ResourceClient, error) {
|
||||
ctx := context.Background()
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/grafana/authlib/claims"
|
||||
claims "github.com/grafana/authlib/types"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||
"github.com/grafana/grafana/pkg/storage/legacysql"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/resource"
|
||||
|
||||
@@ -7,34 +7,16 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/authlib/authz"
|
||||
"github.com/grafana/authlib/claims"
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
"github.com/grafana/grafana/pkg/services/authn/grpcutils"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
"go.opentelemetry.io/otel/trace/noop"
|
||||
|
||||
claims "github.com/grafana/authlib/types"
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
"github.com/grafana/grafana/pkg/services/authn/grpcutils"
|
||||
)
|
||||
|
||||
type staticAuthzClient struct {
|
||||
allowed bool
|
||||
}
|
||||
|
||||
// Check implements authz.AccessClient.
|
||||
func (c *staticAuthzClient) Check(ctx context.Context, id claims.AuthInfo, req authz.CheckRequest) (authz.CheckResponse, error) {
|
||||
return authz.CheckResponse{Allowed: c.allowed}, nil
|
||||
}
|
||||
|
||||
// Compile implements authz.AccessClient.
|
||||
func (c *staticAuthzClient) Compile(ctx context.Context, id claims.AuthInfo, req authz.ListRequest) (authz.ItemChecker, error) {
|
||||
return func(namespace string, name, folder string) bool {
|
||||
return c.allowed
|
||||
}, nil
|
||||
}
|
||||
|
||||
var _ authz.AccessClient = &staticAuthzClient{}
|
||||
|
||||
type groupResource map[string]map[string]interface{}
|
||||
|
||||
const (
|
||||
@@ -91,7 +73,7 @@ func newMetrics(reg prometheus.Registerer) *accessMetrics {
|
||||
// The authz service will be responsible for enforcing RBAC.
|
||||
// For now, it makes one call to the authz service for each list items. This is known to be inefficient.
|
||||
type authzLimitedClient struct {
|
||||
client authz.AccessClient
|
||||
client claims.AccessClient
|
||||
// allowlist is a map of group to resources that are compatible with RBAC.
|
||||
allowlist groupResource
|
||||
logger *slog.Logger
|
||||
@@ -105,7 +87,7 @@ type AuthzOptions struct {
|
||||
}
|
||||
|
||||
// NewAuthzLimitedClient creates a new authzLimitedClient.
|
||||
func NewAuthzLimitedClient(client authz.AccessClient, opts AuthzOptions) authz.AccessClient {
|
||||
func NewAuthzLimitedClient(client claims.AccessClient, opts AuthzOptions) claims.AccessClient {
|
||||
logger := slog.Default().With("logger", "limited-authz-client")
|
||||
if opts.Tracer == nil {
|
||||
opts.Tracer = noop.NewTracerProvider().Tracer("limited-authz-client")
|
||||
@@ -125,8 +107,8 @@ func NewAuthzLimitedClient(client authz.AccessClient, opts AuthzOptions) authz.A
|
||||
}
|
||||
}
|
||||
|
||||
// Check implements authz.AccessClient.
|
||||
func (c authzLimitedClient) Check(ctx context.Context, id claims.AuthInfo, req authz.CheckRequest) (authz.CheckResponse, error) {
|
||||
// Check implements claims.AccessClient.
|
||||
func (c authzLimitedClient) Check(ctx context.Context, id claims.AuthInfo, req claims.CheckRequest) (claims.CheckResponse, error) {
|
||||
t := time.Now()
|
||||
ctx, span := c.tracer.Start(ctx, "authzLimitedClient.Check", trace.WithAttributes(
|
||||
attribute.String("group", req.Group),
|
||||
@@ -140,11 +122,11 @@ func (c authzLimitedClient) Check(ctx context.Context, id claims.AuthInfo, req a
|
||||
defer span.End()
|
||||
if grpcutils.FallbackUsed(ctx) {
|
||||
span.SetAttributes(attribute.Bool("allowed", true))
|
||||
return authz.CheckResponse{Allowed: true}, nil
|
||||
return claims.CheckResponse{Allowed: true}, nil
|
||||
}
|
||||
if !c.IsCompatibleWithRBAC(req.Group, req.Resource) {
|
||||
span.SetAttributes(attribute.Bool("allowed", true))
|
||||
return authz.CheckResponse{Allowed: true}, nil
|
||||
return claims.CheckResponse{Allowed: true}, nil
|
||||
}
|
||||
resp, err := c.client.Check(ctx, id, req)
|
||||
if err != nil {
|
||||
@@ -158,8 +140,8 @@ func (c authzLimitedClient) Check(ctx context.Context, id claims.AuthInfo, req a
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// Compile implements authz.AccessClient.
|
||||
func (c authzLimitedClient) Compile(ctx context.Context, id claims.AuthInfo, req authz.ListRequest) (authz.ItemChecker, error) {
|
||||
// Compile implements claims.AccessClient.
|
||||
func (c authzLimitedClient) Compile(ctx context.Context, id claims.AuthInfo, req claims.ListRequest) (claims.ItemChecker, error) {
|
||||
t := time.Now()
|
||||
fallbackUsed := grpcutils.FallbackUsed(ctx)
|
||||
ctx, span := c.tracer.Start(ctx, "authzLimitedClient.Compile", trace.WithAttributes(
|
||||
@@ -195,4 +177,4 @@ func (c authzLimitedClient) IsCompatibleWithRBAC(group, resource string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
var _ authz.AccessClient = &authzLimitedClient{}
|
||||
var _ claims.AccessClient = &authzLimitedClient{}
|
||||
|
||||
@@ -4,12 +4,13 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/authlib/authz"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
authlib "github.com/grafana/authlib/types"
|
||||
)
|
||||
|
||||
func TestAuthzLimitedClient_Check(t *testing.T) {
|
||||
mockClient := &staticAuthzClient{allowed: false}
|
||||
mockClient := authlib.FixedAccessClient(false)
|
||||
client := NewAuthzLimitedClient(mockClient, AuthzOptions{})
|
||||
|
||||
tests := []struct {
|
||||
@@ -23,7 +24,7 @@ func TestAuthzLimitedClient_Check(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
req := authz.CheckRequest{
|
||||
req := authlib.CheckRequest{
|
||||
Group: test.group,
|
||||
Resource: test.resource,
|
||||
}
|
||||
@@ -34,7 +35,7 @@ func TestAuthzLimitedClient_Check(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestAuthzLimitedClient_Compile(t *testing.T) {
|
||||
mockClient := &staticAuthzClient{allowed: false}
|
||||
mockClient := authlib.FixedAccessClient(false)
|
||||
client := NewAuthzLimitedClient(mockClient, AuthzOptions{})
|
||||
|
||||
tests := []struct {
|
||||
@@ -48,7 +49,7 @@ func TestAuthzLimitedClient_Compile(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
req := authz.ListRequest{
|
||||
req := authlib.ListRequest{
|
||||
Group: test.group,
|
||||
Resource: test.resource,
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
"google.golang.org/grpc"
|
||||
|
||||
authnlib "github.com/grafana/authlib/authn"
|
||||
"github.com/grafana/authlib/claims"
|
||||
claims "github.com/grafana/authlib/types"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
"github.com/grafana/grafana/pkg/services/authn/grpcutils"
|
||||
@@ -132,7 +132,7 @@ func NewCloudResourceClient(tracer tracing.Tracer, conn *grpc.ClientConn, cfg au
|
||||
}
|
||||
|
||||
func idTokenExtractor(ctx context.Context) (string, error) {
|
||||
authInfo, ok := claims.From(ctx)
|
||||
authInfo, ok := claims.AuthInfoFrom(ctx)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("no claims found")
|
||||
}
|
||||
|
||||
@@ -4,9 +4,10 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/authlib/claims"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
claims "github.com/grafana/authlib/types"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
)
|
||||
|
||||
func TestIDTokenExtractor(t *testing.T) {
|
||||
|
||||
@@ -11,8 +11,8 @@ replace (
|
||||
require (
|
||||
github.com/fullstorydev/grpchan v1.1.1
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/grafana/authlib v0.0.0-20250108202437-7a039176d884
|
||||
github.com/grafana/authlib/claims v0.0.0-20241202085737-df90af04f335
|
||||
github.com/grafana/authlib v0.0.0-20250120145936-5f0e28e7a87c
|
||||
github.com/grafana/authlib/types v0.0.0-20250120145936-5f0e28e7a87c
|
||||
github.com/grafana/dskit v0.0.0-20241105154643-a6b453a88040
|
||||
github.com/grafana/grafana v0.0.0-00010101000000-000000000000
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.262.0
|
||||
@@ -109,7 +109,6 @@ require (
|
||||
github.com/google/flatbuffers v24.3.25+incompatible // indirect
|
||||
github.com/google/gnostic-models v0.6.8 // indirect
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/google/go-querystring v1.1.0 // indirect
|
||||
github.com/google/gofuzz v1.2.0 // indirect
|
||||
github.com/google/s2a-go v0.1.8 // indirect
|
||||
github.com/google/wire v0.6.0 // indirect
|
||||
|
||||
@@ -364,7 +364,6 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
@@ -372,8 +371,6 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
||||
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
||||
github.com/google/go-replayers/grpcreplay v1.3.0 h1:1Keyy0m1sIpqstQmgz307zhiJ1pV4uIlFds5weTmxbo=
|
||||
github.com/google/go-replayers/grpcreplay v1.3.0/go.mod h1:v6NgKtkijC0d3e3RW8il6Sy5sqRVUwoQa4mHOGEy8DI=
|
||||
github.com/google/go-replayers/httpreplay v1.2.0 h1:VM1wEyyjaoU53BwrOnaf9VhAyQQEEioJvFYxYcLRKzk=
|
||||
@@ -408,10 +405,10 @@ github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
|
||||
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
|
||||
github.com/grafana/alerting v0.0.0-20250115195200-209e052dba64 h1:OrFa8vDe7iFMasag7cbaqiTZQ+9Nhy3WRZUhGU8MJAw=
|
||||
github.com/grafana/alerting v0.0.0-20250115195200-209e052dba64/go.mod h1:QsnoKX/iYZxA4Cv+H+wC7uxutBD8qi8ZW5UJvD2TYmU=
|
||||
github.com/grafana/authlib v0.0.0-20250108202437-7a039176d884 h1:MSRBiQrSJZ+iowjU4Tgtq8+uC5/cs9XdtUdSWCNHrNE=
|
||||
github.com/grafana/authlib v0.0.0-20250108202437-7a039176d884/go.mod h1:x7df73G3xuSD35Xv9cjaMLyPJCgM9Z/Wj5ISouoAfiI=
|
||||
github.com/grafana/authlib/claims v0.0.0-20241202085737-df90af04f335 h1:3DHH81RJCi8Bcgn2MdBh7vgWUshmAFjZzBCVuxiQ0uk=
|
||||
github.com/grafana/authlib/claims v0.0.0-20241202085737-df90af04f335/go.mod h1:r+F8H6awwjNQt/KPZ2GNwjk8TvsJ7/gxzkXN26GlL/A=
|
||||
github.com/grafana/authlib v0.0.0-20250120145936-5f0e28e7a87c h1:duHQ8Bih3nt9p68aQdp+22a6mFBLpK4IOURhEq+Cvk8=
|
||||
github.com/grafana/authlib v0.0.0-20250120145936-5f0e28e7a87c/go.mod h1:/gYfphsNu9v1qYWXxpv1NSvMEMSwvdf8qb8YlgwIRl8=
|
||||
github.com/grafana/authlib/types v0.0.0-20250120145936-5f0e28e7a87c h1:b0sPDtt33uFdmvUJjSCld3kwE2E49dUvevuUDSJsEuo=
|
||||
github.com/grafana/authlib/types v0.0.0-20250120145936-5f0e28e7a87c/go.mod h1:qYjSd1tmJiuVoSICp7Py9/zD54O9uQQA3wuM6Gg4DFM=
|
||||
github.com/grafana/dataplane/sdata v0.0.9 h1:AGL1LZnCUG4MnQtnWpBPbQ8ZpptaZs14w6kE/MWfg7s=
|
||||
github.com/grafana/dataplane/sdata v0.0.9/go.mod h1:Jvs5ddpGmn6vcxT7tCTWAZ1mgi4sbcdFt9utQx5uMAU=
|
||||
github.com/grafana/dskit v0.0.0-20241105154643-a6b453a88040 h1:IR+UNYHqaU31t8/TArJk8K/GlDwOyxMpGNkWCXeZ28g=
|
||||
|
||||
@@ -9,8 +9,7 @@ import (
|
||||
"google.golang.org/grpc/metadata"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
authClaims "github.com/grafana/authlib/claims"
|
||||
|
||||
"github.com/grafana/authlib/types"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
)
|
||||
@@ -74,7 +73,7 @@ func (f *Authenticator) decodeMetadata(meta metadata.MD) (identity.Requester, er
|
||||
// TODO, remove after this has been deployed to unified storage
|
||||
if getter(mdUserID) == "" {
|
||||
var err error
|
||||
user.Type = authClaims.TypeUser
|
||||
user.Type = types.TypeUser
|
||||
user.UserID, err = strconv.ParseInt(getter("grafana-userid"), 10, 64)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Unauthenticated, "invalid user id")
|
||||
@@ -86,7 +85,7 @@ func (f *Authenticator) decodeMetadata(meta metadata.MD) (identity.Requester, er
|
||||
return user, nil
|
||||
}
|
||||
|
||||
typ, id, err := authClaims.ParseTypeID(getter(mdUserID))
|
||||
typ, id, err := types.ParseTypeID(getter(mdUserID))
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Unauthenticated, "invalid user id")
|
||||
}
|
||||
@@ -96,7 +95,7 @@ func (f *Authenticator) decodeMetadata(meta metadata.MD) (identity.Requester, er
|
||||
return nil, status.Error(codes.Unauthenticated, "invalid user id")
|
||||
}
|
||||
|
||||
_, uid, err := authClaims.ParseTypeID(getter(mdUserUID))
|
||||
_, uid, err := types.ParseTypeID(getter(mdUserUID))
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Unauthenticated, "invalid user uid")
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/authlib/claims"
|
||||
claims "github.com/grafana/authlib/types"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
)
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
context "context"
|
||||
"fmt"
|
||||
|
||||
"github.com/grafana/authlib/claims"
|
||||
claims "github.com/grafana/authlib/types"
|
||||
)
|
||||
|
||||
type WriteAccessHooks struct {
|
||||
|
||||
@@ -16,7 +16,7 @@ import (
|
||||
"golang.org/x/sync/errgroup"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
||||
"github.com/grafana/authlib/authz"
|
||||
"github.com/grafana/authlib/types"
|
||||
)
|
||||
|
||||
type NamespacedResource struct {
|
||||
@@ -42,7 +42,7 @@ type ResourceIndex interface {
|
||||
|
||||
// Search within a namespaced resource
|
||||
// When working with federated queries, the additional indexes will be passed in explicitly
|
||||
Search(ctx context.Context, access authz.AccessClient, req *ResourceSearchRequest, federate []ResourceIndex) (*ResourceSearchResponse, error)
|
||||
Search(ctx context.Context, access types.AccessClient, req *ResourceSearchRequest, federate []ResourceIndex) (*ResourceSearchResponse, error)
|
||||
|
||||
// List within an response
|
||||
ListRepositoryObjects(ctx context.Context, req *ListRepositoryObjectsRequest) (*ListRepositoryObjectsResponse, error)
|
||||
@@ -89,7 +89,7 @@ type searchSupport struct {
|
||||
log *slog.Logger
|
||||
storage StorageBackend
|
||||
search SearchBackend
|
||||
access authz.AccessClient
|
||||
access types.AccessClient
|
||||
builders *builderCache
|
||||
initWorkers int
|
||||
initMinSize int
|
||||
@@ -100,7 +100,7 @@ var (
|
||||
_ RepositoryIndexServer = (*searchSupport)(nil)
|
||||
)
|
||||
|
||||
func newSearchSupport(opts SearchOptions, storage StorageBackend, access authz.AccessClient, blob BlobSupport, tracer trace.Tracer) (support *searchSupport, err error) {
|
||||
func newSearchSupport(opts SearchOptions, storage StorageBackend, access types.AccessClient, blob BlobSupport, tracer trace.Tracer) (support *searchSupport, err error) {
|
||||
// No backend search support
|
||||
if opts.Backend == nil {
|
||||
return nil, nil
|
||||
|
||||
@@ -19,8 +19,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
|
||||
"github.com/grafana/authlib/authz"
|
||||
"github.com/grafana/authlib/claims"
|
||||
claims "github.com/grafana/authlib/types"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
||||
)
|
||||
@@ -170,7 +169,7 @@ type ResourceServerOptions struct {
|
||||
WriteHooks WriteAccessHooks
|
||||
|
||||
// Link RBAC
|
||||
AccessClient authz.AccessClient
|
||||
AccessClient claims.AccessClient
|
||||
|
||||
// Callbacks for startup and shutdown
|
||||
Lifecycle LifecycleHooks
|
||||
@@ -192,7 +191,7 @@ func NewResourceServer(opts ResourceServerOptions) (ResourceServer, error) {
|
||||
}
|
||||
|
||||
if opts.AccessClient == nil {
|
||||
opts.AccessClient = &staticAuthzClient{allowed: true} // everything OK
|
||||
opts.AccessClient = claims.FixedAccessClient(true) // everything OK
|
||||
}
|
||||
|
||||
if opts.Diagnostics == nil {
|
||||
@@ -234,7 +233,7 @@ func NewResourceServer(opts ResourceServerOptions) (ResourceServer, error) {
|
||||
}
|
||||
|
||||
// Make this cancelable
|
||||
ctx, cancel := context.WithCancel(claims.WithClaims(context.Background(),
|
||||
ctx, cancel := context.WithCancel(claims.WithAuthInfo(context.Background(),
|
||||
&identity.StaticRequester{
|
||||
Type: claims.TypeServiceAccount,
|
||||
Login: "watcher", // admin user for watch
|
||||
@@ -281,7 +280,7 @@ type server struct {
|
||||
blob BlobSupport
|
||||
search *searchSupport
|
||||
diagnostics DiagnosticsServer
|
||||
access authz.AccessClient
|
||||
access claims.AccessClient
|
||||
writeHooks WriteAccessHooks
|
||||
lifecycle LifecycleHooks
|
||||
now func() int64
|
||||
@@ -378,7 +377,7 @@ func (s *server) newEvent(ctx context.Context, user claims.AuthInfo, key *Resour
|
||||
}
|
||||
}
|
||||
|
||||
check := authz.CheckRequest{
|
||||
check := claims.CheckRequest{
|
||||
Verb: utils.VerbCreate,
|
||||
Group: key.Group,
|
||||
Resource: key.Resource,
|
||||
@@ -478,7 +477,7 @@ func (s *server) Create(ctx context.Context, req *CreateRequest) (*CreateRespons
|
||||
defer span.End()
|
||||
|
||||
rsp := &CreateResponse{}
|
||||
user, ok := claims.From(ctx)
|
||||
user, ok := claims.AuthInfoFrom(ctx)
|
||||
if !ok || user == nil {
|
||||
rsp.Error = &ErrorResult{
|
||||
Message: "no user found in context",
|
||||
@@ -516,7 +515,7 @@ func (s *server) Update(ctx context.Context, req *UpdateRequest) (*UpdateRespons
|
||||
defer span.End()
|
||||
|
||||
rsp := &UpdateResponse{}
|
||||
user, ok := claims.From(ctx)
|
||||
user, ok := claims.AuthInfoFrom(ctx)
|
||||
if !ok || user == nil {
|
||||
rsp.Error = &ErrorResult{
|
||||
Message: "no user found in context",
|
||||
@@ -569,7 +568,7 @@ func (s *server) Delete(ctx context.Context, req *DeleteRequest) (*DeleteRespons
|
||||
if req.ResourceVersion < 0 {
|
||||
return nil, apierrors.NewBadRequest("update must include the previous version")
|
||||
}
|
||||
user, ok := claims.From(ctx)
|
||||
user, ok := claims.AuthInfoFrom(ctx)
|
||||
if !ok || user == nil {
|
||||
rsp.Error = &ErrorResult{
|
||||
Message: "no user found in context",
|
||||
@@ -590,7 +589,7 @@ func (s *server) Delete(ctx context.Context, req *DeleteRequest) (*DeleteRespons
|
||||
return rsp, nil
|
||||
}
|
||||
|
||||
access, err := s.access.Check(ctx, user, authz.CheckRequest{
|
||||
access, err := s.access.Check(ctx, user, claims.CheckRequest{
|
||||
Verb: "delete",
|
||||
Group: req.Key.Group,
|
||||
Resource: req.Key.Resource,
|
||||
@@ -615,7 +614,7 @@ func (s *server) Delete(ctx context.Context, req *DeleteRequest) (*DeleteRespons
|
||||
Type: WatchEvent_DELETED,
|
||||
PreviousRV: latest.ResourceVersion,
|
||||
}
|
||||
requester, ok := claims.From(ctx)
|
||||
requester, ok := claims.AuthInfoFrom(ctx)
|
||||
if !ok {
|
||||
return nil, apierrors.NewBadRequest("unable to get user")
|
||||
}
|
||||
@@ -650,7 +649,7 @@ func (s *server) Delete(ctx context.Context, req *DeleteRequest) (*DeleteRespons
|
||||
}
|
||||
|
||||
func (s *server) Read(ctx context.Context, req *ReadRequest) (*ReadResponse, error) {
|
||||
user, ok := claims.From(ctx)
|
||||
user, ok := claims.AuthInfoFrom(ctx)
|
||||
if !ok || user == nil {
|
||||
return &ReadResponse{
|
||||
Error: &ErrorResult{
|
||||
@@ -669,7 +668,7 @@ func (s *server) Read(ctx context.Context, req *ReadRequest) (*ReadResponse, err
|
||||
|
||||
rsp := s.backend.ReadResource(ctx, req)
|
||||
|
||||
a, err := s.access.Check(ctx, user, authz.CheckRequest{
|
||||
a, err := s.access.Check(ctx, user, claims.CheckRequest{
|
||||
Verb: "get",
|
||||
Group: req.Key.Group,
|
||||
Resource: req.Key.Resource,
|
||||
@@ -706,7 +705,7 @@ func (s *server) List(ctx context.Context, req *ListRequest) (*ListResponse, err
|
||||
}
|
||||
}
|
||||
|
||||
user, ok := claims.From(ctx)
|
||||
user, ok := claims.AuthInfoFrom(ctx)
|
||||
if !ok || user == nil {
|
||||
return &ListResponse{
|
||||
Error: &ErrorResult{
|
||||
@@ -730,7 +729,7 @@ func (s *server) List(ctx context.Context, req *ListRequest) (*ListResponse, err
|
||||
rsp := &ListResponse{}
|
||||
|
||||
key := req.Options.Key
|
||||
checker, err := s.access.Compile(ctx, user, authz.ListRequest{
|
||||
checker, err := s.access.Compile(ctx, user, claims.ListRequest{
|
||||
Group: key.Group,
|
||||
Resource: key.Resource,
|
||||
Namespace: key.Namespace,
|
||||
@@ -793,7 +792,7 @@ func (s *server) Restore(ctx context.Context, req *RestoreRequest) (*RestoreResp
|
||||
defer span.End()
|
||||
|
||||
// check that the user has access
|
||||
user, ok := claims.From(ctx)
|
||||
user, ok := claims.AuthInfoFrom(ctx)
|
||||
if !ok || user == nil {
|
||||
return &RestoreResponse{
|
||||
Error: &ErrorResult{
|
||||
@@ -806,7 +805,7 @@ func (s *server) Restore(ctx context.Context, req *RestoreRequest) (*RestoreResp
|
||||
return nil, err
|
||||
}
|
||||
|
||||
checker, err := s.access.Compile(ctx, user, authz.ListRequest{
|
||||
checker, err := s.access.Compile(ctx, user, claims.ListRequest{
|
||||
Group: req.Key.Group,
|
||||
Resource: req.Key.Resource,
|
||||
Namespace: req.Key.Namespace,
|
||||
@@ -933,13 +932,13 @@ func (s *server) initWatcher() error {
|
||||
func (s *server) Watch(req *WatchRequest, srv ResourceStore_WatchServer) error {
|
||||
ctx := srv.Context()
|
||||
|
||||
user, ok := claims.From(ctx)
|
||||
user, ok := claims.AuthInfoFrom(ctx)
|
||||
if !ok || user == nil {
|
||||
return apierrors.NewUnauthorized("no user found in context")
|
||||
}
|
||||
|
||||
key := req.Options.Key
|
||||
checker, err := s.access.Compile(ctx, user, authz.ListRequest{
|
||||
checker, err := s.access.Compile(ctx, user, claims.ListRequest{
|
||||
Group: key.Group,
|
||||
Resource: key.Resource,
|
||||
Namespace: key.Namespace,
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
"gocloud.dev/blob/memblob"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
|
||||
"github.com/grafana/authlib/claims"
|
||||
claims "github.com/grafana/authlib/types"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
||||
)
|
||||
@@ -27,7 +27,7 @@ func TestSimpleServer(t *testing.T) {
|
||||
OrgRole: identity.RoleAdmin,
|
||||
IsGrafanaAdmin: true, // can do anything
|
||||
}
|
||||
ctx := claims.WithClaims(context.Background(), testUserA)
|
||||
ctx := claims.WithAuthInfo(context.Background(), testUserA)
|
||||
|
||||
bucket := memblob.OpenBucket(nil)
|
||||
if false {
|
||||
|
||||
@@ -18,14 +18,12 @@ import (
|
||||
"github.com/blevesearch/bleve/v2/search/query"
|
||||
bleveSearch "github.com/blevesearch/bleve/v2/search/searcher"
|
||||
index "github.com/blevesearch/bleve_index_api"
|
||||
"github.com/grafana/authlib/claims"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
"k8s.io/apimachinery/pkg/selection"
|
||||
|
||||
"github.com/grafana/authlib/authz"
|
||||
|
||||
authlib "github.com/grafana/authlib/types"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/resource"
|
||||
)
|
||||
|
||||
@@ -395,7 +393,7 @@ func (b *bleveIndex) CountRepositoryObjects(ctx context.Context) ([]*resource.Co
|
||||
// Search implements resource.DocumentIndex.
|
||||
func (b *bleveIndex) Search(
|
||||
ctx context.Context,
|
||||
access authz.AccessClient,
|
||||
access authlib.AccessClient,
|
||||
req *resource.ResourceSearchRequest,
|
||||
federate []resource.ResourceIndex, // For federated queries, these will match the values in req.federate
|
||||
) (*resource.ResourceSearchResponse, error) {
|
||||
@@ -521,7 +519,7 @@ func (b *bleveIndex) getIndex(
|
||||
return b.index, nil
|
||||
}
|
||||
|
||||
func (b *bleveIndex) toBleveSearchRequest(ctx context.Context, req *resource.ResourceSearchRequest, access authz.AccessClient) (*bleve.SearchRequest, *resource.ErrorResult) {
|
||||
func (b *bleveIndex) toBleveSearchRequest(ctx context.Context, req *resource.ResourceSearchRequest, access authlib.AccessClient) (*bleve.SearchRequest, *resource.ErrorResult) {
|
||||
facets := bleve.FacetsRequest{}
|
||||
for _, f := range req.Facet {
|
||||
facets[f.Field] = bleve.NewFacetRequest(f.Field, int(f.Limit))
|
||||
@@ -583,11 +581,11 @@ func (b *bleveIndex) toBleveSearchRequest(ctx context.Context, req *resource.Res
|
||||
|
||||
// Can we remove this? Is access ever nil?
|
||||
if access != nil {
|
||||
auth, ok := claims.From(ctx)
|
||||
auth, ok := authlib.AuthInfoFrom(ctx)
|
||||
if !ok {
|
||||
return nil, resource.AsErrorResult(fmt.Errorf("missing claims"))
|
||||
return nil, resource.AsErrorResult(fmt.Errorf("missing auth info"))
|
||||
}
|
||||
checker, err := access.Compile(ctx, auth, authz.ListRequest{
|
||||
checker, err := access.Compile(ctx, auth, authlib.ListRequest{
|
||||
Namespace: b.key.Namespace,
|
||||
Group: b.key.Group,
|
||||
Resource: b.key.Resource,
|
||||
@@ -596,13 +594,13 @@ func (b *bleveIndex) toBleveSearchRequest(ctx context.Context, req *resource.Res
|
||||
if err != nil {
|
||||
return nil, resource.AsErrorResult(err)
|
||||
}
|
||||
checkers := map[string]authz.ItemChecker{
|
||||
checkers := map[string]authlib.ItemChecker{
|
||||
b.key.Resource: checker,
|
||||
}
|
||||
|
||||
// handle federation
|
||||
for _, federated := range req.Federated {
|
||||
checker, err := access.Compile(ctx, auth, authz.ListRequest{
|
||||
checker, err := access.Compile(ctx, auth, authlib.ListRequest{
|
||||
Namespace: federated.Namespace,
|
||||
Group: federated.Group,
|
||||
Resource: federated.Resource,
|
||||
@@ -862,11 +860,11 @@ func newResponseFacet(v *search.FacetResult) *resource.ResourceSearchResponse_Fa
|
||||
|
||||
type permissionScopedQuery struct {
|
||||
query.Query
|
||||
checkers map[string]authz.ItemChecker // one checker per resource
|
||||
checkers map[string]authlib.ItemChecker // one checker per resource
|
||||
log log.Logger
|
||||
}
|
||||
|
||||
func newPermissionScopedQuery(q query.Query, checkers map[string]authz.ItemChecker) *permissionScopedQuery {
|
||||
func newPermissionScopedQuery(q query.Query, checkers map[string]authlib.ItemChecker) *permissionScopedQuery {
|
||||
return &permissionScopedQuery{
|
||||
Query: q,
|
||||
checkers: checkers,
|
||||
|
||||
@@ -9,13 +9,13 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/authlib/authz"
|
||||
"github.com/grafana/authlib/claims"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
authlib "github.com/grafana/authlib/types"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
authzextv1 "github.com/grafana/grafana/pkg/services/authz/proto/v1"
|
||||
"github.com/grafana/grafana/pkg/services/user"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
@@ -536,7 +536,7 @@ func asTimePointer(milli int64) *time.Time {
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ authz.AccessClient = (*StubAccessClient)(nil)
|
||||
var _ authlib.AccessClient = (*StubAccessClient)(nil)
|
||||
|
||||
func NewStubAccessClient(permissions map[string]bool) *StubAccessClient {
|
||||
return &StubAccessClient{resourceResponses: permissions}
|
||||
@@ -546,11 +546,11 @@ type StubAccessClient struct {
|
||||
resourceResponses map[string]bool // key is the resource name, and bool if what the checker will return
|
||||
}
|
||||
|
||||
func (nc *StubAccessClient) Check(ctx context.Context, id claims.AuthInfo, req authz.CheckRequest) (authz.CheckResponse, error) {
|
||||
return authz.CheckResponse{Allowed: nc.resourceResponses[req.Resource]}, nil
|
||||
func (nc *StubAccessClient) Check(ctx context.Context, id authlib.AuthInfo, req authlib.CheckRequest) (authlib.CheckResponse, error) {
|
||||
return authlib.CheckResponse{Allowed: nc.resourceResponses[req.Resource]}, nil
|
||||
}
|
||||
|
||||
func (nc *StubAccessClient) Compile(ctx context.Context, id claims.AuthInfo, req authz.ListRequest) (authz.ItemChecker, error) {
|
||||
func (nc *StubAccessClient) Compile(ctx context.Context, id authlib.AuthInfo, req authlib.ListRequest) (authlib.ItemChecker, error) {
|
||||
return func(namespace string, name, folder string) bool {
|
||||
return nc.resourceResponses[req.Resource]
|
||||
}, nil
|
||||
|
||||
@@ -3,7 +3,7 @@ package search
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/grafana/authlib/claims"
|
||||
claims "github.com/grafana/authlib/types"
|
||||
"github.com/grafana/grafana/pkg/infra/db"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/services/store/kind/dashboard"
|
||||
|
||||
@@ -7,23 +7,22 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/grafana/authlib/authz"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
|
||||
"github.com/grafana/grafana/pkg/storage/unified/search"
|
||||
|
||||
"github.com/grafana/authlib/types"
|
||||
infraDB "github.com/grafana/grafana/pkg/infra/db"
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/resource"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/search"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/sql/db/dbimpl"
|
||||
)
|
||||
|
||||
// Creates a new ResourceServer
|
||||
func NewResourceServer(ctx context.Context, db infraDB.DB, cfg *setting.Cfg,
|
||||
features featuremgmt.FeatureToggles, docs resource.DocumentBuilderSupplier,
|
||||
tracer tracing.Tracer, reg prometheus.Registerer, ac authz.AccessClient) (resource.ResourceServer, error) {
|
||||
tracer tracing.Tracer, reg prometheus.Registerer, ac types.AccessClient) (resource.ResourceServer, error) {
|
||||
apiserverCfg := cfg.SectionWithEnvOverrides("grafana-apiserver")
|
||||
opts := resource.ResourceServerOptions{
|
||||
Tracer: tracer,
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
|
||||
"github.com/grafana/authlib/claims"
|
||||
claims "github.com/grafana/authlib/types"
|
||||
"github.com/grafana/dskit/services"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
||||
|
||||
Reference in New Issue
Block a user