Added unique case-insensitive index on auth_user.username
Changed login code to look up lowercase usernames
This commit is contained in:
parent
649f353b8c
commit
4f9df3382f
|
@ -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"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -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")
|
||||||
|
}
|
|
@ -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"))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue