mirror of
https://github.com/grafana/grafana.git
synced 2026-08-26 13:27:30 -05:00
User: Add uid colum to user table (#81615)
This commit is contained in:
@@ -105,6 +105,7 @@ export interface AnalyticsSettings {
|
||||
export interface CurrentUserDTO {
|
||||
isSignedIn: boolean;
|
||||
id: number;
|
||||
uid: string;
|
||||
externalUserId: string;
|
||||
login: string;
|
||||
email: string;
|
||||
|
||||
@@ -30,6 +30,7 @@ type LoginCommand struct {
|
||||
type CurrentUser struct {
|
||||
IsSignedIn bool `json:"isSignedIn"`
|
||||
Id int64 `json:"id"`
|
||||
UID string `json:"uid"`
|
||||
Login string `json:"login"`
|
||||
Email string `json:"email"`
|
||||
Name string `json:"name"`
|
||||
|
||||
@@ -92,6 +92,7 @@ func (hs *HTTPServer) setIndexViewData(c *contextmodel.ReqContext) (*dtos.IndexV
|
||||
data := dtos.IndexViewData{
|
||||
User: &dtos.CurrentUser{
|
||||
Id: userID,
|
||||
UID: c.UserUID, // << not set yet
|
||||
IsSignedIn: c.IsSignedIn,
|
||||
Login: c.Login,
|
||||
Email: c.SignedInUser.GetEmail(),
|
||||
|
||||
@@ -82,6 +82,7 @@ func TestUserAPIEndpoint_userLoggedIn(t *testing.T) {
|
||||
}
|
||||
usr, err := userSvc.Create(context.Background(), &createUserCmd)
|
||||
require.NoError(t, err)
|
||||
theUserUID := usr.UID
|
||||
|
||||
sc.handlerFunc = hs.GetUserByID
|
||||
|
||||
@@ -108,6 +109,7 @@ func TestUserAPIEndpoint_userLoggedIn(t *testing.T) {
|
||||
|
||||
expected := user.UserProfileDTO{
|
||||
ID: 1,
|
||||
UID: theUserUID, // from original request
|
||||
Email: "user@test.com",
|
||||
Name: "user",
|
||||
Login: "loginuser",
|
||||
|
||||
@@ -643,6 +643,7 @@ func TestDashAlertPermissionMigration(t *testing.T) {
|
||||
for i := 1; i < 3; i++ {
|
||||
_, err := x.Insert(user.User{
|
||||
ID: int64(i),
|
||||
UID: fmt.Sprintf("u%d", i),
|
||||
OrgID: 1,
|
||||
Name: fmt.Sprintf("user%v", i),
|
||||
Login: fmt.Sprintf("user%v", i),
|
||||
|
||||
@@ -46,6 +46,7 @@ var (
|
||||
users = []user.User{
|
||||
{
|
||||
ID: 1,
|
||||
UID: "u1",
|
||||
Email: "viewer1@example.org",
|
||||
Name: "viewer1",
|
||||
Login: "viewer1",
|
||||
@@ -55,6 +56,7 @@ var (
|
||||
},
|
||||
{
|
||||
ID: 2,
|
||||
UID: "u2",
|
||||
Email: "viewer2@example.org",
|
||||
Name: "viewer2",
|
||||
Login: "viewer2",
|
||||
@@ -64,6 +66,7 @@ var (
|
||||
},
|
||||
{
|
||||
ID: 3,
|
||||
UID: "u3",
|
||||
Email: "editor1@example.org",
|
||||
Name: "editor1",
|
||||
Login: "editor1",
|
||||
@@ -73,6 +76,7 @@ var (
|
||||
},
|
||||
{
|
||||
ID: 4,
|
||||
UID: "u4",
|
||||
Email: "admin1@example.org",
|
||||
Name: "admin1",
|
||||
Login: "admin1",
|
||||
@@ -82,6 +86,7 @@ var (
|
||||
},
|
||||
{
|
||||
ID: 5,
|
||||
UID: "u5",
|
||||
Email: "editor2@example.org",
|
||||
Name: "editor2",
|
||||
Login: "editor2",
|
||||
|
||||
@@ -140,6 +140,19 @@ func addUserMigrations(mg *Migrator) {
|
||||
SQLite(migSQLITEisServiceAccountNullable).
|
||||
Postgres("ALTER TABLE `user` ALTER COLUMN is_service_account DROP NOT NULL;").
|
||||
Mysql("ALTER TABLE user MODIFY is_service_account BOOLEAN DEFAULT 0;"))
|
||||
|
||||
mg.AddMigration("Add uid column to user", NewAddColumnMigration(userV2, &Column{
|
||||
Name: "uid", Type: DB_NVarchar, Length: 40, Nullable: true,
|
||||
}))
|
||||
|
||||
mg.AddMigration("Update uid column values for users", NewRawSQLMigration("").
|
||||
SQLite("UPDATE user SET uid=printf('u%09d',id) WHERE uid IS NULL;").
|
||||
Postgres("UPDATE `user` SET uid='u' || lpad('' || id::text,9,'0') WHERE uid IS NULL;").
|
||||
Mysql("UPDATE user SET uid=concat('u',lpad(id,9,'0')) WHERE uid IS NULL;"))
|
||||
|
||||
mg.AddMigration("Add unique index user_uid", NewAddIndexMigration(userV2, &Index{
|
||||
Cols: []string{"uid"}, Type: UniqueIndex,
|
||||
}))
|
||||
}
|
||||
|
||||
const migSQLITEisServiceAccountNullable = `ALTER TABLE user ADD COLUMN tmp_service_account BOOLEAN DEFAULT 0;
|
||||
|
||||
@@ -13,8 +13,9 @@ const (
|
||||
)
|
||||
|
||||
type SignedInUser struct {
|
||||
UserID int64 `xorm:"user_id"`
|
||||
OrgID int64 `xorm:"org_id"`
|
||||
UserID int64 `xorm:"user_id"`
|
||||
UserUID string `xorm:"user_uid"`
|
||||
OrgID int64 `xorm:"org_id"`
|
||||
OrgName string
|
||||
OrgRole roletype.RoleType
|
||||
Login string
|
||||
@@ -58,6 +59,7 @@ func (u *SignedInUser) NameOrFallback() string {
|
||||
func (u *SignedInUser) ToUserDisplayDTO() *UserDisplayDTO {
|
||||
return &UserDisplayDTO{
|
||||
ID: u.UserID,
|
||||
UID: u.UserUID,
|
||||
Login: u.Login,
|
||||
Name: u.Name,
|
||||
// AvatarURL: dtos.GetGravatarUrl(u.GetEmail()),
|
||||
|
||||
@@ -20,7 +20,8 @@ const (
|
||||
)
|
||||
|
||||
type User struct {
|
||||
ID int64 `xorm:"pk autoincr 'id'"`
|
||||
ID int64 `xorm:"pk autoincr 'id'"`
|
||||
UID string `json:"uid" xorm:"uid"`
|
||||
Version int
|
||||
Email string
|
||||
Name string
|
||||
@@ -44,6 +45,7 @@ type User struct {
|
||||
}
|
||||
|
||||
type CreateUserCommand struct {
|
||||
UID string
|
||||
Email string
|
||||
Login string
|
||||
Name string
|
||||
@@ -115,6 +117,7 @@ type SearchUserQueryResult struct {
|
||||
|
||||
type UserSearchHitDTO struct {
|
||||
ID int64 `json:"id" xorm:"id"`
|
||||
UID string `json:"uid" xorm:"id"`
|
||||
Name string `json:"name"`
|
||||
Login string `json:"login"`
|
||||
Email string `json:"email"`
|
||||
@@ -133,6 +136,7 @@ type GetUserProfileQuery struct {
|
||||
|
||||
type UserProfileDTO struct {
|
||||
ID int64 `json:"id"`
|
||||
UID string `json:"uid"`
|
||||
Email string `json:"email"`
|
||||
Name string `json:"name"`
|
||||
Login string `json:"login"`
|
||||
@@ -215,6 +219,7 @@ type ErrCaseInsensitiveLoginConflict struct {
|
||||
|
||||
type UserDisplayDTO struct {
|
||||
ID int64 `json:"id,omitempty"`
|
||||
UID string `json:"uid,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Login string `json:"login,omitempty"`
|
||||
AvatarURL string `json:"avatarUrl"`
|
||||
|
||||
@@ -63,6 +63,9 @@ func (ss *sqlStore) Insert(ctx context.Context, cmd *user.User) (int64, error) {
|
||||
var err error
|
||||
err = ss.db.WithTransactionalDbSession(ctx, func(sess *db.Session) error {
|
||||
sess.UseBool("is_admin")
|
||||
if cmd.UID == "" {
|
||||
cmd.UID = util.GenerateShortUID()
|
||||
}
|
||||
|
||||
if _, err = sess.Insert(cmd); err != nil {
|
||||
return err
|
||||
@@ -393,6 +396,7 @@ func (ss *sqlStore) GetSignedInUser(ctx context.Context, query *user.GetSignedIn
|
||||
|
||||
var rawSQL = `SELECT
|
||||
u.id as user_id,
|
||||
u.uid as user_uid,
|
||||
u.is_admin as is_grafana_admin,
|
||||
u.email as email,
|
||||
u.login as login,
|
||||
@@ -466,6 +470,7 @@ func (ss *sqlStore) GetProfile(ctx context.Context, query *user.GetUserProfileQu
|
||||
|
||||
userProfile = user.UserProfileDTO{
|
||||
ID: usr.ID,
|
||||
UID: usr.UID,
|
||||
Name: usr.Name,
|
||||
Email: usr.Email,
|
||||
Login: usr.Login,
|
||||
|
||||
@@ -104,6 +104,7 @@ func TestIntegrationUserGet(t *testing.T) {
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, usr)
|
||||
require.NotEmpty(t, usr.UID)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -150,6 +151,32 @@ func TestIntegrationUserDataAccess(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
})
|
||||
|
||||
t.Run("insert user (with known UID)", func(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
id, err := userStore.Insert(ctx,
|
||||
&user.User{
|
||||
UID: "abcd",
|
||||
Email: "next-test@email.com",
|
||||
Name: "next-test1",
|
||||
Login: "next-test1",
|
||||
Created: time.Now(),
|
||||
Updated: time.Now(),
|
||||
},
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
found, err := userStore.GetByID(ctx, id)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "abcd", found.UID)
|
||||
|
||||
siu, err := userStore.GetSignedInUser(ctx, &user.GetSignedInUserQuery{
|
||||
UserID: id,
|
||||
OrgID: found.OrgID,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "abcd", siu.UserUID)
|
||||
})
|
||||
|
||||
t.Run("get user", func(t *testing.T) {
|
||||
_, err := userStore.Get(context.Background(),
|
||||
&user.User{
|
||||
|
||||
@@ -129,6 +129,7 @@ func (s *Service) Create(ctx context.Context, cmd *user.CreateUserCommand) (*use
|
||||
|
||||
// create user
|
||||
usr := &user.User{
|
||||
UID: cmd.UID,
|
||||
Email: cmd.Email,
|
||||
Name: cmd.Name,
|
||||
Login: cmd.Login,
|
||||
|
||||
@@ -7951,6 +7951,9 @@
|
||||
"theme": {
|
||||
"type": "string"
|
||||
},
|
||||
"uid": {
|
||||
"type": "string"
|
||||
},
|
||||
"updatedAt": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
@@ -7994,6 +7997,9 @@
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"uid": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -21361,6 +21361,9 @@
|
||||
"theme": {
|
||||
"type": "string"
|
||||
},
|
||||
"uid": {
|
||||
"type": "string"
|
||||
},
|
||||
"updatedAt": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
@@ -21404,6 +21407,9 @@
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"uid": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -15,6 +15,7 @@ export const AutoRefreshInterval = 'auto';
|
||||
export class User implements Omit<CurrentUserInternal, 'lightTheme'> {
|
||||
isSignedIn: boolean;
|
||||
id: number;
|
||||
uid: string;
|
||||
login: string;
|
||||
email: string;
|
||||
name: string;
|
||||
@@ -39,6 +40,7 @@ export class User implements Omit<CurrentUserInternal, 'lightTheme'> {
|
||||
|
||||
constructor() {
|
||||
this.id = 0;
|
||||
this.uid = '';
|
||||
this.isGrafanaAdmin = false;
|
||||
this.isSignedIn = false;
|
||||
this.orgRole = '';
|
||||
|
||||
@@ -11843,6 +11843,9 @@
|
||||
"theme": {
|
||||
"type": "string"
|
||||
},
|
||||
"uid": {
|
||||
"type": "string"
|
||||
},
|
||||
"updatedAt": {
|
||||
"format": "date-time",
|
||||
"type": "string"
|
||||
@@ -11886,6 +11889,9 @@
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"uid": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
|
||||
Reference in New Issue
Block a user