appidea-restapi/routers/api/v1/user/login.go

103 lines
2.8 KiB
Go

package user
import (
"encoding/base64"
"git.umbach.dev/app-idea/rest-api/modules/database"
"git.umbach.dev/app-idea/rest-api/modules/structs"
"github.com/gofiber/fiber/v2"
log "github.com/sirupsen/logrus"
"golang.org/x/crypto/bcrypt"
)
type LoginInput struct {
Username string `json:"username"`
Email string `json:"email"`
Password string `json:"password"`
}
func Login(c *fiber.Ctx) error {
// swagger:operation POST /user/login User userLogin
// ---
// summary: Login a user
// produces:
// - application/json
// parameters:
// - name: username or email
// in: query
// description: username or email
// type: string
// required: true
// - name: password
// in: query
// description: password (base64) of the user
// type: string
// required: true
// responses:
// '200':
// description: login success
// '401':
// description: login credentials not correct
var input LoginInput
if err := c.BodyParser(&input); err != nil {
return c.SendStatus(fiber.StatusBadRequest)
}
log.Println(input)
if input.Username != "" && /*!isValid(input.Username, 3, 30) */ !isUsernameValid(input.Username) || input.Email != "" && !isEmailValid(input.Email) || input.Username == "" && input.Email == "" || input.Password == "" {
log.Info("bad")
return c.SendStatus(fiber.StatusBadRequest)
}
decodedPassword, err := base64.StdEncoding.DecodeString(input.Password)
if err != nil {
log.Debugln("base64 decoding failed:", err)
return c.SendStatus(fiber.StatusBadRequest)
}
input.Password = string(decodedPassword)
db := database.DB
user := structs.User{Name: input.Username, Email: input.Email}
if input.Username != "" {
db.Select("id, hashtag, password").Where("name = ?", input.Username).Find(&user)
} else {
db.Select("id, hashtag, name, password").Where("email = ?", input.Email).Find(&user)
}
if user.Name == "" && user.Email == "" {
log.Info("test1", user)
return c.SendStatus(fiber.StatusUnauthorized)
}
err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(input.Password))
if err != nil {
log.Warnln("Failed to comapare bcrypt password", err)
return c.SendStatus(fiber.StatusUnauthorized)
}
sessionId, err := createUserSession(database.DB, user.Id, c.IP(), string(c.Context().UserAgent()))
if err != nil {
return c.SendStatus(fiber.StatusInternalServerError)
}
expires := getUserSessionExpiresTime()
cfg := cfg.Settings.Cookies
c.Cookie(&fiber.Cookie{Name: cfg.SessionId, Value: sessionId, Secure: true, HTTPOnly: true, Expires: expires})
if user.Name != "" {
c.Cookie(&fiber.Cookie{Name: cfg.Username, Value: user.Name, Secure: true, Expires: expires})
}
c.Cookie(&fiber.Cookie{Name: cfg.UserHashtag, Value: user.Hashtag, Secure: true, Expires: expires})
return c.SendStatus(fiber.StatusCreated)
}