IAM: Add and use identity ref (#92978)

* Add and use identity ref

---------

Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
pull/92991/head
Karl Persson 11 months ago committed by GitHub
parent 95ef2a1eb2
commit bc20592fd4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 2
      pkg/apis/iam/v0alpha1/register.go
  2. 23
      pkg/apis/iam/v0alpha1/types_identity.go
  3. 6
      pkg/apis/iam/v0alpha1/types_team.go
  4. 20
      pkg/apis/iam/v0alpha1/zz_generated.deepcopy.go
  5. 87
      pkg/apis/iam/v0alpha1/zz_generated.openapi.go
  6. 1
      pkg/apis/iam/v0alpha1/zz_generated.openapi_violation_exceptions.list
  7. 12
      pkg/registry/apis/iam/team/rest_members.go
  8. 7
      pkg/registry/apis/iam/team/store_binding.go
  9. 48
      pkg/registry/apis/iam/user/rest_display.go

@ -137,7 +137,7 @@ var TeamBindingResourceInfo = utils.NewResourceInfo(
}
return []interface{}{
m.Name,
m.Spec.TeamRef.Name,
m.Spec.Team.Name,
m.CreationTimestamp.UTC().Format(time.RFC3339),
}, nil
},

@ -2,6 +2,7 @@ package v0alpha1
import (
"github.com/grafana/authlib/claims"
"github.com/grafana/grafana/pkg/apimachinery/identity"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
@ -23,15 +24,10 @@ type IdentityDisplayResults struct {
}
type IdentityDisplay struct {
// Type of identity e.g. "user".
// For a full list see https://github.com/grafana/authlib/blob/2f8d13a83ca3e82da08b53726de1697ee5b5b4cc/claims/type.go#L15-L24
IdentityType claims.IdentityType `json:"type"`
// UID for identity, is a unique value for the type within a namespace.
UID string `json:"uid"`
Identity IdentityRef `json:"identity"`
// Display name for identity.
Display string `json:"display"`
DisplayName string `json:"displayName"`
// AvatarURL is the url where we can get the avatar for identity
AvatarURL string `json:"avatarURL,omitempty"`
@ -39,3 +35,16 @@ type IdentityDisplay struct {
// InternalID is the legacy numreric id for identity, this is deprecated and should be phased out
InternalID int64 `json:"internalId,omitempty"`
}
type IdentityRef struct {
// Type of identity e.g. "user".
// For a full list see https://github.com/grafana/authlib/blob/2f8d13a83ca3e82da08b53726de1697ee5b5b4cc/claims/type.go#L15-L24
Type claims.IdentityType `json:"type"`
// Name is the unique identifier for identity, guaranteed jo be a unique value for the type within a namespace.
Name string `json:"name"`
}
func (i *IdentityRef) String() string {
return identity.NewTypedIDString(i.Type, i.Name)
}

@ -35,7 +35,7 @@ type TeamBinding struct {
type TeamBindingSpec struct {
Subjects []TeamSubject `json:"subjects,omitempty"`
TeamRef TeamRef `json:"teamRef,omitempty"`
Team TeamRef `json:"team,omitempty"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
@ -47,8 +47,8 @@ type TeamBindingList struct {
}
type TeamSubject struct {
// Name is the unique identifier for subject.
Name string `json:"name,omitempty"`
// Identity is a reference to the identity of this subject.
Identity IdentityRef `json:"identity"`
// Permission subject has in team.
Permission TeamPermission `json:"permission,omitempty"`

@ -14,6 +14,7 @@ import (
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *IdentityDisplay) DeepCopyInto(out *IdentityDisplay) {
*out = *in
out.Identity = in.Identity
return
}
@ -67,6 +68,22 @@ func (in *IdentityDisplayResults) DeepCopyObject() runtime.Object {
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *IdentityRef) DeepCopyInto(out *IdentityRef) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IdentityRef.
func (in *IdentityRef) DeepCopy() *IdentityRef {
if in == nil {
return nil
}
out := new(IdentityRef)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *SSOSetting) DeepCopyInto(out *SSOSetting) {
*out = *in
@ -373,7 +390,7 @@ func (in *TeamBindingSpec) DeepCopyInto(out *TeamBindingSpec) {
*out = make([]TeamSubject, len(*in))
copy(*out, *in)
}
out.TeamRef = in.TeamRef
out.Team = in.Team
return
}
@ -503,6 +520,7 @@ func (in *TeamSpec) DeepCopy() *TeamSpec {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *TeamSubject) DeepCopyInto(out *TeamSubject) {
*out = *in
out.Identity = in.Identity
return
}

@ -16,6 +16,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA
return map[string]common.OpenAPIDefinition{
"github.com/grafana/grafana/pkg/apis/iam/v0alpha1.IdentityDisplay": schema_pkg_apis_iam_v0alpha1_IdentityDisplay(ref),
"github.com/grafana/grafana/pkg/apis/iam/v0alpha1.IdentityDisplayResults": schema_pkg_apis_iam_v0alpha1_IdentityDisplayResults(ref),
"github.com/grafana/grafana/pkg/apis/iam/v0alpha1.IdentityRef": schema_pkg_apis_iam_v0alpha1_IdentityRef(ref),
"github.com/grafana/grafana/pkg/apis/iam/v0alpha1.SSOSetting": schema_pkg_apis_iam_v0alpha1_SSOSetting(ref),
"github.com/grafana/grafana/pkg/apis/iam/v0alpha1.SSOSettingList": schema_pkg_apis_iam_v0alpha1_SSOSettingList(ref),
"github.com/grafana/grafana/pkg/apis/iam/v0alpha1.SSOSettingSpec": schema_pkg_apis_iam_v0alpha1_SSOSettingSpec(ref),
@ -48,23 +49,13 @@ func schema_pkg_apis_iam_v0alpha1_IdentityDisplay(ref common.ReferenceCallback)
SchemaProps: spec.SchemaProps{
Type: []string{"object"},
Properties: map[string]spec.Schema{
"type": {
SchemaProps: spec.SchemaProps{
Description: "Type of identity e.g. \"user\". For a full list see https://github.com/grafana/authlib/blob/2f8d13a83ca3e82da08b53726de1697ee5b5b4cc/claims/type.go#L15-L24",
Default: "",
Type: []string{"string"},
Format: "",
},
},
"uid": {
"identity": {
SchemaProps: spec.SchemaProps{
Description: "UID for identity, is a unique value for the type within a namespace.",
Default: "",
Type: []string{"string"},
Format: "",
Default: map[string]interface{}{},
Ref: ref("github.com/grafana/grafana/pkg/apis/iam/v0alpha1.IdentityRef"),
},
},
"display": {
"displayName": {
SchemaProps: spec.SchemaProps{
Description: "Display name for identity.",
Default: "",
@ -87,9 +78,11 @@ func schema_pkg_apis_iam_v0alpha1_IdentityDisplay(ref common.ReferenceCallback)
},
},
},
Required: []string{"type", "uid", "display"},
Required: []string{"identity", "displayName"},
},
},
Dependencies: []string{
"github.com/grafana/grafana/pkg/apis/iam/v0alpha1.IdentityRef"},
}
}
@ -181,6 +174,35 @@ func schema_pkg_apis_iam_v0alpha1_IdentityDisplayResults(ref common.ReferenceCal
}
}
func schema_pkg_apis_iam_v0alpha1_IdentityRef(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{
Schema: spec.Schema{
SchemaProps: spec.SchemaProps{
Type: []string{"object"},
Properties: map[string]spec.Schema{
"type": {
SchemaProps: spec.SchemaProps{
Description: "Type of identity e.g. \"user\". For a full list see https://github.com/grafana/authlib/blob/2f8d13a83ca3e82da08b53726de1697ee5b5b4cc/claims/type.go#L15-L24",
Default: "",
Type: []string{"string"},
Format: "",
},
},
"name": {
SchemaProps: spec.SchemaProps{
Description: "Name is the unique identifier for identity, guaranteed jo be a unique value for the type within a namespace.",
Default: "",
Type: []string{"string"},
Format: "",
},
},
},
Required: []string{"type", "name"},
},
},
}
}
func schema_pkg_apis_iam_v0alpha1_SSOSetting(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{
Schema: spec.Schema{
@ -645,7 +667,7 @@ func schema_pkg_apis_iam_v0alpha1_TeamBindingSpec(ref common.ReferenceCallback)
},
},
},
"teamRef": {
"team": {
SchemaProps: spec.SchemaProps{
Default: map[string]interface{}{},
Ref: ref("github.com/grafana/grafana/pkg/apis/iam/v0alpha1.TeamRef"),
@ -712,23 +734,13 @@ func schema_pkg_apis_iam_v0alpha1_TeamMember(ref common.ReferenceCallback) commo
SchemaProps: spec.SchemaProps{
Type: []string{"object"},
Properties: map[string]spec.Schema{
"type": {
SchemaProps: spec.SchemaProps{
Description: "Type of identity e.g. \"user\". For a full list see https://github.com/grafana/authlib/blob/2f8d13a83ca3e82da08b53726de1697ee5b5b4cc/claims/type.go#L15-L24",
Default: "",
Type: []string{"string"},
Format: "",
},
},
"uid": {
"identity": {
SchemaProps: spec.SchemaProps{
Description: "UID for identity, is a unique value for the type within a namespace.",
Default: "",
Type: []string{"string"},
Format: "",
Default: map[string]interface{}{},
Ref: ref("github.com/grafana/grafana/pkg/apis/iam/v0alpha1.IdentityRef"),
},
},
"display": {
"displayName": {
SchemaProps: spec.SchemaProps{
Description: "Display name for identity.",
Default: "",
@ -766,9 +778,11 @@ func schema_pkg_apis_iam_v0alpha1_TeamMember(ref common.ReferenceCallback) commo
},
},
},
Required: []string{"type", "uid", "display"},
Required: []string{"identity", "displayName"},
},
},
Dependencies: []string{
"github.com/grafana/grafana/pkg/apis/iam/v0alpha1.IdentityRef"},
}
}
@ -868,11 +882,11 @@ func schema_pkg_apis_iam_v0alpha1_TeamSubject(ref common.ReferenceCallback) comm
SchemaProps: spec.SchemaProps{
Type: []string{"object"},
Properties: map[string]spec.Schema{
"name": {
"identity": {
SchemaProps: spec.SchemaProps{
Description: "Name is the unique identifier for subject.",
Type: []string{"string"},
Format: "",
Description: "Identity is a reference to the identity of this subject.",
Default: map[string]interface{}{},
Ref: ref("github.com/grafana/grafana/pkg/apis/iam/v0alpha1.IdentityRef"),
},
},
"permission": {
@ -884,8 +898,11 @@ func schema_pkg_apis_iam_v0alpha1_TeamSubject(ref common.ReferenceCallback) comm
},
},
},
Required: []string{"identity"},
},
},
Dependencies: []string{
"github.com/grafana/grafana/pkg/apis/iam/v0alpha1.IdentityRef"},
}
}

@ -1,3 +1,2 @@
API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/iam/v0alpha1,TeamBindingSpec,Subjects
API rule violation: names_match,github.com/grafana/grafana/pkg/apis/iam/v0alpha1,IdentityDisplay,IdentityType
API rule violation: names_match,github.com/grafana/grafana/pkg/apis/iam/v0alpha1,IdentityDisplay,InternalID

@ -98,11 +98,13 @@ var cfg = &setting.Cfg{}
func mapToTeamMember(m legacy.TeamMember) iamv0.TeamMember {
return iamv0.TeamMember{
IdentityDisplay: iamv0.IdentityDisplay{
IdentityType: claims.TypeUser,
UID: m.UserUID,
Display: m.Name,
AvatarURL: dtos.GetGravatarUrlWithDefault(cfg, m.Email, m.Name),
InternalID: m.UserID,
Identity: iamv0.IdentityRef{
Type: claims.TypeUser,
Name: m.UserUID,
},
DisplayName: m.Name,
AvatarURL: dtos.GetGravatarUrlWithDefault(cfg, m.Email, m.Name),
InternalID: m.UserID,
},
External: m.External,
Permission: mapPermisson(m.Permission),

@ -137,7 +137,7 @@ func mapToBindingObject(ns claims.NamespaceInfo, b legacy.TeamBinding) iamv0.Tea
CreationTimestamp: metav1.NewTime(ct),
},
Spec: iamv0.TeamBindingSpec{
TeamRef: iamv0.TeamRef{
Team: iamv0.TeamRef{
Name: b.TeamUID,
},
Subjects: mapToSubjects(b.Members),
@ -149,7 +149,10 @@ func mapToSubjects(members []legacy.TeamMember) []iamv0.TeamSubject {
out := make([]iamv0.TeamSubject, 0, len(members))
for _, m := range members {
out = append(out, iamv0.TeamSubject{
Name: m.MemberID(),
Identity: iamv0.IdentityRef{
Type: claims.TypeUser,
Name: m.UserUID,
},
Permission: common.MapTeamPermission(m.Permission),
})
}

@ -98,14 +98,17 @@ func (r *LegacyDisplayREST) Connect(ctx context.Context, name string, _ runtime.
}
for _, user := range users.Users {
disp := iamv0.IdentityDisplay{
IdentityType: claims.TypeUser,
Display: user.NameOrFallback(),
UID: user.UID,
Identity: iamv0.IdentityRef{
Type: claims.TypeUser,
Name: user.UID,
},
DisplayName: user.NameOrFallback(),
InternalID: user.ID,
}
if user.IsServiceAccount {
disp.IdentityType = claims.TypeServiceAccount
disp.Identity.Type = claims.TypeServiceAccount
}
disp.AvatarURL = dtos.GetGravatarUrlWithDefault(fakeCfgForGravatar, user.Email, disp.Display)
disp.AvatarURL = dtos.GetGravatarUrlWithDefault(fakeCfgForGravatar, user.Email, disp.DisplayName)
rsp.Display = append(rsp.Display, disp)
}
@ -146,25 +149,30 @@ func parseKeys(req []string) dispKeys {
switch t {
case claims.TypeAnonymous:
keys.disp = append(keys.disp, iamv0.IdentityDisplay{
IdentityType: t,
Display: "Anonymous",
AvatarURL: dtos.GetGravatarUrl(fakeCfgForGravatar, string(t)),
Identity: iamv0.IdentityRef{
Type: t,
},
DisplayName: "Anonymous",
AvatarURL: dtos.GetGravatarUrl(fakeCfgForGravatar, string(t)),
})
continue
case claims.TypeAPIKey:
keys.disp = append(keys.disp, iamv0.IdentityDisplay{
IdentityType: t,
UID: key,
Display: "API Key",
AvatarURL: dtos.GetGravatarUrl(fakeCfgForGravatar, string(t)),
Identity: iamv0.IdentityRef{
Type: t,
Name: key,
},
DisplayName: "API Key",
AvatarURL: dtos.GetGravatarUrl(fakeCfgForGravatar, string(t)),
})
continue
case claims.TypeProvisioning:
keys.disp = append(keys.disp, iamv0.IdentityDisplay{
IdentityType: t,
UID: "Provisioning",
Display: "Provisioning",
AvatarURL: dtos.GetGravatarUrl(fakeCfgForGravatar, string(t)),
Identity: iamv0.IdentityRef{
Type: t,
},
DisplayName: "Provisioning",
AvatarURL: dtos.GetGravatarUrl(fakeCfgForGravatar, string(t)),
})
continue
default:
@ -177,9 +185,11 @@ func parseKeys(req []string) dispKeys {
if err == nil {
if id == 0 {
keys.disp = append(keys.disp, iamv0.IdentityDisplay{
IdentityType: claims.TypeUser,
UID: key,
Display: "System admin",
Identity: iamv0.IdentityRef{
Type: claims.TypeUser,
Name: key,
},
DisplayName: "System admin",
})
continue
}

Loading…
Cancel
Save