diff --git a/pkg/services/sqlstore/sqlstore.go b/pkg/services/sqlstore/sqlstore.go index d6268f3a2aa..a401e8c8c83 100644 --- a/pkg/services/sqlstore/sqlstore.go +++ b/pkg/services/sqlstore/sqlstore.go @@ -143,30 +143,32 @@ func (ss *SqlStore) ensureAdminUser() error { systemUserCountQuery := m.GetSystemUserCountStatsQuery{} err := bus.InTransaction(context.Background(), func(ctx context.Context) error { - return bus.DispatchCtx(ctx, &systemUserCountQuery) + + err := bus.DispatchCtx(ctx, &systemUserCountQuery) + if err != nil { + return fmt.Errorf("Could not determine if admin user exists: %v", err) + } + + if systemUserCountQuery.Result.Count > 0 { + return nil + } + + cmd := m.CreateUserCommand{} + cmd.Login = setting.AdminUser + cmd.Email = setting.AdminUser + "@localhost" + cmd.Password = setting.AdminPassword + cmd.IsAdmin = true + + if err := bus.DispatchCtx(ctx, &cmd); err != nil { + return fmt.Errorf("Failed to create admin user: %v", err) + } + + ss.log.Info("Created default admin", "user", setting.AdminUser) + + return nil }) - if err != nil { - return fmt.Errorf("Could not determine if admin user exists: %v", err) - } - - if systemUserCountQuery.Result.Count > 0 { - return nil - } - - cmd := m.CreateUserCommand{} - cmd.Login = setting.AdminUser - cmd.Email = setting.AdminUser + "@localhost" - cmd.Password = setting.AdminPassword - cmd.IsAdmin = true - - if err := bus.Dispatch(&cmd); err != nil { - return fmt.Errorf("Failed to create admin user: %v", err) - } - - ss.log.Info("Created default admin user: %v", setting.AdminUser) - - return nil + return err } func (ss *SqlStore) buildConnectionString() (string, error) { diff --git a/pkg/services/sqlstore/user.go b/pkg/services/sqlstore/user.go index e7aa8da837a..befc3a08401 100644 --- a/pkg/services/sqlstore/user.go +++ b/pkg/services/sqlstore/user.go @@ -1,6 +1,7 @@ package sqlstore import ( + "context" "strconv" "strings" "time" @@ -30,6 +31,8 @@ func init() { bus.AddHandler("sql", DeleteUser) bus.AddHandler("sql", UpdateUserPermissions) bus.AddHandler("sql", SetUserHelpFlag) + + bus.AddCtxHandler("sql", CreateUserCtx) } func getOrgIdForNewUser(cmd *m.CreateUserCommand, sess *DBSession) (int64, error) { @@ -79,77 +82,87 @@ func getOrgIdForNewUser(cmd *m.CreateUserCommand, sess *DBSession) (int64, error return org.Id, nil } +func internalCreateUser(sess *DBSession, cmd *m.CreateUserCommand) error { + orgId, err := getOrgIdForNewUser(cmd, sess) + if err != nil { + return err + } + + if cmd.Email == "" { + cmd.Email = cmd.Login + } + + // create user + user := m.User{ + Email: cmd.Email, + Name: cmd.Name, + Login: cmd.Login, + Company: cmd.Company, + IsAdmin: cmd.IsAdmin, + OrgId: orgId, + EmailVerified: cmd.EmailVerified, + Created: time.Now(), + Updated: time.Now(), + LastSeenAt: time.Now().AddDate(-10, 0, 0), + } + + if len(cmd.Password) > 0 { + user.Salt = util.GetRandomString(10) + user.Rands = util.GetRandomString(10) + user.Password = util.EncodePassword(cmd.Password, user.Salt) + } + + sess.UseBool("is_admin") + + if _, err := sess.Insert(&user); err != nil { + return err + } + + sess.publishAfterCommit(&events.UserCreated{ + Timestamp: user.Created, + Id: user.Id, + Name: user.Name, + Login: user.Login, + Email: user.Email, + }) + + cmd.Result = user + + // create org user link + if !cmd.SkipOrgSetup { + orgUser := m.OrgUser{ + OrgId: orgId, + UserId: user.Id, + Role: m.ROLE_ADMIN, + Created: time.Now(), + Updated: time.Now(), + } + + if setting.AutoAssignOrg && !user.IsAdmin { + if len(cmd.DefaultOrgRole) > 0 { + orgUser.Role = m.RoleType(cmd.DefaultOrgRole) + } else { + orgUser.Role = m.RoleType(setting.AutoAssignOrgRole) + } + } + + if _, err = sess.Insert(&orgUser); err != nil { + return err + } + } + + return nil +} + +func CreateUserCtx(ctx context.Context, cmd *m.CreateUserCommand) error { + return inTransactionWithRetryCtx(ctx, func(sess *DBSession) error { + return internalCreateUser(sess, cmd) + }, 0) +} + func CreateUser(cmd *m.CreateUserCommand) error { return inTransaction(func(sess *DBSession) error { - orgId, err := getOrgIdForNewUser(cmd, sess) - if err != nil { - return err - } - - if cmd.Email == "" { - cmd.Email = cmd.Login - } - - // create user - user := m.User{ - Email: cmd.Email, - Name: cmd.Name, - Login: cmd.Login, - Company: cmd.Company, - IsAdmin: cmd.IsAdmin, - OrgId: orgId, - EmailVerified: cmd.EmailVerified, - Created: time.Now(), - Updated: time.Now(), - LastSeenAt: time.Now().AddDate(-10, 0, 0), - } - - if len(cmd.Password) > 0 { - user.Salt = util.GetRandomString(10) - user.Rands = util.GetRandomString(10) - user.Password = util.EncodePassword(cmd.Password, user.Salt) - } - - sess.UseBool("is_admin") - - if _, err := sess.Insert(&user); err != nil { - return err - } - - sess.publishAfterCommit(&events.UserCreated{ - Timestamp: user.Created, - Id: user.Id, - Name: user.Name, - Login: user.Login, - Email: user.Email, - }) - - cmd.Result = user - - // create org user link - if !cmd.SkipOrgSetup { - orgUser := m.OrgUser{ - OrgId: orgId, - UserId: user.Id, - Role: m.ROLE_ADMIN, - Created: time.Now(), - Updated: time.Now(), - } - - if setting.AutoAssignOrg && !user.IsAdmin { - if len(cmd.DefaultOrgRole) > 0 { - orgUser.Role = m.RoleType(cmd.DefaultOrgRole) - } else { - orgUser.Role = m.RoleType(setting.AutoAssignOrgRole) - } - } - - if _, err = sess.Insert(&orgUser); err != nil { - return err - } - } - - return nil + return internalCreateUser(sess, cmd) }) }