Skip to content

Commit 3e5abe7

Browse files
Shavonn Brownmarefr
Shavonn Brown
authored andcommitted
Admin: Adds setting to disable creating initial admin user (grafana#19505)
Adds a new setting disable_admin_user and when true the default admin user will not be created when Grafana starts for the first time (or no users exists in the system). Closes grafana#19038
1 parent 7ebc4a1 commit 3e5abe7

File tree

7 files changed

+110
-67
lines changed

7 files changed

+110
-67
lines changed

conf/defaults.ini

+3
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,9 @@ google_tag_manager_id =
155155

156156
#################################### Security ############################
157157
[security]
158+
# disable creation of admin user on first start of grafana
159+
disable_initial_admin_creation = false
160+
158161
# default admin user, created on startup
159162
admin_user = admin
160163

conf/sample.ini

+3
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,9 @@
151151

152152
#################################### Security ####################################
153153
[security]
154+
# disable creation of admin user on first start of grafana
155+
;disable_initial_admin_creation = false
156+
154157
# default admin user, created on startup
155158
;admin_user = admin
156159

docs/sources/installation/configuration.md

+6
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,12 @@ Example connstr: `127.0.0.1:11211`
305305

306306
## [security]
307307

308+
### disable_initial_admin_creation
309+
310+
> Only available in Grafana v6.5+.
311+
312+
Disable creation of admin user on first start of grafana.
313+
308314
### admin_user
309315

310316
The name of the default Grafana admin user (who has full permissions).

pkg/services/sqlstore/org.go

+62
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
package sqlstore
22

33
import (
4+
"context"
5+
"fmt"
46
"time"
57

68
"github.com/grafana/grafana/pkg/bus"
79
"github.com/grafana/grafana/pkg/events"
810
m "github.com/grafana/grafana/pkg/models"
11+
"github.com/grafana/grafana/pkg/setting"
912
)
1013

14+
const mainOrgName = "Main Org."
15+
1116
func init() {
1217
bus.AddHandler("sql", GetOrgById)
1318
bus.AddHandler("sql", CreateOrg)
@@ -214,3 +219,60 @@ func DeleteOrg(cmd *m.DeleteOrgCommand) error {
214219
return nil
215220
})
216221
}
222+
223+
func getOrCreateOrg(sess *DBSession, orgName string) (int64, error) {
224+
var org m.Org
225+
226+
if setting.AutoAssignOrg {
227+
has, err := sess.Where("id=?", setting.AutoAssignOrgId).Get(&org)
228+
if err != nil {
229+
return 0, err
230+
}
231+
if has {
232+
return org.Id, nil
233+
}
234+
if setting.AutoAssignOrgId == 1 {
235+
org.Name = mainOrgName
236+
org.Id = int64(setting.AutoAssignOrgId)
237+
} else {
238+
sqlog.Info("Could not create user: organization id %v does not exist",
239+
setting.AutoAssignOrgId)
240+
return 0, fmt.Errorf("Could not create user: organization id %v does not exist",
241+
setting.AutoAssignOrgId)
242+
}
243+
} else {
244+
org.Name = orgName
245+
}
246+
247+
org.Created = time.Now()
248+
org.Updated = time.Now()
249+
250+
if org.Id != 0 {
251+
if _, err := sess.InsertId(&org); err != nil {
252+
return 0, err
253+
}
254+
} else {
255+
if _, err := sess.InsertOne(&org); err != nil {
256+
return 0, err
257+
}
258+
}
259+
260+
sess.publishAfterCommit(&events.OrgCreated{
261+
Timestamp: org.Created,
262+
Id: org.Id,
263+
Name: org.Name,
264+
})
265+
266+
return org.Id, nil
267+
}
268+
269+
func createDefaultOrg(ctx context.Context) error {
270+
return inTransactionCtx(ctx, func(sess *DBSession) error {
271+
_, err := getOrCreateOrg(sess, mainOrgName)
272+
if err != nil {
273+
return err
274+
}
275+
276+
return nil
277+
})
278+
}

pkg/services/sqlstore/sqlstore.go

+28-21
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,11 @@ type SqlStore struct {
5555
Bus bus.Bus `inject:""`
5656
CacheService *localcache.CacheService `inject:""`
5757

58-
dbCfg DatabaseConfig
59-
engine *xorm.Engine
60-
log log.Logger
61-
Dialect migrator.Dialect
62-
skipEnsureAdmin bool
58+
dbCfg DatabaseConfig
59+
engine *xorm.Engine
60+
log log.Logger
61+
Dialect migrator.Dialect
62+
skipEnsureDefaultOrgAndUser bool
6363
}
6464

6565
func (ss *SqlStore) Init() error {
@@ -100,19 +100,16 @@ func (ss *SqlStore) Init() error {
100100
// Register handlers
101101
ss.addUserQueryAndCommandHandlers()
102102

103-
// ensure admin user
104-
if ss.skipEnsureAdmin {
103+
if ss.skipEnsureDefaultOrgAndUser {
105104
return nil
106105
}
107106

108-
return ss.ensureAdminUser()
107+
return ss.ensureMainOrgAndAdminUser()
109108
}
110109

111-
func (ss *SqlStore) ensureAdminUser() error {
112-
systemUserCountQuery := m.GetSystemUserCountStatsQuery{}
113-
110+
func (ss *SqlStore) ensureMainOrgAndAdminUser() error {
114111
err := ss.InTransaction(context.Background(), func(ctx context.Context) error {
115-
112+
systemUserCountQuery := m.GetSystemUserCountStatsQuery{}
116113
err := bus.DispatchCtx(ctx, &systemUserCountQuery)
117114
if err != nil {
118115
return fmt.Errorf("Could not determine if admin user exists: %v", err)
@@ -122,18 +119,28 @@ func (ss *SqlStore) ensureAdminUser() error {
122119
return nil
123120
}
124121

125-
cmd := m.CreateUserCommand{}
126-
cmd.Login = setting.AdminUser
127-
cmd.Email = setting.AdminUser + "@localhost"
128-
cmd.Password = setting.AdminPassword
129-
cmd.IsAdmin = true
122+
// ensure admin user
123+
if !ss.Cfg.DisableInitAdminCreation {
124+
cmd := m.CreateUserCommand{}
125+
cmd.Login = setting.AdminUser
126+
cmd.Email = setting.AdminUser + "@localhost"
127+
cmd.Password = setting.AdminPassword
128+
cmd.IsAdmin = true
129+
130+
if err := bus.DispatchCtx(ctx, &cmd); err != nil {
131+
return fmt.Errorf("Failed to create admin user: %v", err)
132+
}
130133

131-
if err := bus.DispatchCtx(ctx, &cmd); err != nil {
132-
return fmt.Errorf("Failed to create admin user: %v", err)
134+
ss.log.Info("Created default admin", "user", setting.AdminUser)
135+
return nil
133136
}
134137

135-
ss.log.Info("Created default admin", "user", setting.AdminUser)
138+
// ensure default org if default admin user is disabled
139+
if err := createDefaultOrg(ctx); err != nil {
140+
return errutil.Wrap("Failed to create default organization", err)
141+
}
136142

143+
ss.log.Info("Created default organization")
137144
return nil
138145
})
139146

@@ -305,9 +312,9 @@ type ITestDB interface {
305312
func InitTestDB(t ITestDB) *SqlStore {
306313
t.Helper()
307314
sqlstore := &SqlStore{}
308-
sqlstore.skipEnsureAdmin = true
309315
sqlstore.Bus = bus.New()
310316
sqlstore.CacheService = localcache.New(5*time.Minute, 10*time.Minute)
317+
sqlstore.skipEnsureDefaultOrgAndUser = true
311318

312319
dbType := migrator.SQLITE
313320

pkg/services/sqlstore/user.go

+6-46
Original file line numberDiff line numberDiff line change
@@ -35,62 +35,22 @@ func (ss *SqlStore) addUserQueryAndCommandHandlers() {
3535
bus.AddHandlerCtx("sql", CreateUser)
3636
}
3737

38-
func getOrgIdForNewUser(cmd *models.CreateUserCommand, sess *DBSession) (int64, error) {
38+
func getOrgIdForNewUser(sess *DBSession, cmd *models.CreateUserCommand) (int64, error) {
3939
if cmd.SkipOrgSetup {
4040
return -1, nil
4141
}
4242

43-
var org models.Org
44-
45-
if setting.AutoAssignOrg {
46-
has, err := sess.Where("id=?", setting.AutoAssignOrgId).Get(&org)
47-
if err != nil {
48-
return 0, err
49-
}
50-
if has {
51-
return org.Id, nil
52-
}
53-
if setting.AutoAssignOrgId == 1 {
54-
org.Name = "Main Org."
55-
org.Id = int64(setting.AutoAssignOrgId)
56-
} else {
57-
sqlog.Info("Could not create user: organization id %v does not exist",
58-
setting.AutoAssignOrgId)
59-
return 0, fmt.Errorf("Could not create user: organization id %v does not exist",
60-
setting.AutoAssignOrgId)
61-
}
62-
} else {
63-
org.Name = cmd.OrgName
64-
if len(org.Name) == 0 {
65-
org.Name = util.StringsFallback2(cmd.Email, cmd.Login)
66-
}
43+
orgName := cmd.OrgName
44+
if len(orgName) == 0 {
45+
orgName = util.StringsFallback2(cmd.Email, cmd.Login)
6746
}
6847

69-
org.Created = time.Now()
70-
org.Updated = time.Now()
71-
72-
if org.Id != 0 {
73-
if _, err := sess.InsertId(&org); err != nil {
74-
return 0, err
75-
}
76-
} else {
77-
if _, err := sess.InsertOne(&org); err != nil {
78-
return 0, err
79-
}
80-
}
81-
82-
sess.publishAfterCommit(&events.OrgCreated{
83-
Timestamp: org.Created,
84-
Id: org.Id,
85-
Name: org.Name,
86-
})
87-
88-
return org.Id, nil
48+
return getOrCreateOrg(sess, orgName)
8949
}
9050

9151
func CreateUser(ctx context.Context, cmd *models.CreateUserCommand) error {
9252
return inTransactionCtx(ctx, func(sess *DBSession) error {
93-
orgId, err := getOrgIdForNewUser(cmd, sess)
53+
orgId, err := getOrgIdForNewUser(sess, cmd)
9454
if err != nil {
9555
return err
9656
}

pkg/setting/setting.go

+2
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ type Cfg struct {
243243
RendererLimitAlerting int
244244

245245
// Security
246+
DisableInitAdminCreation bool
246247
DisableBruteForceLoginProtection bool
247248
CookieSecure bool
248249
CookieSameSite http.SameSite
@@ -763,6 +764,7 @@ func (cfg *Cfg) Load(args *CommandLineArgs) error {
763764
}
764765

765766
// admin
767+
cfg.DisableInitAdminCreation = security.Key("disable_initial_admin_creation").MustBool(false)
766768
AdminUser, err = valueAsString(security, "admin_user", "")
767769
if err != nil {
768770
return err

0 commit comments

Comments
 (0)