forked from grafana/grafana
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathidentity.go
314 lines (265 loc) · 8.25 KB
/
identity.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
package authn
import (
"fmt"
"strconv"
"time"
"github.com/grafana/authlib/authn"
"github.com/grafana/authlib/claims"
"golang.org/x/oauth2"
"github.com/grafana/grafana/pkg/apimachinery/identity"
"github.com/grafana/grafana/pkg/models/usertoken"
"github.com/grafana/grafana/pkg/services/login"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/user"
)
const GlobalOrgID = int64(0)
var _ identity.Requester = (*Identity)(nil)
type Identity struct {
// ID is the unique identifier for the entity in the Grafana database.
ID string
// UID is a unique identifier stored for the entity in Grafana database. Not all entities support uid so it can be empty.
UID string
// Type is the IdentityType of entity.
Type claims.IdentityType
// OrgID is the active organization for the entity.
OrgID int64
// OrgName is the name of the active organization.
OrgName string
// OrgRoles is the list of organizations the entity is a member of and their roles.
OrgRoles map[int64]org.RoleType
// Login is the shorthand identifier of the entity. Should be unique.
Login string
// Name is the display name of the entity. It is not guaranteed to be unique.
Name string
// Email is the email address of the entity. Should be unique.
Email string
// EmailVerified is true if entity has verified their email with grafana.
EmailVerified bool
// IsGrafanaAdmin is true if the entity is a Grafana admin.
IsGrafanaAdmin *bool
// AuthenticatedBy is the name of the authentication client that was used to authenticate the current Identity.
// For example, "password", "apikey", "auth_ldap" or "auth_azuread".
AuthenticatedBy string
// AuthId is the unique identifier for the entity in the external system.
// Empty if the identity is provided by Grafana.
AuthID string
// AllowedKubernetesNamespace
AllowedKubernetesNamespace string
// IsDisabled is true if the entity is disabled.
IsDisabled bool
// HelpFlags1 is the help flags for the entity.
HelpFlags1 user.HelpFlags1
// LastSeenAt is the time when the entity was last seen.
LastSeenAt time.Time
// Teams is the list of teams the entity is a member of.
Teams []int64
// idP Groups that the entity is a member of. This is only populated if the
// identity provider supports groups.
Groups []string
// OAuthToken is the OAuth token used to authenticate the entity.
OAuthToken *oauth2.Token
// SessionToken is the session token used to authenticate the entity.
SessionToken *usertoken.UserToken
// ClientParams are hints for the auth service on how to handle the identity.
// Set by the authenticating client.
ClientParams ClientParams
// Permissions is the list of permissions the entity has.
Permissions map[int64]map[string][]string
// IDToken is a signed token representing the identity that can be forwarded to plugins and external services.
IDToken string
IDTokenClaims *authn.Claims[authn.IDTokenClaims]
AccessTokenClaims *authn.Claims[authn.AccessTokenClaims]
}
// Access implements claims.AuthInfo.
func (i *Identity) GetAccess() claims.AccessClaims {
return &identity.IDClaimsWrapper{Source: i}
}
// Identity implements claims.AuthInfo.
func (i *Identity) GetIdentity() claims.IdentityClaims {
if i.IDTokenClaims != nil {
return authn.NewIdentityClaims(*i.IDTokenClaims)
}
return &identity.IDClaimsWrapper{Source: i}
}
// GetRawIdentifier implements Requester.
func (i *Identity) GetRawIdentifier() string {
return i.UID
}
// GetInternalID implements Requester.
func (i *Identity) GetInternalID() (int64, error) {
return identity.IntIdentifier(i.GetID())
}
// GetIdentityType implements Requester.
func (i *Identity) GetIdentityType() claims.IdentityType {
return i.Type
}
// GetIdentityType implements Requester.
func (i *Identity) IsIdentityType(expected ...claims.IdentityType) bool {
return claims.IsIdentityType(i.GetIdentityType(), expected...)
}
// GetExtra implements identity.Requester.
func (i *Identity) GetExtra() map[string][]string {
extra := map[string][]string{}
if i.IDToken != "" {
extra["id-token"] = []string{i.IDToken}
}
if i.GetOrgRole().IsValid() {
extra["user-instance-role"] = []string{string(i.GetOrgRole())}
}
return extra
}
// GetGroups implements identity.Requester.
func (i *Identity) GetGroups() []string {
return []string{} // teams?
}
// GetName implements identity.Requester.
func (i *Identity) GetName() string {
return i.Name
}
func (i *Identity) GetID() string {
return identity.NewTypedIDString(i.Type, i.ID)
}
func (i *Identity) GetUID() string {
return identity.NewTypedIDString(i.Type, i.UID)
}
func (i *Identity) GetAuthID() string {
return i.AuthID
}
func (i *Identity) GetAuthenticatedBy() string {
return i.AuthenticatedBy
}
func (i *Identity) GetCacheKey() string {
id := i.ID
if !i.HasUniqueId() {
// Hack use the org role as id for identities that do not have a unique id
// e.g. anonymous and render key.
id = string(i.GetOrgRole())
}
return fmt.Sprintf("%d-%s-%s", i.GetOrgID(), i.Type, id)
}
func (i *Identity) GetDisplayName() string {
return i.Name
}
func (i *Identity) GetEmail() string {
return i.Email
}
func (i *Identity) IsEmailVerified() bool {
return i.EmailVerified
}
func (i *Identity) GetIDToken() string {
return i.IDToken
}
func (i *Identity) GetIsGrafanaAdmin() bool {
return i.IsGrafanaAdmin != nil && *i.IsGrafanaAdmin
}
func (i *Identity) GetLogin() string {
return i.Login
}
func (i *Identity) GetAllowedKubernetesNamespace() string {
return i.AllowedKubernetesNamespace
}
func (i *Identity) GetOrgID() int64 {
return i.OrgID
}
func (i *Identity) GetOrgName() string {
return i.OrgName
}
func (i *Identity) GetOrgRole() org.RoleType {
if i.OrgRoles == nil {
return org.RoleNone
}
if i.OrgRoles[i.GetOrgID()] == "" {
return org.RoleNone
}
return i.OrgRoles[i.GetOrgID()]
}
func (i *Identity) GetPermissions() map[string][]string {
if i.Permissions == nil {
return make(map[string][]string)
}
if i.Permissions[i.GetOrgID()] == nil {
return make(map[string][]string)
}
return i.Permissions[i.GetOrgID()]
}
// GetGlobalPermissions returns the permissions of the active entity that are available across all organizations
func (i *Identity) GetGlobalPermissions() map[string][]string {
if i.Permissions == nil {
return make(map[string][]string)
}
if i.Permissions[GlobalOrgID] == nil {
return make(map[string][]string)
}
return i.Permissions[GlobalOrgID]
}
func (i *Identity) GetTeams() []int64 {
return i.Teams
}
func (i *Identity) HasRole(role org.RoleType) bool {
if i.GetIsGrafanaAdmin() {
return true
}
return i.GetOrgRole().Includes(role)
}
func (i *Identity) HasUniqueId() bool {
return i.IsIdentityType(claims.TypeUser, claims.TypeAPIKey, claims.TypeServiceAccount)
}
func (i *Identity) IsAuthenticatedBy(providers ...string) bool {
for _, p := range providers {
if i.AuthenticatedBy == p {
return true
}
}
return false
}
func (i *Identity) IsNil() bool {
return i == nil
}
// SignedInUser returns a SignedInUser from the identity.
func (i *Identity) SignedInUser() *user.SignedInUser {
u := &user.SignedInUser{
OrgID: i.OrgID,
OrgName: i.OrgName,
OrgRole: i.GetOrgRole(),
Login: i.Login,
Name: i.Name,
Email: i.Email,
AuthID: i.AuthID,
AuthenticatedBy: i.AuthenticatedBy,
IsGrafanaAdmin: i.GetIsGrafanaAdmin(),
IsAnonymous: i.IsIdentityType(claims.TypeAnonymous),
IsDisabled: i.IsDisabled,
HelpFlags1: i.HelpFlags1,
LastSeenAt: i.LastSeenAt,
Teams: i.Teams,
Permissions: i.Permissions,
IDToken: i.IDToken,
FallbackType: i.Type,
}
if i.IsIdentityType(claims.TypeAPIKey) {
id, _ := i.GetInternalID()
u.ApiKeyID = id
} else {
id, _ := i.GetInternalID()
u.UserID = id
u.UserUID = i.UID
u.IsServiceAccount = i.IsIdentityType(claims.TypeServiceAccount)
}
return u
}
func (i *Identity) ExternalUserInfo() login.ExternalUserInfo {
id, _ := strconv.ParseInt(i.ID, 10, 64)
return login.ExternalUserInfo{
OAuthToken: i.OAuthToken,
AuthModule: i.AuthenticatedBy,
AuthId: i.AuthID,
UserId: id,
Email: i.Email,
Login: i.Login,
Name: i.Name,
Groups: i.Groups,
OrgRoles: i.OrgRoles,
IsGrafanaAdmin: i.IsGrafanaAdmin,
IsDisabled: i.IsDisabled,
}
}