grafana/pkg/services/loginattempt/loginattemptimpl/store.go
Serge Zaitsev 927ddf9376
Chore: Move login attempt methods to separate service (#54479)
* Chore: Move login attempt methods to separate service

* attempt to fix tests

* fix syntax

* better time mocking

* initialise now func
2022-09-01 18:08:42 +02:00

102 lines
2.4 KiB
Go

package loginattemptimpl
import (
"context"
"strconv"
"time"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/sqlstore/db"
)
type xormStore struct {
db db.DB
now func() time.Time
}
type store interface {
CreateLoginAttempt(context.Context, *models.CreateLoginAttemptCommand) error
DeleteOldLoginAttempts(context.Context, *models.DeleteOldLoginAttemptsCommand) error
GetUserLoginAttemptCount(context.Context, *models.GetUserLoginAttemptCountQuery) error
}
func (xs *xormStore) CreateLoginAttempt(ctx context.Context, cmd *models.CreateLoginAttemptCommand) error {
return xs.db.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error {
loginAttempt := models.LoginAttempt{
Username: cmd.Username,
IpAddress: cmd.IpAddress,
Created: xs.now().Unix(),
}
if _, err := sess.Insert(&loginAttempt); err != nil {
return err
}
cmd.Result = loginAttempt
return nil
})
}
func (xs *xormStore) DeleteOldLoginAttempts(ctx context.Context, cmd *models.DeleteOldLoginAttemptsCommand) error {
return xs.db.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error {
var maxId int64
sql := "SELECT max(id) as id FROM login_attempt WHERE created < ?"
result, err := sess.Query(sql, cmd.OlderThan.Unix())
if err != nil {
return err
}
if len(result) == 0 || result[0] == nil {
return nil
}
// TODO: why don't we know the type of ID?
maxId = toInt64(result[0]["id"])
if maxId == 0 {
return nil
}
sql = "DELETE FROM login_attempt WHERE id <= ?"
if result, err := sess.Exec(sql, maxId); err != nil {
return err
} else if cmd.DeletedRows, err = result.RowsAffected(); err != nil {
return err
}
return nil
})
}
func (xs *xormStore) GetUserLoginAttemptCount(ctx context.Context, query *models.GetUserLoginAttemptCountQuery) error {
return xs.db.WithDbSession(ctx, func(dbSession *sqlstore.DBSession) error {
loginAttempt := new(models.LoginAttempt)
total, err := dbSession.
Where("username = ?", query.Username).
And("created >= ?", query.Since.Unix()).
Count(loginAttempt)
if err != nil {
return err
}
query.Result = total
return nil
})
}
func toInt64(i interface{}) int64 {
switch i := i.(type) {
case []byte:
n, _ := strconv.ParseInt(string(i), 10, 64)
return n
case int:
return int64(i)
case int64:
return i
}
return 0
}