package router import ( "github.com/gofiber/fiber/v2" "github.com/johannesbuehl/golunteer/backend/pkg/db" "golang.org/x/crypto/bcrypt" ) // handle welcome-messages from clients func handleWelcome(c *fiber.Ctx) error { args := Handler{C: c} logger.Debug().Msgf("HTTP %s request: %q", c.Method(), c.OriginalURL()) args.Data = UserChecked{ Admin: false, } if loggedIn, err := args.checkUser(); err != nil { args.Status = fiber.StatusInternalServerError logger.Warn().Msgf("can't check user: %v", err) } else if !loggedIn { args.Status = fiber.StatusUnauthorized logger.Debug().Msgf("user not authorized") } else { args.Data = UserChecked{ UserName: args.UserName, Admin: args.Admin, } logger.Debug().Msgf("welcomed user %q", args.UserName) } return args.send(c) } const messageWrongLogin = "Unkown user or wrong password" func handleLogin(c *fiber.Ctx) error { logger.Debug().Msgf("HTTP %s request: %q", c.Method(), c.OriginalURL()) args := Handler{C: c} // extract username and password from the request requestBody := struct { Username string `json:"userName" validate:"required"` Password string `json:"password" validate:"required"` }{} if err := args.C.BodyParser(&requestBody); err != nil { logger.Debug().Msgf("can't parse login-body: %v", err) args.Status = fiber.StatusBadRequest // validate the body } else if err := validate.Struct(requestBody); err != nil { logger.Warn().Msgf("can't parse login-body: %v", err) } else { // query the database for the user var result userDB if err := db.DB.QueryRowx("SELECT password, admin, tokenID FROM USERS WHERE userName = ?", requestBody.Username).StructScan(&result); err != nil { args.Status = fiber.StatusForbidden args.Message = messageWrongLogin logger.Info().Msgf("can't get user with userName = %q from database", requestBody.Username) } else { // hash the password if bcrypt.CompareHashAndPassword(result.Password, []byte(requestBody.Password)) != nil { args.Status = fiber.StatusForbidden logger.Info().Msgf("login denied: wrong password for user with userName = %q", requestBody.Username) } else { // password is correct -> generate the JWT if jwt, err := config.SignJWT(JWTPayload{ UserName: requestBody.Username, TokenID: result.TokenID, }); err != nil { args.Status = fiber.StatusInternalServerError logger.Error().Msgf("can't create JWT: %v", err) } else { args.setSessionCookie(&jwt) args.Data = UserChecked{ UserName: requestBody.Username, Admin: true, } logger.Debug().Msgf("user %q logged in", requestBody.Username) } } } } return args.send(args.C) } // handles logout-requests func handleLogout(c *fiber.Ctx) error { logger.Debug().Msgf("HTTP %s request: %q", c.Method(), c.OriginalURL()) args := Handler{ C: c, } args.removeSessionCookie() return args.send(c) }