From 79b685ea8ab157afccc482047eb3da21a0698f99 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Sat, 19 Oct 2024 18:07:07 +0200 Subject: [PATCH] Add proper error handling and fix del /sessions/current --- auth/go.mod | 2 +- auth/go.sum | 2 ++ auth/sessions.go | 9 ++++++--- auth/users.go | 31 +++++++++++++++++++++++-------- auth/utils.go | 11 +++++++++++ 5 files changed, 43 insertions(+), 12 deletions(-) diff --git a/auth/go.mod b/auth/go.mod index a926db35..8cd5a8d3 100644 --- a/auth/go.mod +++ b/auth/go.mod @@ -30,7 +30,7 @@ require ( github.com/golang-migrate/migrate/v4 v4.17.1 github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/jackc/pgerrcode v0.0.0-20220416144525-469b46aa5efa // indirect + github.com/jackc/pgerrcode v0.0.0-20240316143900-6e2875d9b438 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect github.com/jackc/puddle/v2 v2.2.1 // indirect diff --git a/auth/go.sum b/auth/go.sum index 6233c759..6d6184f1 100644 --- a/auth/go.sum +++ b/auth/go.sum @@ -65,6 +65,8 @@ github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+l github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/jackc/pgerrcode v0.0.0-20220416144525-469b46aa5efa h1:s+4MhCQ6YrzisK6hFJUX53drDT4UsSW3DEhKn0ifuHw= github.com/jackc/pgerrcode v0.0.0-20220416144525-469b46aa5efa/go.mod h1:a/s9Lp5W7n/DD0VrVoyJ00FbP2ytTPDVOivvn2bMlds= +github.com/jackc/pgerrcode v0.0.0-20240316143900-6e2875d9b438 h1:Dj0L5fhJ9F82ZJyVOmBx6msDp/kfd1t9GRfny/mfJA0= +github.com/jackc/pgerrcode v0.0.0-20240316143900-6e2875d9b438/go.mod h1:a/s9Lp5W7n/DD0VrVoyJ00FbP2ytTPDVOivvn2bMlds= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= diff --git a/auth/sessions.go b/auth/sessions.go index 5f61bb5d..1092f5fa 100644 --- a/auth/sessions.go +++ b/auth/sessions.go @@ -11,6 +11,7 @@ import ( "github.com/alexedwards/argon2id" "github.com/golang-jwt/jwt/v5" "github.com/google/uuid" + "github.com/jackc/pgx/v5" "github.com/labstack/echo/v4" "github.com/zoriya/kyoo/keibi/dbc" ) @@ -102,7 +103,7 @@ func (h *Handler) createSession(c echo.Context, user *User) error { session, err := h.db.CreateSession(ctx, dbc.CreateSessionParams{ Token: base64.StdEncoding.EncodeToString(id), - UserId: user.Id, + UserPk: user.Pk, Device: device, }) if err != nil { @@ -131,7 +132,7 @@ func (h *Handler) Logout(c echo.Context) error { } session := c.Param("id") - if session == "" { + if session == "current" { sid, ok := c.Get("user").(*jwt.Token).Claims.(jwt.MapClaims)["sid"] if !ok { return echo.NewHTTPError(400, "Missing session id") @@ -147,8 +148,10 @@ func (h *Handler) Logout(c echo.Context) error { Id: sid, UserId: uid, }) - if err != nil { + if err == pgx.ErrNoRows { return echo.NewHTTPError(404, "Session not found with specified id") + } else if err != nil { + return err } return c.JSON(200, MapSession(&ret)) } diff --git a/auth/users.go b/auth/users.go index 88b7c39f..31ee799c 100644 --- a/auth/users.go +++ b/auth/users.go @@ -8,11 +8,15 @@ import ( "github.com/alexedwards/argon2id" "github.com/golang-jwt/jwt/v5" "github.com/google/uuid" + "github.com/jackc/pgerrcode" + "github.com/jackc/pgx/v5" "github.com/labstack/echo/v4" "github.com/zoriya/kyoo/keibi/dbc" ) type User struct { + // Primary key in database + Pk int32 `json:"-"` // Id of the user. Id uuid.UUID `json:"id"` // Username of the user. Can be used as a login. @@ -49,6 +53,7 @@ type RegisterDto struct { func MapDbUser(user *dbc.User) User { return User{ + Pk: user.Pk, Id: user.Id, Username: user.Username, Email: user.Email, @@ -59,10 +64,10 @@ func MapDbUser(user *dbc.User) User { } } -func MapOidc(oidc *dbc.OidcHandle) OidcHandle { +func MapOidc(oidc *dbc.GetUserRow) OidcHandle { return OidcHandle{ - Id: oidc.Id, - Username: oidc.Username, + Id: *oidc.Id, + Username: *oidc.Username, ProfileUrl: oidc.ProfileUrl, } } @@ -139,7 +144,9 @@ func (h *Handler) GetUser(c echo.Context) error { user := MapDbUser(&dbuser[0].User) for _, oidc := range dbuser { - user.Oidc[oidc.OidcHandle.Provider] = MapOidc(&oidc.OidcHandle) + if oidc.Provider != nil { + user.Oidc[*oidc.Provider] = MapOidc(&oidc) + } } return c.JSON(200, user) @@ -166,7 +173,9 @@ func (h *Handler) GetMe(c echo.Context) error { user := MapDbUser(&dbuser[0].User) for _, oidc := range dbuser { - user.Oidc[oidc.OidcHandle.Provider] = MapOidc(&oidc.OidcHandle) + if oidc.Provider != nil { + user.Oidc[*oidc.Provider] = MapOidc(&oidc) + } } return c.JSON(200, user) @@ -204,8 +213,10 @@ func (h *Handler) Register(c echo.Context) error { Password: &pass, Claims: h.config.DefaultClaims, }) - if err != nil { + if ErrIs(err, pgerrcode.UniqueViolation) { return echo.NewHTTPError(409, "Email or username already taken") + } else if err != nil { + return err } user := MapDbUser(&duser) return h.createSession(c, &user) @@ -229,8 +240,10 @@ func (h *Handler) DeleteUser(c echo.Context) error { } ret, err := h.db.DeleteUser(context.Background(), uid) - if err != nil { + if err == pgx.ErrNoRows { return echo.NewHTTPError(404, "No user found with given id") + } else if err != nil { + return err } return c.JSON(200, MapDbUser(&ret)) } @@ -250,8 +263,10 @@ func (h *Handler) DeleteSelf(c echo.Context) error { } ret, err := h.db.DeleteUser(context.Background(), uid) - if err != nil { + if err == pgx.ErrNoRows { return echo.NewHTTPError(403, "Invalid token, user already deleted.") + } else if err != nil { + return err } return c.JSON(200, MapDbUser(&ret)) } diff --git a/auth/utils.go b/auth/utils.go index c5040341..38753bc3 100644 --- a/auth/utils.go +++ b/auth/utils.go @@ -1,12 +1,14 @@ package main import ( + "errors" "fmt" "slices" "strings" "github.com/golang-jwt/jwt/v5" "github.com/google/uuid" + "github.com/jackc/pgx/v5/pgconn" "github.com/labstack/echo/v4" ) @@ -60,3 +62,12 @@ func CheckPermissions(c echo.Context, perms []string) error { } return nil } + +func ErrIs(err error, code string) bool { + var pgerr *pgconn.PgError + + if !errors.As(err, &pgerr) { + return false + } + return pgerr.Code == code +}