package organization import ( "encoding/base64" "time" "git.ex.umbach.dev/Alex/roese-utils/rsutils" "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/structs" "lms.de/backend/modules/utils" ) func CreateOrganization(c *fiber.Ctx) error { // swagger:operation POST /organization organization createOrganization // --- // summary: Create organization // consumes: // - application/json // produces: // - application/json // parameters: // - name: body // in: body // schema: // "$ref": "#/definitions/CreateOrganizationRequest" // responses: // '200': // description: Organization created successfully // schema: // "$ref": "#/definitions/CreateOrganizationResponse" // '400': // description: Invalid request body // '500': // description: Failed to create organization var body structs.CreateOrganizationRequest 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) } hashedPassword, err := bcrypt.GenerateFromPassword(decodedPassword, bcrypt.DefaultCost) if err != nil { log.Error().Msg("Failed to hash password, err: " + err.Error()) return c.SendStatus(fiber.StatusInternalServerError) } organizationId := uuid.New().String() userId := uuid.New().String() subdomain := utils.GenerateSubdomain() database.DB.Create(&structs.Organization{ Id: organizationId, Subdomain: subdomain, OwnerUserId: userId, CompanyName: "Mustermann GmbH", }) database.DB.Create(&structs.User{ Id: userId, OrganizationId: organizationId, Active: true, FirstName: "Max", LastName: "Mustermann", Email: body.Email, Password: string(hashedPassword), }) session, err := rsutils.GenerateSession() if err != nil { return c.SendStatus(fiber.StatusInternalServerError) } database.DB.Create(&structs.UserSession{ Id: session, OrganizationId: organizationId, Session: uuid.New().String(), UserId: userId, UserAgent: string(c.Context().UserAgent()), ExpiresAt: utils.GetSessionExpiresAtTime(), LastUsedAt: time.Now(), }) return c.JSON(structs.CreateOrganizationResponse{ OrganizationSubdomain: subdomain, Session: session, }) } func IsSubdomainAvailable(c *fiber.Ctx) error { // swagger:operation GET /organization/subdomain/{subdomain} organization isSubdomainAvailable // --- // summary: Check if subdomain is available // produces: // - application/json // parameters: // - name: subdomain // in: path // required: true // type: string // responses: // '200': // description: Subdomain is available // schema: // "$ref": "#/definitions/IsSubdomainAvailableResponse" // '400': // description: Invalid subdomain // '500': // description: Failed to check subdomain var params structs.SubdomainParam if err := rsutils.ParamsParserHelper(c, ¶ms); err != nil { return c.SendStatus(fiber.StatusBadRequest) } var organization structs.Organization database.DB.Select("Id").Where("subdomain = ?", params.Subdomain).First(&organization) if organization.Id != "" { return c.JSON(structs.IsSubdomainAvailableResponse{ Available: false, }) } return c.JSON(structs.IsSubdomainAvailableResponse{ Available: true, }) } func UpdateSubdomain(c *fiber.Ctx) error { // swagger:operation PATCH /organization/subdomain/{subdomain} organization updateSubdomain // --- // summary: Update organization subdomain // consumes: // - application/json // produces: // - application/json // parameters: // - name: subdomain // in: path // required: true // type: string // responses: // '200': // description: Subdomain updated successfully // '400': // description: Invalid request body // '500': // description: Failed to update subdomain var params structs.SubdomainParam if err := rsutils.ParamsParserHelper(c, ¶ms); err != nil { return c.SendStatus(fiber.StatusBadRequest) } organization := structs.Organization{ Id: c.Locals("organizationId").(string), } database.DB.Select("subdomain").Model(organization).First(&organization) if organization.Subdomain == "" { return c.SendStatus(fiber.StatusBadRequest) } database.DB.Model(&organization).Update("subdomain", params.Subdomain) return c.JSON(fiber.Map{ "status": "success", }) }