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 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!")
|
fmt.Printf("Could not connect to database, check your env variables!")
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer db.Close()
|
|
||||||
|
|
||||||
if schema != "disabled" {
|
if schema != "disabled" {
|
||||||
_, err = db.Exec(ctx, fmt.Sprintf("create schema if not exists %s", schema))
|
_, 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)
|
dbi := stdlib.OpenDBFromPool(db)
|
||||||
defer dbi.Close()
|
defer dbi.Close()
|
||||||
|
|
||||||
@ -104,8 +104,9 @@ func OpenDatabase() (*pgxpool.Pool, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
m.Up()
|
m.Up()
|
||||||
|
fmt.Println("Migrating finished")
|
||||||
|
|
||||||
return db, err
|
return db, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type Handler struct {
|
type Handler struct {
|
||||||
@ -149,6 +150,9 @@ func main() {
|
|||||||
|
|
||||||
e.GET("/users", h.ListUsers)
|
e.GET("/users", h.ListUsers)
|
||||||
e.POST("/users", h.Register)
|
e.POST("/users", h.Register)
|
||||||
|
|
||||||
|
e.POST("/session", h.Login)
|
||||||
|
|
||||||
e.GET("/swagger/*", echoSwagger.WrapHandler)
|
e.GET("/swagger/*", echoSwagger.WrapHandler)
|
||||||
|
|
||||||
e.Logger.Fatal(e.Start(":4568"))
|
e.Logger.Fatal(e.Start(":4568"))
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/alexedwards/argon2id"
|
||||||
"github.com/golang-jwt/jwt/v5"
|
"github.com/golang-jwt/jwt/v5"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
"github.com/zoriya/kyoo/keibi/dbc"
|
"github.com/zoriya/kyoo/keibi/dbc"
|
||||||
@ -19,6 +20,48 @@ type LoginDto struct {
|
|||||||
Password string `json:"password" validate:"required"`
|
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 {
|
func (h *Handler) createSession(c echo.Context, user *User) error {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ order by
|
|||||||
id
|
id
|
||||||
limit $1;
|
limit $1;
|
||||||
|
|
||||||
-- name: GetUser :one
|
-- name: GetUser :many
|
||||||
select
|
select
|
||||||
sqlc.embed(u),
|
sqlc.embed(u),
|
||||||
sqlc.embed(h)
|
sqlc.embed(h)
|
||||||
@ -26,7 +26,16 @@ from
|
|||||||
users as u
|
users as u
|
||||||
left join oidc_handle as h on u.id = h.user_id
|
left join oidc_handle as h on u.id = h.user_id
|
||||||
where
|
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;
|
limit 1;
|
||||||
|
|
||||||
-- name: CreateUser :one
|
-- name: CreateUser :one
|
||||||
|
@ -29,7 +29,7 @@ type OidcHandle struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type RegisterDto 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"`
|
Email string `json:"email" validate:"required,email" format:"email"`
|
||||||
Password string `json:"password" validate:"required"`
|
Password string `json:"password" validate:"required"`
|
||||||
}
|
}
|
||||||
@ -51,7 +51,7 @@ func MapDbUser(user *dbc.User) User {
|
|||||||
// @Tags users
|
// @Tags users
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Produce 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[]
|
// @Success 200 {object} User[]
|
||||||
// @Failure 400 {object} problem.Problem
|
// @Failure 400 {object} problem.Problem
|
||||||
// @Router /users [get]
|
// @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 device query uuid false "The device the created session will be used on"
|
||||||
// @Param user body RegisterDto false "Registration informations"
|
// @Param user body RegisterDto false "Registration informations"
|
||||||
// @Success 201 {object} dbc.Session
|
// @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]
|
// @Router /users [post]
|
||||||
func (h *Handler) Register(c echo.Context) error {
|
func (h *Handler) Register(c echo.Context) error {
|
||||||
var req RegisterDto
|
var req RegisterDto
|
||||||
@ -109,7 +110,7 @@ func (h *Handler) Register(c echo.Context) error {
|
|||||||
|
|
||||||
pass, err := argon2id.CreateHash(req.Password, argon2id.DefaultParams)
|
pass, err := argon2id.CreateHash(req.Password, argon2id.DefaultParams)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return echo.NewHTTPError(400, "Invalid password")
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
duser, err := h.db.CreateUser(context.Background(), dbc.CreateUserParams{
|
duser, err := h.db.CreateUser(context.Background(), dbc.CreateUserParams{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user