mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
IAM: remove duplicated functions (#96989)
* Remove duplicated function and use the one provided by claims package
This commit is contained in:
@@ -11,7 +11,6 @@ import (
|
||||
"github.com/grafana/authlib/claims"
|
||||
"github.com/grafana/grafana/pkg/api/dtos"
|
||||
"github.com/grafana/grafana/pkg/api/response"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/auth"
|
||||
@@ -363,12 +362,13 @@ func (hs *HTTPServer) AdminEnableUser(c *contextmodel.ReqContext) response.Respo
|
||||
// 404: notFoundError
|
||||
// 500: internalServerError
|
||||
func (hs *HTTPServer) AdminLogoutUser(c *contextmodel.ReqContext) response.Response {
|
||||
userID, err := strconv.ParseInt(web.Params(c.Req)[":id"], 10, 64)
|
||||
id := web.Params(c.Req)[":id"]
|
||||
userID, err := strconv.ParseInt(id, 10, 64)
|
||||
if err != nil {
|
||||
return response.Error(http.StatusBadRequest, "id is invalid", err)
|
||||
}
|
||||
|
||||
if c.SignedInUser.GetID() == identity.NewTypedID(claims.TypeUser, userID) {
|
||||
if c.SignedInUser.GetID() == claims.NewTypeID(claims.TypeUser, id) {
|
||||
return response.Error(http.StatusBadRequest, "You cannot logout yourself", nil)
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
|
||||
var (
|
||||
ErrInvalidIDType = errutil.BadRequest("auth.identity.invalid-id-type")
|
||||
ErrInvalidTypedID = errutil.BadRequest("auth.identity.invalid-typed-id")
|
||||
ErrNotIntIdentifier = errors.New("identifier is not an int64")
|
||||
ErrIdentifierNotInitialized = errors.New("identifier is not initialized")
|
||||
)
|
||||
|
||||
@@ -80,7 +80,7 @@ type Requester interface {
|
||||
// Applicable for users, service accounts, api keys and renderer service.
|
||||
// Errors if the identifier is not initialized or if type is not recognized.
|
||||
func IntIdentifier(typedID string) (int64, error) {
|
||||
typ, id, err := ParseTypeAndID(typedID)
|
||||
typ, id, err := claims.ParseTypeID(typedID)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -92,7 +92,7 @@ func IntIdentifier(typedID string) (int64, error) {
|
||||
// Errors if the identifier is not initialized or if namespace is not recognized.
|
||||
// Returns 0 if the type is not user or service account
|
||||
func UserIdentifier(typedID string) (int64, error) {
|
||||
typ, id, err := ParseTypeAndID(typedID)
|
||||
typ, id, err := claims.ParseTypeID(typedID)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
@@ -168,7 +168,7 @@ func (u *StaticRequester) HasUniqueId() bool {
|
||||
|
||||
// GetID returns typed id for the entity
|
||||
func (u *StaticRequester) GetID() string {
|
||||
return NewTypedIDString(u.Type, fmt.Sprintf("%d", u.UserID))
|
||||
return claims.NewTypeID(u.Type, fmt.Sprintf("%d", u.UserID))
|
||||
}
|
||||
|
||||
func (u *StaticRequester) GetAuthID() string {
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
package identity
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/grafana/authlib/claims"
|
||||
)
|
||||
|
||||
func ParseTypeAndID(str string) (claims.IdentityType, string, error) {
|
||||
parts := strings.Split(str, ":")
|
||||
if len(parts) != 2 {
|
||||
return "", "", ErrInvalidTypedID.Errorf("expected typed id to have 2 parts")
|
||||
}
|
||||
|
||||
t, err := claims.ParseType(parts[0])
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
return t, parts[1], nil
|
||||
}
|
||||
|
||||
func NewTypedID(t claims.IdentityType, id int64) string {
|
||||
return fmt.Sprintf("%s:%d", t, id)
|
||||
}
|
||||
|
||||
// NewTypedIDString creates a new TypedID with a string id
|
||||
func NewTypedIDString(t claims.IdentityType, id string) string {
|
||||
return fmt.Sprintf("%s:%s", t, id)
|
||||
}
|
||||
@@ -2,7 +2,6 @@ package v0alpha1
|
||||
|
||||
import (
|
||||
"github.com/grafana/authlib/claims"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
@@ -47,5 +46,5 @@ type IdentityRef struct {
|
||||
}
|
||||
|
||||
func (i *IdentityRef) String() string {
|
||||
return identity.NewTypedIDString(i.Type, i.Name)
|
||||
return claims.NewTypeID(i.Type, i.Name)
|
||||
}
|
||||
|
||||
@@ -314,10 +314,10 @@ func (a *dashboardSqlAccess) scanRow(rows *sql.Rows) (*dashboardRow, error) {
|
||||
|
||||
func getUserID(v sql.NullString, id sql.NullInt64) string {
|
||||
if v.Valid && v.String != "" {
|
||||
return identity.NewTypedIDString(claims.TypeUser, v.String)
|
||||
return claims.NewTypeID(claims.TypeUser, v.String)
|
||||
}
|
||||
if id.Valid && id.Int64 == -1 {
|
||||
return identity.NewTypedIDString(claims.TypeProvisioning, "")
|
||||
return claims.NewTypeID(claims.TypeProvisioning, "")
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/grafana/authlib/claims"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
"github.com/grafana/grafana/pkg/registry/apis/iam/common"
|
||||
"github.com/grafana/grafana/pkg/services/team"
|
||||
"github.com/grafana/grafana/pkg/storage/legacysql"
|
||||
@@ -206,7 +205,7 @@ type TeamMember struct {
|
||||
}
|
||||
|
||||
func (m TeamMember) MemberID() string {
|
||||
return identity.NewTypedIDString(claims.TypeUser, m.UserUID)
|
||||
return claims.NewTypeID(claims.TypeUser, m.UserUID)
|
||||
}
|
||||
|
||||
type TeamBinding struct {
|
||||
|
||||
@@ -111,7 +111,7 @@ func (s *SearchOptions) Wildcards() []string {
|
||||
}
|
||||
|
||||
func (s *SearchOptions) ComputeUserID() (int64, error) {
|
||||
typ, id, err := identity.ParseTypeAndID(s.TypedID)
|
||||
typ, id, err := claims.ParseTypeID(s.TypedID)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/authlib/claims"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
"github.com/grafana/grafana/pkg/infra/db"
|
||||
"github.com/grafana/grafana/pkg/infra/localcache"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
@@ -263,7 +262,7 @@ func benchSearchUserWithAction(b *testing.B, usersCount, resourceCount int) {
|
||||
|
||||
for n := 0; n < b.N; n++ {
|
||||
usersPermissions, err := acService.SearchUsersPermissions(context.Background(), siu,
|
||||
accesscontrol.SearchOptions{Action: "resources:action2", TypedID: identity.NewTypedID(claims.TypeUser, 14)})
|
||||
accesscontrol.SearchOptions{Action: "resources:action2", TypedID: claims.NewTypeID(claims.TypeUser, "14")})
|
||||
require.NoError(b, err)
|
||||
require.Len(b, usersPermissions, 1)
|
||||
for _, permissions := range usersPermissions {
|
||||
|
||||
@@ -547,7 +547,7 @@ func TestService_SearchUsersPermissions(t *testing.T) {
|
||||
// only the user's basic roles and the user's stored permissions
|
||||
name: "check namespacedId filter works correctly",
|
||||
siuPermissions: listAllPerms,
|
||||
searchOption: accesscontrol.SearchOptions{TypedID: identity.NewTypedID(claims.TypeServiceAccount, 1)},
|
||||
searchOption: accesscontrol.SearchOptions{TypedID: claims.NewTypeID(claims.TypeServiceAccount, "1")},
|
||||
ramRoles: map[string]*accesscontrol.RoleDTO{
|
||||
string(identity.RoleEditor): {Permissions: []accesscontrol.Permission{
|
||||
{Action: accesscontrol.ActionTeamsRead, Scope: "teams:*"},
|
||||
@@ -619,7 +619,7 @@ func TestService_SearchUserPermissions(t *testing.T) {
|
||||
name: "ram only",
|
||||
searchOption: accesscontrol.SearchOptions{
|
||||
ActionPrefix: "teams",
|
||||
TypedID: identity.NewTypedID(claims.TypeUser, 2),
|
||||
TypedID: claims.NewTypeID(claims.TypeUser, "2"),
|
||||
},
|
||||
ramRoles: map[string]*accesscontrol.RoleDTO{
|
||||
string(identity.RoleEditor): {Permissions: []accesscontrol.Permission{
|
||||
@@ -644,7 +644,7 @@ func TestService_SearchUserPermissions(t *testing.T) {
|
||||
name: "stored only",
|
||||
searchOption: accesscontrol.SearchOptions{
|
||||
ActionPrefix: "teams",
|
||||
TypedID: identity.NewTypedID(claims.TypeUser, 2),
|
||||
TypedID: claims.NewTypeID(claims.TypeUser, "2"),
|
||||
},
|
||||
storedPerms: map[int64][]accesscontrol.Permission{
|
||||
1: {{Action: accesscontrol.ActionTeamsRead, Scope: "teams:id:1"}},
|
||||
@@ -664,7 +664,7 @@ func TestService_SearchUserPermissions(t *testing.T) {
|
||||
name: "ram and stored",
|
||||
searchOption: accesscontrol.SearchOptions{
|
||||
ActionPrefix: "teams",
|
||||
TypedID: identity.NewTypedID(claims.TypeUser, 2),
|
||||
TypedID: claims.NewTypeID(claims.TypeUser, "2"),
|
||||
},
|
||||
ramRoles: map[string]*accesscontrol.RoleDTO{
|
||||
string(identity.RoleAdmin): {Permissions: []accesscontrol.Permission{
|
||||
@@ -694,7 +694,7 @@ func TestService_SearchUserPermissions(t *testing.T) {
|
||||
name: "check action prefix filter works correctly",
|
||||
searchOption: accesscontrol.SearchOptions{
|
||||
ActionPrefix: "teams",
|
||||
TypedID: identity.NewTypedID(claims.TypeUser, 1),
|
||||
TypedID: claims.NewTypeID(claims.TypeUser, "1"),
|
||||
},
|
||||
ramRoles: map[string]*accesscontrol.RoleDTO{
|
||||
string(identity.RoleEditor): {Permissions: []accesscontrol.Permission{
|
||||
@@ -716,7 +716,7 @@ func TestService_SearchUserPermissions(t *testing.T) {
|
||||
name: "check action filter works correctly",
|
||||
searchOption: accesscontrol.SearchOptions{
|
||||
Action: accesscontrol.ActionTeamsRead,
|
||||
TypedID: identity.NewTypedID(claims.TypeUser, 1),
|
||||
TypedID: claims.NewTypeID(claims.TypeUser, "1"),
|
||||
},
|
||||
ramRoles: map[string]*accesscontrol.RoleDTO{
|
||||
string(identity.RoleEditor): {Permissions: []accesscontrol.Permission{
|
||||
@@ -738,7 +738,7 @@ func TestService_SearchUserPermissions(t *testing.T) {
|
||||
name: "check action sets are correctly included if an action is specified",
|
||||
searchOption: accesscontrol.SearchOptions{
|
||||
Action: "dashboards:read",
|
||||
TypedID: identity.NewTypedID(claims.TypeUser, 1),
|
||||
TypedID: claims.NewTypeID(claims.TypeUser, "1"),
|
||||
},
|
||||
withActionSets: true,
|
||||
actionSets: map[string][]string{
|
||||
@@ -771,7 +771,7 @@ func TestService_SearchUserPermissions(t *testing.T) {
|
||||
name: "check action sets are correctly included if an action prefix is specified",
|
||||
searchOption: accesscontrol.SearchOptions{
|
||||
ActionPrefix: "dashboards",
|
||||
TypedID: identity.NewTypedID(claims.TypeUser, 1),
|
||||
TypedID: claims.NewTypeID(claims.TypeUser, "1"),
|
||||
},
|
||||
withActionSets: true,
|
||||
actionSets: map[string][]string{
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/authlib/claims"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
"github.com/grafana/grafana/pkg/infra/db"
|
||||
"github.com/grafana/grafana/pkg/infra/localcache"
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
@@ -626,7 +625,7 @@ func TestIntegrationAccessControlStore_SearchUsersPermissions(t *testing.T) {
|
||||
},
|
||||
options: accesscontrol.SearchOptions{
|
||||
ActionPrefix: "teams:",
|
||||
TypedID: identity.NewTypedID(claims.TypeUser, 1),
|
||||
TypedID: claims.NewTypeID(claims.TypeUser, "1"),
|
||||
},
|
||||
wantPerm: map[int64][]accesscontrol.Permission{
|
||||
1: {{Action: "teams:read", Scope: "teams:id:1"}, {Action: "teams:read", Scope: "teams:id:10"},
|
||||
|
||||
@@ -408,7 +408,7 @@ func (s *Service) resolveIdenity(ctx context.Context, orgID int64, typedID strin
|
||||
ctx, span := s.tracer.Start(ctx, "authn.resolveIdentity")
|
||||
defer span.End()
|
||||
|
||||
t, i, err := identity.ParseTypeAndID(typedID)
|
||||
t, i, err := claims.ParseTypeID(typedID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
|
||||
"github.com/grafana/authlib/claims"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/errutil"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
"github.com/grafana/grafana/pkg/components/apikeygen"
|
||||
"github.com/grafana/grafana/pkg/components/satokengen"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
@@ -25,6 +24,8 @@ var (
|
||||
errAPIKeyExpired = errutil.Unauthorized("api-key.expired", errutil.WithPublicMessage("Expired API key"))
|
||||
errAPIKeyRevoked = errutil.Unauthorized("api-key.revoked", errutil.WithPublicMessage("Revoked API key"))
|
||||
errAPIKeyOrgMismatch = errutil.Unauthorized("api-key.organization-mismatch", errutil.WithPublicMessage("API key does not belong to the requested organization"))
|
||||
|
||||
errAPIKeyInvalidType = errutil.BadRequest("api-key.invalid-type-id")
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -157,7 +158,7 @@ func (s *APIKey) IdentityType() claims.IdentityType {
|
||||
|
||||
func (s *APIKey) ResolveIdentity(ctx context.Context, orgID int64, typ claims.IdentityType, id string) (*authn.Identity, error) {
|
||||
if !claims.IsIdentityType(typ, claims.TypeAPIKey) {
|
||||
return nil, identity.ErrInvalidTypedID.Errorf("got unexpected type: %s", typ)
|
||||
return nil, errAPIKeyInvalidType.Errorf("got unexpected type: %s", typ)
|
||||
}
|
||||
|
||||
apiKeyID, err := strconv.ParseInt(id, 10, 64)
|
||||
@@ -177,7 +178,7 @@ func (s *APIKey) ResolveIdentity(ctx context.Context, orgID int64, typ claims.Id
|
||||
}
|
||||
|
||||
if key.ServiceAccountId != nil && *key.ServiceAccountId >= 1 {
|
||||
return nil, identity.ErrInvalidTypedID.Errorf("api key belongs to service account")
|
||||
return nil, errAPIKeyInvalidType.Errorf("api key belongs to service account")
|
||||
}
|
||||
|
||||
return newAPIKeyIdentity(key), nil
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/grafana/authlib/claims"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
"github.com/grafana/grafana/pkg/components/apikeygen"
|
||||
"github.com/grafana/grafana/pkg/components/satokengen"
|
||||
"github.com/grafana/grafana/pkg/services/apikey"
|
||||
@@ -206,7 +205,7 @@ func TestAPIKey_ResolveIdentity(t *testing.T) {
|
||||
desc: "should return error for invalid type",
|
||||
id: "1",
|
||||
typ: claims.TypeUser,
|
||||
expectedErr: identity.ErrInvalidTypedID,
|
||||
expectedErr: errAPIKeyInvalidType,
|
||||
},
|
||||
{
|
||||
desc: "should return error when api key has expired",
|
||||
@@ -240,7 +239,7 @@ func TestAPIKey_ResolveIdentity(t *testing.T) {
|
||||
OrgID: 1,
|
||||
ServiceAccountId: intPtr(1),
|
||||
},
|
||||
expectedErr: identity.ErrInvalidTypedID,
|
||||
expectedErr: errAPIKeyInvalidType,
|
||||
},
|
||||
{
|
||||
desc: "should return error when api key is belongs to different org",
|
||||
|
||||
@@ -11,7 +11,6 @@ import (
|
||||
"github.com/grafana/authlib/claims"
|
||||
|
||||
"github.com/grafana/grafana/pkg/apimachinery/errutil"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
|
||||
"github.com/grafana/grafana/pkg/services/authn"
|
||||
@@ -110,7 +109,7 @@ func (s *ExtendedJWT) authenticateAsUser(
|
||||
return nil, errExtJWTMisMatchedNamespaceClaims.Errorf("unexpected access token namespace: %s", accessTokenClaims.Rest.Namespace)
|
||||
}
|
||||
|
||||
accessType, _, err := identity.ParseTypeAndID(accessTokenClaims.Subject)
|
||||
accessType, _, err := claims.ParseTypeID(accessTokenClaims.Subject)
|
||||
if err != nil {
|
||||
return nil, errExtJWTInvalidSubject.Errorf("unexpected identity: %s", accessTokenClaims.Subject)
|
||||
}
|
||||
@@ -119,7 +118,7 @@ func (s *ExtendedJWT) authenticateAsUser(
|
||||
return nil, errExtJWTInvalid.Errorf("unexpected identity: %s", accessTokenClaims.Subject)
|
||||
}
|
||||
|
||||
t, id, err := identity.ParseTypeAndID(idTokenClaims.Subject)
|
||||
t, id, err := claims.ParseTypeID(idTokenClaims.Subject)
|
||||
if err != nil {
|
||||
return nil, errExtJWTInvalid.Errorf("failed to parse id token subject: %w", err)
|
||||
}
|
||||
@@ -160,7 +159,7 @@ func (s *ExtendedJWT) authenticateAsService(accessTokenClaims authlib.Claims[aut
|
||||
return nil, errExtJWTDisallowedNamespaceClaim.Errorf("unexpected access token namespace: %s", accessTokenClaims.Rest.Namespace)
|
||||
}
|
||||
|
||||
t, id, err := identity.ParseTypeAndID(accessTokenClaims.Subject)
|
||||
t, id, err := claims.ParseTypeID(accessTokenClaims.Subject)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse access token subject: %w", err)
|
||||
}
|
||||
|
||||
@@ -139,11 +139,11 @@ func (i *Identity) GetName() string {
|
||||
}
|
||||
|
||||
func (i *Identity) GetID() string {
|
||||
return identity.NewTypedIDString(i.Type, i.ID)
|
||||
return claims.NewTypeID(i.Type, i.ID)
|
||||
}
|
||||
|
||||
func (i *Identity) GetUID() string {
|
||||
return identity.NewTypedIDString(i.Type, i.UID)
|
||||
return claims.NewTypeID(i.Type, i.UID)
|
||||
}
|
||||
|
||||
func (i *Identity) GetAuthID() string {
|
||||
|
||||
@@ -152,7 +152,7 @@ func TestContextHandler(t *testing.T) {
|
||||
|
||||
t.Run("id response headers", func(t *testing.T) {
|
||||
run := func(cfg *setting.Cfg, id string) *http.Response {
|
||||
typ, i, err := identity.ParseTypeAndID(id)
|
||||
typ, i, err := claims.ParseTypeID(id)
|
||||
require.NoError(t, err)
|
||||
|
||||
handler := contexthandler.ProvideService(
|
||||
|
||||
@@ -268,7 +268,7 @@ func (u *SignedInUser) GetOrgRole() identity.RoleType {
|
||||
// GetID returns namespaced id for the entity
|
||||
func (u *SignedInUser) GetID() string {
|
||||
ns, id := u.getTypeAndID()
|
||||
return identity.NewTypedIDString(ns, id)
|
||||
return claims.NewTypeID(ns, id)
|
||||
}
|
||||
|
||||
func (u *SignedInUser) getTypeAndID() (claims.IdentityType, string) {
|
||||
|
||||
@@ -89,7 +89,7 @@ func (f *Authenticator) decodeMetadata(ctx context.Context, meta metadata.MD) (i
|
||||
return user, nil
|
||||
}
|
||||
|
||||
typ, id, err := identity.ParseTypeAndID(getter(mdUserID))
|
||||
typ, id, err := authClaims.ParseTypeID(getter(mdUserID))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid user id: %w", err)
|
||||
}
|
||||
@@ -99,7 +99,7 @@ func (f *Authenticator) decodeMetadata(ctx context.Context, meta metadata.MD) (i
|
||||
return nil, fmt.Errorf("invalid user id: %w", err)
|
||||
}
|
||||
|
||||
_, id, err = identity.ParseTypeAndID(getter(mdUserUID))
|
||||
_, id, err = authClaims.ParseTypeID(getter(mdUserUID))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid user id: %w", err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user