mirror of
https://github.com/grafana/grafana.git
synced 2025-02-20 11:48:34 -06:00
Admin: Adds setting to disable creating initial admin user (#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 #19038
This commit is contained in:
parent
7ebc4a1568
commit
3e5abe7c21
@ -155,6 +155,9 @@ google_tag_manager_id =
|
||||
|
||||
#################################### Security ############################
|
||||
[security]
|
||||
# disable creation of admin user on first start of grafana
|
||||
disable_initial_admin_creation = false
|
||||
|
||||
# default admin user, created on startup
|
||||
admin_user = admin
|
||||
|
||||
|
@ -151,6 +151,9 @@
|
||||
|
||||
#################################### Security ####################################
|
||||
[security]
|
||||
# disable creation of admin user on first start of grafana
|
||||
;disable_initial_admin_creation = false
|
||||
|
||||
# default admin user, created on startup
|
||||
;admin_user = admin
|
||||
|
||||
|
@ -305,6 +305,12 @@ Example connstr: `127.0.0.1:11211`
|
||||
|
||||
## [security]
|
||||
|
||||
### disable_initial_admin_creation
|
||||
|
||||
> Only available in Grafana v6.5+.
|
||||
|
||||
Disable creation of admin user on first start of grafana.
|
||||
|
||||
### admin_user
|
||||
|
||||
The name of the default Grafana admin user (who has full permissions).
|
||||
|
@ -1,13 +1,18 @@
|
||||
package sqlstore
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/events"
|
||||
m "github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
const mainOrgName = "Main Org."
|
||||
|
||||
func init() {
|
||||
bus.AddHandler("sql", GetOrgById)
|
||||
bus.AddHandler("sql", CreateOrg)
|
||||
@ -214,3 +219,60 @@ func DeleteOrg(cmd *m.DeleteOrgCommand) error {
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func getOrCreateOrg(sess *DBSession, orgName string) (int64, error) {
|
||||
var org m.Org
|
||||
|
||||
if setting.AutoAssignOrg {
|
||||
has, err := sess.Where("id=?", setting.AutoAssignOrgId).Get(&org)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if has {
|
||||
return org.Id, nil
|
||||
}
|
||||
if setting.AutoAssignOrgId == 1 {
|
||||
org.Name = mainOrgName
|
||||
org.Id = int64(setting.AutoAssignOrgId)
|
||||
} else {
|
||||
sqlog.Info("Could not create user: organization id %v does not exist",
|
||||
setting.AutoAssignOrgId)
|
||||
return 0, fmt.Errorf("Could not create user: organization id %v does not exist",
|
||||
setting.AutoAssignOrgId)
|
||||
}
|
||||
} else {
|
||||
org.Name = orgName
|
||||
}
|
||||
|
||||
org.Created = time.Now()
|
||||
org.Updated = time.Now()
|
||||
|
||||
if org.Id != 0 {
|
||||
if _, err := sess.InsertId(&org); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
} else {
|
||||
if _, err := sess.InsertOne(&org); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
|
||||
sess.publishAfterCommit(&events.OrgCreated{
|
||||
Timestamp: org.Created,
|
||||
Id: org.Id,
|
||||
Name: org.Name,
|
||||
})
|
||||
|
||||
return org.Id, nil
|
||||
}
|
||||
|
||||
func createDefaultOrg(ctx context.Context) error {
|
||||
return inTransactionCtx(ctx, func(sess *DBSession) error {
|
||||
_, err := getOrCreateOrg(sess, mainOrgName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
@ -55,11 +55,11 @@ type SqlStore struct {
|
||||
Bus bus.Bus `inject:""`
|
||||
CacheService *localcache.CacheService `inject:""`
|
||||
|
||||
dbCfg DatabaseConfig
|
||||
engine *xorm.Engine
|
||||
log log.Logger
|
||||
Dialect migrator.Dialect
|
||||
skipEnsureAdmin bool
|
||||
dbCfg DatabaseConfig
|
||||
engine *xorm.Engine
|
||||
log log.Logger
|
||||
Dialect migrator.Dialect
|
||||
skipEnsureDefaultOrgAndUser bool
|
||||
}
|
||||
|
||||
func (ss *SqlStore) Init() error {
|
||||
@ -100,19 +100,16 @@ func (ss *SqlStore) Init() error {
|
||||
// Register handlers
|
||||
ss.addUserQueryAndCommandHandlers()
|
||||
|
||||
// ensure admin user
|
||||
if ss.skipEnsureAdmin {
|
||||
if ss.skipEnsureDefaultOrgAndUser {
|
||||
return nil
|
||||
}
|
||||
|
||||
return ss.ensureAdminUser()
|
||||
return ss.ensureMainOrgAndAdminUser()
|
||||
}
|
||||
|
||||
func (ss *SqlStore) ensureAdminUser() error {
|
||||
systemUserCountQuery := m.GetSystemUserCountStatsQuery{}
|
||||
|
||||
func (ss *SqlStore) ensureMainOrgAndAdminUser() error {
|
||||
err := ss.InTransaction(context.Background(), func(ctx context.Context) error {
|
||||
|
||||
systemUserCountQuery := m.GetSystemUserCountStatsQuery{}
|
||||
err := bus.DispatchCtx(ctx, &systemUserCountQuery)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Could not determine if admin user exists: %v", err)
|
||||
@ -122,18 +119,28 @@ func (ss *SqlStore) ensureAdminUser() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
cmd := m.CreateUserCommand{}
|
||||
cmd.Login = setting.AdminUser
|
||||
cmd.Email = setting.AdminUser + "@localhost"
|
||||
cmd.Password = setting.AdminPassword
|
||||
cmd.IsAdmin = true
|
||||
// ensure admin user
|
||||
if !ss.Cfg.DisableInitAdminCreation {
|
||||
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)
|
||||
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
|
||||
}
|
||||
|
||||
ss.log.Info("Created default admin", "user", setting.AdminUser)
|
||||
// ensure default org if default admin user is disabled
|
||||
if err := createDefaultOrg(ctx); err != nil {
|
||||
return errutil.Wrap("Failed to create default organization", err)
|
||||
}
|
||||
|
||||
ss.log.Info("Created default organization")
|
||||
return nil
|
||||
})
|
||||
|
||||
@ -305,9 +312,9 @@ type ITestDB interface {
|
||||
func InitTestDB(t ITestDB) *SqlStore {
|
||||
t.Helper()
|
||||
sqlstore := &SqlStore{}
|
||||
sqlstore.skipEnsureAdmin = true
|
||||
sqlstore.Bus = bus.New()
|
||||
sqlstore.CacheService = localcache.New(5*time.Minute, 10*time.Minute)
|
||||
sqlstore.skipEnsureDefaultOrgAndUser = true
|
||||
|
||||
dbType := migrator.SQLITE
|
||||
|
||||
|
@ -35,62 +35,22 @@ func (ss *SqlStore) addUserQueryAndCommandHandlers() {
|
||||
bus.AddHandlerCtx("sql", CreateUser)
|
||||
}
|
||||
|
||||
func getOrgIdForNewUser(cmd *models.CreateUserCommand, sess *DBSession) (int64, error) {
|
||||
func getOrgIdForNewUser(sess *DBSession, cmd *models.CreateUserCommand) (int64, error) {
|
||||
if cmd.SkipOrgSetup {
|
||||
return -1, nil
|
||||
}
|
||||
|
||||
var org models.Org
|
||||
|
||||
if setting.AutoAssignOrg {
|
||||
has, err := sess.Where("id=?", setting.AutoAssignOrgId).Get(&org)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if has {
|
||||
return org.Id, nil
|
||||
}
|
||||
if setting.AutoAssignOrgId == 1 {
|
||||
org.Name = "Main Org."
|
||||
org.Id = int64(setting.AutoAssignOrgId)
|
||||
} else {
|
||||
sqlog.Info("Could not create user: organization id %v does not exist",
|
||||
setting.AutoAssignOrgId)
|
||||
return 0, fmt.Errorf("Could not create user: organization id %v does not exist",
|
||||
setting.AutoAssignOrgId)
|
||||
}
|
||||
} else {
|
||||
org.Name = cmd.OrgName
|
||||
if len(org.Name) == 0 {
|
||||
org.Name = util.StringsFallback2(cmd.Email, cmd.Login)
|
||||
}
|
||||
orgName := cmd.OrgName
|
||||
if len(orgName) == 0 {
|
||||
orgName = util.StringsFallback2(cmd.Email, cmd.Login)
|
||||
}
|
||||
|
||||
org.Created = time.Now()
|
||||
org.Updated = time.Now()
|
||||
|
||||
if org.Id != 0 {
|
||||
if _, err := sess.InsertId(&org); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
} else {
|
||||
if _, err := sess.InsertOne(&org); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
|
||||
sess.publishAfterCommit(&events.OrgCreated{
|
||||
Timestamp: org.Created,
|
||||
Id: org.Id,
|
||||
Name: org.Name,
|
||||
})
|
||||
|
||||
return org.Id, nil
|
||||
return getOrCreateOrg(sess, orgName)
|
||||
}
|
||||
|
||||
func CreateUser(ctx context.Context, cmd *models.CreateUserCommand) error {
|
||||
return inTransactionCtx(ctx, func(sess *DBSession) error {
|
||||
orgId, err := getOrgIdForNewUser(cmd, sess)
|
||||
orgId, err := getOrgIdForNewUser(sess, cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -243,6 +243,7 @@ type Cfg struct {
|
||||
RendererLimitAlerting int
|
||||
|
||||
// Security
|
||||
DisableInitAdminCreation bool
|
||||
DisableBruteForceLoginProtection bool
|
||||
CookieSecure bool
|
||||
CookieSameSite http.SameSite
|
||||
@ -763,6 +764,7 @@ func (cfg *Cfg) Load(args *CommandLineArgs) error {
|
||||
}
|
||||
|
||||
// admin
|
||||
cfg.DisableInitAdminCreation = security.Key("disable_initial_admin_creation").MustBool(false)
|
||||
AdminUser, err = valueAsString(security, "admin_user", "")
|
||||
if err != nil {
|
||||
return err
|
||||
|
Loading…
Reference in New Issue
Block a user