Fixes mm-1355 adds rate limiting apis
Этот коммит содержится в:
@@ -59,6 +59,8 @@ func (us SqlUserStore) UpgradeSchemaIfNeeded() {
|
||||
}
|
||||
|
||||
us.CreateColumnIfNotExists("Users", "AuthService", "AuthData", "varchar(32)", "") // for OAuth Client
|
||||
|
||||
us.CreateColumnIfNotExists("Users", "FailedAttempts", "FailedAttempts", "int(11)", "0")
|
||||
}
|
||||
|
||||
//func (ss SqlStore) CreateColumnIfNotExists(tableName string, columnName string, afterName string, colType string, defaultValue string) bool {
|
||||
@@ -150,6 +152,7 @@ func (us SqlUserStore) Update(user *model.User, allowActiveUpdate bool) StoreCha
|
||||
user.LastActivityAt = oldUser.LastActivityAt
|
||||
user.LastPingAt = oldUser.LastPingAt
|
||||
user.EmailVerified = oldUser.EmailVerified
|
||||
user.FailedAttempts = oldUser.FailedAttempts
|
||||
|
||||
if !allowActiveUpdate {
|
||||
user.Roles = oldUser.Roles
|
||||
@@ -265,7 +268,7 @@ func (us SqlUserStore) UpdatePassword(userId, hashedPassword string) StoreChanne
|
||||
|
||||
updateAt := model.GetMillis()
|
||||
|
||||
if _, err := us.GetMaster().Exec("UPDATE Users SET Password = :Password, LastPasswordUpdate = :LastPasswordUpdate, UpdateAt = :UpdateAt WHERE Id = :UserId", map[string]interface{}{"Password": hashedPassword, "LastPasswordUpdate": updateAt, "UpdateAt": updateAt, "UserId": userId}); err != nil {
|
||||
if _, err := us.GetMaster().Exec("UPDATE Users SET Password = :Password, LastPasswordUpdate = :LastPasswordUpdate, UpdateAt = :UpdateAt, FailedAttempts = 0 WHERE Id = :UserId", map[string]interface{}{"Password": hashedPassword, "LastPasswordUpdate": updateAt, "UpdateAt": updateAt, "UserId": userId}); err != nil {
|
||||
result.Err = model.NewAppError("SqlUserStore.UpdatePassword", "We couldn't update the user password", "id="+userId+", "+err.Error())
|
||||
} else {
|
||||
result.Data = userId
|
||||
@@ -278,6 +281,25 @@ func (us SqlUserStore) UpdatePassword(userId, hashedPassword string) StoreChanne
|
||||
return storeChannel
|
||||
}
|
||||
|
||||
func (us SqlUserStore) UpdateFailedPasswordAttempts(userId string, attempts int) StoreChannel {
|
||||
storeChannel := make(StoreChannel)
|
||||
|
||||
go func() {
|
||||
result := StoreResult{}
|
||||
|
||||
if _, err := us.GetMaster().Exec("UPDATE Users SET FailedAttempts = :FailedAttempts WHERE Id = :UserId", map[string]interface{}{"FailedAttempts": attempts, "UserId": userId}); err != nil {
|
||||
result.Err = model.NewAppError("SqlUserStore.UpdateFailedPasswordAttempts", "We couldn't update the failed_attempts", "user_id="+userId)
|
||||
} else {
|
||||
result.Data = userId
|
||||
}
|
||||
|
||||
storeChannel <- result
|
||||
close(storeChannel)
|
||||
}()
|
||||
|
||||
return storeChannel
|
||||
}
|
||||
|
||||
func (us SqlUserStore) Get(id string) StoreChannel {
|
||||
|
||||
storeChannel := make(StoreChannel)
|
||||
|
||||
@@ -128,6 +128,28 @@ func TestUserStoreUpdateLastActivityAt(t *testing.T) {
|
||||
|
||||
}
|
||||
|
||||
func TestUserStoreUpdateFailedPasswordAttempts(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
u1 := model.User{}
|
||||
u1.TeamId = model.NewId()
|
||||
u1.Email = model.NewId()
|
||||
Must(store.User().Save(&u1))
|
||||
|
||||
if err := (<-store.User().UpdateFailedPasswordAttempts(u1.Id, 3)).Err; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if r1 := <-store.User().Get(u1.Id); r1.Err != nil {
|
||||
t.Fatal(r1.Err)
|
||||
} else {
|
||||
if r1.Data.(*model.User).FailedAttempts != 3 {
|
||||
t.Fatal("LastActivityAt not updated correctly")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestUserStoreUpdateUserAndSessionActivity(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
|
||||
@@ -89,6 +89,7 @@ type UserStore interface {
|
||||
GetByUsername(teamId string, username string) StoreChannel
|
||||
VerifyEmail(userId string) StoreChannel
|
||||
GetEtagForProfiles(teamId string) StoreChannel
|
||||
UpdateFailedPasswordAttempts(userId string, attempts int) StoreChannel
|
||||
}
|
||||
|
||||
type SessionStore interface {
|
||||
|
||||
Ссылка в новой задаче
Block a user