mirror of
https://github.com/paralus/paralus.git
synced 2026-05-07 00:46:52 +00:00
361 lines
11 KiB
Go
361 lines
11 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/RafaySystems/rcloud-base/internal/models"
|
|
"github.com/RafaySystems/rcloud-base/internal/persistence/provider/pg"
|
|
v3 "github.com/RafaySystems/rcloud-base/proto/types/commonpb/v3"
|
|
systemv3 "github.com/RafaySystems/rcloud-base/proto/types/systempb/v3"
|
|
"github.com/google/uuid"
|
|
bun "github.com/uptrace/bun"
|
|
"google.golang.org/protobuf/types/known/timestamppb"
|
|
)
|
|
|
|
const (
|
|
organizationKind = "Organization"
|
|
organizationListKind = "OrganizationList"
|
|
)
|
|
|
|
// OrganizationService is the interface for organization operations
|
|
type OrganizationService interface {
|
|
// create organization
|
|
Create(ctx context.Context, organization *systemv3.Organization) (*systemv3.Organization, error)
|
|
// get organization by id
|
|
GetByID(ctx context.Context, id string) (*systemv3.Organization, error)
|
|
// get organization by id
|
|
GetByName(ctx context.Context, name string) (*systemv3.Organization, error)
|
|
// create or update organization
|
|
Update(ctx context.Context, organization *systemv3.Organization) (*systemv3.Organization, error)
|
|
// delete organization
|
|
Delete(ctx context.Context, organization *systemv3.Organization) (*systemv3.Organization, error)
|
|
// list organization
|
|
List(ctx context.Context, organization *systemv3.Organization) (*systemv3.OrganizationList, error)
|
|
}
|
|
|
|
// organizationService implements OrganizationService
|
|
type organizationService struct {
|
|
db *bun.DB
|
|
}
|
|
|
|
// NewOrganizationService return new organization service
|
|
func NewOrganizationService(db *bun.DB) OrganizationService {
|
|
return &organizationService{db}
|
|
}
|
|
|
|
func (s *organizationService) Create(ctx context.Context, org *systemv3.Organization) (*systemv3.Organization, error) {
|
|
|
|
var partner models.Partner
|
|
_, err := pg.GetByName(ctx, s.db, org.Metadata.Partner, &partner)
|
|
if err != nil {
|
|
return &systemv3.Organization{}, err
|
|
}
|
|
|
|
//update default organization setting values
|
|
org.Spec.Settings = &systemv3.OrganizationSettings{
|
|
Lockout: &systemv3.Lockout{
|
|
Enabled: true,
|
|
PeriodMin: 15,
|
|
Attempts: 5,
|
|
},
|
|
IdleLogoutMin: 60,
|
|
}
|
|
sb, err := json.MarshalIndent(org.GetSpec().GetSettings(), "", "\t")
|
|
if err != nil {
|
|
return &systemv3.Organization{}, err
|
|
}
|
|
//convert v3 spec to internal models
|
|
organization := models.Organization{
|
|
Name: org.GetMetadata().GetName(),
|
|
Description: org.GetMetadata().GetDescription(),
|
|
Trash: false,
|
|
Settings: json.RawMessage(sb),
|
|
BillingAddress: org.GetSpec().GetBillingAddress(),
|
|
PartnerId: partner.ID,
|
|
Active: org.GetSpec().GetActive(),
|
|
Approved: org.GetSpec().GetApproved(),
|
|
Type: org.GetSpec().GetType(),
|
|
AddressLine1: org.GetSpec().GetAddressLine1(),
|
|
AddressLine2: org.GetSpec().GetAddressLine2(),
|
|
City: org.GetSpec().GetCity(),
|
|
Country: org.GetSpec().GetCountry(),
|
|
Phone: org.GetSpec().GetPhone(),
|
|
State: org.GetSpec().GetState(),
|
|
Zipcode: org.GetSpec().GetZipcode(),
|
|
IsPrivate: org.GetSpec().GetIsPrivate(),
|
|
IsTOTPEnabled: org.GetSpec().GetIsTotpEnabled(),
|
|
AreClustersShared: org.GetSpec().GetAreClustersShared(),
|
|
CreatedAt: time.Now(),
|
|
ModifiedAt: time.Now(),
|
|
}
|
|
entity, err := pg.Create(ctx, s.db, &organization)
|
|
if err != nil {
|
|
return &systemv3.Organization{}, err
|
|
}
|
|
|
|
if createdOrg, ok := entity.(*models.Organization); ok {
|
|
//update v3 spec
|
|
org.Metadata.Id = createdOrg.ID.String()
|
|
}
|
|
|
|
return org, nil
|
|
}
|
|
|
|
func (s *organizationService) GetByID(ctx context.Context, id string) (*systemv3.Organization, error) {
|
|
|
|
organization := &systemv3.Organization{
|
|
ApiVersion: apiVersion,
|
|
Kind: organizationKind,
|
|
Metadata: &v3.Metadata{
|
|
Id: id,
|
|
},
|
|
Spec: &systemv3.OrganizationSpec{},
|
|
}
|
|
|
|
uid, err := uuid.Parse(id)
|
|
if err != nil {
|
|
return &systemv3.Organization{}, err
|
|
}
|
|
entity, err := pg.GetByID(ctx, s.db, uid, &models.Organization{})
|
|
if err != nil {
|
|
return &systemv3.Organization{}, err
|
|
}
|
|
|
|
if org, ok := entity.(*models.Organization); ok {
|
|
|
|
var partner models.Partner
|
|
_, err := pg.GetByID(ctx, s.db, org.PartnerId, &partner)
|
|
if err != nil {
|
|
return &systemv3.Organization{}, err
|
|
}
|
|
|
|
organization, err = prepareOrganizationResponse(organization, org, partner.Name)
|
|
if err != nil {
|
|
return &systemv3.Organization{}, err
|
|
}
|
|
|
|
return organization, nil
|
|
|
|
} else {
|
|
organization := &systemv3.Organization{
|
|
ApiVersion: apiVersion,
|
|
Kind: organizationKind,
|
|
Status: &v3.Status{
|
|
ConditionType: "Describe",
|
|
ConditionStatus: v3.ConditionStatus_StatusNotSet,
|
|
Reason: "Unable to fetch organization information",
|
|
LastUpdated: timestamppb.Now(),
|
|
},
|
|
}
|
|
|
|
return organization, nil
|
|
}
|
|
|
|
}
|
|
|
|
func (s *organizationService) GetByName(ctx context.Context, name string) (*systemv3.Organization, error) {
|
|
|
|
organization := &systemv3.Organization{
|
|
ApiVersion: apiVersion,
|
|
Kind: organizationKind,
|
|
Metadata: &v3.Metadata{
|
|
Name: name,
|
|
},
|
|
}
|
|
entity, err := pg.GetByName(ctx, s.db, name, &models.Organization{})
|
|
if err != nil {
|
|
return &systemv3.Organization{}, err
|
|
}
|
|
|
|
if org, ok := entity.(*models.Organization); ok {
|
|
|
|
var partner models.Partner
|
|
_, err := pg.GetByID(ctx, s.db, org.PartnerId, &partner)
|
|
if err != nil {
|
|
return &systemv3.Organization{}, err
|
|
}
|
|
|
|
organization, err = prepareOrganizationResponse(organization, org, partner.Name)
|
|
if err != nil {
|
|
return &systemv3.Organization{}, err
|
|
}
|
|
}
|
|
|
|
return organization, nil
|
|
}
|
|
|
|
func (s *organizationService) Update(ctx context.Context, organization *systemv3.Organization) (*systemv3.Organization, error) {
|
|
|
|
entity, err := pg.GetByName(ctx, s.db, organization.Metadata.Name, &models.Organization{})
|
|
if err != nil {
|
|
return &systemv3.Organization{}, err
|
|
}
|
|
|
|
if org, ok := entity.(*models.Organization); ok {
|
|
|
|
sb, err := json.MarshalIndent(organization.GetSpec().GetSettings(), "", "\t")
|
|
if err != nil {
|
|
return &systemv3.Organization{}, err
|
|
}
|
|
|
|
//update organization details
|
|
org.Name = organization.GetMetadata().GetName()
|
|
org.Description = organization.GetMetadata().GetDescription()
|
|
org.ModifiedAt = time.Now()
|
|
org.Trash = false
|
|
org.Settings = json.RawMessage(sb)
|
|
org.BillingAddress = organization.GetSpec().GetBillingAddress()
|
|
org.Active = organization.GetSpec().GetActive()
|
|
org.Approved = organization.GetSpec().GetApproved()
|
|
org.Type = organization.GetSpec().GetType()
|
|
org.AddressLine1 = organization.GetSpec().GetAddressLine1()
|
|
org.AddressLine2 = organization.GetSpec().GetAddressLine2()
|
|
org.City = organization.GetSpec().GetCity()
|
|
org.Country = organization.GetSpec().GetCountry()
|
|
org.Phone = organization.GetSpec().GetPhone()
|
|
org.State = organization.GetSpec().GetState()
|
|
org.Zipcode = organization.GetSpec().GetZipcode()
|
|
org.IsPrivate = organization.GetSpec().GetIsPrivate()
|
|
org.IsTOTPEnabled = organization.GetSpec().GetIsTotpEnabled()
|
|
org.AreClustersShared = organization.GetSpec().GetAreClustersShared()
|
|
|
|
_, err = pg.Update(ctx, s.db, org.ID, org)
|
|
if err != nil {
|
|
return &systemv3.Organization{}, err
|
|
}
|
|
}
|
|
|
|
return organization, nil
|
|
}
|
|
|
|
func (s *organizationService) Delete(ctx context.Context, organization *systemv3.Organization) (*systemv3.Organization, error) {
|
|
|
|
entity, err := pg.GetByName(ctx, s.db, organization.Metadata.Name, &models.Organization{})
|
|
if err != nil {
|
|
return &systemv3.Organization{}, err
|
|
}
|
|
|
|
if org, ok := entity.(*models.Organization); ok {
|
|
org.Trash = true
|
|
_, err := pg.Update(ctx, s.db, org.ID, org)
|
|
if err != nil {
|
|
return &systemv3.Organization{}, err
|
|
}
|
|
|
|
//update v3 status
|
|
organization.Metadata.Name = org.Name
|
|
organization.Metadata.ModifiedAt = timestamppb.New(org.ModifiedAt)
|
|
}
|
|
return organization, nil
|
|
|
|
}
|
|
|
|
func (s *organizationService) List(ctx context.Context, organization *systemv3.Organization) (*systemv3.OrganizationList, error) {
|
|
|
|
var organizations []*systemv3.Organization
|
|
organinzationList := &systemv3.OrganizationList{
|
|
ApiVersion: apiVersion,
|
|
Kind: organizationListKind,
|
|
Metadata: &v3.ListMetadata{
|
|
Count: 0,
|
|
},
|
|
}
|
|
if len(organization.Metadata.Partner) > 0 {
|
|
var partner models.Partner
|
|
_, err := pg.GetByName(ctx, s.db, organization.Metadata.Partner, &partner)
|
|
if err != nil {
|
|
return &systemv3.OrganizationList{}, err
|
|
}
|
|
|
|
var orgs []models.Organization
|
|
entities, err := pg.List(ctx, s.db, uuid.NullUUID{UUID: partner.ID, Valid: true}, uuid.NullUUID{UUID: uuid.Nil}, &orgs)
|
|
if err != nil {
|
|
return &systemv3.OrganizationList{}, err
|
|
}
|
|
if orgs, ok := entities.(*[]models.Organization); ok {
|
|
for _, org := range *orgs {
|
|
var settings systemv3.OrganizationSettings
|
|
err := json.Unmarshal(org.Settings, &settings)
|
|
if err != nil {
|
|
return &systemv3.OrganizationList{}, err
|
|
}
|
|
organization.Metadata = &v3.Metadata{
|
|
Name: org.Name,
|
|
Description: org.Description,
|
|
Partner: partner.Name,
|
|
ModifiedAt: timestamppb.New(org.ModifiedAt),
|
|
}
|
|
organization.Spec = &systemv3.OrganizationSpec{
|
|
BillingAddress: org.BillingAddress,
|
|
Active: org.Active,
|
|
Approved: org.Approved,
|
|
Type: org.Type,
|
|
AddressLine1: org.AddressLine1,
|
|
AddressLine2: org.AddressLine2,
|
|
City: org.City,
|
|
Country: org.Country,
|
|
Phone: org.Phone,
|
|
State: org.State,
|
|
Zipcode: org.Zipcode,
|
|
IsPrivate: org.IsPrivate,
|
|
IsTotpEnabled: org.IsTOTPEnabled,
|
|
AreClustersShared: org.AreClustersShared,
|
|
Settings: &settings,
|
|
}
|
|
organizations = append(organizations, organization)
|
|
}
|
|
|
|
//update the list metadata and items response
|
|
organinzationList.Metadata = &v3.ListMetadata{
|
|
Count: int64(len(organizations)),
|
|
}
|
|
organinzationList.Items = organizations
|
|
}
|
|
|
|
} else {
|
|
return organinzationList, fmt.Errorf("missing partner in metadata")
|
|
}
|
|
return organinzationList, nil
|
|
}
|
|
|
|
func prepareOrganizationResponse(organization *systemv3.Organization, org *models.Organization, partnerName string) (*systemv3.Organization, error) {
|
|
|
|
var settings systemv3.OrganizationSettings
|
|
if org.Settings != nil {
|
|
err := json.Unmarshal(org.Settings, &settings)
|
|
if err != nil {
|
|
return &systemv3.Organization{}, err
|
|
}
|
|
}
|
|
|
|
organization.Metadata = &v3.Metadata{
|
|
Name: org.Name,
|
|
Id: org.ID.String(),
|
|
Description: org.Description,
|
|
Partner: partnerName,
|
|
ModifiedAt: timestamppb.New(org.ModifiedAt),
|
|
}
|
|
organization.Spec = &systemv3.OrganizationSpec{
|
|
BillingAddress: org.BillingAddress,
|
|
Active: org.Active,
|
|
Approved: org.Approved,
|
|
Type: org.Type,
|
|
AddressLine1: org.AddressLine1,
|
|
AddressLine2: org.AddressLine2,
|
|
City: org.City,
|
|
Country: org.Country,
|
|
Phone: org.Phone,
|
|
State: org.State,
|
|
Zipcode: org.Zipcode,
|
|
IsPrivate: org.IsPrivate,
|
|
IsTotpEnabled: org.IsTOTPEnabled,
|
|
AreClustersShared: org.AreClustersShared,
|
|
Settings: &settings,
|
|
}
|
|
|
|
return organization, nil
|
|
}
|