Added unique case-insensitive index on auth_user.username

Changed login code to look up lowercase usernames
This commit is contained in:
Asaf Gartner 2021-04-27 06:55:17 +03:00
parent 649f353b8c
commit 4f9df3382f
3 changed files with 44 additions and 3 deletions

View File

@ -5,6 +5,7 @@ import (
"time" "time"
"git.handmade.network/hmn/hmn/src/migration/types" "git.handmade.network/hmn/hmn/src/migration/types"
"git.handmade.network/hmn/hmn/src/oops"
"github.com/jackc/pgx/v4" "github.com/jackc/pgx/v4"
) )

View File

@ -0,0 +1,40 @@
package migrations
import (
"context"
"time"
"git.handmade.network/hmn/hmn/src/migration/types"
"git.handmade.network/hmn/hmn/src/oops"
"github.com/jackc/pgx/v4"
)
func init() {
registerMigration(UsernameUniqueIndex{})
}
type UsernameUniqueIndex struct{}
func (m UsernameUniqueIndex) Version() types.MigrationVersion {
return types.MigrationVersion(time.Date(2021, 4, 27, 3, 43, 27, 0, time.UTC))
}
func (m UsernameUniqueIndex) Name() string {
return "UsernameUniqueIndex"
}
func (m UsernameUniqueIndex) Description() string {
return "Prevent the creation of similar usernames with different character cases"
}
func (m UsernameUniqueIndex) Up(ctx context.Context, tx pgx.Tx) error {
_, err := tx.Exec(ctx, `CREATE UNIQUE INDEX auth_user_unique_username_case_insensitive ON auth_user (LOWER(username))`)
if err != nil {
return oops.New(err, "failed to add unique index")
}
return nil
}
func (m UsernameUniqueIndex) Down(ctx context.Context, tx pgx.Tx) error {
panic("Implement me")
}

View File

@ -30,7 +30,7 @@ func Login(c *RequestContext) ResponseData {
redirect = "/" redirect = "/"
} }
userRow, err := db.QueryOne(c.Context(), c.Conn, models.User{}, "SELECT $columns FROM auth_user WHERE username = $1", username) userRow, err := db.QueryOne(c.Context(), c.Conn, models.User{}, "SELECT $columns FROM auth_user WHERE LOWER(username) = LOWER($1)", username)
if err != nil { if err != nil {
if errors.Is(err, db.ErrNoMatchingRows) { if errors.Is(err, db.ErrNoMatchingRows) {
return ResponseData{ return ResponseData{
@ -57,7 +57,7 @@ func Login(c *RequestContext) ResponseData {
if hashed.IsOutdated() { if hashed.IsOutdated() {
newHashed, err := auth.HashPassword(password) newHashed, err := auth.HashPassword(password)
if err == nil { if err == nil {
err := auth.UpdatePassword(c.Context(), c.Conn, username, newHashed) err := auth.UpdatePassword(c.Context(), c.Conn, user.Username, newHashed)
if err != nil { if err != nil {
c.Logger.Error().Err(err).Msg("failed to update user's password") c.Logger.Error().Err(err).Msg("failed to update user's password")
} }
@ -67,7 +67,7 @@ func Login(c *RequestContext) ResponseData {
// If errors happen here, we can still continue with logging them in // If errors happen here, we can still continue with logging them in
} }
session, err := auth.CreateSession(c.Context(), c.Conn, username) session, err := auth.CreateSession(c.Context(), c.Conn, user.Username)
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to create session")) return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to create session"))
} }