Skip to content

Commit

Permalink
update verify limit data
Browse files Browse the repository at this point in the history
  • Loading branch information
le-xuan-quynh committed May 4, 2022
1 parent 2e8fa1a commit 7d73bf5
Show file tree
Hide file tree
Showing 7 changed files with 134 additions and 88 deletions.
31 changes: 27 additions & 4 deletions cmd/authorization/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@ const limitSchema = `
create table if not exists limits (
id Varchar(36) not null,
userid Varchar(36) not null,
numofsendmail Int default 0,
numofsendmailverify Int default 0,
numofsendresetpassword Int default 0,
numofchangepassword Int default 0,
numoflogin Int default 0,
createdat Timestamp not null,
Expand Down Expand Up @@ -135,20 +136,42 @@ func main() {
// authService contains all methods that help in authorizing a user request
auth := middleware.NewAuthService(logger, configs)

// Reset limit data for users.
s := gocron.NewScheduler(time.UTC)
// Reset limit send mail for users.
_, err = s.Every(1).Day().At("00:01").Do(func() {
logger.Info("Clear limit data for users after 1 day at 00:01.")
var ctx = context.Background()
err := repository.ClearAllLimitData(ctx)
err := repository.ClearLimitData(ctx, database.LimitTypeSendVerifyMail)
if err != nil {
logger.Error("Error clearing limit data", "error", err)
logger.Error("Error clearing limit send mail data", "error", err)
}
// Reset limit login for users.
err = repository.ClearLimitData(ctx, database.LimitTypeLogin)
if err != nil {
logger.Error("Error clearing limit login data", "error", err)
}
})
if err != nil {
logger.Error("Error scheduling limit data", "error", err)
return
}
// Reset limit change password for users after 15 minutes.
_, err = s.Every(15).Minute().Do(func() {
logger.Info("Clear change password, send pass reset mail limit data for users after 15 minutes.")
var ctx = context.Background()
err := repository.ClearLimitData(ctx, database.LimitTypeChangePassword)
if err != nil {
logger.Error("Error clearing limit change password data", "error", err)
}
// Limit for send mail get password code reset
err = repository.ClearLimitData(ctx, database.LimitTypeSendPassResetMail)
if err != nil {
logger.Error("Error clearing limit send mail data", "error", err)
}
})
if err != nil {
logger.Error("Error scheduling limit data", "error", err)
}
s.StartAsync()

// Create rate limiter for users.
Expand Down
3 changes: 2 additions & 1 deletion internal/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ type Configurations struct {
HttpPort string `mapstructure:"HTTP_PORT"`
MailTitle string `mapstructure:"MAIL_TITLE"`
ChangePasswordLimit int `mapstructure:"CHANGE_PASSWORD_LIMIT"`
SendMailLimit int `mapstructure:"SEND_MAIL_LIMIT"`
SendMailVerifyLimit int `mapstructure:"SEND_MAIL_VERIFY_LIMIT"`
SendMailResetPasswordLimit int `mapstructure:"SEND_MAIL_RESET_PASSWORD_LIMIT"`
LoginLimit int `mapstructure:"LOGIN_LIMIT"`
}

Expand Down
15 changes: 8 additions & 7 deletions internal/database/limit-data.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ package database
import "time"

type LimitData struct {
ID string `json:"id" sql:"id"`
UserID string `json:"user_id" sql:"userid"`
NumOfSendMail int `json:"num_of_send_mail" sql:"numofsendmail"`
NumOfChangePassword int `json:"num_of_change_password" sql:"numofchangepassword"`
NumOfLogin int `json:"num_of_login" sql:"numoflogin"`
CreatedAt time.Time `json:"createdat" sql:"createdat"`
UpdatedAt time.Time `json:"updatedat" sql:"updatedat"`
ID string `json:"id" sql:"id"`
UserID string `json:"user_id" sql:"userid"`
NumOfSendMailVerify int `json:"num_of_send_mail_verify" sql:"numofsendmailverify"`
NumOfSendResetPassword int `json:"num_of_send_reset_password" sql:"numofsendresetpassword"`
NumOfChangePassword int `json:"num_of_change_password" sql:"numofchangepassword"`
NumOfLogin int `json:"num_of_login" sql:"numoflogin"`
CreatedAt time.Time `json:"createdat" sql:"createdat"`
UpdatedAt time.Time `json:"updatedat" sql:"updatedat"`
}
63 changes: 54 additions & 9 deletions internal/database/postgres-repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package database
import (
"context"
"database/sql"
"errors"
"github.com/hashicorp/go-hclog"
"github.com/jmoiron/sqlx"
uuid "github.com/satori/go.uuid"
Expand Down Expand Up @@ -219,36 +220,66 @@ func (repo *postgresRepository) InsertListOfPasswords(ctx context.Context, passw
}

// GetLimitData returns the limit data
func (repo *postgresRepository) GetLimitData(ctx context.Context, userID string) (*LimitData, error) {
func (repo *postgresRepository) GetLimitData(ctx context.Context, userID string, limitType LimitType) (*LimitData, error) {
query := "select * from limits where userid = $1"
limitData := &LimitData{}
err := repo.db.GetContext(ctx, limitData, query, userID)
if err != nil {
if limitType == LimitTypeLogin {
limitData.NumOfLogin = 1
} else if limitType == LimitTypeSendVerifyMail {
limitData.NumOfSendMailVerify = 1
} else if limitType == LimitTypeSendPassResetMail {
limitData.NumOfSendResetPassword = 1
} else if limitType == LimitTypeChangePassword {
limitData.NumOfChangePassword = 1
}
} else {
if limitType == LimitTypeLogin {
limitData.NumOfLogin += 1
} else if limitType == LimitTypeSendVerifyMail {
limitData.NumOfSendMailVerify += 1
} else if limitType == LimitTypeSendPassResetMail {
limitData.NumOfSendResetPassword += 1
} else if limitType == LimitTypeChangePassword {
limitData.NumOfChangePassword += 1
}
}
limitData.UserID = userID
return limitData, err
}

// InsertOrUpdateLimitData updates the limit data
func (repo *postgresRepository) InsertOrUpdateLimitData(ctx context.Context, limitData *LimitData, isInsert bool) error {
func (repo *postgresRepository) InsertOrUpdateLimitData(ctx context.Context, limitData *LimitData, limitType LimitType) error {
// Check exist or not limit data
_, err := repo.GetLimitData(ctx, limitData.UserID, limitType)
isInsert := false
if err != nil {
isInsert = true
}
limitData.ID = uuid.NewV4().String()
limitData.CreatedAt = time.Now()
limitData.UpdatedAt = time.Now()
// Insert or update
if isInsert {
// Insert the limit data
query := "insert into limits(id, userid, numofsendmail, numofchangepassword, numoflogin, createdat, updatedat) values($1, $2, $3, $4, $5, $6, $7)"
query := "insert into limits(id, userid, numofsendmailverify, numofsendresetpassword, numofchangepassword, numoflogin, createdat, updatedat) values($1, $2, $3, $4, $5, $6, $7, $8)"
_, err := repo.db.ExecContext(ctx, query,
limitData.ID,
limitData.UserID,
limitData.NumOfSendMail,
limitData.NumOfSendMailVerify,
limitData.NumOfSendResetPassword,
limitData.NumOfChangePassword,
limitData.NumOfLogin,
limitData.CreatedAt,
limitData.UpdatedAt)
return err
} else {
// Update the limit data
query := "update limits set numofsendmail = $1, numofchangepassword = $2, numoflogin = $3, updatedat = $4 where userid = $5"
query := "update limits set numofsendmailverify = $1, numofsendresetpassword = $2, numofchangepassword = $3, numoflogin = $4, updatedat = $5 where userid = $6"
_, err := repo.db.ExecContext(ctx, query,
limitData.NumOfSendMail,
limitData.NumOfSendMailVerify,
limitData.NumOfSendResetPassword,
limitData.NumOfChangePassword,
limitData.NumOfLogin,
limitData.UpdatedAt,
Expand All @@ -257,9 +288,23 @@ func (repo *postgresRepository) InsertOrUpdateLimitData(ctx context.Context, lim
}
}

// ClearAllLimitData clears all limit data
func (repo *postgresRepository) ClearAllLimitData(ctx context.Context) error {
query := "delete from limits"
// ClearLimitData clears the limit data
func (repo *postgresRepository) ClearLimitData(ctx context.Context, limitType LimitType) error {
var query string
if limitType == LimitTypeLogin {
// Clear all num of login limit
query = "update limits set numoflogin = 0"
} else if limitType == LimitTypeSendVerifyMail {
// Clear all num of send mail limit
query = "update limits set numofsendmailverify = 0"
} else if limitType == LimitTypeSendPassResetMail {
query = "update limits set numofsendresetpassword = 0"
} else if limitType == LimitTypeChangePassword {
// Clear all num of change password limit
query = "update limits set numofchangepassword = 0"
} else {
return errors.New("limit type is not valid")
}
_, err := repo.db.ExecContext(ctx, query)
return err
}
8 changes: 4 additions & 4 deletions internal/database/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ type UserRepository interface {
// InsertListOfPasswords Update password into list of passwords
InsertListOfPasswords(ctx context.Context, passwordUsers *PassworUsers) error
// GetLimitData Get limit table data
GetLimitData(ctx context.Context, userID string) (*LimitData, error)
GetLimitData(ctx context.Context, userID string, limitType LimitType) (*LimitData, error)
// InsertOrUpdateLimitData Insert or update limit data
InsertOrUpdateLimitData(ctx context.Context, limitData *LimitData, isInsert bool) error
// ClearAllLimitData Clear all limit data
ClearAllLimitData(ctx context.Context) error
InsertOrUpdateLimitData(ctx context.Context, limitData *LimitData, limitType LimitType) error
// ClearLimitData Clear limit data
ClearLimitData(ctx context.Context, limitType LimitType) error
}
10 changes: 10 additions & 0 deletions internal/database/verification-data.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,16 @@ const (
PassReset
)

type LimitType int

const (
LimitTypeNone LimitType = iota
LimitTypeLogin
LimitTypeSendVerifyMail
LimitTypeSendPassResetMail
LimitTypeChangePassword
)

// Type of verification data
const (
RefreshType = "refresh"
Expand Down
Loading

0 comments on commit 7d73bf5

Please sign in to comment.