192 lines
4.8 KiB
Go
192 lines
4.8 KiB
Go
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",
|
|
})
|
|
}
|