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) }