package user import ( "encoding/base64" "git.ex.umbach.dev/Alex/roese-utils/rslogger" "git.ex.umbach.dev/Alex/roese-utils/rsutils" "git.ex.umbach.dev/LMS/libcore/models" "github.com/gofiber/fiber/v2" "github.com/google/uuid" "github.com/rs/zerolog/log" "golang.org/x/crypto/bcrypt" "lms.de/backend/modules/database" "lms.de/backend/modules/logger" "lms.de/backend/modules/structs" "lms.de/backend/modules/utils" ) func UserLogin(c *fiber.Ctx) error { // swagger:operation POST /user/auth/login user userLogin // --- // summary: Login user // consumes: // - application/json // produces: // - application/json // parameters: // - name: body // in: body // schema: // "$ref": "#/definitions/UserLoginRequest" // responses: // '200': // description: User logged in successfully // schema: // "$ref": "#/definitions/UserLoginResponse" // '400': // description: Invalid request body // '401': // description: Incorrect password or user deactivated // '500': // description: Failed to login user var body structs.UserLoginRequest if err := rsutils.BodyParserHelper(c, &body); err != nil { return c.SendStatus(fiber.StatusBadRequest) } decodedPassword, err := base64.StdEncoding.DecodeString(body.Password) if err != nil { log.Error().Msg("Failed to decode base64 password, err: " + err.Error()) return c.SendStatus(fiber.StatusBadRequest) } if passwordValid := utils.IsPasswordLengthValid(string(decodedPassword)); !passwordValid { return c.SendStatus(fiber.StatusBadRequest) } var user models.User organizationId := c.Locals("organizationId").(string) if err := database.DB.Select("id", "disabled", "password"). First(&user, "email = ? AND organization_id = ?", body.Email, organizationId).Error; err != nil { logger.AddSystemLog(rslogger.LogTypeError, "Failed to find user with email %s", body.Email) return c.SendStatus(fiber.StatusBadRequest) } if user.Id == "" { log.Error().Msg("User not found") return c.SendStatus(fiber.StatusBadRequest) } if err := bcrypt.CompareHashAndPassword([]byte(user.Password), decodedPassword); err != nil { log.Error().Msg("Incorrect password") return c.SendStatus(fiber.StatusBadRequest) } if user.Disabled { return c.SendStatus(fiber.StatusUnauthorized) } session, err := rsutils.GenerateSession() if err != nil { return c.SendStatus(fiber.StatusInternalServerError) } if err := database.DB.Create(&models.UserSession{ Id: uuid.New().String(), OrganizationId: organizationId, Session: session, UserId: user.Id, UserAgent: string(c.Context().UserAgent()), ExpiresAt: utils.GetSessionExpiresAtTime()}).Error; err != nil { logger.AddSystemLog(rslogger.LogTypeError, "Failed to create user session, err: "+err.Error()) return c.SendStatus(fiber.StatusInternalServerError) } logger.AddSystemLog(rslogger.LogTypeInfo, "User %s has logged in", user.Id) return c.JSON(structs.UserLoginResponse{Session: session}) }