* Remove unused custom-alphabet feature of random string generator Fix random string generator Random string generator should return error if it fails to read random data via crypto/rand * Fixes variable (un)initialization mixed assign Update test GetRandomStringtags/v1.0.0
} | } | ||||
for _, org := range orgs { | for _, org := range orgs { | ||||
org.Rands = base.GetRandomString(10) | |||||
org.Salt = base.GetRandomString(10) | |||||
if org.Rands, err = base.GetRandomString(10); err != nil { | |||||
return err | |||||
} | |||||
if org.Salt, err = base.GetRandomString(10); err != nil { | |||||
return err | |||||
} | |||||
if _, err = sess.Id(org.ID).Update(org); err != nil { | if _, err = sess.Id(org.ID).Update(org); err != nil { | ||||
return err | return err | ||||
} | } |
} | } | ||||
org.LowerName = strings.ToLower(org.Name) | org.LowerName = strings.ToLower(org.Name) | ||||
org.Rands = GetUserSalt() | |||||
org.Salt = GetUserSalt() | |||||
if org.Rands, err = GetUserSalt(); err != nil { | |||||
return err | |||||
} | |||||
if org.Salt, err = GetUserSalt(); err != nil { | |||||
return err | |||||
} | |||||
org.UseCustomAvatar = true | org.UseCustomAvatar = true | ||||
org.MaxRepoCreation = -1 | org.MaxRepoCreation = -1 | ||||
org.NumTeams = 1 | org.NumTeams = 1 |
} | } | ||||
// GetUserSalt returns a ramdom user salt token. | // GetUserSalt returns a ramdom user salt token. | ||||
func GetUserSalt() string { | |||||
func GetUserSalt() (string, error) { | |||||
return base.GetRandomString(10) | return base.GetRandomString(10) | ||||
} | } | ||||
u.LowerName = strings.ToLower(u.Name) | u.LowerName = strings.ToLower(u.Name) | ||||
u.AvatarEmail = u.Email | u.AvatarEmail = u.Email | ||||
u.Avatar = base.HashEmail(u.AvatarEmail) | u.Avatar = base.HashEmail(u.AvatarEmail) | ||||
u.Rands = GetUserSalt() | |||||
u.Salt = GetUserSalt() | |||||
if u.Rands, err = GetUserSalt(); err != nil { | |||||
return err | |||||
} | |||||
if u.Salt, err = GetUserSalt(); err != nil { | |||||
return err | |||||
} | |||||
u.EncodePasswd() | u.EncodePasswd() | ||||
u.MaxRepoCreation = -1 | u.MaxRepoCreation = -1 | ||||
if err != nil { | if err != nil { | ||||
return err | return err | ||||
} | } | ||||
user.Rands = GetUserSalt() | |||||
if user.Rands, err = GetUserSalt(); err != nil { | |||||
return err | |||||
} | |||||
sess := x.NewSession() | sess := x.NewSession() | ||||
defer sessionRelease(sess) | defer sessionRelease(sess) |
"fmt" | "fmt" | ||||
"html/template" | "html/template" | ||||
"math" | "math" | ||||
"math/big" | |||||
"net/http" | "net/http" | ||||
"strconv" | "strconv" | ||||
"strings" | "strings" | ||||
} | } | ||||
// GetRandomString generate random string by specify chars. | // GetRandomString generate random string by specify chars. | ||||
func GetRandomString(n int, alphabets ...byte) string { | |||||
func GetRandomString(n int) (string, error) { | |||||
const alphanum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" | const alphanum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" | ||||
var bytes = make([]byte, n) | |||||
rand.Read(bytes) | |||||
for i, b := range bytes { | |||||
if len(alphabets) == 0 { | |||||
bytes[i] = alphanum[b%byte(len(alphanum))] | |||||
} else { | |||||
bytes[i] = alphabets[b%byte(len(alphabets))] | |||||
buffer := make([]byte, n) | |||||
max := big.NewInt(int64(len(alphanum))) | |||||
for i := 0; i < n; i++ { | |||||
index, err := randomInt(max) | |||||
if err != nil { | |||||
return "", err | |||||
} | } | ||||
buffer[i] = alphanum[index] | |||||
} | } | ||||
return string(bytes) | |||||
return string(buffer), nil | |||||
} | |||||
func randomInt(max *big.Int) (int, error) { | |||||
rand, err := rand.Int(rand.Reader, max) | |||||
if err != nil { | |||||
return 0, err | |||||
} | |||||
return int(rand.Int64()), nil | |||||
} | } | ||||
// VerifyTimeLimitCode verify time limit code | // VerifyTimeLimitCode verify time limit code |
} | } | ||||
func TestGetRandomString(t *testing.T) { | func TestGetRandomString(t *testing.T) { | ||||
assert.Len(t, GetRandomString(4), 4) | |||||
randomString, err := GetRandomString(4) | |||||
assert.NoError(t, err) | |||||
assert.Len(t, randomString, 4) | |||||
} | } | ||||
// TODO: Test PBKDF2() | // TODO: Test PBKDF2() |
if len(form.Password) > 0 { | if len(form.Password) > 0 { | ||||
u.Passwd = form.Password | u.Passwd = form.Password | ||||
u.Salt = models.GetUserSalt() | |||||
var err error | |||||
if u.Salt, err = models.GetUserSalt(); err != nil { | |||||
ctx.Handle(500, "UpdateUser", err) | |||||
return | |||||
} | |||||
u.EncodePasswd() | u.EncodePasswd() | ||||
} | } | ||||
if len(form.Password) > 0 { | if len(form.Password) > 0 { | ||||
u.Passwd = form.Password | u.Passwd = form.Password | ||||
u.Salt = models.GetUserSalt() | |||||
var err error | |||||
if u.Salt, err = models.GetUserSalt(); err != nil { | |||||
ctx.Error(500, "UpdateUser", err) | |||||
return | |||||
} | |||||
u.EncodePasswd() | u.EncodePasswd() | ||||
} | } | ||||
// InstallPost response for submit install items | // InstallPost response for submit install items | ||||
func InstallPost(ctx *context.Context, form auth.InstallForm) { | func InstallPost(ctx *context.Context, form auth.InstallForm) { | ||||
var err error | |||||
ctx.Data["CurDbOption"] = form.DbType | ctx.Data["CurDbOption"] = form.DbType | ||||
if ctx.HasError() { | if ctx.HasError() { | ||||
return | return | ||||
} | } | ||||
if _, err := exec.LookPath("git"); err != nil { | |||||
if _, err = exec.LookPath("git"); err != nil { | |||||
ctx.RenderWithErr(ctx.Tr("install.test_git_failed", err), tplInstall, &form) | ctx.RenderWithErr(ctx.Tr("install.test_git_failed", err), tplInstall, &form) | ||||
return | return | ||||
} | } | ||||
// Set test engine. | // Set test engine. | ||||
var x *xorm.Engine | var x *xorm.Engine | ||||
if err := models.NewTestEngine(x); err != nil { | |||||
if err = models.NewTestEngine(x); err != nil { | |||||
if strings.Contains(err.Error(), `Unknown database type: sqlite3`) { | if strings.Contains(err.Error(), `Unknown database type: sqlite3`) { | ||||
ctx.Data["Err_DbType"] = true | ctx.Data["Err_DbType"] = true | ||||
ctx.RenderWithErr(ctx.Tr("install.sqlite3_not_available", "https://docs.gitea.io/installation/install_from_binary.html"), tplInstall, &form) | ctx.RenderWithErr(ctx.Tr("install.sqlite3_not_available", "https://docs.gitea.io/installation/install_from_binary.html"), tplInstall, &form) | ||||
// Test repository root path. | // Test repository root path. | ||||
form.RepoRootPath = strings.Replace(form.RepoRootPath, "\\", "/", -1) | form.RepoRootPath = strings.Replace(form.RepoRootPath, "\\", "/", -1) | ||||
if err := os.MkdirAll(form.RepoRootPath, os.ModePerm); err != nil { | |||||
if err = os.MkdirAll(form.RepoRootPath, os.ModePerm); err != nil { | |||||
ctx.Data["Err_RepoRootPath"] = true | ctx.Data["Err_RepoRootPath"] = true | ||||
ctx.RenderWithErr(ctx.Tr("install.invalid_repo_path", err), tplInstall, &form) | ctx.RenderWithErr(ctx.Tr("install.invalid_repo_path", err), tplInstall, &form) | ||||
return | return | ||||
// Test log root path. | // Test log root path. | ||||
form.LogRootPath = strings.Replace(form.LogRootPath, "\\", "/", -1) | form.LogRootPath = strings.Replace(form.LogRootPath, "\\", "/", -1) | ||||
if err := os.MkdirAll(form.LogRootPath, os.ModePerm); err != nil { | |||||
if err = os.MkdirAll(form.LogRootPath, os.ModePerm); err != nil { | |||||
ctx.Data["Err_LogRootPath"] = true | ctx.Data["Err_LogRootPath"] = true | ||||
ctx.RenderWithErr(ctx.Tr("install.invalid_log_root_path", err), tplInstall, &form) | ctx.RenderWithErr(ctx.Tr("install.invalid_log_root_path", err), tplInstall, &form) | ||||
return | return | ||||
cfg := ini.Empty() | cfg := ini.Empty() | ||||
if com.IsFile(setting.CustomConf) { | if com.IsFile(setting.CustomConf) { | ||||
// Keeps custom settings if there is already something. | // Keeps custom settings if there is already something. | ||||
if err := cfg.Append(setting.CustomConf); err != nil { | |||||
if err = cfg.Append(setting.CustomConf); err != nil { | |||||
log.Error(4, "Fail to load custom conf '%s': %v", setting.CustomConf, err) | log.Error(4, "Fail to load custom conf '%s': %v", setting.CustomConf, err) | ||||
} | } | ||||
} | } | ||||
cfg.Section("log").Key("ROOT_PATH").SetValue(form.LogRootPath) | cfg.Section("log").Key("ROOT_PATH").SetValue(form.LogRootPath) | ||||
cfg.Section("security").Key("INSTALL_LOCK").SetValue("true") | cfg.Section("security").Key("INSTALL_LOCK").SetValue("true") | ||||
cfg.Section("security").Key("SECRET_KEY").SetValue(base.GetRandomString(15)) | |||||
var secretKey string | |||||
if secretKey, err = base.GetRandomString(10); err != nil { | |||||
ctx.RenderWithErr(ctx.Tr("install.secret_key_failed", err), tplInstall, &form) | |||||
return | |||||
} | |||||
cfg.Section("security").Key("SECRET_KEY").SetValue(secretKey) | |||||
err := os.MkdirAll(filepath.Dir(setting.CustomConf), os.ModePerm) | |||||
err = os.MkdirAll(filepath.Dir(setting.CustomConf), os.ModePerm) | |||||
if err != nil { | if err != nil { | ||||
ctx.RenderWithErr(ctx.Tr("install.save_config_failed", err), tplInstall, &form) | ctx.RenderWithErr(ctx.Tr("install.save_config_failed", err), tplInstall, &form) | ||||
return | return | ||||
} | } | ||||
if err := cfg.SaveTo(setting.CustomConf); err != nil { | |||||
if err = cfg.SaveTo(setting.CustomConf); err != nil { | |||||
ctx.RenderWithErr(ctx.Tr("install.save_config_failed", err), tplInstall, &form) | ctx.RenderWithErr(ctx.Tr("install.save_config_failed", err), tplInstall, &form) | ||||
return | return | ||||
} | } | ||||
IsAdmin: true, | IsAdmin: true, | ||||
IsActive: true, | IsActive: true, | ||||
} | } | ||||
if err := models.CreateUser(u); err != nil { | |||||
if err = models.CreateUser(u); err != nil { | |||||
if !models.IsErrUserAlreadyExist(err) { | if !models.IsErrUserAlreadyExist(err) { | ||||
setting.InstallLock = false | setting.InstallLock = false | ||||
ctx.Data["Err_AdminName"] = true | ctx.Data["Err_AdminName"] = true | ||||
} | } | ||||
// Auto-login for admin | // Auto-login for admin | ||||
if err := ctx.Session.Set("uid", u.ID); err != nil { | |||||
if err = ctx.Session.Set("uid", u.ID); err != nil { | |||||
ctx.RenderWithErr(ctx.Tr("install.save_config_failed", err), tplInstall, &form) | ctx.RenderWithErr(ctx.Tr("install.save_config_failed", err), tplInstall, &form) | ||||
return | return | ||||
} | } | ||||
if err := ctx.Session.Set("uname", u.Name); err != nil { | |||||
if err = ctx.Session.Set("uname", u.Name); err != nil { | |||||
ctx.RenderWithErr(ctx.Tr("install.save_config_failed", err), tplInstall, &form) | ctx.RenderWithErr(ctx.Tr("install.save_config_failed", err), tplInstall, &form) | ||||
return | return | ||||
} | } |
// Verify code. | // Verify code. | ||||
if user := models.VerifyUserActiveCode(code); user != nil { | if user := models.VerifyUserActiveCode(code); user != nil { | ||||
user.IsActive = true | user.IsActive = true | ||||
user.Rands = models.GetUserSalt() | |||||
var err error | |||||
if user.Rands, err = models.GetUserSalt(); err != nil { | |||||
ctx.Handle(500, "UpdateUser", err) | |||||
return | |||||
} | |||||
if err := models.UpdateUser(user); err != nil { | if err := models.UpdateUser(user); err != nil { | ||||
if models.IsErrUserNotExist(err) { | if models.IsErrUserNotExist(err) { | ||||
ctx.Error(404) | ctx.Error(404) | ||||
} | } | ||||
u.Passwd = passwd | u.Passwd = passwd | ||||
u.Rands = models.GetUserSalt() | |||||
u.Salt = models.GetUserSalt() | |||||
var err error | |||||
if u.Rands, err = models.GetUserSalt(); err != nil { | |||||
ctx.Handle(500, "UpdateUser", err) | |||||
return | |||||
} | |||||
if u.Salt, err = models.GetUserSalt(); err != nil { | |||||
ctx.Handle(500, "UpdateUser", err) | |||||
return | |||||
} | |||||
u.EncodePasswd() | u.EncodePasswd() | ||||
if err := models.UpdateUser(u); err != nil { | if err := models.UpdateUser(u); err != nil { | ||||
ctx.Handle(500, "UpdateUser", err) | ctx.Handle(500, "UpdateUser", err) |
ctx.Flash.Error(ctx.Tr("form.password_not_match")) | ctx.Flash.Error(ctx.Tr("form.password_not_match")) | ||||
} else { | } else { | ||||
ctx.User.Passwd = form.Password | ctx.User.Passwd = form.Password | ||||
ctx.User.Salt = models.GetUserSalt() | |||||
var err error | |||||
if ctx.User.Salt, err = models.GetUserSalt(); err != nil { | |||||
ctx.Handle(500, "UpdateUser", err) | |||||
return | |||||
} | |||||
ctx.User.EncodePasswd() | ctx.User.EncodePasswd() | ||||
if err := models.UpdateUser(ctx.User); err != nil { | if err := models.UpdateUser(ctx.User); err != nil { | ||||
ctx.Handle(500, "UpdateUser", err) | ctx.Handle(500, "UpdateUser", err) |