mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-24 02:02:36 -04:00
Add login route
This commit is contained in:
parent
4685f76cad
commit
b340958348
@ -1 +1,2 @@
|
||||
replace jwt.MapClaims map[string]string
|
||||
replace uuid.UUID string
|
||||
|
@ -83,7 +83,6 @@ func OpenDatabase() (*pgxpool.Pool, error) {
|
||||
fmt.Printf("Could not connect to database, check your env variables!")
|
||||
return nil, err
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
if schema != "disabled" {
|
||||
_, err = db.Exec(ctx, fmt.Sprintf("create schema if not exists %s", schema))
|
||||
@ -92,6 +91,7 @@ func OpenDatabase() (*pgxpool.Pool, error) {
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println("Migrating database")
|
||||
dbi := stdlib.OpenDBFromPool(db)
|
||||
defer dbi.Close()
|
||||
|
||||
@ -104,8 +104,9 @@ func OpenDatabase() (*pgxpool.Pool, error) {
|
||||
return nil, err
|
||||
}
|
||||
m.Up()
|
||||
fmt.Println("Migrating finished")
|
||||
|
||||
return db, err
|
||||
return db, nil
|
||||
}
|
||||
|
||||
type Handler struct {
|
||||
@ -149,6 +150,9 @@ func main() {
|
||||
|
||||
e.GET("/users", h.ListUsers)
|
||||
e.POST("/users", h.Register)
|
||||
|
||||
e.POST("/session", h.Login)
|
||||
|
||||
e.GET("/swagger/*", echoSwagger.WrapHandler)
|
||||
|
||||
e.Logger.Fatal(e.Start(":4568"))
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/alexedwards/argon2id"
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/zoriya/kyoo/keibi/dbc"
|
||||
@ -19,6 +20,48 @@ type LoginDto struct {
|
||||
Password string `json:"password" validate:"required"`
|
||||
}
|
||||
|
||||
// @Summary Login
|
||||
// @Description Login to your account and open a session
|
||||
// @Tags sessions
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param device query uuid false "The device the created session will be used on"
|
||||
// @Param user body LoginDto false "Account informations"
|
||||
// @Success 201 {object} dbc.Session
|
||||
// @Failure 400 {object} problem.Problem "Invalid login body"
|
||||
// @Failure 400 {object} problem.Problem "Invalid password"
|
||||
// @Failure 404 {object} problem.Problem "Account does not exists"
|
||||
// @Router /sessions [post]
|
||||
func (h *Handler) Login(c echo.Context) error {
|
||||
var req LoginDto
|
||||
err := c.Bind(&req)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if err = c.Validate(&req); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dbuser, err := h.db.GetUserByLogin(context.Background(), req.Login)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusNotFound, "No account exists with the specified email or username.")
|
||||
}
|
||||
if dbuser.Password == nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "Can't login with password, this account was created with OIDC.")
|
||||
}
|
||||
|
||||
match, err := argon2id.ComparePasswordAndHash(req.Password, *dbuser.Password)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !match {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "Invalid password")
|
||||
}
|
||||
|
||||
user := MapDbUser(&dbuser)
|
||||
return h.createSession(c, &user)
|
||||
}
|
||||
|
||||
func (h *Handler) createSession(c echo.Context, user *User) error {
|
||||
ctx := context.Background()
|
||||
|
||||
|
@ -18,7 +18,7 @@ order by
|
||||
id
|
||||
limit $1;
|
||||
|
||||
-- name: GetUser :one
|
||||
-- name: GetUser :many
|
||||
select
|
||||
sqlc.embed(u),
|
||||
sqlc.embed(h)
|
||||
@ -26,7 +26,16 @@ from
|
||||
users as u
|
||||
left join oidc_handle as h on u.id = h.user_id
|
||||
where
|
||||
u.id = $1
|
||||
u.id = $1;
|
||||
|
||||
-- name: GetUserByLogin :one
|
||||
select
|
||||
*
|
||||
from
|
||||
users
|
||||
where
|
||||
email = sqlc.arg(login)
|
||||
or username = sqlc.arg(login)
|
||||
limit 1;
|
||||
|
||||
-- name: CreateUser :one
|
||||
|
@ -29,7 +29,7 @@ type OidcHandle struct {
|
||||
}
|
||||
|
||||
type RegisterDto struct {
|
||||
Username string `json:"username" validate:"required"`
|
||||
Username string `json:"username" validate:"required,excludes=@"`
|
||||
Email string `json:"email" validate:"required,email" format:"email"`
|
||||
Password string `json:"password" validate:"required"`
|
||||
}
|
||||
@ -51,7 +51,7 @@ func MapDbUser(user *dbc.User) User {
|
||||
// @Tags users
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param afterId query uuid false "used for pagination."
|
||||
// @Param afterId query string false "used for pagination." Format(uuid)
|
||||
// @Success 200 {object} User[]
|
||||
// @Failure 400 {object} problem.Problem
|
||||
// @Router /users [get]
|
||||
@ -95,7 +95,8 @@ func (h *Handler) ListUsers(c echo.Context) error {
|
||||
// @Param device query uuid false "The device the created session will be used on"
|
||||
// @Param user body RegisterDto false "Registration informations"
|
||||
// @Success 201 {object} dbc.Session
|
||||
// @Failure 400 {object} problem.Problem
|
||||
// @Failure 400 {object} problem.Problem "Invalid register body"
|
||||
// @Success 409 {object} problem.Problem "Duplicated email or username"
|
||||
// @Router /users [post]
|
||||
func (h *Handler) Register(c echo.Context) error {
|
||||
var req RegisterDto
|
||||
@ -109,7 +110,7 @@ func (h *Handler) Register(c echo.Context) error {
|
||||
|
||||
pass, err := argon2id.CreateHash(req.Password, argon2id.DefaultParams)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(400, "Invalid password")
|
||||
return err
|
||||
}
|
||||
|
||||
duser, err := h.db.CreateUser(context.Background(), dbc.CreateUserParams{
|
||||
|
Loading…
x
Reference in New Issue
Block a user