Add proper error handling and fix del /sessions/current

This commit is contained in:
Zoe Roux 2024-10-19 18:07:07 +02:00
parent a2df0ae305
commit 79b685ea8a
No known key found for this signature in database
5 changed files with 43 additions and 12 deletions

View File

@ -30,7 +30,7 @@ require (
github.com/golang-migrate/migrate/v4 v4.17.1 github.com/golang-migrate/migrate/v4 v4.17.1
github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // 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/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
github.com/jackc/puddle/v2 v2.2.1 // indirect github.com/jackc/puddle/v2 v2.2.1 // indirect

View File

@ -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/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 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-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 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= 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= github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=

View File

@ -11,6 +11,7 @@ import (
"github.com/alexedwards/argon2id" "github.com/alexedwards/argon2id"
"github.com/golang-jwt/jwt/v5" "github.com/golang-jwt/jwt/v5"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/jackc/pgx/v5"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
"github.com/zoriya/kyoo/keibi/dbc" "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{ session, err := h.db.CreateSession(ctx, dbc.CreateSessionParams{
Token: base64.StdEncoding.EncodeToString(id), Token: base64.StdEncoding.EncodeToString(id),
UserId: user.Id, UserPk: user.Pk,
Device: device, Device: device,
}) })
if err != nil { if err != nil {
@ -131,7 +132,7 @@ func (h *Handler) Logout(c echo.Context) error {
} }
session := c.Param("id") session := c.Param("id")
if session == "" { if session == "current" {
sid, ok := c.Get("user").(*jwt.Token).Claims.(jwt.MapClaims)["sid"] sid, ok := c.Get("user").(*jwt.Token).Claims.(jwt.MapClaims)["sid"]
if !ok { if !ok {
return echo.NewHTTPError(400, "Missing session id") return echo.NewHTTPError(400, "Missing session id")
@ -147,8 +148,10 @@ func (h *Handler) Logout(c echo.Context) error {
Id: sid, Id: sid,
UserId: uid, UserId: uid,
}) })
if err != nil { if err == pgx.ErrNoRows {
return echo.NewHTTPError(404, "Session not found with specified id") return echo.NewHTTPError(404, "Session not found with specified id")
} else if err != nil {
return err
} }
return c.JSON(200, MapSession(&ret)) return c.JSON(200, MapSession(&ret))
} }

View File

@ -8,11 +8,15 @@ import (
"github.com/alexedwards/argon2id" "github.com/alexedwards/argon2id"
"github.com/golang-jwt/jwt/v5" "github.com/golang-jwt/jwt/v5"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/jackc/pgerrcode"
"github.com/jackc/pgx/v5"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
"github.com/zoriya/kyoo/keibi/dbc" "github.com/zoriya/kyoo/keibi/dbc"
) )
type User struct { type User struct {
// Primary key in database
Pk int32 `json:"-"`
// Id of the user. // Id of the user.
Id uuid.UUID `json:"id"` Id uuid.UUID `json:"id"`
// Username of the user. Can be used as a login. // Username of the user. Can be used as a login.
@ -49,6 +53,7 @@ type RegisterDto struct {
func MapDbUser(user *dbc.User) User { func MapDbUser(user *dbc.User) User {
return User{ return User{
Pk: user.Pk,
Id: user.Id, Id: user.Id,
Username: user.Username, Username: user.Username,
Email: user.Email, 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{ return OidcHandle{
Id: oidc.Id, Id: *oidc.Id,
Username: oidc.Username, Username: *oidc.Username,
ProfileUrl: oidc.ProfileUrl, ProfileUrl: oidc.ProfileUrl,
} }
} }
@ -139,7 +144,9 @@ func (h *Handler) GetUser(c echo.Context) error {
user := MapDbUser(&dbuser[0].User) user := MapDbUser(&dbuser[0].User)
for _, oidc := range dbuser { 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) return c.JSON(200, user)
@ -166,7 +173,9 @@ func (h *Handler) GetMe(c echo.Context) error {
user := MapDbUser(&dbuser[0].User) user := MapDbUser(&dbuser[0].User)
for _, oidc := range dbuser { 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) return c.JSON(200, user)
@ -204,8 +213,10 @@ func (h *Handler) Register(c echo.Context) error {
Password: &pass, Password: &pass,
Claims: h.config.DefaultClaims, Claims: h.config.DefaultClaims,
}) })
if err != nil { if ErrIs(err, pgerrcode.UniqueViolation) {
return echo.NewHTTPError(409, "Email or username already taken") return echo.NewHTTPError(409, "Email or username already taken")
} else if err != nil {
return err
} }
user := MapDbUser(&duser) user := MapDbUser(&duser)
return h.createSession(c, &user) 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) 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") return echo.NewHTTPError(404, "No user found with given id")
} else if err != nil {
return err
} }
return c.JSON(200, MapDbUser(&ret)) 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) ret, err := h.db.DeleteUser(context.Background(), uid)
if err != nil { if err == pgx.ErrNoRows {
return echo.NewHTTPError(403, "Invalid token, user already deleted.") return echo.NewHTTPError(403, "Invalid token, user already deleted.")
} else if err != nil {
return err
} }
return c.JSON(200, MapDbUser(&ret)) return c.JSON(200, MapDbUser(&ret))
} }

View File

@ -1,12 +1,14 @@
package main package main
import ( import (
"errors"
"fmt" "fmt"
"slices" "slices"
"strings" "strings"
"github.com/golang-jwt/jwt/v5" "github.com/golang-jwt/jwt/v5"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/jackc/pgx/v5/pgconn"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
) )
@ -60,3 +62,12 @@ func CheckPermissions(c echo.Context, perms []string) error {
} }
return nil return nil
} }
func ErrIs(err error, code string) bool {
var pgerr *pgconn.PgError
if !errors.As(err, &pgerr) {
return false
}
return pgerr.Code == code
}