diff options
Diffstat (limited to 'internal/route/user')
-rw-r--r-- | internal/route/user/auth.go | 77 | ||||
-rw-r--r-- | internal/route/user/home.go | 8 | ||||
-rw-r--r-- | internal/route/user/setting.go | 6 |
3 files changed, 76 insertions, 15 deletions
diff --git a/internal/route/user/auth.go b/internal/route/user/auth.go index 17229a40..86cf1f2e 100644 --- a/internal/route/user/auth.go +++ b/internal/route/user/auth.go @@ -5,12 +5,15 @@ package user import ( + gocontext "context" + "encoding/hex" "fmt" "net/http" "net/url" "github.com/go-macaron/captcha" "github.com/pkg/errors" + "github.com/unknwon/com" log "unknwon.dev/clog/v2" "gogs.io/gogs/internal/auth" @@ -54,7 +57,7 @@ func AutoLogin(c *context.Context) (bool, error) { } }() - u, err := db.GetUserByName(uname) + u, err := db.Users.GetByUsername(c.Req.Context(), uname) if err != nil { if !db.IsErrUserNotExist(err) { return false, fmt.Errorf("get user by name: %v", err) @@ -229,7 +232,7 @@ func LoginTwoFactorPost(c *context.Context) { return } - u, err := db.GetUserByID(userID) + u, err := db.Users.GetByID(c.Req.Context(), userID) if err != nil { c.Error(err, "get user by ID") return @@ -275,7 +278,7 @@ func LoginTwoFactorRecoveryCodePost(c *context.Context) { return } - u, err := db.GetUserByID(userID) + u, err := db.Users.GetByID(c.Req.Context(), userID) if err != nil { c.Error(err, "get user by ID") return @@ -360,8 +363,11 @@ func SignUpPost(c *context.Context, cpt *captcha.Captcha, f form.Register) { } log.Trace("Account created: %s", user.Name) + // FIXME: Count has pretty bad performance implication in large instances, we + // should have a dedicate method to check whether the "user" table is empty. + // // Auto-set admin for the only user. - if db.CountUsers() == 1 { + if db.Users.Count(c.Req.Context()) == 1 { user.IsAdmin = true user.IsActive = true if err := db.UpdateUser(user); err != nil { @@ -387,6 +393,61 @@ func SignUpPost(c *context.Context, cpt *captcha.Captcha, f form.Register) { c.RedirectSubpath("/user/login") } +// parseUserFromCode returns user by username encoded in code. +// It returns nil if code or username is invalid. +func parseUserFromCode(code string) (user *db.User) { + if len(code) <= tool.TIME_LIMIT_CODE_LENGTH { + return nil + } + + // Use tail hex username to query user + hexStr := code[tool.TIME_LIMIT_CODE_LENGTH:] + if b, err := hex.DecodeString(hexStr); err == nil { + if user, err = db.Users.GetByUsername(gocontext.TODO(), string(b)); user != nil { + return user + } else if !db.IsErrUserNotExist(err) { + log.Error("Failed to get user by name %q: %v", string(b), err) + } + } + + return nil +} + +// verify active code when active account +func verifyUserActiveCode(code string) (user *db.User) { + minutes := conf.Auth.ActivateCodeLives + + if user = parseUserFromCode(code); user != nil { + // time limit code + prefix := code[:tool.TIME_LIMIT_CODE_LENGTH] + data := com.ToStr(user.ID) + user.Email + user.LowerName + user.Password + user.Rands + + if tool.VerifyTimeLimitCode(data, minutes, prefix) { + return user + } + } + return nil +} + +// verify active code when active account +func verifyActiveEmailCode(code, email string) *db.EmailAddress { + minutes := conf.Auth.ActivateCodeLives + + if user := parseUserFromCode(code); user != nil { + // time limit code + prefix := code[:tool.TIME_LIMIT_CODE_LENGTH] + data := com.ToStr(user.ID) + email + user.LowerName + user.Password + user.Rands + + if tool.VerifyTimeLimitCode(data, minutes, prefix) { + emailAddress, err := db.EmailAddresses.GetByEmail(gocontext.TODO(), email) + if err == nil { + return emailAddress + } + } + } + return nil +} + func Activate(c *context.Context) { code := c.Query("code") if code == "" { @@ -415,7 +476,7 @@ func Activate(c *context.Context) { } // Verify code. - if user := db.VerifyUserActiveCode(code); user != nil { + if user := verifyUserActiveCode(code); user != nil { user.IsActive = true var err error if user.Rands, err = userutil.RandomSalt(); err != nil { @@ -444,7 +505,7 @@ func ActivateEmail(c *context.Context) { emailAddr := c.Query("email") // Verify code. - if email := db.VerifyActiveEmailCode(code, emailAddr); email != nil { + if email := verifyActiveEmailCode(code, emailAddr); email != nil { if err := email.Activate(); err != nil { c.Error(err, "activate email") } @@ -481,7 +542,7 @@ func ForgotPasswdPost(c *context.Context) { emailAddr := c.Query("email") c.Data["Email"] = emailAddr - u, err := db.GetUserByEmail(emailAddr) + u, err := db.Users.GetByEmail(c.Req.Context(), emailAddr) if err != nil { if db.IsErrUserNotExist(err) { c.Data["Hours"] = conf.Auth.ActivateCodeLives / 60 @@ -539,7 +600,7 @@ func ResetPasswdPost(c *context.Context) { } c.Data["Code"] = code - if u := db.VerifyUserActiveCode(code); u != nil { + if u := verifyUserActiveCode(code); u != nil { // Validate password length. passwd := c.Query("password") if len(passwd) < 6 { diff --git a/internal/route/user/home.go b/internal/route/user/home.go index 04b5eb65..f9f1b7b1 100644 --- a/internal/route/user/home.go +++ b/internal/route/user/home.go @@ -31,7 +31,7 @@ func getDashboardContextUser(c *context.Context) *db.User { orgName := c.Params(":org") if len(orgName) > 0 { // Organization. - org, err := db.GetUserByName(orgName) + org, err := db.Users.GetByUsername(c.Req.Context(), orgName) if err != nil { c.NotFoundOrError(err, "get user by name") return nil @@ -42,7 +42,7 @@ func getDashboardContextUser(c *context.Context) *db.User { orgs, err := db.Orgs.List( c.Req.Context(), - db.ListOrgOptions{ + db.ListOrgsOptions{ MemberID: c.User.ID, IncludePrivateMembers: true, }, @@ -81,7 +81,7 @@ func retrieveFeeds(c *context.Context, ctxUser *db.User, userID int64, isProfile // Cache results to reduce queries. _, ok := unameAvatars[act.ActUserName] if !ok { - u, err := db.GetUserByName(act.ActUserName) + u, err := db.Users.GetByUsername(c.Req.Context(), act.ActUserName) if err != nil { if db.IsErrUserNotExist(err) { continue @@ -444,7 +444,7 @@ func showOrgProfile(c *context.Context) { } func Email2User(c *context.Context) { - u, err := db.GetUserByEmail(c.Query("email")) + u, err := db.Users.GetByEmail(c.Req.Context(), c.Query("email")) if err != nil { c.NotFoundOrError(err, "get user by email") return diff --git a/internal/route/user/setting.go b/internal/route/user/setting.go index 6d781cbe..c873aeaf 100644 --- a/internal/route/user/setting.go +++ b/internal/route/user/setting.go @@ -256,7 +256,7 @@ func SettingsEmailPost(c *context.Context, f form.AddEmail) { } emailAddr := &db.EmailAddress{ - UID: c.User.ID, + UserID: c.User.ID, Email: f.Email, IsActivated: !conf.Auth.RequireEmailConfirmation, } @@ -286,8 +286,8 @@ func SettingsEmailPost(c *context.Context, f form.AddEmail) { func DeleteEmail(c *context.Context) { if err := db.DeleteEmailAddress(&db.EmailAddress{ - ID: c.QueryInt64("id"), - UID: c.User.ID, + ID: c.QueryInt64("id"), + UserID: c.User.ID, }); err != nil { c.Errorf(err, "delete email address") return |