mirror of
https://github.com/MirageNetwork/MirageServer.git
synced 2025-11-01 20:22:42 +08:00
修改:user uniqIndex name-> name+orgName导致的联合唯一键使用
This commit is contained in:
@@ -173,7 +173,7 @@ func (h *Mirage) expireEphemeralNodesWorker() {
|
||||
}
|
||||
|
||||
for _, user := range users {
|
||||
machines, err := h.ListMachinesByUser(user.Name)
|
||||
machines, err := h.ListMachinesByUser(user.ID)
|
||||
if err != nil {
|
||||
log.Error().
|
||||
Err(err).
|
||||
@@ -218,7 +218,7 @@ func (h *Mirage) expireExpiredMachinesWorker() {
|
||||
}
|
||||
|
||||
for _, user := range users {
|
||||
machines, err := h.ListMachinesByUser(user.Name)
|
||||
machines, err := h.ListMachinesByUser(user.ID)
|
||||
if err != nil {
|
||||
log.Error().
|
||||
Err(err).
|
||||
|
||||
@@ -179,7 +179,7 @@ func (h *Mirage) ConsoleSelfAPI(
|
||||
func (h *Mirage) verifyTokenIDandGetUser(
|
||||
writer http.ResponseWriter,
|
||||
req *http.Request,
|
||||
) string {
|
||||
) *User {
|
||||
controlCodeCookie, err := req.Cookie("miragecontrol")
|
||||
if err == http.ErrNoCookie {
|
||||
errRes := adminTemplateConfig{ErrorMsg: "Token不存在"}
|
||||
@@ -190,7 +190,7 @@ func (h *Mirage) verifyTokenIDandGetUser(
|
||||
Err(err).
|
||||
Msg("Failed to write response")
|
||||
}
|
||||
return ""
|
||||
return nil
|
||||
}
|
||||
controlCode := controlCodeCookie.Value
|
||||
controlCodeC, concontrolCodeExpiration, ok := h.controlCodeCache.GetWithExpiration(controlCode)
|
||||
@@ -203,7 +203,7 @@ func (h *Mirage) verifyTokenIDandGetUser(
|
||||
Err(err).
|
||||
Msg("Failed to write response")
|
||||
}
|
||||
return ""
|
||||
return nil
|
||||
}
|
||||
controlCodeItem := controlCodeC.(ControlCacheItem)
|
||||
user, err := h.GetUserByID(controlCodeItem.uid)
|
||||
@@ -216,10 +216,9 @@ func (h *Mirage) verifyTokenIDandGetUser(
|
||||
Err(err).
|
||||
Msg("Failed to write response")
|
||||
}
|
||||
return ""
|
||||
return nil
|
||||
}
|
||||
userName := user.Name
|
||||
return userName
|
||||
return user
|
||||
}
|
||||
|
||||
// 控制台获取设备信息列表的API
|
||||
@@ -266,9 +265,8 @@ func (h *Mirage) ConsoleMachinesAPI(
|
||||
}
|
||||
return
|
||||
}
|
||||
userName := user.Name
|
||||
|
||||
UserMachines, err := h.ListMachinesByUser(userName)
|
||||
UserMachines, err := h.ListMachinesByUser(user.ID)
|
||||
if err != nil {
|
||||
errRes := adminTemplateConfig{ErrorMsg: "查询用户节点列表失败"}
|
||||
err = json.NewEncoder(writer).Encode(&errRes)
|
||||
@@ -450,16 +448,11 @@ func (h *Mirage) getNetSettingAPI(
|
||||
writer http.ResponseWriter,
|
||||
req *http.Request,
|
||||
) {
|
||||
userName := h.verifyTokenIDandGetUser(writer, req)
|
||||
if userName == "" {
|
||||
user := h.verifyTokenIDandGetUser(writer, req)
|
||||
if user.CheckEmpty() {
|
||||
h.doAPIResponse(writer, "用户信息核对失败", nil)
|
||||
return
|
||||
}
|
||||
user, err := h.GetUser(userName)
|
||||
if err != nil {
|
||||
h.doAPIResponse(writer, "查询用户失败:"+err.Error(), nil)
|
||||
return
|
||||
}
|
||||
netsettingData := NetSettingResData{
|
||||
FileSharing: false, //未实现
|
||||
ServicesCollection: false, //未实现
|
||||
@@ -478,8 +471,8 @@ func (h *Mirage) ConsoleUpdateKeyExpiryAPI(
|
||||
writer http.ResponseWriter,
|
||||
req *http.Request,
|
||||
) {
|
||||
userName := h.verifyTokenIDandGetUser(writer, req)
|
||||
if userName == "" {
|
||||
user := h.verifyTokenIDandGetUser(writer, req)
|
||||
if user.CheckEmpty() {
|
||||
h.doAPIResponse(writer, "用户信息核对失败", nil)
|
||||
return
|
||||
}
|
||||
@@ -496,7 +489,7 @@ func (h *Mirage) ConsoleUpdateKeyExpiryAPI(
|
||||
h.doAPIResponse(writer, "从请求获取新值失败:"+err.Error(), nil)
|
||||
return
|
||||
}
|
||||
err = h.UpdateUserKeyExpiry(userName, uint(newExpiryDuration))
|
||||
err = h.UpdateUserKeyExpiry(user.Name, user.OrgName, uint(newExpiryDuration))
|
||||
if err != nil {
|
||||
h.doAPIResponse(writer, "更新密钥过期时长失败:"+err.Error(), nil)
|
||||
return
|
||||
@@ -508,8 +501,8 @@ func (h *Mirage) ConsoleMachinesUpdateAPI(
|
||||
writer http.ResponseWriter,
|
||||
req *http.Request,
|
||||
) {
|
||||
userName := h.verifyTokenIDandGetUser(writer, req)
|
||||
if userName == "" {
|
||||
user := h.verifyTokenIDandGetUser(writer, req)
|
||||
if user.CheckEmpty() {
|
||||
h.doAPIResponse(writer, "用户信息核对失败", nil)
|
||||
return
|
||||
}
|
||||
@@ -535,7 +528,7 @@ func (h *Mirage) ConsoleMachinesUpdateAPI(
|
||||
h.doAPIResponse(writer, "查询用户设备失败", nil)
|
||||
return
|
||||
}
|
||||
if toUpdateMachine.User.Name != userName {
|
||||
if toUpdateMachine.User.ID != user.ID {
|
||||
h.doAPIResponse(writer, "用户没有该权限", nil)
|
||||
return
|
||||
}
|
||||
@@ -669,9 +662,9 @@ func (h *Mirage) ConsoleRemoveMachineAPI(
|
||||
writer http.ResponseWriter,
|
||||
req *http.Request,
|
||||
) {
|
||||
userName := h.verifyTokenIDandGetUser(writer, req)
|
||||
user := h.verifyTokenIDandGetUser(writer, req)
|
||||
resData := removeMachineRes{}
|
||||
if userName == "" {
|
||||
if user.CheckEmpty() {
|
||||
resData.Status = "Error"
|
||||
resData.ErrMsg = "用户信息核对失败"
|
||||
writer.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
@@ -685,7 +678,7 @@ func (h *Mirage) ConsoleRemoveMachineAPI(
|
||||
}
|
||||
return
|
||||
}
|
||||
UserMachines, err := h.ListMachinesByUser(userName)
|
||||
UserMachines, err := h.ListMachinesByUser(user.ID)
|
||||
if err != nil {
|
||||
resData.Status = "Error"
|
||||
resData.ErrMsg = "用户设备检索失败"
|
||||
|
||||
@@ -23,16 +23,11 @@ func (h *Mirage) CAPIGetDNS(
|
||||
w http.ResponseWriter,
|
||||
r *http.Request,
|
||||
) {
|
||||
userName := h.verifyTokenIDandGetUser(w, r)
|
||||
if userName == "" {
|
||||
user := h.verifyTokenIDandGetUser(w, r)
|
||||
if user.CheckEmpty() {
|
||||
h.doAPIResponse(w, "用户信息核对失败", nil)
|
||||
return
|
||||
}
|
||||
user, err := h.GetUser(userName)
|
||||
if err != nil {
|
||||
h.doAPIResponse(w, "查询用户失败:"+err.Error(), nil)
|
||||
return
|
||||
}
|
||||
userDNSCfg, userBaseDomain := user.GetDNSConfig(h.cfg.IPPrefixes)
|
||||
dnsData := DNSData{
|
||||
Domains: make([]string, 0),
|
||||
@@ -78,8 +73,8 @@ func (h *Mirage) CAPIPostDNS(
|
||||
w http.ResponseWriter,
|
||||
r *http.Request,
|
||||
) {
|
||||
userName := h.verifyTokenIDandGetUser(w, r)
|
||||
if userName == "" {
|
||||
user := h.verifyTokenIDandGetUser(w, r)
|
||||
if user.CheckEmpty() {
|
||||
h.doAPIResponse(w, "用户信息核对失败", nil)
|
||||
return
|
||||
}
|
||||
@@ -90,7 +85,7 @@ func (h *Mirage) CAPIPostDNS(
|
||||
}
|
||||
reqData := DNSData{}
|
||||
json.NewDecoder(r.Body).Decode(&reqData)
|
||||
err = h.UpdateDNSConfig(userName, reqData)
|
||||
err = h.UpdateDNSConfig(user, reqData)
|
||||
if err != nil {
|
||||
h.doAPIResponse(w, "更新用户DNS设置失败", nil)
|
||||
return
|
||||
@@ -104,9 +99,13 @@ func (h *Mirage) CAPIDelDNS(
|
||||
w http.ResponseWriter,
|
||||
r *http.Request,
|
||||
) {
|
||||
userName := h.verifyTokenIDandGetUser(w, r)
|
||||
user := h.verifyTokenIDandGetUser(w, r)
|
||||
if user.CheckEmpty() {
|
||||
h.doAPIResponse(w, "用户信息核对失败", nil)
|
||||
return
|
||||
}
|
||||
targetKeyID := strings.TrimPrefix(r.URL.Path, "/admin/api/keys/")
|
||||
allKeys, err := h.ListPreAuthKeys(userName)
|
||||
allKeys, err := h.ListPreAuthKeys(user.ID)
|
||||
if err != nil {
|
||||
h.doAPIResponse(w, "查询用户密钥信息失败", nil)
|
||||
return
|
||||
|
||||
@@ -57,13 +57,13 @@ func (h *Mirage) CAPIGetKeys(
|
||||
w http.ResponseWriter,
|
||||
r *http.Request,
|
||||
) {
|
||||
userName := h.verifyTokenIDandGetUser(w, r)
|
||||
if userName == "" {
|
||||
user := h.verifyTokenIDandGetUser(w, r)
|
||||
if user.CheckEmpty() {
|
||||
h.doAPIResponse(w, "用户信息核对失败", nil)
|
||||
return
|
||||
}
|
||||
|
||||
authKeys, err := h.ListPreAuthKeys(userName)
|
||||
authKeys, err := h.ListPreAuthKeys(user.ID)
|
||||
if err != nil {
|
||||
h.doAPIResponse(w, "授权密钥查询失败", nil)
|
||||
return
|
||||
@@ -109,8 +109,8 @@ func (h *Mirage) CAPIPostKeys(
|
||||
w http.ResponseWriter,
|
||||
r *http.Request,
|
||||
) {
|
||||
userName := h.verifyTokenIDandGetUser(w, r)
|
||||
if userName == "" {
|
||||
user := h.verifyTokenIDandGetUser(w, r)
|
||||
if user.CheckEmpty() {
|
||||
h.doAPIResponse(w, "用户信息核对失败", nil)
|
||||
return
|
||||
}
|
||||
@@ -125,7 +125,7 @@ func (h *Mirage) CAPIPostKeys(
|
||||
case "authkey":
|
||||
keyCfg := reqData.KeyData.Authkey
|
||||
keyExpiration := time.Now().Add(time.Duration(reqData.KeyData.ExpirySeconds) * time.Second)
|
||||
genedAuthKey, err := h.CreatePreAuthKey(userName, keyCfg.Reusable, keyCfg.Ephemeral, &keyExpiration, keyCfg.Tags)
|
||||
genedAuthKey, err := h.CreatePreAuthKey(user, keyCfg.Reusable, keyCfg.Ephemeral, &keyExpiration, keyCfg.Tags)
|
||||
if err != nil {
|
||||
h.doAPIResponse(w, "授权密钥创建失败", nil)
|
||||
return
|
||||
@@ -145,9 +145,13 @@ func (h *Mirage) CAPIDelKeys(
|
||||
w http.ResponseWriter,
|
||||
r *http.Request,
|
||||
) {
|
||||
userName := h.verifyTokenIDandGetUser(w, r)
|
||||
user := h.verifyTokenIDandGetUser(w, r)
|
||||
if user.CheckEmpty() {
|
||||
h.doAPIResponse(w, "用户信息核对失败", nil)
|
||||
return
|
||||
}
|
||||
targetKeyID := strings.TrimPrefix(r.URL.Path, "/admin/api/keys/")
|
||||
allKeys, err := h.ListPreAuthKeys(userName)
|
||||
allKeys, err := h.ListPreAuthKeys(user.ID)
|
||||
if err != nil {
|
||||
h.doAPIResponse(w, "查询用户密钥信息失败", nil)
|
||||
return
|
||||
|
||||
@@ -20,8 +20,8 @@ func (h *Mirage) CAPIGetTags(
|
||||
w http.ResponseWriter,
|
||||
r *http.Request,
|
||||
) {
|
||||
userName := h.verifyTokenIDandGetUser(w, r)
|
||||
if userName == "" {
|
||||
user := h.verifyTokenIDandGetUser(w, r)
|
||||
if user.CheckEmpty() {
|
||||
h.doAPIResponse(w, "用户信息核对失败", nil)
|
||||
return
|
||||
}
|
||||
@@ -51,8 +51,8 @@ func (h *Mirage) CAPIPostTags(
|
||||
w http.ResponseWriter,
|
||||
r *http.Request,
|
||||
) {
|
||||
userName := h.verifyTokenIDandGetUser(w, r)
|
||||
if userName == "" {
|
||||
user := h.verifyTokenIDandGetUser(w, r)
|
||||
if user.CheckEmpty() {
|
||||
h.doAPIResponse(w, "用户信息核对失败", nil)
|
||||
return
|
||||
}
|
||||
@@ -96,8 +96,8 @@ func (h *Mirage) CAPIDelTags(
|
||||
w http.ResponseWriter,
|
||||
r *http.Request,
|
||||
) {
|
||||
userName := h.verifyTokenIDandGetUser(w, r)
|
||||
if userName == "" {
|
||||
user := h.verifyTokenIDandGetUser(w, r)
|
||||
if user.CheckEmpty() {
|
||||
h.doAPIResponse(w, "用户信息核对失败", nil)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -465,8 +465,8 @@ func (h *Mirage) GetMachinesInPrefix(ip netip.Prefix) []Machine {
|
||||
|
||||
// cgao6
|
||||
// GetMachine finds a Machine by user and backendlogid and returns the Machine struct.
|
||||
func (h *Mirage) GetMachineNSBLID(user string, backendlogid string) (*Machine, error) {
|
||||
machines, err := h.ListMachinesByUser(user)
|
||||
func (h *Mirage) GetMachineNSBLID(userID int64, backendlogid string) (*Machine, error) {
|
||||
machines, err := h.ListMachinesByUser(userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -481,8 +481,8 @@ func (h *Mirage) GetMachineNSBLID(user string, backendlogid string) (*Machine, e
|
||||
}
|
||||
|
||||
// GetMachine finds a Machine by name and user and returns the Machine struct.
|
||||
func (h *Mirage) GetMachine(user string, name string) (*Machine, error) {
|
||||
machines, err := h.ListMachinesByUser(user)
|
||||
func (h *Mirage) GetMachine(userID int64, name string) (*Machine, error) {
|
||||
machines, err := h.ListMachinesByUser(userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -497,8 +497,8 @@ func (h *Mirage) GetMachine(user string, name string) (*Machine, error) {
|
||||
}
|
||||
|
||||
// GetMachineByGivenName finds a Machine by given name and user and returns the Machine struct.
|
||||
func (h *Mirage) GetMachineByGivenName(user string, givenName string) (*Machine, error) {
|
||||
machines, err := h.ListMachinesByUser(user)
|
||||
func (h *Mirage) GetMachineByGivenName(userID int64, givenName string) (*Machine, error) {
|
||||
machines, err := h.ListMachinesByUser(userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -622,7 +622,7 @@ func (h *Mirage) setAutoGenName(machine *Machine, newName string) (string, error
|
||||
}
|
||||
machine.GivenName = h.GenMachineName(machine.Hostname, machine.User.toTailscaleUser().ID, machine.MachineKey)
|
||||
} else {
|
||||
_, err := h.GetMachineByGivenName(machine.User.Name, newName)
|
||||
_, err := h.GetMachineByGivenName(machine.User.ID, newName)
|
||||
if err != nil && err != ErrMachineNotFound {
|
||||
return "", fmt.Errorf("fail to check whether new name already exist: %w", err)
|
||||
} else if err == nil {
|
||||
|
||||
@@ -318,7 +318,7 @@ func (h *Mirage) findOrCreateNewUserForOIDCCallback(
|
||||
userDisName string,
|
||||
orgName string,
|
||||
) (*User, error) {
|
||||
user, err := h.GetUser(userName)
|
||||
user, err := h.GetUser(userName, orgName)
|
||||
if errors.Is(err, ErrUserNotFound) {
|
||||
user, err = h.CreateUser(userName, userDisName, orgName)
|
||||
if err != nil {
|
||||
|
||||
@@ -16,6 +16,7 @@ const (
|
||||
|
||||
type Organization struct {
|
||||
ID int64 `gorm:"primary_key;unique;not null"`
|
||||
StableID string `gorm:"unique"`
|
||||
Name string `gorm:"unique"`
|
||||
ExpiryDuration uint `gorm:"default:180"`
|
||||
EnableMagic bool `gorm:"default:false"`
|
||||
@@ -36,6 +37,7 @@ func (o *Organization) BeforeCreate(tx *gorm.DB) error {
|
||||
id := flakeID.Generate().Int64()
|
||||
o.ID = id
|
||||
}
|
||||
o.StableID = GetShortId(o.ID)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -67,6 +69,22 @@ func CreateOrgnaizationInTx(tx *gorm.DB, name string) (*Organization, error) {
|
||||
return &org, nil
|
||||
}
|
||||
|
||||
func (m *Mirage) GetOrgnaizationByName(name string) (*Organization, error) {
|
||||
return GetOrgnaizationByNameInTx(m.db.Session(&gorm.Session{}), name)
|
||||
}
|
||||
|
||||
func GetOrgnaizationByNameInTx(tx *gorm.DB, name string) (*Organization, error) {
|
||||
var org Organization
|
||||
if err := tx.Where("name = ?", name).Take(&org).Error; err != nil {
|
||||
log.Error().
|
||||
Str("func", "GetOrgnaizationByName").
|
||||
Err(err).
|
||||
Msg("Could not get row")
|
||||
return nil, err
|
||||
}
|
||||
return &org, nil
|
||||
}
|
||||
|
||||
func (m *Mirage) DestroyOrgnaization(orgId int64) error {
|
||||
tx := m.db.Session(&gorm.Session{})
|
||||
return DestroyOrgnaizationInTx(tx, orgId)
|
||||
|
||||
@@ -43,16 +43,12 @@ type PreAuthKeyACLTag struct {
|
||||
|
||||
// CreatePreAuthKey creates a new PreAuthKey in a user, and returns it.
|
||||
func (h *Mirage) CreatePreAuthKey(
|
||||
userName string,
|
||||
user *User,
|
||||
reusable bool,
|
||||
ephemeral bool,
|
||||
expiration *time.Time,
|
||||
aclTags []string,
|
||||
) (*PreAuthKey, error) {
|
||||
user, err := h.GetUser(userName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, tag := range aclTags {
|
||||
if !strings.HasPrefix(tag, "tag:") {
|
||||
@@ -108,14 +104,9 @@ func (h *Mirage) CreatePreAuthKey(
|
||||
}
|
||||
|
||||
// ListPreAuthKeys returns the list of PreAuthKeys for a user.
|
||||
func (h *Mirage) ListPreAuthKeys(userName string) ([]PreAuthKey, error) {
|
||||
user, err := h.GetUser(userName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func (h *Mirage) ListPreAuthKeys(userID int64) ([]PreAuthKey, error) {
|
||||
keys := []PreAuthKey{}
|
||||
if err := h.db.Preload("User").Preload("ACLTags").Where(&PreAuthKey{UserID: user.ID}).Find(&keys).Error; err != nil {
|
||||
if err := h.db.Preload("User").Preload("ACLTags").Where(&PreAuthKey{UserID: userID}).Find(&keys).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,8 @@ var invalidCharsInUserRegex = regexp.MustCompile("[^a-z0-9-.]+")
|
||||
type User struct {
|
||||
ID int64 `gorm:"primary_key;unique;not null"`
|
||||
StableID string `gorm:"unique"`
|
||||
Name string `gorm:"unique"`
|
||||
Name string `gorm:"uniqueIndex:idx_user_org"`
|
||||
OrgName string `gorm:"uniqueIndex:idx_user_org"`
|
||||
OrgId int64
|
||||
Org Organization
|
||||
Display_Name string `gorm:"unique"`
|
||||
@@ -71,86 +72,78 @@ func (user *User) BeforeCreate(tx *gorm.DB) error {
|
||||
id := flakeID.Generate().Int64()
|
||||
user.ID = id
|
||||
}
|
||||
longid := user.ID
|
||||
shortID := ""
|
||||
for longid > 0 {
|
||||
shortID = string("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"[longid%62]) + shortID
|
||||
longid /= 62
|
||||
}
|
||||
user.StableID = shortID
|
||||
user.StableID = GetShortId(user.ID)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (user *User) CheckEmpty() bool {
|
||||
return user == nil || user.ID == 0
|
||||
}
|
||||
|
||||
// CreateUser creates a new User. Returns error if could not be created
|
||||
// or another user already exists.
|
||||
func (h *Mirage) CreateUser(name string, DisName string, OrgName string) (*User, error) {
|
||||
func (h *Mirage) CreateUser(name string, disName string, orgName string) (*User, error) {
|
||||
err := CheckForFQDNRules(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
user := User{}
|
||||
if err := h.db.Where("name = ?", name).First(&user).Error; err == nil {
|
||||
var count int64
|
||||
err = h.db.Model(&User{}).Where("name = ?", name).Count(&count).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if count > 0 {
|
||||
return nil, ErrUserExists
|
||||
}
|
||||
user := User{}
|
||||
user.Name = name
|
||||
user.Display_Name = DisName
|
||||
// 个人用户新建时候orgName为空
|
||||
if len(OrgName) == 0 {
|
||||
err := h.db.Transaction(func(tx *gorm.DB) error {
|
||||
org, err := CreateOrgnaizationInTx(tx, name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = tx.Create(&user).Error
|
||||
if err != nil {
|
||||
log.Error().
|
||||
Str("func", "CreateUser").
|
||||
Err(err).
|
||||
Msg("Could not create row")
|
||||
|
||||
return err
|
||||
user.Display_Name = disName
|
||||
err = h.db.Transaction(func(tx *gorm.DB) error {
|
||||
var org *Organization
|
||||
var trxErr error
|
||||
//个人用户: userName 和 orgName相同
|
||||
if user.Name == orgName {
|
||||
org, trxErr = CreateOrgnaizationInTx(tx, orgName)
|
||||
user.Role = RoleAdmin
|
||||
} else {
|
||||
//企业用户,需要先查询orgName是否存在
|
||||
org, trxErr = GetOrgnaizationByNameInTx(tx, orgName)
|
||||
if trxErr == nil && org.ID == 0 {
|
||||
trxErr = ErrOrgNotFound
|
||||
}
|
||||
user.IsBelongToOrg = true
|
||||
}
|
||||
if trxErr == nil {
|
||||
user.OrgId = org.ID
|
||||
user.Org = *org
|
||||
user.Role = RoleAdmin
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
user.OrgName = org.Name
|
||||
trxErr = tx.Create(&user).Error
|
||||
}
|
||||
return &user, nil
|
||||
// 非个人用户新建,先查询组织id,再进行新建
|
||||
} else {
|
||||
org := Organization{}
|
||||
err := h.db.Model(&Organization{}).Where("name = ?", OrgName).Take(&org).Error
|
||||
if err == nil && org.ID == 0 {
|
||||
err = ErrOrgNotFound
|
||||
}
|
||||
if err == nil {
|
||||
user.IsBelongToOrg = true
|
||||
err = h.db.Create(&user).Error
|
||||
}
|
||||
if err != nil {
|
||||
if trxErr != nil {
|
||||
log.Error().
|
||||
Str("func", "CreateUser").
|
||||
Err(err).
|
||||
Err(trxErr).
|
||||
Msg("Could not create row")
|
||||
return nil, err
|
||||
|
||||
return trxErr
|
||||
}
|
||||
user.Org = org
|
||||
return &user, nil
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &user, nil
|
||||
}
|
||||
|
||||
// DestroyUser destroys a User. Returns error if the User does
|
||||
// not exist or if there are machines associated with it.
|
||||
func (h *Mirage) DestroyUser(name string) error {
|
||||
user, err := h.GetUser(name)
|
||||
func (h *Mirage) DestroyUser(name, orgName string) error {
|
||||
user, err := h.GetUser(name, orgName)
|
||||
if err != nil {
|
||||
return ErrUserNotFound
|
||||
}
|
||||
|
||||
machines, err := h.ListMachinesByUser(name)
|
||||
machines, err := h.ListMachinesByUser(user.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -158,7 +151,7 @@ func (h *Mirage) DestroyUser(name string) error {
|
||||
return ErrUserStillHasNodes
|
||||
}
|
||||
|
||||
keys, err := h.ListPreAuthKeys(name)
|
||||
keys, err := h.ListPreAuthKeys(user.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -183,9 +176,9 @@ func (h *Mirage) DestroyUser(name string) error {
|
||||
}
|
||||
|
||||
// Update User's node key expiry duration.
|
||||
func (h *Mirage) UpdateUserKeyExpiry(name string, newDuration uint) error {
|
||||
func (h *Mirage) UpdateUserKeyExpiry(name, orgName string, newDuration uint) error {
|
||||
var err error
|
||||
user, err := h.GetUser(name)
|
||||
user, err := h.GetUser(name, orgName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -197,9 +190,9 @@ func (h *Mirage) UpdateUserKeyExpiry(name string, newDuration uint) error {
|
||||
|
||||
// RenameUser renames a User. Returns error if the User does
|
||||
// not exist or if another User exists with the new name.
|
||||
func (h *Mirage) RenameUser(oldName, newName string) error {
|
||||
func (h *Mirage) RenameUser(oldName, newName string, orgName string) error {
|
||||
var err error
|
||||
oldUser, err := h.GetUser(oldName)
|
||||
oldUser, err := h.GetUser(oldName, orgName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -207,7 +200,7 @@ func (h *Mirage) RenameUser(oldName, newName string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = h.GetUser(newName)
|
||||
_, err = h.GetUser(newName, orgName)
|
||||
if err == nil {
|
||||
return ErrUserExists
|
||||
}
|
||||
@@ -238,6 +231,22 @@ func (h *Mirage) GetUserByID(id tailcfg.UserID) (*User, error) {
|
||||
}
|
||||
|
||||
// GetUser fetches a user by name.
|
||||
func (h *Mirage) GetUser(name, orgName string) (*User, error) {
|
||||
user := User{}
|
||||
if result := h.db.Preload("Org").First(&User{
|
||||
Name: name,
|
||||
OrgName: orgName,
|
||||
}); errors.Is(
|
||||
result.Error,
|
||||
gorm.ErrRecordNotFound,
|
||||
) {
|
||||
return nil, ErrUserNotFound
|
||||
}
|
||||
|
||||
return &user, nil
|
||||
}
|
||||
|
||||
/*
|
||||
func (h *Mirage) GetUser(name string) (*User, error) {
|
||||
user := User{}
|
||||
if result := h.db.Preload("Org").First(&user, "name = ?", name); errors.Is(
|
||||
@@ -249,6 +258,7 @@ func (h *Mirage) GetUser(name string) (*User, error) {
|
||||
|
||||
return &user, nil
|
||||
}
|
||||
*/
|
||||
|
||||
// ListUsers gets all the existing users.
|
||||
func (h *Mirage) ListUsers() ([]User, error) {
|
||||
@@ -261,19 +271,13 @@ func (h *Mirage) ListUsers() ([]User, error) {
|
||||
}
|
||||
|
||||
// ListMachinesByUser gets all the nodes in a given user.
|
||||
func (h *Mirage) ListMachinesByUser(name string) ([]Machine, error) {
|
||||
err := CheckForFQDNRules(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
func (h *Mirage) ListMachinesByUser(userID int64) ([]Machine, error) {
|
||||
if userID == 0 {
|
||||
return nil, ErrUserNotFound
|
||||
}
|
||||
user, err := h.GetUser(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
machines := []Machine{}
|
||||
//TODO 是否需要组织信息
|
||||
if err := h.db.Preload("AuthKey").Preload("AuthKey.User").Preload("User").Where(&Machine{UserID: user.ID}).Find(&machines).Error; err != nil {
|
||||
if err := h.db.Preload("AuthKey").Preload("AuthKey.User").Preload("User").Where(&Machine{UserID: userID}).Find(&machines).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -281,12 +285,12 @@ func (h *Mirage) ListMachinesByUser(name string) ([]Machine, error) {
|
||||
}
|
||||
|
||||
// SetMachineUser assigns a Machine to a user.
|
||||
func (h *Mirage) SetMachineUser(machine *Machine, username string) error {
|
||||
func (h *Mirage) SetMachineUser(machine *Machine, username, orgName string) error {
|
||||
err := CheckForFQDNRules(username)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
user, err := h.GetUser(username)
|
||||
user, err := h.GetUser(username, orgName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -524,13 +528,8 @@ func (me *User) GetDNSConfig(ipPrefixesCfg []netip.Prefix) (*tailcfg.DNSConfig,
|
||||
return dnsConfig, baseDomain
|
||||
}
|
||||
|
||||
func (h *Mirage) UpdateDNSConfig(userName string, newDNSCfg DNSData) error {
|
||||
var err error
|
||||
user, err := h.GetUser(userName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if user.Org.ID == 0 {
|
||||
func (h *Mirage) UpdateDNSConfig(user *User, newDNSCfg DNSData) error {
|
||||
if user == nil || user.Org.ID == 0 {
|
||||
return ErrOrgNotFound
|
||||
}
|
||||
org := &user.Org
|
||||
|
||||
@@ -348,3 +348,12 @@ func AbsolutePathFromConfigPath(path string) string {
|
||||
|
||||
return path
|
||||
}
|
||||
|
||||
func GetShortId(longID int64) string {
|
||||
shortID := ""
|
||||
for longID > 0 {
|
||||
shortID = string("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"[longID%62]) + shortID
|
||||
longID /= 62
|
||||
}
|
||||
return shortID
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user