IAM: Add and use identity ref (#92978)
* Add and use identity ref --------- Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
This commit is contained in:
co-authored by
Ryan McKinley
parent
95ef2a1eb2
commit
bc20592fd4
@@ -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": {
|
||||
"identity": {
|
||||
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: "",
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("github.com/grafana/grafana/pkg/apis/iam/v0alpha1.IdentityRef"),
|
||||
},
|
||||
},
|
||||
"uid": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "UID for identity, is a unique value for the type within a namespace.",
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"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": {
|
||||
"identity": {
|
||||
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: "",
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("github.com/grafana/grafana/pkg/apis/iam/v0alpha1.IdentityRef"),
|
||||
},
|
||||
},
|
||||
"uid": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "UID for identity, is a unique value for the type within a namespace.",
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user