You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
OneAuth/api/org/create.go

113 lines
3.2 KiB
Go

// Copyright (C) 2024 veypi <i@veypi.com>
// 2025-03-04 16:08:06
// Distributed under terms of the MIT license.
package org
import (
1 week ago
"github.com/veypi/vbase/auth"
"github.com/veypi/vbase/cfg"
"github.com/veypi/vbase/models"
"github.com/veypi/vigo"
)
type CreateRequest struct {
Name string `json:"name" src:"json" desc:"组织名称"`
Code string `json:"code" src:"json" desc:"组织代码"`
Description string `json:"description,omitempty" src:"json" desc:"描述"`
Logo string `json:"logo,omitempty" src:"json" desc:"Logo"`
ParentID *string `json:"parent_id,omitempty" src:"json" desc:"父组织ID"`
}
func create(x *vigo.X, req *CreateRequest) (*models.Org, error) {
// 检查代码是否已存在
var count int64
cfg.DB().Model(&models.Org{}).Where("code = ?", req.Code).Count(&count)
if count > 0 {
return nil, vigo.ErrInvalidArg.WithString("organization code already exists")
}
// 获取当前用户ID作为所有者
ownerID := auth.GetUserID(x)
if ownerID == "" {
return nil, vigo.ErrUnauthorized
}
org := &models.Org{
Name: req.Name,
Code: req.Code,
Description: req.Description,
Logo: req.Logo,
OwnerID: ownerID,
ParentID: req.ParentID,
Status: models.OrgStatusActive,
}
if err := cfg.DB().Create(org).Error; err != nil {
return nil, vigo.ErrInternalServer.WithError(err)
}
// 创建组织的默认角色
adminRole := &models.Role{
OrgID: &org.ID,
Code: "admin",
Name: "管理员",
Status: 1,
IsSystem: true,
}
memberRole := &models.Role{
OrgID: &org.ID,
Code: "member",
Name: "成员",
Status: 1,
IsSystem: true,
}
if err := cfg.DB().Create(adminRole).Error; err != nil {
cfg.DB().Delete(org)
return nil, vigo.ErrInternalServer.WithError(err)
}
if err := cfg.DB().Create(memberRole).Error; err != nil {
cfg.DB().Delete(org)
cfg.DB().Delete(adminRole)
return nil, vigo.ErrInternalServer.WithError(err)
}
// 为组织 admin 角色添加权限 (vb:*:* 表示该组织下的所有权限)
adminPerms := []models.RolePermission{
{RoleID: adminRole.ID, PermissionID: "vb:*:*", Condition: "none"},
{RoleID: adminRole.ID, PermissionID: "vb:org:read", Condition: "none"},
{RoleID: adminRole.ID, PermissionID: "vb:org:update", Condition: "none"},
{RoleID: adminRole.ID, PermissionID: "vb:org:delete", Condition: "none"},
}
for _, perm := range adminPerms {
if err := cfg.DB().Create(&perm).Error; err != nil {
cfg.DB().Delete(&models.Role{}).Where("org_id = ?", org.ID)
cfg.DB().Delete(org)
return nil, vigo.ErrInternalServer.WithError(err)
}
}
1 week ago
// 授予创建者 admin 角色
1 week ago
if err := auth.VBaseAuth.GrantRole(x.Context(), ownerID, org.ID, "admin"); err != nil {
// 回滚
cfg.DB().Delete(&models.Role{}).Where("org_id = ?", org.ID)
cfg.DB().Delete(org)
1 week ago
return nil, vigo.ErrInternalServer.WithError(err)
}
1 week ago
member := &models.OrgMember{
OrgID: org.ID,
UserID: ownerID,
Status: models.MemberStatusActive,
JoinedAt: org.CreatedAt.Format("2006-01-02 15:04:05"),
}
if err := cfg.DB().Create(member).Error; err != nil {
// 回滚
auth.VBaseAuth.RevokeRole(x.Context(), ownerID, org.ID, "admin")
cfg.DB().Delete(org)
return nil, vigo.ErrInternalServer.WithError(err)
}
return org, nil
}