User: Add uid colum to user table (#81615)

This commit is contained in:
Ryan McKinley
2024-02-01 18:14:10 -08:00
committed by GitHub
parent 9d17f6e6aa
commit 9c9e5e68c8
16 changed files with 87 additions and 3 deletions
@@ -105,6 +105,7 @@ export interface AnalyticsSettings {
export interface CurrentUserDTO {
isSignedIn: boolean;
id: number;
uid: string;
externalUserId: string;
login: string;
email: string;
+1
View File
@@ -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"`
+1
View File
@@ -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(),
+2
View File
@@ -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;
+4 -2
View File
@@ -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()),
+6 -1
View File
@@ -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"`
+5
View File
@@ -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,
+27
View File
@@ -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{
+1
View File
@@ -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,
+6
View File
@@ -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"
}
}
},
+6
View File
@@ -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"
}
}
},
+2
View File
@@ -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 = '';
+6
View File
@@ -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"