Compare commits
39 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
78798060e7 | ||
|
|
b2569a8dac | ||
|
|
4bd7ec9871 | ||
|
|
95cfad60c4 | ||
|
|
7f51d451f7 | ||
|
|
a4fb0fd795 | ||
|
|
c02928dd44 | ||
|
|
e70c49d407 | ||
|
|
e1c1984fd4 | ||
|
|
f801d304c6 | ||
|
|
178a38c6d9 | ||
|
|
e356707db7 | ||
|
|
8d3043d0fe | ||
|
|
1e494bd1fd | ||
|
|
b726c8d589 | ||
|
|
e71e80703d | ||
|
|
c9b666e5bc | ||
|
|
874139ea07 | ||
|
|
05d79ad606 | ||
|
|
13c78a5fec | ||
|
|
f3e3824b7d | ||
|
|
67473c2dcf | ||
|
|
3921c547be | ||
|
|
3e0d2fda6a | ||
|
|
7ff6c0c18b | ||
|
|
e76464673a | ||
|
|
1ab849d9b0 | ||
|
|
781c851571 | ||
|
|
0b19d93a47 | ||
|
|
2856f7716b | ||
|
|
c9ba24dc96 | ||
|
|
a660fb1f42 | ||
|
|
8586ad6478 | ||
|
|
0fab6fecfe | ||
|
|
d752bb08c7 | ||
|
|
6f845f36c9 | ||
|
|
66bc60a47c | ||
|
|
1c048da1f0 | ||
|
|
da8aa20f83 |
@@ -1,7 +1,7 @@
|
||||
package teaconst
|
||||
|
||||
const (
|
||||
Version = "0.5.8"
|
||||
Version = "0.6.2"
|
||||
|
||||
ProductName = "Edge API"
|
||||
ProcessName = "edge-api"
|
||||
@@ -18,8 +18,8 @@ const (
|
||||
|
||||
// 其他节点版本号,用来检测是否有需要升级的节点
|
||||
|
||||
NodeVersion = "0.5.8"
|
||||
NodeVersion = "0.6.2"
|
||||
|
||||
// SQLVersion SQL版本号
|
||||
SQLVersion = "4"
|
||||
SQLVersion = "9"
|
||||
)
|
||||
|
||||
@@ -44,11 +44,17 @@ func (this *AdminDAO) EnableAdmin(tx *dbs.Tx, id int64) (rowsAffected int64, err
|
||||
}
|
||||
|
||||
// DisableAdmin 禁用条目
|
||||
func (this *AdminDAO) DisableAdmin(tx *dbs.Tx, id int64) (rowsAffected int64, err error) {
|
||||
return this.Query(tx).
|
||||
Pk(id).
|
||||
func (this *AdminDAO) DisableAdmin(tx *dbs.Tx, adminId int64) error {
|
||||
err := this.Query(tx).
|
||||
Pk(adminId).
|
||||
Set("state", AdminStateDisabled).
|
||||
Update()
|
||||
UpdateQuickly()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 删除AccessTokens
|
||||
return SharedAPIAccessTokenDAO.DeleteAccessTokens(tx, adminId, 0)
|
||||
}
|
||||
|
||||
// FindEnabledAdmin 查找启用中的条目
|
||||
@@ -190,7 +196,19 @@ func (this *AdminDAO) UpdateAdmin(tx *dbs.Tx, adminId int64, username string, ca
|
||||
}
|
||||
op.IsOn = isOn
|
||||
err := this.Save(tx, op)
|
||||
return err
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !isOn {
|
||||
// 删除AccessTokens
|
||||
err = SharedAPIAccessTokenDAO.DeleteAccessTokens(tx, adminId, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// CheckAdminUsername 检查用户名是否存在
|
||||
|
||||
@@ -81,3 +81,16 @@ func (this *APIAccessTokenDAO) FindAccessToken(tx *dbs.Tx, token string) (*APIAc
|
||||
}
|
||||
return one.(*APIAccessToken), nil
|
||||
}
|
||||
|
||||
// DeleteAccessTokens 删除用户的令牌
|
||||
func (this *APIAccessTokenDAO) DeleteAccessTokens(tx *dbs.Tx, adminId int64, userId int64) error {
|
||||
var query = this.Query(tx)
|
||||
if adminId > 0 {
|
||||
query.Attr("adminId", adminId)
|
||||
} else if userId > 0 {
|
||||
query.Attr("userId", userId)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return query.DeleteQuickly()
|
||||
}
|
||||
|
||||
@@ -43,9 +43,9 @@ func (this *APINode) DecodeHTTPS(tx *dbs.Tx, cacheMap *utils.CacheMap) (*serverc
|
||||
}
|
||||
|
||||
if config.SSLPolicyRef != nil {
|
||||
policyId := config.SSLPolicyRef.SSLPolicyId
|
||||
var policyId = config.SSLPolicyRef.SSLPolicyId
|
||||
if policyId > 0 {
|
||||
sslPolicy, err := SharedSSLPolicyDAO.ComposePolicyConfig(tx, policyId, cacheMap)
|
||||
sslPolicy, err := SharedSSLPolicyDAO.ComposePolicyConfig(tx, policyId, false, cacheMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -143,7 +143,7 @@ func (this *APINode) DecodeRestHTTPS(tx *dbs.Tx, cacheMap *utils.CacheMap) (*ser
|
||||
if config.SSLPolicyRef != nil {
|
||||
policyId := config.SSLPolicyRef.SSLPolicyId
|
||||
if policyId > 0 {
|
||||
sslPolicy, err := SharedSSLPolicyDAO.ComposePolicyConfig(tx, policyId, cacheMap)
|
||||
sslPolicy, err := SharedSSLPolicyDAO.ComposePolicyConfig(tx, policyId, false, cacheMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
98
internal/db/models/clients/client_agent_dao.go
Normal file
98
internal/db/models/clients/client_agent_dao.go
Normal file
@@ -0,0 +1,98 @@
|
||||
package clients
|
||||
|
||||
import (
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/iwind/TeaGo/Tea"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
)
|
||||
|
||||
type ClientAgentDAO dbs.DAO
|
||||
|
||||
func NewClientAgentDAO() *ClientAgentDAO {
|
||||
return dbs.NewDAO(&ClientAgentDAO{
|
||||
DAOObject: dbs.DAOObject{
|
||||
DB: Tea.Env,
|
||||
Table: "edgeClientAgents",
|
||||
Model: new(ClientAgent),
|
||||
PkName: "id",
|
||||
},
|
||||
}).(*ClientAgentDAO)
|
||||
}
|
||||
|
||||
var SharedClientAgentDAO *ClientAgentDAO
|
||||
|
||||
func init() {
|
||||
dbs.OnReady(func() {
|
||||
SharedClientAgentDAO = NewClientAgentDAO()
|
||||
})
|
||||
}
|
||||
|
||||
// FindClientAgentName 根据主键查找名称
|
||||
func (this *ClientAgentDAO) FindClientAgentName(tx *dbs.Tx, id int64) (string, error) {
|
||||
return this.Query(tx).
|
||||
Pk(id).
|
||||
Result("name").
|
||||
FindStringCol("")
|
||||
}
|
||||
|
||||
// FindAgent 查找Agent
|
||||
func (this *ClientAgentDAO) FindAgent(tx *dbs.Tx, agentId int64) (*ClientAgent, error) {
|
||||
if agentId <= 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
one, err := this.Query(tx).
|
||||
Pk(agentId).
|
||||
Find()
|
||||
if err != nil || one == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return one.(*ClientAgent), nil
|
||||
}
|
||||
|
||||
// FindAgentIdWithCode 根据代号查找ID
|
||||
func (this *ClientAgentDAO) FindAgentIdWithCode(tx *dbs.Tx, code string) (int64, error) {
|
||||
return this.Query(tx).
|
||||
ResultPk().
|
||||
Attr("code", code).
|
||||
FindInt64Col(0)
|
||||
}
|
||||
|
||||
// FindAgentNameWithCode 根据代号查找Agent名称
|
||||
func (this *ClientAgentDAO) FindAgentNameWithCode(tx *dbs.Tx, code string) (string, error) {
|
||||
return this.Query(tx).
|
||||
Result("name").
|
||||
Attr("code", code).
|
||||
FindStringCol("")
|
||||
}
|
||||
|
||||
// UpdateAgentCountIPs 修改Agent拥有的IP数量
|
||||
func (this *ClientAgentDAO) UpdateAgentCountIPs(tx *dbs.Tx, agentId int64, countIPs int64) error {
|
||||
return this.Query(tx).
|
||||
Pk(agentId).
|
||||
Set("countIPs", countIPs).
|
||||
UpdateQuickly()
|
||||
}
|
||||
|
||||
// FindAllAgents 查找所有Agents
|
||||
func (this *ClientAgentDAO) FindAllAgents(tx *dbs.Tx) (result []*ClientAgent, err error) {
|
||||
_, err = this.Query(tx).
|
||||
Desc("order").
|
||||
AscPk().
|
||||
Slice(&result).
|
||||
FindAll()
|
||||
return
|
||||
}
|
||||
|
||||
// FindAllNSAgents 查找所有DNS可以使用的Agents
|
||||
func (this *ClientAgentDAO) FindAllNSAgents(tx *dbs.Tx) (result []*ClientAgent, err error) {
|
||||
// 注意:允许NS使用所有的Agent,不管有没有IP数据
|
||||
_, err = this.Query(tx).
|
||||
Result("id", "name", "code").
|
||||
Desc("order").
|
||||
AscPk().
|
||||
Slice(&result).
|
||||
FindAll()
|
||||
return
|
||||
}
|
||||
6
internal/db/models/clients/client_agent_dao_test.go
Normal file
6
internal/db/models/clients/client_agent_dao_test.go
Normal file
@@ -0,0 +1,6 @@
|
||||
package clients_test
|
||||
|
||||
import (
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
_ "github.com/iwind/TeaGo/bootstrap"
|
||||
)
|
||||
105
internal/db/models/clients/client_agent_ip_dao.go
Normal file
105
internal/db/models/clients/client_agent_ip_dao.go
Normal file
@@ -0,0 +1,105 @@
|
||||
package clients
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/iwind/TeaGo/Tea"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
)
|
||||
|
||||
// TODO 需要定时对所有IP的PTR进行检查,剔除已经变更的IP
|
||||
|
||||
type ClientAgentIPDAO dbs.DAO
|
||||
|
||||
func NewClientAgentIPDAO() *ClientAgentIPDAO {
|
||||
return dbs.NewDAO(&ClientAgentIPDAO{
|
||||
DAOObject: dbs.DAOObject{
|
||||
DB: Tea.Env,
|
||||
Table: "edgeClientAgentIPs",
|
||||
Model: new(ClientAgentIP),
|
||||
PkName: "id",
|
||||
},
|
||||
}).(*ClientAgentIPDAO)
|
||||
}
|
||||
|
||||
var SharedClientAgentIPDAO *ClientAgentIPDAO
|
||||
|
||||
func init() {
|
||||
dbs.OnReady(func() {
|
||||
SharedClientAgentIPDAO = NewClientAgentIPDAO()
|
||||
})
|
||||
}
|
||||
|
||||
// CreateIP 写入IP
|
||||
func (this *ClientAgentIPDAO) CreateIP(tx *dbs.Tx, agentId int64, ip string, ptr string) error {
|
||||
// 检查数据有效性
|
||||
if agentId <= 0 || len(ip) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 限制ptr长度
|
||||
if len(ptr) > 100 {
|
||||
ptr = ptr[:100]
|
||||
}
|
||||
|
||||
// 检查是否存在
|
||||
exists, err := this.Query(tx).
|
||||
Attr("agentId", agentId).
|
||||
Attr("ip", ip).
|
||||
Exist()
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if exists {
|
||||
return nil
|
||||
}
|
||||
|
||||
var op = NewClientAgentIPOperator()
|
||||
op.AgentId = agentId
|
||||
op.IP = ip
|
||||
op.Ptr = ptr
|
||||
err = this.Save(tx, op)
|
||||
if err != nil {
|
||||
// 忽略duplicate错误
|
||||
if models.CheckSQLDuplicateErr(err) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// 更新Agent IP数量
|
||||
countIPs, err := this.CountAgentIPs(tx, agentId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = SharedClientAgentDAO.UpdateAgentCountIPs(tx, agentId, countIPs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ListIPsAfterId 列出某个ID之后的IP
|
||||
func (this *ClientAgentIPDAO) ListIPsAfterId(tx *dbs.Tx, id int64, size int64) (result []*ClientAgentIP, err error) {
|
||||
if id < 0 {
|
||||
id = 0
|
||||
}
|
||||
|
||||
_, err = this.Query(tx).
|
||||
Result("id", "ip", "ptr", "agentId").
|
||||
Gt("id", id).
|
||||
AscPk().
|
||||
Limit(size). // 限制单次读取个数
|
||||
Slice(&result).
|
||||
FindAll()
|
||||
return
|
||||
}
|
||||
|
||||
// CountAgentIPs 计算Agent IP数量
|
||||
func (this *ClientAgentIPDAO) CountAgentIPs(tx *dbs.Tx, agentId int64) (int64, error) {
|
||||
return this.Query(tx).
|
||||
Attr("agentId", agentId).
|
||||
Count()
|
||||
}
|
||||
16
internal/db/models/clients/client_agent_ip_dao_test.go
Normal file
16
internal/db/models/clients/client_agent_ip_dao_test.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package clients_test
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models/clients"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
_ "github.com/iwind/TeaGo/bootstrap"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestClientAgentIPDAO_CreateIP(t *testing.T) {
|
||||
var dao = clients.NewClientAgentIPDAO()
|
||||
err := dao.CreateIP(nil, 1, "127.0.0.1", "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
20
internal/db/models/clients/client_agent_ip_model.go
Normal file
20
internal/db/models/clients/client_agent_ip_model.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package clients
|
||||
|
||||
// ClientAgentIP Agent IP
|
||||
type ClientAgentIP struct {
|
||||
Id uint64 `field:"id"` // ID
|
||||
AgentId uint32 `field:"agentId"` // Agent ID
|
||||
IP string `field:"ip"` // IP地址
|
||||
Ptr string `field:"ptr"` // PTR值
|
||||
}
|
||||
|
||||
type ClientAgentIPOperator struct {
|
||||
Id any // ID
|
||||
AgentId any // Agent ID
|
||||
IP any // IP地址
|
||||
Ptr any // PTR值
|
||||
}
|
||||
|
||||
func NewClientAgentIPOperator() *ClientAgentIPOperator {
|
||||
return &ClientAgentIPOperator{}
|
||||
}
|
||||
1
internal/db/models/clients/client_agent_ip_model_ext.go
Normal file
1
internal/db/models/clients/client_agent_ip_model_ext.go
Normal file
@@ -0,0 +1 @@
|
||||
package clients
|
||||
24
internal/db/models/clients/client_agent_model.go
Normal file
24
internal/db/models/clients/client_agent_model.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package clients
|
||||
|
||||
// ClientAgent Agent库
|
||||
type ClientAgent struct {
|
||||
Id uint32 `field:"id"` // ID
|
||||
Name string `field:"name"` // 名称
|
||||
Code string `field:"code"` // 代号
|
||||
Description string `field:"description"` // 介绍
|
||||
Order uint32 `field:"order"` // 排序
|
||||
CountIPs uint32 `field:"countIPs"` // IP数量
|
||||
}
|
||||
|
||||
type ClientAgentOperator struct {
|
||||
Id any // ID
|
||||
Name any // 名称
|
||||
Code any // 代号
|
||||
Description any // 介绍
|
||||
Order any // 排序
|
||||
CountIPs any // IP数量
|
||||
}
|
||||
|
||||
func NewClientAgentOperator() *ClientAgentOperator {
|
||||
return &ClientAgentOperator{}
|
||||
}
|
||||
6
internal/db/models/clients/client_agent_model_ext.go
Normal file
6
internal/db/models/clients/client_agent_model_ext.go
Normal file
@@ -0,0 +1,6 @@
|
||||
package clients
|
||||
|
||||
// NSRouteCode NS线路代号
|
||||
func (this *ClientAgent) NSRouteCode() string {
|
||||
return "agent:" + this.Code
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package models
|
||||
package clients
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/goman"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/utils/ttlcache"
|
||||
@@ -130,7 +131,7 @@ func (this *ClientBrowserDAO) CreateBrowserIfNotExists(tx *dbs.Tx, browserName s
|
||||
op.CreatedDay = timeutil.Format("Ymd")
|
||||
op.State = ClientBrowserStateEnabled
|
||||
browserId, err = this.SaveInt64(tx, op)
|
||||
if err != nil && CheckSQLErrCode(err, 1062 /** duplicate entry **/) {
|
||||
if err != nil && models.CheckSQLErrCode(err, 1062 /** duplicate entry **/) {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package models_test
|
||||
package clients_test
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models/clients"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestClientBrowserDAO_CreateBrowser(t *testing.T) {
|
||||
var dao = models.NewClientBrowserDAO()
|
||||
var dao = clients.NewClientBrowserDAO()
|
||||
err := dao.CreateBrowserIfNotExists(nil, "Hello")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -25,7 +25,7 @@ func TestClientBrowserDAO_CreateBrowser(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestClientBrowserDAO_Clean(t *testing.T) {
|
||||
var dao = models.NewClientBrowserDAO()
|
||||
var dao = clients.NewClientBrowserDAO()
|
||||
err := dao.Clean(nil, 30)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -1,10 +1,10 @@
|
||||
package models
|
||||
package clients
|
||||
|
||||
import "github.com/iwind/TeaGo/dbs"
|
||||
|
||||
// ClientBrowser 终端浏览器信息
|
||||
type ClientBrowser struct {
|
||||
Id uint32 `field:"id"` // ID
|
||||
Id uint64 `field:"id"` // ID
|
||||
Name string `field:"name"` // 浏览器名称
|
||||
Codes dbs.JSON `field:"codes"` // 代号
|
||||
CreatedDay string `field:"createdDay"` // 创建日期YYYYMMDD
|
||||
1
internal/db/models/clients/client_browser_model_ext.go
Normal file
1
internal/db/models/clients/client_browser_model_ext.go
Normal file
@@ -0,0 +1 @@
|
||||
package clients
|
||||
@@ -1,6 +1,7 @@
|
||||
package models
|
||||
package clients
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/goman"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/utils/ttlcache"
|
||||
@@ -129,7 +130,7 @@ func (this *ClientSystemDAO) CreateSystemIfNotExists(tx *dbs.Tx, systemName stri
|
||||
op.CreatedDay = timeutil.Format("Ymd")
|
||||
op.State = ClientSystemStateEnabled
|
||||
systemId, err = this.SaveInt64(tx, op)
|
||||
if err != nil && CheckSQLErrCode(err, 1062 /** duplicate entry **/) {
|
||||
if err != nil && models.CheckSQLErrCode(err, 1062 /** duplicate entry **/) {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package models_test
|
||||
package clients_test
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models/clients"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestClientSystemDAO_CreateSystemIfNotExists(t *testing.T) {
|
||||
var dao = models.NewClientSystemDAO()
|
||||
var dao = clients.NewClientSystemDAO()
|
||||
{
|
||||
err := dao.CreateSystemIfNotExists(nil, "Mac OS X")
|
||||
if err != nil {
|
||||
@@ -23,7 +23,7 @@ func TestClientSystemDAO_CreateSystemIfNotExists(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestClientSystemDAO_Clean(t *testing.T) {
|
||||
var dao = models.NewClientSystemDAO()
|
||||
var dao = clients.NewClientSystemDAO()
|
||||
err := dao.Clean(nil, 30)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -1,10 +1,10 @@
|
||||
package models
|
||||
package clients
|
||||
|
||||
import "github.com/iwind/TeaGo/dbs"
|
||||
|
||||
// ClientSystem 终端操作系统信息
|
||||
type ClientSystem struct {
|
||||
Id uint32 `field:"id"` // ID
|
||||
Id uint64 `field:"id"` // ID
|
||||
Name string `field:"name"` // 系统名称
|
||||
Codes dbs.JSON `field:"codes"` // 代号
|
||||
CreatedDay string `field:"createdDay"` // 创建日期YYYYMMDD
|
||||
1
internal/db/models/clients/client_system_model_ext.go
Normal file
1
internal/db/models/clients/client_system_model_ext.go
Normal file
@@ -0,0 +1 @@
|
||||
package clients
|
||||
@@ -206,6 +206,7 @@ func (this *HTTPCacheTaskDAO) UpdateTaskStatus(tx *dbs.Tx, taskId int64, isDone
|
||||
|
||||
if isDone {
|
||||
op.DoneAt = time.Now().Unix()
|
||||
op.IsReady = true // 让后台列表能列出来
|
||||
}
|
||||
|
||||
return this.Save(tx, op)
|
||||
|
||||
@@ -182,19 +182,19 @@ func (this *HTTPHeaderPolicyDAO) ComposeHeaderPolicyConfig(tx *dbs.Tx, headerPol
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
config := &shared.HTTPHeaderPolicy{}
|
||||
var config = &shared.HTTPHeaderPolicy{}
|
||||
config.Id = int64(policy.Id)
|
||||
config.IsOn = policy.IsOn
|
||||
|
||||
// SetHeaders
|
||||
if IsNotNull(policy.SetHeaders) {
|
||||
refs := []*shared.HTTPHeaderRef{}
|
||||
var refs = []*shared.HTTPHeaderRef{}
|
||||
err = json.Unmarshal(policy.SetHeaders, &refs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(refs) > 0 {
|
||||
resultRefs := []*shared.HTTPHeaderRef{}
|
||||
var resultRefs = []*shared.HTTPHeaderRef{}
|
||||
for _, ref := range refs {
|
||||
headerConfig, err := SharedHTTPHeaderDAO.ComposeHeaderConfig(tx, ref.HeaderId)
|
||||
if err != nil {
|
||||
@@ -212,7 +212,7 @@ func (this *HTTPHeaderPolicyDAO) ComposeHeaderPolicyConfig(tx *dbs.Tx, headerPol
|
||||
|
||||
// Delete Headers
|
||||
if IsNotNull(policy.DeleteHeaders) {
|
||||
headers := []string{}
|
||||
var headers = []string{}
|
||||
err = json.Unmarshal(policy.DeleteHeaders, &headers)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -220,6 +220,16 @@ func (this *HTTPHeaderPolicyDAO) ComposeHeaderPolicyConfig(tx *dbs.Tx, headerPol
|
||||
config.DeleteHeaders = headers
|
||||
}
|
||||
|
||||
// CORS
|
||||
if IsNotNull(policy.Cors) {
|
||||
var corsConfig = &shared.HTTPCORSHeaderConfig{}
|
||||
err = json.Unmarshal(policy.Cors, corsConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config.CORS = corsConfig
|
||||
}
|
||||
|
||||
// Expires
|
||||
// TODO
|
||||
|
||||
@@ -235,6 +245,46 @@ func (this *HTTPHeaderPolicyDAO) FindHeaderPolicyIdWithHeaderId(tx *dbs.Tx, head
|
||||
FindInt64Col(0)
|
||||
}
|
||||
|
||||
// UpdateHeaderPolicyCORS 修改CORS
|
||||
func (this *HTTPHeaderPolicyDAO) UpdateHeaderPolicyCORS(tx *dbs.Tx, headerPolicyId int64, corsConfig *shared.HTTPCORSHeaderConfig) error {
|
||||
if headerPolicyId <= 0 {
|
||||
return errors.New("invalid headerId")
|
||||
}
|
||||
|
||||
corsJSON, err := json.Marshal(corsConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = this.Query(tx).
|
||||
Pk(headerPolicyId).
|
||||
Set("cors", corsJSON).
|
||||
UpdateQuickly()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return this.NotifyUpdate(tx, headerPolicyId)
|
||||
}
|
||||
|
||||
// CheckUserHeaderPolicy 检查用户权限
|
||||
func (this *HTTPHeaderPolicyDAO) CheckUserHeaderPolicy(tx *dbs.Tx, userId int64, policyId int64) error {
|
||||
if userId <= 0 || policyId <= 0 {
|
||||
return ErrNotFound
|
||||
}
|
||||
|
||||
webId, err := SharedHTTPWebDAO.FindEnabledWebIdWithHeaderPolicyId(tx, policyId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if webId <= 0 {
|
||||
return ErrNotFound
|
||||
}
|
||||
|
||||
return SharedHTTPWebDAO.CheckUserWeb(tx, userId, webId)
|
||||
}
|
||||
|
||||
// NotifyUpdate 通知更新
|
||||
func (this *HTTPHeaderPolicyDAO) NotifyUpdate(tx *dbs.Tx, policyId int64) error {
|
||||
webId, err := SharedHTTPWebDAO.FindEnabledWebIdWithHeaderPolicyId(tx, policyId)
|
||||
|
||||
@@ -2,7 +2,7 @@ package models
|
||||
|
||||
import "github.com/iwind/TeaGo/dbs"
|
||||
|
||||
//
|
||||
// HTTPHeaderPolicy Header定义
|
||||
type HTTPHeaderPolicy struct {
|
||||
Id uint32 `field:"id"` // ID
|
||||
IsOn bool `field:"isOn"` // 是否启用
|
||||
@@ -16,21 +16,23 @@ type HTTPHeaderPolicy struct {
|
||||
ReplaceHeaders dbs.JSON `field:"replaceHeaders"` // 替换Header内容
|
||||
Expires dbs.JSON `field:"expires"` // Expires单独设置
|
||||
DeleteHeaders dbs.JSON `field:"deleteHeaders"` // 删除的Headers
|
||||
Cors dbs.JSON `field:"cors"` // CORS配置
|
||||
}
|
||||
|
||||
type HTTPHeaderPolicyOperator struct {
|
||||
Id interface{} // ID
|
||||
IsOn interface{} // 是否启用
|
||||
State interface{} // 状态
|
||||
AdminId interface{} // 管理员ID
|
||||
UserId interface{} // 用户ID
|
||||
CreatedAt interface{} // 创建时间
|
||||
AddHeaders interface{} // 添加的Header
|
||||
AddTrailers interface{} // 添加的Trailers
|
||||
SetHeaders interface{} // 设置Header
|
||||
ReplaceHeaders interface{} // 替换Header内容
|
||||
Expires interface{} // Expires单独设置
|
||||
DeleteHeaders interface{} // 删除的Headers
|
||||
Id any // ID
|
||||
IsOn any // 是否启用
|
||||
State any // 状态
|
||||
AdminId any // 管理员ID
|
||||
UserId any // 用户ID
|
||||
CreatedAt any // 创建时间
|
||||
AddHeaders any // 添加的Header
|
||||
AddTrailers any // 添加的Trailers
|
||||
SetHeaders any // 设置Header
|
||||
ReplaceHeaders any // 替换Header内容
|
||||
Expires any // Expires单独设置
|
||||
DeleteHeaders any // 删除的Headers
|
||||
Cors any // CORS配置
|
||||
}
|
||||
|
||||
func NewHTTPHeaderPolicyOperator() *HTTPHeaderPolicyOperator {
|
||||
|
||||
@@ -468,6 +468,16 @@ func (this *HTTPWebDAO) ComposeWebConfig(tx *dbs.Tx, webId int64, cacheMap *util
|
||||
config.Referers = referersConfig
|
||||
}
|
||||
|
||||
// User-Agent
|
||||
if IsNotNull(web.UserAgent) {
|
||||
var userAgentConfig = serverconfigs.NewUserAgentConfig()
|
||||
err = json.Unmarshal(web.UserAgent, userAgentConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config.UserAgent = userAgentConfig
|
||||
}
|
||||
|
||||
if cacheMap != nil {
|
||||
cacheMap.Put(cacheKey, config)
|
||||
}
|
||||
@@ -1252,6 +1262,35 @@ func (this *HTTPWebDAO) FindWebReferers(tx *dbs.Tx, webId int64) ([]byte, error)
|
||||
FindJSONCol()
|
||||
}
|
||||
|
||||
// UpdateWebUserAgent 修改User-Agent设置
|
||||
func (this *HTTPWebDAO) UpdateWebUserAgent(tx *dbs.Tx, webId int64, userAgentConfig *serverconfigs.UserAgentConfig) error {
|
||||
if userAgentConfig == nil {
|
||||
return nil
|
||||
}
|
||||
configJSON, err := json.Marshal(userAgentConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = this.Query(tx).
|
||||
Pk(webId).
|
||||
Set("userAgent", configJSON).
|
||||
UpdateQuickly()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return this.NotifyUpdate(tx, webId)
|
||||
}
|
||||
|
||||
// FindWebUserAgent 查找服务User-Agent配置
|
||||
func (this *HTTPWebDAO) FindWebUserAgent(tx *dbs.Tx, webId int64) ([]byte, error) {
|
||||
return this.Query(tx).
|
||||
Pk(webId).
|
||||
Result("userAgent").
|
||||
FindJSONCol()
|
||||
}
|
||||
|
||||
// NotifyUpdate 通知更新
|
||||
func (this *HTTPWebDAO) NotifyUpdate(tx *dbs.Tx, webId int64) error {
|
||||
// server
|
||||
|
||||
@@ -39,6 +39,7 @@ type HTTPWeb struct {
|
||||
RequestScripts dbs.JSON `field:"requestScripts"` // 请求脚本
|
||||
Uam dbs.JSON `field:"uam"` // UAM设置
|
||||
Referers dbs.JSON `field:"referers"` // 防盗链设置
|
||||
UserAgent dbs.JSON `field:"userAgent"` // UserAgent设置
|
||||
}
|
||||
|
||||
type HTTPWebOperator struct {
|
||||
@@ -77,6 +78,7 @@ type HTTPWebOperator struct {
|
||||
RequestScripts any // 请求脚本
|
||||
Uam any // UAM设置
|
||||
Referers any // 防盗链设置
|
||||
UserAgent any // UserAgent设置
|
||||
}
|
||||
|
||||
func NewHTTPWebOperator() *HTTPWebOperator {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package models
|
||||
package models_test
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
_ "github.com/iwind/TeaGo/bootstrap"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
@@ -11,7 +12,7 @@ func TestMessageTaskDAO_FindSendingMessageTasks(t *testing.T) {
|
||||
dbs.NotifyReady()
|
||||
|
||||
var tx *dbs.Tx
|
||||
tasks, err := NewMessageTaskDAO().FindSendingMessageTasks(tx, 100)
|
||||
tasks, err := models.NewMessageTaskDAO().FindSendingMessageTasks(tx, 100)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -20,3 +21,12 @@ func TestMessageTaskDAO_FindSendingMessageTasks(t *testing.T) {
|
||||
t.Log("task:", task.Id, "recipient:", task.RecipientId)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMessageTaskDAO_CleanExpiredMessageTasks(t *testing.T) {
|
||||
var dao = models.NewMessageTaskDAO()
|
||||
var tx *dbs.Tx
|
||||
err := dao.CleanExpiredMessageTasks(tx, 30)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,11 @@ type NSRecord struct {
|
||||
Type string `field:"type"` // 类型
|
||||
Value string `field:"value"` // 值
|
||||
MxPriority uint32 `field:"mxPriority"` // MX优先级
|
||||
SrvPriority uint32 `field:"srvPriority"` // SRV优先级
|
||||
SrvWeight uint32 `field:"srvWeight"` // SRV权重
|
||||
SrvPort uint32 `field:"srvPort"` // SRV端口
|
||||
CaaFlag uint8 `field:"caaFlag"` // CAA Flag
|
||||
CaaTag string `field:"caaTag"` // CAA TAG
|
||||
Ttl uint32 `field:"ttl"` // TTL(秒)
|
||||
Weight uint32 `field:"weight"` // 权重
|
||||
RouteIds dbs.JSON `field:"routeIds"` // 线路
|
||||
@@ -29,6 +34,11 @@ type NSRecordOperator struct {
|
||||
Type any // 类型
|
||||
Value any // 值
|
||||
MxPriority any // MX优先级
|
||||
SrvPriority any // SRV优先级
|
||||
SrvWeight any // SRV权重
|
||||
SrvPort any // SRV端口
|
||||
CaaFlag any // CAA Flag
|
||||
CaaTag any // CAA TAG
|
||||
Ttl any // TTL(秒)
|
||||
Weight any // 权重
|
||||
RouteIds any // 线路
|
||||
|
||||
@@ -16,6 +16,7 @@ type NSRoute struct {
|
||||
Ranges dbs.JSON `field:"ranges"` // 范围
|
||||
Order uint32 `field:"order"` // 排序
|
||||
Version uint64 `field:"version"` // 版本号
|
||||
Priority uint32 `field:"priority"` // 优先级,越高越优先
|
||||
Code string `field:"code"` // 代号
|
||||
State uint8 `field:"state"` // 状态
|
||||
}
|
||||
@@ -33,6 +34,7 @@ type NSRouteOperator struct {
|
||||
Ranges any // 范围
|
||||
Order any // 排序
|
||||
Version any // 版本号
|
||||
Priority any // 优先级,越高越优先
|
||||
Code any // 代号
|
||||
State any // 状态
|
||||
}
|
||||
|
||||
@@ -978,7 +978,7 @@ func (this *NodeDAO) ComposeNodeConfig(tx *dbs.Tx, nodeId int64, cacheMap *utils
|
||||
}
|
||||
|
||||
for _, server := range servers {
|
||||
serverConfig, err := SharedServerDAO.ComposeServerConfig(tx, server, cacheMap, true, false)
|
||||
serverConfig, err := SharedServerDAO.ComposeServerConfig(tx, server, false, cacheMap, true, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ type NSCluster struct {
|
||||
Answer dbs.JSON `field:"answer"` // 应答设置
|
||||
SoaSerial uint64 `field:"soaSerial"` // SOA序列号
|
||||
Email string `field:"email"` // 管理员邮箱
|
||||
DetectAgents bool `field:"detectAgents"` // 是否监测Agents
|
||||
}
|
||||
|
||||
type NSClusterOperator struct {
|
||||
@@ -45,6 +46,7 @@ type NSClusterOperator struct {
|
||||
Answer any // 应答设置
|
||||
SoaSerial any // SOA序列号
|
||||
Email any // 管理员邮箱
|
||||
DetectAgents any // 是否监测Agents
|
||||
}
|
||||
|
||||
func NewNSClusterOperator() *NSClusterOperator {
|
||||
|
||||
@@ -403,7 +403,7 @@ func (this *OriginDAO) ComposeOriginConfig(tx *dbs.Tx, originId int64, cacheMap
|
||||
}
|
||||
config.CertRef = ref
|
||||
if ref.CertId > 0 {
|
||||
certConfig, err := SharedSSLCertDAO.ComposeCertConfig(tx, ref.CertId, cacheMap)
|
||||
certConfig, err := SharedSSLCertDAO.ComposeCertConfig(tx, ref.CertId, false, cacheMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -195,15 +195,20 @@ func (this *ServerDailyStatDAO) SumUserMonthlyPeek(tx *dbs.Tx, userId int64, reg
|
||||
|
||||
// SumUserDaily 获取某天流量总和
|
||||
// day 格式为YYYYMMDD
|
||||
func (this *ServerDailyStatDAO) SumUserDaily(tx *dbs.Tx, userId int64, regionId int64, day string) (int64, error) {
|
||||
func (this *ServerDailyStatDAO) SumUserDaily(tx *dbs.Tx, userId int64, regionId int64, day string) (stat *ServerDailyStat, err error) {
|
||||
var query = this.Query(tx)
|
||||
if regionId > 0 {
|
||||
query.Attr("regionId", regionId)
|
||||
}
|
||||
return query.
|
||||
Attr("day", day).
|
||||
|
||||
one, err := query.Attr("day", day).
|
||||
Attr("userId", userId).
|
||||
SumInt64("bytes", 0)
|
||||
Result("SUM(bytes) AS bytes", "SUM(cachedBytes) AS cachedBytes", "SUM(attackBytes) AS attackBytes", "SUM(countRequests) AS countRequests", "SUM(countCachedRequests) AS countCachedRequests", "SUM(countAttackRequests) AS countAttackRequests").
|
||||
Find()
|
||||
if err != nil || one == nil {
|
||||
return nil, err
|
||||
}
|
||||
return one.(*ServerDailyStat), nil
|
||||
}
|
||||
|
||||
// SumUserTrafficBytesBetweenDays 获取用户某个日期段内的流量总和
|
||||
|
||||
@@ -1001,7 +1001,7 @@ func (this *ServerDAO) FindServerNodeFilters(tx *dbs.Tx, serverId int64) (isOk b
|
||||
}
|
||||
|
||||
// ComposeServerConfigWithServerId 构造服务的Config
|
||||
func (this *ServerDAO) ComposeServerConfigWithServerId(tx *dbs.Tx, serverId int64, forNode bool) (*serverconfigs.ServerConfig, error) {
|
||||
func (this *ServerDAO) ComposeServerConfigWithServerId(tx *dbs.Tx, serverId int64, ignoreCertData bool, forNode bool) (*serverconfigs.ServerConfig, error) {
|
||||
server, err := this.FindEnabledServer(tx, serverId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -1009,12 +1009,12 @@ func (this *ServerDAO) ComposeServerConfigWithServerId(tx *dbs.Tx, serverId int6
|
||||
if server == nil {
|
||||
return nil, ErrNotFound
|
||||
}
|
||||
return this.ComposeServerConfig(tx, server, nil, forNode, false)
|
||||
return this.ComposeServerConfig(tx, server, ignoreCertData, nil, forNode, false)
|
||||
}
|
||||
|
||||
// ComposeServerConfig 构造服务的Config
|
||||
// forNode 是否是节点请求
|
||||
func (this *ServerDAO) ComposeServerConfig(tx *dbs.Tx, server *Server, cacheMap *utils.CacheMap, forNode bool, forList bool) (*serverconfigs.ServerConfig, error) {
|
||||
func (this *ServerDAO) ComposeServerConfig(tx *dbs.Tx, server *Server, ignoreCerts bool, cacheMap *utils.CacheMap, forNode bool, forList bool) (*serverconfigs.ServerConfig, error) {
|
||||
if server == nil {
|
||||
return nil, ErrNotFound
|
||||
}
|
||||
@@ -1110,8 +1110,8 @@ func (this *ServerDAO) ComposeServerConfig(tx *dbs.Tx, server *Server, cacheMap
|
||||
}
|
||||
|
||||
// SSL
|
||||
if httpsConfig.SSLPolicyRef != nil && httpsConfig.SSLPolicyRef.SSLPolicyId > 0 {
|
||||
sslPolicyConfig, err := SharedSSLPolicyDAO.ComposePolicyConfig(tx, httpsConfig.SSLPolicyRef.SSLPolicyId, cacheMap)
|
||||
if httpsConfig.SSLPolicyRef != nil && httpsConfig.SSLPolicyRef.SSLPolicyId > 0 && !ignoreCerts {
|
||||
sslPolicyConfig, err := SharedSSLPolicyDAO.ComposePolicyConfig(tx, httpsConfig.SSLPolicyRef.SSLPolicyId, false, cacheMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1142,8 +1142,8 @@ func (this *ServerDAO) ComposeServerConfig(tx *dbs.Tx, server *Server, cacheMap
|
||||
}
|
||||
|
||||
// SSL
|
||||
if tlsConfig.SSLPolicyRef != nil {
|
||||
sslPolicyConfig, err := SharedSSLPolicyDAO.ComposePolicyConfig(tx, tlsConfig.SSLPolicyRef.SSLPolicyId, cacheMap)
|
||||
if tlsConfig.SSLPolicyRef != nil && !ignoreCerts {
|
||||
sslPolicyConfig, err := SharedSSLPolicyDAO.ComposePolicyConfig(tx, tlsConfig.SSLPolicyRef.SSLPolicyId, false, cacheMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -2494,6 +2494,14 @@ func (this *ServerDAO) UpdateServersClusterIdWithPlanId(tx *dbs.Tx, planId int64
|
||||
|
||||
// UpdateServerUserPlanId 设置服务所属套餐
|
||||
func (this *ServerDAO) UpdateServerUserPlanId(tx *dbs.Tx, serverId int64, userPlanId int64) error {
|
||||
oldClusterId, err := this.Query(tx).
|
||||
Pk(serverId).
|
||||
Result("clusterId").
|
||||
FindInt64Col(0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 取消套餐
|
||||
if userPlanId <= 0 {
|
||||
// 所属用户
|
||||
@@ -2524,7 +2532,24 @@ func (this *ServerDAO) UpdateServerUserPlanId(tx *dbs.Tx, serverId int64, userPl
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return this.NotifyUpdate(tx, serverId)
|
||||
err = this.NotifyUpdate(tx, serverId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 通知DNS更新
|
||||
if oldClusterId != clusterId {
|
||||
if oldClusterId > 0 {
|
||||
err = this.NotifyClusterDNSUpdate(tx, oldClusterId, serverId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return this.NotifyClusterDNSUpdate(tx, clusterId, serverId)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// 设置新套餐
|
||||
@@ -2544,16 +2569,34 @@ func (this *ServerDAO) UpdateServerUserPlanId(tx *dbs.Tx, serverId int64, userPl
|
||||
return errors.New("can not find plan with id '" + types.String(userPlan.PlanId) + "'")
|
||||
}
|
||||
|
||||
var clusterId = int64(plan.ClusterId)
|
||||
err = this.Query(tx).
|
||||
Pk(serverId).
|
||||
Set("userPlanId", userPlanId).
|
||||
Set("lastUserPlanId", userPlanId).
|
||||
Set("clusterId", plan.ClusterId).
|
||||
Set("clusterId", clusterId).
|
||||
UpdateQuickly()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return this.NotifyUpdate(tx, serverId)
|
||||
err = this.NotifyUpdate(tx, serverId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 通知DNS更新
|
||||
if oldClusterId != clusterId {
|
||||
if oldClusterId > 0 {
|
||||
err = this.NotifyClusterDNSUpdate(tx, oldClusterId, serverId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return this.NotifyClusterDNSUpdate(tx, clusterId, serverId)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// FindServerLastUserPlanIdAndUserId 查找最后使用的套餐
|
||||
@@ -2654,6 +2697,72 @@ func (this *ServerDAO) UpdateServerBandwidth(tx *dbs.Tx, serverId int64, fullTim
|
||||
}
|
||||
}
|
||||
|
||||
// UpdateServerUserId 修改服务所属用户
|
||||
func (this *ServerDAO) UpdateServerUserId(tx *dbs.Tx, serverId int64, userId int64) error {
|
||||
if serverId <= 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
serverOne, err := this.Query(tx).
|
||||
Result("https", "tls").
|
||||
Pk(serverId).
|
||||
State(ServerStateEnabled).
|
||||
Find()
|
||||
if err != nil || serverOne == nil {
|
||||
return err
|
||||
}
|
||||
var server = serverOne.(*Server)
|
||||
|
||||
// 修改服务
|
||||
err = this.Query(tx).
|
||||
Pk(serverId).
|
||||
Set("userId", userId).
|
||||
UpdateQuickly()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 修改证书相关数据
|
||||
var sslPolicyIds = []int64{}
|
||||
var httpsConfig = server.DecodeHTTPS()
|
||||
if httpsConfig != nil && httpsConfig.SSLPolicyRef != nil && httpsConfig.SSLPolicyRef.SSLPolicyId > 0 {
|
||||
sslPolicyIds = append(sslPolicyIds, httpsConfig.SSLPolicyRef.SSLPolicyId)
|
||||
}
|
||||
|
||||
var tlsConfig = server.DecodeTLS()
|
||||
if tlsConfig != nil && tlsConfig.SSLPolicyRef != nil && tlsConfig.SSLPolicyRef.SSLPolicyId > 0 {
|
||||
sslPolicyIds = append(sslPolicyIds, tlsConfig.SSLPolicyRef.SSLPolicyId)
|
||||
}
|
||||
if len(sslPolicyIds) > 0 {
|
||||
for _, sslPolicyId := range sslPolicyIds {
|
||||
policy, err := SharedSSLPolicyDAO.FindEnabledSSLPolicy(tx, sslPolicyId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if policy != nil {
|
||||
// 修改策略
|
||||
err = SharedSSLPolicyDAO.UpdatePolicyUser(tx, sslPolicyId, userId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var certRefs = policy.DecodeCerts()
|
||||
for _, certRef := range certRefs {
|
||||
if certRef.CertId > 0 {
|
||||
// 修改证书
|
||||
err = SharedSSLCertDAO.UpdateCertUser(tx, certRef.CertId, userId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return this.NotifyUpdate(tx, serverId)
|
||||
}
|
||||
|
||||
// NotifyUpdate 同步服务所在的集群
|
||||
func (this *ServerDAO) NotifyUpdate(tx *dbs.Tx, serverId int64) error {
|
||||
// 创建任务
|
||||
|
||||
@@ -42,10 +42,38 @@ func (this *Server) DecodeHTTPPorts() (ports []int) {
|
||||
return
|
||||
}
|
||||
|
||||
// DecodeHTTPS 解析HTTPS设置
|
||||
func (this *Server) DecodeHTTPS() *serverconfigs.HTTPSProtocolConfig {
|
||||
if len(this.Https) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
var config = &serverconfigs.HTTPSProtocolConfig{}
|
||||
err := json.Unmarshal(this.Https, config)
|
||||
if err != nil {
|
||||
remotelogs.Error("Server_DecodeHTTPS", err.Error())
|
||||
}
|
||||
return config
|
||||
}
|
||||
|
||||
// DecodeTLS 解析TLS设置
|
||||
func (this *Server) DecodeTLS() *serverconfigs.TLSProtocolConfig {
|
||||
if len(this.Tls) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
var config = &serverconfigs.TLSProtocolConfig{}
|
||||
err := json.Unmarshal(this.Tls, config)
|
||||
if err != nil {
|
||||
remotelogs.Error("Server_DecodeTLS", err.Error())
|
||||
}
|
||||
return config
|
||||
}
|
||||
|
||||
// DecodeHTTPSPorts 获取HTTPS所有端口
|
||||
func (this *Server) DecodeHTTPSPorts() (ports []int) {
|
||||
if len(this.Https) > 0 {
|
||||
config := &serverconfigs.HTTPSProtocolConfig{}
|
||||
var config = &serverconfigs.HTTPSProtocolConfig{}
|
||||
err := json.Unmarshal(this.Https, config)
|
||||
if err != nil {
|
||||
return nil
|
||||
|
||||
@@ -200,7 +200,8 @@ func (this *SSLCertDAO) UpdateCert(tx *dbs.Tx,
|
||||
}
|
||||
|
||||
// ComposeCertConfig 组合配置
|
||||
func (this *SSLCertDAO) ComposeCertConfig(tx *dbs.Tx, certId int64, cacheMap *utils.CacheMap) (*sslconfigs.SSLCertConfig, error) {
|
||||
// ignoreData 是否忽略证书数据,避免因为数据过大影响传输
|
||||
func (this *SSLCertDAO) ComposeCertConfig(tx *dbs.Tx, certId int64, ignoreData bool, cacheMap *utils.CacheMap) (*sslconfigs.SSLCertConfig, error) {
|
||||
if cacheMap == nil {
|
||||
cacheMap = utils.NewCacheMap()
|
||||
}
|
||||
@@ -218,15 +219,17 @@ func (this *SSLCertDAO) ComposeCertConfig(tx *dbs.Tx, certId int64, cacheMap *ut
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
config := &sslconfigs.SSLCertConfig{}
|
||||
var config = &sslconfigs.SSLCertConfig{}
|
||||
config.Id = int64(cert.Id)
|
||||
config.IsOn = cert.IsOn
|
||||
config.IsCA = cert.IsCA
|
||||
config.IsACME = cert.IsACME
|
||||
config.Name = cert.Name
|
||||
config.Description = cert.Description
|
||||
config.CertData = cert.CertData
|
||||
config.KeyData = cert.KeyData
|
||||
if !ignoreData {
|
||||
config.CertData = cert.CertData
|
||||
config.KeyData = cert.KeyData
|
||||
}
|
||||
config.ServerName = cert.ServerName
|
||||
config.TimeBeginAt = int64(cert.TimeBeginAt)
|
||||
config.TimeEndAt = int64(cert.TimeEndAt)
|
||||
@@ -239,7 +242,7 @@ func (this *SSLCertDAO) ComposeCertConfig(tx *dbs.Tx, certId int64, cacheMap *ut
|
||||
config.OCSPError = cert.OcspError
|
||||
|
||||
if IsNotNull(cert.DnsNames) {
|
||||
dnsNames := []string{}
|
||||
var dnsNames = []string{}
|
||||
err := json.Unmarshal(cert.DnsNames, &dnsNames)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -248,7 +251,7 @@ func (this *SSLCertDAO) ComposeCertConfig(tx *dbs.Tx, certId int64, cacheMap *ut
|
||||
}
|
||||
|
||||
if cert.CommonNames.IsNotNull() {
|
||||
commonNames := []string{}
|
||||
var commonNames = []string{}
|
||||
err := json.Unmarshal(cert.CommonNames, &commonNames)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -399,6 +402,17 @@ func (this *SSLCertDAO) CheckUserCert(tx *dbs.Tx, certId int64, userId int64) er
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateCertUser 修改证书所属用户
|
||||
func (this *SSLCertDAO) UpdateCertUser(tx *dbs.Tx, certId int64, userId int64) error {
|
||||
if certId <= 0 || userId <= 0 {
|
||||
return nil
|
||||
}
|
||||
return this.Query(tx).
|
||||
Pk(certId).
|
||||
Set("userId", userId).
|
||||
UpdateQuickly()
|
||||
}
|
||||
|
||||
// ListCertsToUpdateOCSP 查找需要更新OCSP的证书
|
||||
func (this *SSLCertDAO) ListCertsToUpdateOCSP(tx *dbs.Tx, maxTries int, size int64) (result []*SSLCert, err error) {
|
||||
var nowTime = time.Now().Unix()
|
||||
|
||||
@@ -77,7 +77,7 @@ func (this *SSLPolicyDAO) FindEnabledSSLPolicy(tx *dbs.Tx, id int64) (*SSLPolicy
|
||||
}
|
||||
|
||||
// ComposePolicyConfig 组合配置
|
||||
func (this *SSLPolicyDAO) ComposePolicyConfig(tx *dbs.Tx, policyId int64, cacheMap *utils.CacheMap) (*sslconfigs.SSLPolicy, error) {
|
||||
func (this *SSLPolicyDAO) ComposePolicyConfig(tx *dbs.Tx, policyId int64, ignoreData bool, cacheMap *utils.CacheMap) (*sslconfigs.SSLPolicy, error) {
|
||||
if cacheMap == nil {
|
||||
cacheMap = utils.NewCacheMap()
|
||||
}
|
||||
@@ -95,7 +95,7 @@ func (this *SSLPolicyDAO) ComposePolicyConfig(tx *dbs.Tx, policyId int64, cacheM
|
||||
if policy == nil {
|
||||
return nil, nil
|
||||
}
|
||||
config := &sslconfigs.SSLPolicy{}
|
||||
var config = &sslconfigs.SSLPolicy{}
|
||||
config.Id = int64(policy.Id)
|
||||
config.IsOn = policy.IsOn
|
||||
config.ClientAuthType = int(policy.ClientAuthType)
|
||||
@@ -104,14 +104,14 @@ func (this *SSLPolicyDAO) ComposePolicyConfig(tx *dbs.Tx, policyId int64, cacheM
|
||||
|
||||
// certs
|
||||
if IsNotNull(policy.Certs) {
|
||||
refs := []*sslconfigs.SSLCertRef{}
|
||||
var refs = []*sslconfigs.SSLCertRef{}
|
||||
err = json.Unmarshal(policy.Certs, &refs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(refs) > 0 {
|
||||
for _, ref := range refs {
|
||||
certConfig, err := SharedSSLCertDAO.ComposeCertConfig(tx, ref.CertId, cacheMap)
|
||||
certConfig, err := SharedSSLCertDAO.ComposeCertConfig(tx, ref.CertId, ignoreData, cacheMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -126,14 +126,14 @@ func (this *SSLPolicyDAO) ComposePolicyConfig(tx *dbs.Tx, policyId int64, cacheM
|
||||
|
||||
// client CA certs
|
||||
if IsNotNull(policy.ClientCACerts) {
|
||||
refs := []*sslconfigs.SSLCertRef{}
|
||||
var refs = []*sslconfigs.SSLCertRef{}
|
||||
err = json.Unmarshal(policy.ClientCACerts, &refs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(refs) > 0 {
|
||||
for _, ref := range refs {
|
||||
certConfig, err := SharedSSLCertDAO.ComposeCertConfig(tx, ref.CertId, cacheMap)
|
||||
certConfig, err := SharedSSLCertDAO.ComposeCertConfig(tx, ref.CertId, ignoreData, cacheMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -159,7 +159,7 @@ func (this *SSLPolicyDAO) ComposePolicyConfig(tx *dbs.Tx, policyId int64, cacheM
|
||||
|
||||
// hsts
|
||||
if IsNotNull(policy.Hsts) {
|
||||
hstsConfig := &sslconfigs.HSTSConfig{}
|
||||
var hstsConfig = &sslconfigs.HSTSConfig{}
|
||||
err = json.Unmarshal(policy.Hsts, hstsConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -306,6 +306,18 @@ func (this *SSLPolicyDAO) CheckUserPolicy(tx *dbs.Tx, userId int64, policyId int
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdatePolicyUser 修改策略所属用户
|
||||
func (this *SSLPolicyDAO) UpdatePolicyUser(tx *dbs.Tx, policyId int64, userId int64) error {
|
||||
if policyId <= 0 || userId <= 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return this.Query(tx).
|
||||
Pk(policyId).
|
||||
Set("userId", userId).
|
||||
UpdateQuickly()
|
||||
}
|
||||
|
||||
// NotifyUpdate 通知更新
|
||||
func (this *SSLPolicyDAO) NotifyUpdate(tx *dbs.Tx, policyId int64) error {
|
||||
serverIds, err := SharedServerDAO.FindAllEnabledServerIdsWithSSLPolicyIds(tx, []int64{policyId})
|
||||
|
||||
@@ -1 +1,20 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/sslconfigs"
|
||||
)
|
||||
|
||||
func (this *SSLPolicy) DecodeCerts() []*sslconfigs.SSLCertRef {
|
||||
if len(this.Certs) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
var refs = []*sslconfigs.SSLCertRef{}
|
||||
err := json.Unmarshal(this.Certs, &refs)
|
||||
if err != nil {
|
||||
remotelogs.Error("SSLPolicy_DecodeCerts", err.Error())
|
||||
}
|
||||
return refs
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
"github.com/iwind/TeaGo/Tea"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -172,6 +173,21 @@ func (this *SysSettingDAO) ReadAdminUIConfig(tx *dbs.Tx, cacheMap *utils.CacheMa
|
||||
return &systemconfigs.AdminUIConfig{}, nil
|
||||
}
|
||||
|
||||
// ReadProductName 读取设置的产品名称
|
||||
func (this *SysSettingDAO) ReadProductName(tx *dbs.Tx) (string, error) {
|
||||
productName, err := this.Query(tx).
|
||||
Attr("code", systemconfigs.SettingCodeAdminUIConfig).
|
||||
Result("JSON_EXTRACT(value, '$.productName')").
|
||||
FindStringCol("")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if len(productName) > 0 {
|
||||
return strconv.Unquote(productName)
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// ReadUserUIConfig 读取用户UI配置
|
||||
func (this *SysSettingDAO) ReadUserUIConfig(tx *dbs.Tx) (*systemconfigs.UserUIConfig, error) {
|
||||
valueJSON, err := this.ReadSetting(tx, systemconfigs.SettingCodeUserUIConfig)
|
||||
@@ -228,3 +244,21 @@ func (this *SysSettingDAO) ReadUserServerConfig(tx *dbs.Tx) (*userconfigs.UserSe
|
||||
}
|
||||
return config, nil
|
||||
}
|
||||
|
||||
// ReadUserRegisterConfig 读取用户注册配置
|
||||
func (this *SysSettingDAO) ReadUserRegisterConfig(tx *dbs.Tx) (*userconfigs.UserRegisterConfig, error) {
|
||||
valueJSON, err := this.ReadSetting(tx, systemconfigs.SettingCodeUserRegisterConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(valueJSON) == 0 {
|
||||
return userconfigs.DefaultUserRegisterConfig(), nil
|
||||
}
|
||||
|
||||
var config = userconfigs.DefaultUserRegisterConfig()
|
||||
err = json.Unmarshal(valueJSON, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return config, nil
|
||||
}
|
||||
|
||||
@@ -42,3 +42,8 @@ func TestSysSettingDAO_CompareInt64Setting(t *testing.T) {
|
||||
}
|
||||
t.Log("result:", i)
|
||||
}
|
||||
|
||||
func TestSysSettingDAO_ReadProductName(t *testing.T) {
|
||||
var tx *dbs.Tx
|
||||
t.Log(NewSysSettingDAO().ReadProductName(tx))
|
||||
}
|
||||
|
||||
@@ -74,6 +74,11 @@ func (this *UserDAO) DisableUser(tx *dbs.Tx, userId int64) error {
|
||||
return err
|
||||
}
|
||||
|
||||
err = SharedAPIAccessTokenDAO.DeleteAccessTokens(tx, 0, userId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return this.NotifyUpdate(tx, userId)
|
||||
}
|
||||
|
||||
@@ -137,7 +142,24 @@ func (this *UserDAO) FindEnabledUserIdWithUsername(tx *dbs.Tx, username string)
|
||||
FindInt64Col(0)
|
||||
}
|
||||
|
||||
// FindUserFullname 获取管理员名称
|
||||
// FindUserId 根据多个条件查找用户ID
|
||||
func (this *UserDAO) FindUserId(tx *dbs.Tx, verifiedEmail string, verifiedMobile string) (int64, error) {
|
||||
var query = this.Query(tx).
|
||||
State(UserStateEnabled).
|
||||
ResultPk()
|
||||
|
||||
if len(verifiedEmail) > 0 {
|
||||
query.Attr("verifiedEmail", verifiedEmail)
|
||||
} else if len(verifiedMobile) > 0 {
|
||||
query.Attr("verifiedMobile", verifiedMobile)
|
||||
} else {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
return query.FindInt64Col(0)
|
||||
}
|
||||
|
||||
// FindUserFullname 获取用户名称
|
||||
func (this *UserDAO) FindUserFullname(tx *dbs.Tx, userId int64) (string, error) {
|
||||
return this.Query(tx).
|
||||
Pk(userId).
|
||||
@@ -145,6 +167,14 @@ func (this *UserDAO) FindUserFullname(tx *dbs.Tx, userId int64) (string, error)
|
||||
FindStringCol("")
|
||||
}
|
||||
|
||||
// FindUserVerifiedEmail 查询用户已绑定邮箱
|
||||
func (this *UserDAO) FindUserVerifiedEmail(tx *dbs.Tx, userId int64) (string, error) {
|
||||
return this.Query(tx).
|
||||
Pk(userId).
|
||||
Result("verifiedEmail").
|
||||
FindStringCol("")
|
||||
}
|
||||
|
||||
// CreateUser 创建用户
|
||||
func (this *UserDAO) CreateUser(tx *dbs.Tx, username string,
|
||||
password string,
|
||||
@@ -217,6 +247,14 @@ func (this *UserDAO) UpdateUser(tx *dbs.Tx, userId int64, username string, passw
|
||||
return err
|
||||
}
|
||||
|
||||
// 删除AccessTokens
|
||||
if !isOn {
|
||||
err = SharedAPIAccessTokenDAO.DeleteAccessTokens(tx, 0, userId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return this.NotifyUpdate(tx, userId)
|
||||
}
|
||||
|
||||
@@ -244,8 +282,20 @@ func (this *UserDAO) UpdateUserLogin(tx *dbs.Tx, userId int64, username string,
|
||||
if len(password) > 0 {
|
||||
op.Password = stringutil.Md5(password)
|
||||
}
|
||||
err := this.Save(tx, op)
|
||||
return err
|
||||
return this.Save(tx, op)
|
||||
}
|
||||
|
||||
// UpdateUserPassword 修改用户密码
|
||||
func (this *UserDAO) UpdateUserPassword(tx *dbs.Tx, userId int64, password string) error {
|
||||
if userId <= 0 {
|
||||
return errors.New("invalid userId")
|
||||
}
|
||||
var op = NewUserOperator()
|
||||
op.Id = userId
|
||||
if len(password) > 0 {
|
||||
op.Password = stringutil.Md5(password)
|
||||
}
|
||||
return this.Save(tx, op)
|
||||
}
|
||||
|
||||
// CountAllEnabledUsers 计算用户数量
|
||||
@@ -327,7 +377,7 @@ func (this *UserDAO) ListEnabledUserIds(tx *dbs.Tx, offset, size int64) ([]int64
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// CheckUserPassword 检查用户名、密码
|
||||
// CheckUserPassword 检查用户名+密码
|
||||
func (this *UserDAO) CheckUserPassword(tx *dbs.Tx, username string, encryptedPassword string) (int64, error) {
|
||||
if len(username) == 0 || len(encryptedPassword) == 0 {
|
||||
return 0, nil
|
||||
@@ -341,6 +391,20 @@ func (this *UserDAO) CheckUserPassword(tx *dbs.Tx, username string, encryptedPas
|
||||
FindInt64Col(0)
|
||||
}
|
||||
|
||||
// CheckUserEmailPassword 检查邮箱+密码
|
||||
func (this *UserDAO) CheckUserEmailPassword(tx *dbs.Tx, verifiedEmail string, encryptedPassword string) (int64, error) {
|
||||
if len(verifiedEmail) == 0 || len(encryptedPassword) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
return this.Query(tx).
|
||||
Attr("verifiedEmail", verifiedEmail).
|
||||
Attr("password", encryptedPassword).
|
||||
Attr("state", UserStateEnabled).
|
||||
Attr("isOn", true).
|
||||
ResultPk().
|
||||
FindInt64Col(0)
|
||||
}
|
||||
|
||||
// FindUserClusterId 查找用户所在集群
|
||||
func (this *UserDAO) FindUserClusterId(tx *dbs.Tx, userId int64) (int64, error) {
|
||||
return this.Query(tx).
|
||||
@@ -573,6 +637,30 @@ func (this *UserDAO) RenewUserServersState(tx *dbs.Tx, userId int64) (bool, erro
|
||||
return newServersEnabled, nil
|
||||
}
|
||||
|
||||
// FindUserIdWithVerifiedEmail 使用验证后Email查找用户ID
|
||||
func (this *UserDAO) FindUserIdWithVerifiedEmail(tx *dbs.Tx, verifiedEmail string) (int64, error) {
|
||||
if len(verifiedEmail) == 0 {
|
||||
|
||||
}
|
||||
return this.Query(tx).
|
||||
ResultPk().
|
||||
State(UserStateEnabled).
|
||||
Attr("verifiedEmail", verifiedEmail).
|
||||
FindInt64Col(0)
|
||||
}
|
||||
|
||||
// UpdateUserVerifiedEmail 修改已激活邮箱
|
||||
func (this *UserDAO) UpdateUserVerifiedEmail(tx *dbs.Tx, userId int64, verifiedEmail string) error {
|
||||
if userId <= 0 {
|
||||
return nil
|
||||
}
|
||||
return this.Query(tx).
|
||||
Pk(userId).
|
||||
Set("verifiedEmail", verifiedEmail).
|
||||
Set("emailIsVerified", true).
|
||||
UpdateQuickly()
|
||||
}
|
||||
|
||||
// NotifyUpdate 用户变更通知
|
||||
func (this *UserDAO) NotifyUpdate(tx *dbs.Tx, userId int64) error {
|
||||
if userId <= 0 {
|
||||
|
||||
28
internal/db/models/user_email_notification_dao.go
Normal file
28
internal/db/models/user_email_notification_dao.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/iwind/TeaGo/Tea"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
)
|
||||
|
||||
type UserEmailNotificationDAO dbs.DAO
|
||||
|
||||
func NewUserEmailNotificationDAO() *UserEmailNotificationDAO {
|
||||
return dbs.NewDAO(&UserEmailNotificationDAO{
|
||||
DAOObject: dbs.DAOObject{
|
||||
DB: Tea.Env,
|
||||
Table: "edgeUserEmailNotifications",
|
||||
Model: new(UserEmailNotification),
|
||||
PkName: "id",
|
||||
},
|
||||
}).(*UserEmailNotificationDAO)
|
||||
}
|
||||
|
||||
var SharedUserEmailNotificationDAO *UserEmailNotificationDAO
|
||||
|
||||
func init() {
|
||||
dbs.OnReady(func() {
|
||||
SharedUserEmailNotificationDAO = NewUserEmailNotificationDAO()
|
||||
})
|
||||
}
|
||||
6
internal/db/models/user_email_notification_dao_test.go
Normal file
6
internal/db/models/user_email_notification_dao_test.go
Normal file
@@ -0,0 +1,6 @@
|
||||
package models_test
|
||||
|
||||
import (
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
_ "github.com/iwind/TeaGo/bootstrap"
|
||||
)
|
||||
24
internal/db/models/user_email_notification_model.go
Normal file
24
internal/db/models/user_email_notification_model.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package models
|
||||
|
||||
// UserEmailNotification 邮件通知队列
|
||||
type UserEmailNotification struct {
|
||||
Id uint64 `field:"id"` // ID
|
||||
Email string `field:"email"` // 邮箱地址
|
||||
Subject string `field:"subject"` // 标题
|
||||
Body string `field:"body"` // 内容
|
||||
CreatedAt uint64 `field:"createdAt"` // 创建时间
|
||||
Day string `field:"day"` // YYYYMMDD
|
||||
}
|
||||
|
||||
type UserEmailNotificationOperator struct {
|
||||
Id any // ID
|
||||
Email any // 邮箱地址
|
||||
Subject any // 标题
|
||||
Body any // 内容
|
||||
CreatedAt any // 创建时间
|
||||
Day any // YYYYMMDD
|
||||
}
|
||||
|
||||
func NewUserEmailNotificationOperator() *UserEmailNotificationOperator {
|
||||
return &UserEmailNotificationOperator{}
|
||||
}
|
||||
28
internal/db/models/user_email_verification_dao.go
Normal file
28
internal/db/models/user_email_verification_dao.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/iwind/TeaGo/Tea"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
)
|
||||
|
||||
type UserEmailVerificationDAO dbs.DAO
|
||||
|
||||
func NewUserEmailVerificationDAO() *UserEmailVerificationDAO {
|
||||
return dbs.NewDAO(&UserEmailVerificationDAO{
|
||||
DAOObject: dbs.DAOObject{
|
||||
DB: Tea.Env,
|
||||
Table: "edgeUserEmailVerifications",
|
||||
Model: new(UserEmailVerification),
|
||||
PkName: "id",
|
||||
},
|
||||
}).(*UserEmailVerificationDAO)
|
||||
}
|
||||
|
||||
var SharedUserEmailVerificationDAO *UserEmailVerificationDAO
|
||||
|
||||
func init() {
|
||||
dbs.OnReady(func() {
|
||||
SharedUserEmailVerificationDAO = NewUserEmailVerificationDAO()
|
||||
})
|
||||
}
|
||||
6
internal/db/models/user_email_verification_dao_test.go
Normal file
6
internal/db/models/user_email_verification_dao_test.go
Normal file
@@ -0,0 +1,6 @@
|
||||
package models_test
|
||||
|
||||
import (
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
_ "github.com/iwind/TeaGo/bootstrap"
|
||||
)
|
||||
28
internal/db/models/user_email_verification_model.go
Normal file
28
internal/db/models/user_email_verification_model.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package models
|
||||
|
||||
// UserEmailVerification 邮箱激活邮件队列
|
||||
type UserEmailVerification struct {
|
||||
Id uint64 `field:"id"` // ID
|
||||
Email string `field:"email"` // 邮箱
|
||||
UserId uint64 `field:"userId"` // 用户ID
|
||||
Code string `field:"code"` // 激活码
|
||||
CreatedAt uint64 `field:"createdAt"` // 创建时间
|
||||
IsSent bool `field:"isSent"` // 是否已发送
|
||||
IsVerified bool `field:"isVerified"` // 是否已激活
|
||||
Day string `field:"day"` // YYYYMMDD
|
||||
}
|
||||
|
||||
type UserEmailVerificationOperator struct {
|
||||
Id any // ID
|
||||
Email any // 邮箱
|
||||
UserId any // 用户ID
|
||||
Code any // 激活码
|
||||
CreatedAt any // 创建时间
|
||||
IsSent any // 是否已发送
|
||||
IsVerified any // 是否已激活
|
||||
Day any // YYYYMMDD
|
||||
}
|
||||
|
||||
func NewUserEmailVerificationOperator() *UserEmailVerificationOperator {
|
||||
return &UserEmailVerificationOperator{}
|
||||
}
|
||||
@@ -10,9 +10,11 @@ type User struct {
|
||||
Password string `field:"password"` // 密码
|
||||
Fullname string `field:"fullname"` // 真实姓名
|
||||
Mobile string `field:"mobile"` // 手机号
|
||||
VerifiedMobile string `field:"verifiedMobile"` // 已验证手机号
|
||||
Tel string `field:"tel"` // 联系电话
|
||||
Remark string `field:"remark"` // 备注
|
||||
Email string `field:"email"` // 邮箱地址
|
||||
VerifiedEmail string `field:"verifiedEmail"` // 激活后的邮箱
|
||||
EmailIsVerified uint8 `field:"emailIsVerified"` // 邮箱是否已验证
|
||||
AvatarFileId uint64 `field:"avatarFileId"` // 头像文件ID
|
||||
CreatedAt uint64 `field:"createdAt"` // 创建时间
|
||||
@@ -31,6 +33,7 @@ type User struct {
|
||||
PriceType string `field:"priceType"` // 计费类型:traffic|bandwidth
|
||||
PricePeriod string `field:"pricePeriod"` // 结算周期
|
||||
ServersEnabled uint8 `field:"serversEnabled"` // 是否禁用所有服务
|
||||
Notification dbs.JSON `field:"notification"` // 通知设置
|
||||
}
|
||||
|
||||
type UserOperator struct {
|
||||
@@ -40,9 +43,11 @@ type UserOperator struct {
|
||||
Password any // 密码
|
||||
Fullname any // 真实姓名
|
||||
Mobile any // 手机号
|
||||
VerifiedMobile any // 已验证手机号
|
||||
Tel any // 联系电话
|
||||
Remark any // 备注
|
||||
Email any // 邮箱地址
|
||||
VerifiedEmail any // 激活后的邮箱
|
||||
EmailIsVerified any // 邮箱是否已验证
|
||||
AvatarFileId any // 头像文件ID
|
||||
CreatedAt any // 创建时间
|
||||
@@ -61,6 +66,7 @@ type UserOperator struct {
|
||||
PriceType any // 计费类型:traffic|bandwidth
|
||||
PricePeriod any // 结算周期
|
||||
ServersEnabled any // 是否禁用所有服务
|
||||
Notification any // 通知设置
|
||||
}
|
||||
|
||||
func NewUserOperator() *UserOperator {
|
||||
|
||||
@@ -44,7 +44,7 @@ func (this *UserNode) DecodeHTTPS(cacheMap *utils.CacheMap) (*serverconfigs.HTTP
|
||||
if config.SSLPolicyRef != nil {
|
||||
policyId := config.SSLPolicyRef.SSLPolicyId
|
||||
if policyId > 0 {
|
||||
sslPolicy, err := SharedSSLPolicyDAO.ComposePolicyConfig(nil, policyId, cacheMap)
|
||||
sslPolicy, err := SharedSSLPolicyDAO.ComposePolicyConfig(nil, policyId, false, cacheMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
28
internal/db/models/user_verify_code_dao.go
Normal file
28
internal/db/models/user_verify_code_dao.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/iwind/TeaGo/Tea"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
)
|
||||
|
||||
type UserVerifyCodeDAO dbs.DAO
|
||||
|
||||
func NewUserVerifyCodeDAO() *UserVerifyCodeDAO {
|
||||
return dbs.NewDAO(&UserVerifyCodeDAO{
|
||||
DAOObject: dbs.DAOObject{
|
||||
DB: Tea.Env,
|
||||
Table: "edgeUserVerifyCodes",
|
||||
Model: new(UserVerifyCode),
|
||||
PkName: "id",
|
||||
},
|
||||
}).(*UserVerifyCodeDAO)
|
||||
}
|
||||
|
||||
var SharedUserVerifyCodeDAO *UserVerifyCodeDAO
|
||||
|
||||
func init() {
|
||||
dbs.OnReady(func() {
|
||||
SharedUserVerifyCodeDAO = NewUserVerifyCodeDAO()
|
||||
})
|
||||
}
|
||||
6
internal/db/models/user_verify_code_dao_test.go
Normal file
6
internal/db/models/user_verify_code_dao_test.go
Normal file
@@ -0,0 +1,6 @@
|
||||
package models_test
|
||||
|
||||
import (
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
_ "github.com/iwind/TeaGo/bootstrap"
|
||||
)
|
||||
32
internal/db/models/user_verify_code_model.go
Normal file
32
internal/db/models/user_verify_code_model.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package models
|
||||
|
||||
// UserVerifyCode 重置密码之验证码
|
||||
type UserVerifyCode struct {
|
||||
Id uint64 `field:"id"` // ID
|
||||
Email string `field:"email"` // 邮箱地址
|
||||
Mobile string `field:"mobile"` // 手机号
|
||||
Code string `field:"code"` // 验证码
|
||||
Type string `field:"type"` // 类型
|
||||
IsSent bool `field:"isSent"` // 是否已发送
|
||||
IsVerified bool `field:"isVerified"` // 是否已激活
|
||||
CreatedAt uint64 `field:"createdAt"` // 创建时间
|
||||
ExpiresAt uint64 `field:"expiresAt"` // 过期时间
|
||||
Day string `field:"day"` // YYYYMMDD
|
||||
}
|
||||
|
||||
type UserVerifyCodeOperator struct {
|
||||
Id any // ID
|
||||
Email any // 邮箱地址
|
||||
Mobile any // 手机号
|
||||
Code any // 验证码
|
||||
Type any // 类型
|
||||
IsSent any // 是否已发送
|
||||
IsVerified any // 是否已激活
|
||||
CreatedAt any // 创建时间
|
||||
ExpiresAt any // 过期时间
|
||||
Day any // YYYYMMDD
|
||||
}
|
||||
|
||||
func NewUserVerifyCodeOperator() *UserVerifyCodeOperator {
|
||||
return &UserVerifyCodeOperator{}
|
||||
}
|
||||
1
internal/db/models/user_verify_code_model_ext.go
Normal file
1
internal/db/models/user_verify_code_model_ext.go
Normal file
@@ -0,0 +1 @@
|
||||
package models
|
||||
@@ -72,3 +72,11 @@ func CheckSQLErrCode(err error, code uint16) bool {
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// CheckSQLDuplicateErr 检查Duplicate错误
|
||||
func CheckSQLDuplicateErr(err error) bool {
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
return CheckSQLErrCode(err, 1062)
|
||||
}
|
||||
|
||||
@@ -206,6 +206,23 @@ func (this *EdgeDNSAPIProvider) GetRoutes(domain string) (routes []*dnstypes.Rou
|
||||
}
|
||||
}
|
||||
|
||||
// Agent
|
||||
{
|
||||
var routesResp = &edgeapi.FindAllNSRoutesResponse{}
|
||||
err = this.doAPI("/NSRouteService/FindAllAgentNSRoutes", map[string]any{}, routesResp)
|
||||
if err != nil {
|
||||
// 忽略错误,因为老版本的EdgeDNS没有提供这个接口
|
||||
err = nil
|
||||
} else {
|
||||
for _, route := range routesResp.Data.NSRoutes {
|
||||
routes = append(routes, &dnstypes.Route{
|
||||
Name: route.Name,
|
||||
Code: route.Code,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 自定义
|
||||
{
|
||||
var routesResp = &edgeapi.FindAllNSRoutesResponse{}
|
||||
|
||||
@@ -17,13 +17,16 @@ import (
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
const HuaweiDNSEndpoint = "https://dns.cn-north-1.myhuaweicloud.com/"
|
||||
// HuaweiDNSDefaultEndpoint 默认Endpoint
|
||||
// 所有Endpoints:https://developer.huaweicloud.com/endpoint?DNS
|
||||
const HuaweiDNSDefaultEndpoint = "https://dns.cn-north-4.myhuaweicloud.com/"
|
||||
|
||||
var huaweiDNSHTTPClient = &http.Client{
|
||||
Timeout: 10 * time.Second,
|
||||
@@ -43,6 +46,10 @@ type HuaweiDNSProvider struct {
|
||||
|
||||
accessKeyId string
|
||||
accessKeySecret string
|
||||
endpoint string
|
||||
|
||||
endpointRegionReg *regexp.Regexp
|
||||
endpointDomainReg *regexp.Regexp
|
||||
}
|
||||
|
||||
// Auth 认证
|
||||
@@ -55,6 +62,12 @@ func (this *HuaweiDNSProvider) Auth(params maps.Map) error {
|
||||
if len(this.accessKeySecret) == 0 {
|
||||
return errors.New("'accessKeySecret' should not be empty")
|
||||
}
|
||||
this.endpoint = params.GetString("endpoint")
|
||||
|
||||
// endpoint相关正则
|
||||
this.endpointRegionReg = regexp.MustCompile(`^[\w-]+$`)
|
||||
this.endpointDomainReg = regexp.MustCompile(`^([\w-]+\.)+[\w-]+$`)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1469,13 +1482,38 @@ func (this *HuaweiDNSProvider) DefaultRoute() string {
|
||||
}
|
||||
|
||||
func (this *HuaweiDNSProvider) doAPI(method string, apiPath string, args map[string]string, bodyMap maps.Map, respPtr interface{}) error {
|
||||
apiURL := HuaweiDNSEndpoint + strings.TrimLeft(apiPath, "/")
|
||||
u, err := url.Parse(HuaweiDNSEndpoint)
|
||||
var endpoint = HuaweiDNSDefaultEndpoint
|
||||
if len(this.endpoint) > 0 {
|
||||
// 是否直接为区域
|
||||
if this.endpointRegionReg.MatchString(this.endpoint) {
|
||||
switch this.endpoint {
|
||||
case "All", "all":
|
||||
endpoint = "https://dns.myhuaweicloud.com/"
|
||||
default:
|
||||
endpoint = "https://dns." + this.endpoint + ".myhuaweicloud.com/"
|
||||
}
|
||||
} else if this.endpointDomainReg.MatchString(this.endpoint) { // 是否直接为域名
|
||||
endpoint = "https://" + this.endpoint + "/"
|
||||
} else {
|
||||
// 是否为URL
|
||||
_, err := url.Parse(this.endpoint)
|
||||
if err != nil {
|
||||
return errors.New("invalid endpoint '" + this.endpoint + "'")
|
||||
}
|
||||
endpoint = this.endpoint
|
||||
if !strings.HasSuffix(endpoint, "/") {
|
||||
endpoint += "/"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var apiURL = endpoint + strings.TrimLeft(apiPath, "/")
|
||||
u, err := url.Parse(endpoint)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
apiHost := u.Host
|
||||
argStrings := []string{}
|
||||
var apiHost = u.Host
|
||||
var argStrings = []string{}
|
||||
if len(args) > 0 {
|
||||
apiURL += "?"
|
||||
for k, v := range args {
|
||||
@@ -1501,28 +1539,28 @@ func (this *HuaweiDNSProvider) doAPI(method string, apiPath string, args map[str
|
||||
return err
|
||||
}
|
||||
|
||||
contentType := "application/json"
|
||||
host := apiHost
|
||||
datetime := time.Now().UTC().Format("20060102T150405Z")
|
||||
var contentType = "application/json"
|
||||
var host = apiHost
|
||||
var datetime = time.Now().UTC().Format("20060102T150405Z")
|
||||
if !strings.HasSuffix(apiPath, "/") {
|
||||
apiPath += "/"
|
||||
}
|
||||
canonicalRequest := method + "\n" + apiPath + "\n" + strings.Join(argStrings, "&") + "\ncontent-type:" + contentType + "\nhost:" + host + "\nx-sdk-date:" + datetime + "\n" + "\ncontent-type;host;x-sdk-date"
|
||||
var canonicalRequest = method + "\n" + apiPath + "\n" + strings.Join(argStrings, "&") + "\ncontent-type:" + contentType + "\nhost:" + host + "\nx-sdk-date:" + datetime + "\n" + "\ncontent-type;host;x-sdk-date"
|
||||
|
||||
h := sha256.New()
|
||||
var h = sha256.New()
|
||||
_, err = h.Write(bodyData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
canonicalRequest += "\n" + fmt.Sprintf("%x", h.Sum(nil))
|
||||
|
||||
h2 := sha256.New()
|
||||
var h2 = sha256.New()
|
||||
_, err = h2.Write([]byte(canonicalRequest))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
source := "SDK-HMAC-SHA256\n" + datetime + "\n" + fmt.Sprintf("%x", h2.Sum(nil))
|
||||
h3 := hmac.New(sha256.New, []byte(this.accessKeySecret))
|
||||
var source = "SDK-HMAC-SHA256\n" + datetime + "\n" + fmt.Sprintf("%x", h2.Sum(nil))
|
||||
var h3 = hmac.New(sha256.New, []byte(this.accessKeySecret))
|
||||
h3.Write([]byte(source))
|
||||
signString := fmt.Sprintf("%x", h3.Sum(nil))
|
||||
req.Header.Set("Host", host)
|
||||
|
||||
@@ -139,16 +139,20 @@ func testHuaweiDNSProvider() (ProviderInterface, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
one, err := db.FindOne("SELECT * FROM edgeDNSProviders WHERE type='huaweiDNS' ORDER BY id DESC")
|
||||
one, err := db.FindOne("SELECT * FROM edgeDNSProviders WHERE type='huaweiDNS' AND state=1 ORDER BY id DESC")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
apiParams := maps.Map{}
|
||||
var apiParams = maps.Map{}
|
||||
//apiParams["endpoint"] = ""
|
||||
//apiParams["endpoint"] = "cn-north-1"
|
||||
//apiParams["endpoint"] = "dns.cn-north-4.myhuaweicloud.com"
|
||||
//apiParams["endpoint"] = "https://dns.cn-south-1.myhuaweicloud.com/"
|
||||
err = json.Unmarshal([]byte(one.GetString("apiParams")), &apiParams)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
provider := &HuaweiDNSProvider{}
|
||||
var provider = &HuaweiDNSProvider{}
|
||||
err = provider.Auth(apiParams)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -125,14 +125,14 @@ func (this *BaseInstaller) LookupLatestInstaller(filePrefix string) (string, err
|
||||
return "", err
|
||||
}
|
||||
|
||||
lastVersion := ""
|
||||
result := ""
|
||||
var lastVersion = ""
|
||||
var result = ""
|
||||
for _, match := range matches {
|
||||
baseName := filepath.Base(match)
|
||||
var baseName = filepath.Base(match)
|
||||
if !pattern.MatchString(baseName) {
|
||||
continue
|
||||
}
|
||||
m := pattern.FindStringSubmatch(baseName)
|
||||
var m = pattern.FindStringSubmatch(baseName)
|
||||
if len(m) < 2 {
|
||||
continue
|
||||
}
|
||||
@@ -147,27 +147,10 @@ func (this *BaseInstaller) LookupLatestInstaller(filePrefix string) (string, err
|
||||
|
||||
// InstallHelper 上传安装助手
|
||||
func (this *BaseInstaller) InstallHelper(targetDir string, role nodeconfigs.NodeRole) (env *Env, err error) {
|
||||
var unameRetries = 3
|
||||
var uname string
|
||||
for i := 0; i < unameRetries; i++ {
|
||||
uname, _, err = this.client.Exec("/usr/bin/uname -a")
|
||||
if len(uname) == 0 {
|
||||
continue
|
||||
}
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return env, errors.New("unable to execute 'uname -a' on this system: " + err.Error())
|
||||
}
|
||||
var uname = this.uname()
|
||||
|
||||
if len(uname) == 0 {
|
||||
return nil, errors.New("unable to execute 'uname -a' on this system")
|
||||
}
|
||||
|
||||
osName := ""
|
||||
archName := ""
|
||||
var osName = ""
|
||||
var archName = ""
|
||||
if strings.Contains(uname, "Darwin") {
|
||||
osName = "darwin"
|
||||
} else if strings.Contains(uname, "Linux") {
|
||||
@@ -229,3 +212,18 @@ func (this *BaseInstaller) InstallHelper(targetDir string, role nodeconfigs.Node
|
||||
}
|
||||
return env, nil
|
||||
}
|
||||
|
||||
func (this *BaseInstaller) uname() (uname string) {
|
||||
var unameRetries = 3
|
||||
|
||||
for i := 0; i < unameRetries; i++ {
|
||||
for _, unameExe := range []string{"uname", "/bin/uname", "/usr/bin/uname"} {
|
||||
uname, _, _ = this.client.Exec(unameExe + " -a")
|
||||
if len(uname) > 0 {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return "x86_64 GNU/Linux"
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ package nodes
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/rpc/services"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/rpc/services/clients"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/rpc/services/users"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"google.golang.org/grpc"
|
||||
"reflect"
|
||||
@@ -197,11 +199,6 @@ func (this *APINode) registerServices(server *grpc.Server) {
|
||||
pb.RegisterMessageReceiverServiceServer(server, instance)
|
||||
this.rest(instance)
|
||||
}
|
||||
{
|
||||
var instance = this.serviceInstance(&services.MessageMediaService{}).(*services.MessageMediaService)
|
||||
pb.RegisterMessageMediaServiceServer(server, instance)
|
||||
this.rest(instance)
|
||||
}
|
||||
{
|
||||
var instance = this.serviceInstance(&services.MessageRecipientGroupService{}).(*services.MessageRecipientGroupService)
|
||||
pb.RegisterMessageRecipientGroupServiceServer(server, instance)
|
||||
@@ -343,7 +340,7 @@ func (this *APINode) registerServices(server *grpc.Server) {
|
||||
this.rest(instance)
|
||||
}
|
||||
{
|
||||
var instance = this.serviceInstance(&services.UserService{}).(*services.UserService)
|
||||
var instance = this.serviceInstance(&users.UserService{}).(*users.UserService)
|
||||
pb.RegisterUserServiceServer(server, instance)
|
||||
this.rest(instance)
|
||||
}
|
||||
@@ -408,15 +405,25 @@ func (this *APINode) registerServices(server *grpc.Server) {
|
||||
this.rest(instance)
|
||||
}
|
||||
{
|
||||
var instance = this.serviceInstance(&services.FormalClientSystemService{}).(*services.FormalClientSystemService)
|
||||
var instance = this.serviceInstance(&clients.FormalClientSystemService{}).(*clients.FormalClientSystemService)
|
||||
pb.RegisterFormalClientSystemServiceServer(server, instance)
|
||||
this.rest(instance)
|
||||
}
|
||||
{
|
||||
var instance = this.serviceInstance(&services.FormalClientBrowserService{}).(*services.FormalClientBrowserService)
|
||||
var instance = this.serviceInstance(&clients.FormalClientBrowserService{}).(*clients.FormalClientBrowserService)
|
||||
pb.RegisterFormalClientBrowserServiceServer(server, instance)
|
||||
this.rest(instance)
|
||||
}
|
||||
{
|
||||
var instance = this.serviceInstance(&clients.ClientAgentIPService{}).(*clients.ClientAgentIPService)
|
||||
pb.RegisterClientAgentIPServiceServer(server, instance)
|
||||
this.rest(instance)
|
||||
}
|
||||
{
|
||||
var instance = this.serviceInstance(&clients.ClientAgentService{}).(*clients.ClientAgentService)
|
||||
pb.RegisterClientAgentServiceServer(server, instance)
|
||||
this.rest(instance)
|
||||
}
|
||||
{
|
||||
var instance = this.serviceInstance(&services.ServerClientSystemMonthlyStatService{}).(*services.ServerClientSystemMonthlyStatService)
|
||||
pb.RegisterServerClientSystemMonthlyStatServiceServer(server, instance)
|
||||
|
||||
40
internal/rpc/services/clients/service_client_agent.go
Normal file
40
internal/rpc/services/clients/service_client_agent.go
Normal file
@@ -0,0 +1,40 @@
|
||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
|
||||
package clients
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models/clients"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/rpc/services"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
)
|
||||
|
||||
// ClientAgentService Agent服务
|
||||
type ClientAgentService struct {
|
||||
services.BaseService
|
||||
}
|
||||
|
||||
// FindAllClientAgents 查找所有Agent
|
||||
func (this *ClientAgentService) FindAllClientAgents(ctx context.Context, req *pb.FindAllClientAgentsRequest) (*pb.FindAllClientAgentsResponse, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
agents, err := clients.SharedClientAgentDAO.FindAllAgents(tx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var pbAgents = []*pb.ClientAgent{}
|
||||
for _, agent := range agents {
|
||||
pbAgents = append(pbAgents, &pb.ClientAgent{
|
||||
Id: int64(agent.Id),
|
||||
Name: agent.Name,
|
||||
Code: agent.Code,
|
||||
Description: agent.Description,
|
||||
CountIPs: int64(agent.CountIPs),
|
||||
})
|
||||
}
|
||||
return &pb.FindAllClientAgentsResponse{ClientAgents: pbAgents}, nil
|
||||
}
|
||||
97
internal/rpc/services/clients/service_client_agent_ip.go
Normal file
97
internal/rpc/services/clients/service_client_agent_ip.go
Normal file
@@ -0,0 +1,97 @@
|
||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
|
||||
package clients
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models/clients"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/rpc/services"
|
||||
rpcutils "github.com/TeaOSLab/EdgeAPI/internal/rpc/utils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
)
|
||||
|
||||
// ClientAgentIPService Agent IP服务
|
||||
type ClientAgentIPService struct {
|
||||
services.BaseService
|
||||
}
|
||||
|
||||
// CreateClientAgentIPs 创建一组IP
|
||||
func (this *ClientAgentIPService) CreateClientAgentIPs(ctx context.Context, req *pb.CreateClientAgentIPsRequest) (*pb.RPCSuccess, error) {
|
||||
_, _, err := this.ValidateNodeId(ctx, rpcutils.UserTypeAdmin, rpcutils.UserTypeDNS, rpcutils.UserTypeNode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(req.AgentIPs) == 0 {
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
for _, agentIP := range req.AgentIPs {
|
||||
agentId, err := clients.SharedClientAgentDAO.FindAgentIdWithCode(tx, agentIP.AgentCode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if agentId <= 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
err = clients.SharedClientAgentIPDAO.CreateIP(tx, agentId, agentIP.Ip, agentIP.Ptr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// ListClientAgentIPsAfterId 查询最新的IP
|
||||
func (this *ClientAgentIPService) ListClientAgentIPsAfterId(ctx context.Context, req *pb.ListClientAgentIPsAfterIdRequest) (*pb.ListClientAgentIPsAfterIdResponse, error) {
|
||||
_, _, err := this.ValidateNodeId(ctx, rpcutils.UserTypeAdmin, rpcutils.UserTypeDNS, rpcutils.UserTypeNode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if req.Size <= 0 {
|
||||
req.Size = 10000
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
var agentMap = map[int64]*clients.ClientAgent{} // agentId => agentCode
|
||||
agentIPs, err := clients.SharedClientAgentIPDAO.ListIPsAfterId(tx, req.Id, req.Size)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var pbIPs = []*pb.ClientAgentIP{}
|
||||
for _, agentIP := range agentIPs {
|
||||
var agentId = int64(agentIP.AgentId)
|
||||
agent, ok := agentMap[agentId]
|
||||
if !ok {
|
||||
agent, err = clients.SharedClientAgentDAO.FindAgent(tx, agentId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if agent == nil {
|
||||
continue
|
||||
}
|
||||
agentMap[agentId] = agent
|
||||
}
|
||||
|
||||
pbIPs = append(pbIPs, &pb.ClientAgentIP{
|
||||
Id: int64(agentIP.Id),
|
||||
Ip: agentIP.IP,
|
||||
Ptr: agentIP.Ptr, // 导出时需要
|
||||
ClientAgent: &pb.ClientAgent{
|
||||
Id: agentId,
|
||||
Name: "",
|
||||
Code: agent.Code,
|
||||
Description: "",
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
return &pb.ListClientAgentIPsAfterIdResponse{
|
||||
ClientAgentIPs: pbIPs,
|
||||
}, nil
|
||||
}
|
||||
@@ -1,18 +1,19 @@
|
||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
|
||||
package services
|
||||
package clients
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/rpc/services"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
)
|
||||
|
||||
// FormalClientBrowserService 浏览器信息库服务
|
||||
type FormalClientBrowserService struct {
|
||||
BaseService
|
||||
services.BaseService
|
||||
}
|
||||
|
||||
// CreateFormalClientBrowser 创建浏览器信息
|
||||
@@ -1,18 +1,19 @@
|
||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
|
||||
package services
|
||||
package clients
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/rpc/services"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
)
|
||||
|
||||
// FormalClientSystemService 操作系统信息库服务
|
||||
type FormalClientSystemService struct {
|
||||
BaseService
|
||||
services.BaseService
|
||||
}
|
||||
|
||||
// CreateFormalClientSystem 创建操作系统信息
|
||||
@@ -425,7 +425,7 @@ func (this *AdminService) DeleteAdmin(ctx context.Context, req *pb.DeleteAdminRe
|
||||
|
||||
// TODO 超级管理员用户是不能删除的,或者要至少留一个超级管理员用户
|
||||
|
||||
_, err = models.SharedAdminDAO.DisableAdmin(tx, req.AdminId)
|
||||
err = models.SharedAdminDAO.DisableAdmin(tx, req.AdminId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@ package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
)
|
||||
|
||||
@@ -14,49 +14,70 @@ type APIAccessTokenService struct {
|
||||
|
||||
// GetAPIAccessToken 获取AccessToken
|
||||
func (this *APIAccessTokenService) GetAPIAccessToken(ctx context.Context, req *pb.GetAPIAccessTokenRequest) (*pb.GetAPIAccessTokenResponse, error) {
|
||||
if req.Type == "user" || req.Type == "admin" { // 用户或管理员
|
||||
var tx = this.NullTx()
|
||||
|
||||
accessKey, err := models.SharedUserAccessKeyDAO.FindAccessKeyWithUniqueId(tx, req.AccessKeyId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if accessKey == nil {
|
||||
return nil, errors.New("access key not found")
|
||||
}
|
||||
if accessKey.Secret != req.AccessKey {
|
||||
return nil, errors.New("access key not found")
|
||||
}
|
||||
|
||||
// 检查数据
|
||||
switch req.Type {
|
||||
case "user":
|
||||
if accessKey.UserId == 0 {
|
||||
return nil, errors.New("access key not found")
|
||||
}
|
||||
case "admin":
|
||||
if accessKey.AdminId == 0 {
|
||||
return nil, errors.New("access key not found")
|
||||
}
|
||||
}
|
||||
|
||||
// 更新AccessKey访问时间
|
||||
err = models.SharedUserAccessKeyDAO.UpdateAccessKeyAccessedAt(tx, int64(accessKey.Id))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 创建AccessToken
|
||||
token, expiresAt, err := models.SharedAPIAccessTokenDAO.GenerateAccessToken(tx, int64(accessKey.AdminId), int64(accessKey.UserId))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pb.GetAPIAccessTokenResponse{
|
||||
Token: token,
|
||||
ExpiresAt: expiresAt,
|
||||
}, nil
|
||||
} else {
|
||||
if req.Type != "user" && req.Type != "admin" {
|
||||
return nil, errors.New("unsupported type '" + req.Type + "'")
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
accessKey, err := models.SharedUserAccessKeyDAO.FindAccessKeyWithUniqueId(tx, req.AccessKeyId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if accessKey == nil {
|
||||
return nil, errors.New("access key not found")
|
||||
}
|
||||
if accessKey.Secret != req.AccessKey {
|
||||
return nil, errors.New("access key not found")
|
||||
}
|
||||
|
||||
// 检查数据
|
||||
switch req.Type {
|
||||
case "user":
|
||||
// TODO 将来支持子用户
|
||||
if accessKey.UserId == 0 {
|
||||
return nil, errors.New("access key not found")
|
||||
}
|
||||
|
||||
// 检查用户状态
|
||||
user, err := models.SharedUserDAO.FindEnabledUser(tx, int64(accessKey.UserId), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if user == nil || !user.IsOn {
|
||||
return nil, errors.New("the user is not available")
|
||||
}
|
||||
case "admin":
|
||||
if accessKey.AdminId == 0 {
|
||||
return nil, errors.New("access key not found")
|
||||
}
|
||||
|
||||
// 检查管理员状态
|
||||
admin, err := models.SharedAdminDAO.FindEnabledAdmin(tx, int64(accessKey.AdminId))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if admin == nil || !admin.IsOn {
|
||||
return nil, errors.New("the admin is not available")
|
||||
}
|
||||
default:
|
||||
return nil, errors.New("invalid type '" + req.Type + "'")
|
||||
}
|
||||
|
||||
// 更新AccessKey访问时间
|
||||
err = models.SharedUserAccessKeyDAO.UpdateAccessKeyAccessedAt(tx, int64(accessKey.Id))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 创建AccessToken
|
||||
token, expiresAt, err := models.SharedAPIAccessTokenDAO.GenerateAccessToken(tx, int64(accessKey.AdminId), int64(accessKey.UserId))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pb.GetAPIAccessTokenResponse{
|
||||
Token: token,
|
||||
ExpiresAt: expiresAt,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -4,7 +4,9 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
|
||||
)
|
||||
|
||||
type HTTPHeaderPolicyService struct {
|
||||
@@ -13,16 +15,22 @@ type HTTPHeaderPolicyService struct {
|
||||
|
||||
// FindEnabledHTTPHeaderPolicyConfig 查找策略配置
|
||||
func (this *HTTPHeaderPolicyService) FindEnabledHTTPHeaderPolicyConfig(ctx context.Context, req *pb.FindEnabledHTTPHeaderPolicyConfigRequest) (*pb.FindEnabledHTTPHeaderPolicyConfigResponse, error) {
|
||||
_, _, err := this.ValidateAdminAndUser(ctx, true)
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
// TODO 检查权限
|
||||
// 检查权限
|
||||
if userId > 0 {
|
||||
err = models.SharedHTTPHeaderPolicyDAO.CheckUserHeaderPolicy(tx, userId, req.HttpHeaderPolicyId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
config, err := models.SharedHTTPHeaderPolicyDAO.ComposeHeaderPolicyConfig(tx, req.HeaderPolicyId)
|
||||
config, err := models.SharedHTTPHeaderPolicyDAO.ComposeHeaderPolicyConfig(tx, req.HttpHeaderPolicyId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -32,7 +40,7 @@ func (this *HTTPHeaderPolicyService) FindEnabledHTTPHeaderPolicyConfig(ctx conte
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pb.FindEnabledHTTPHeaderPolicyConfigResponse{HeaderPolicyJSON: configData}, nil
|
||||
return &pb.FindEnabledHTTPHeaderPolicyConfigResponse{HttpHeaderPolicyJSON: configData}, nil
|
||||
}
|
||||
|
||||
// CreateHTTPHeaderPolicy 创建策略
|
||||
@@ -44,28 +52,32 @@ func (this *HTTPHeaderPolicyService) CreateHTTPHeaderPolicy(ctx context.Context,
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
// TODO 检查权限
|
||||
|
||||
headerPolicyId, err := models.SharedHTTPHeaderPolicyDAO.CreateHeaderPolicy(tx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pb.CreateHTTPHeaderPolicyResponse{HeaderPolicyId: headerPolicyId}, nil
|
||||
return &pb.CreateHTTPHeaderPolicyResponse{HttpHeaderPolicyId: headerPolicyId}, nil
|
||||
}
|
||||
|
||||
// UpdateHTTPHeaderPolicyAddingHeaders 修改AddHeaders
|
||||
func (this *HTTPHeaderPolicyService) UpdateHTTPHeaderPolicyAddingHeaders(ctx context.Context, req *pb.UpdateHTTPHeaderPolicyAddingHeadersRequest) (*pb.RPCSuccess, error) {
|
||||
_, _, err := this.ValidateAdminAndUser(ctx, true)
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
// TODO 检查权限
|
||||
// 检查权限
|
||||
if userId > 0 {
|
||||
err = models.SharedHTTPHeaderPolicyDAO.CheckUserHeaderPolicy(tx, userId, req.HttpHeaderPolicyId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
err = models.SharedHTTPHeaderPolicyDAO.UpdateAddingHeaders(tx, req.HeaderPolicyId, req.HeadersJSON)
|
||||
err = models.SharedHTTPHeaderPolicyDAO.UpdateAddingHeaders(tx, req.HttpHeaderPolicyId, req.HeadersJSON)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -75,16 +87,22 @@ func (this *HTTPHeaderPolicyService) UpdateHTTPHeaderPolicyAddingHeaders(ctx con
|
||||
|
||||
// UpdateHTTPHeaderPolicySettingHeaders 修改SetHeaders
|
||||
func (this *HTTPHeaderPolicyService) UpdateHTTPHeaderPolicySettingHeaders(ctx context.Context, req *pb.UpdateHTTPHeaderPolicySettingHeadersRequest) (*pb.RPCSuccess, error) {
|
||||
_, _, err := this.ValidateAdminAndUser(ctx, true)
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
// TODO 检查权限
|
||||
// 检查权限
|
||||
if userId > 0 {
|
||||
err = models.SharedHTTPHeaderPolicyDAO.CheckUserHeaderPolicy(tx, userId, req.HttpHeaderPolicyId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
err = models.SharedHTTPHeaderPolicyDAO.UpdateSettingHeaders(tx, req.HeaderPolicyId, req.HeadersJSON)
|
||||
err = models.SharedHTTPHeaderPolicyDAO.UpdateSettingHeaders(tx, req.HttpHeaderPolicyId, req.HeadersJSON)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -94,16 +112,22 @@ func (this *HTTPHeaderPolicyService) UpdateHTTPHeaderPolicySettingHeaders(ctx co
|
||||
|
||||
// UpdateHTTPHeaderPolicyAddingTrailers 修改AddTrailers
|
||||
func (this *HTTPHeaderPolicyService) UpdateHTTPHeaderPolicyAddingTrailers(ctx context.Context, req *pb.UpdateHTTPHeaderPolicyAddingTrailersRequest) (*pb.RPCSuccess, error) {
|
||||
_, _, err := this.ValidateAdminAndUser(ctx, true)
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
// TODO 检查权限
|
||||
// 检查权限
|
||||
if userId > 0 {
|
||||
err = models.SharedHTTPHeaderPolicyDAO.CheckUserHeaderPolicy(tx, userId, req.HttpHeaderPolicyId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
err = models.SharedHTTPHeaderPolicyDAO.UpdateAddingTrailers(tx, req.HeaderPolicyId, req.HeadersJSON)
|
||||
err = models.SharedHTTPHeaderPolicyDAO.UpdateAddingTrailers(tx, req.HttpHeaderPolicyId, req.HeadersJSON)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -113,16 +137,22 @@ func (this *HTTPHeaderPolicyService) UpdateHTTPHeaderPolicyAddingTrailers(ctx co
|
||||
|
||||
// UpdateHTTPHeaderPolicyReplacingHeaders 修改ReplaceHeaders
|
||||
func (this *HTTPHeaderPolicyService) UpdateHTTPHeaderPolicyReplacingHeaders(ctx context.Context, req *pb.UpdateHTTPHeaderPolicyReplacingHeadersRequest) (*pb.RPCSuccess, error) {
|
||||
_, _, err := this.ValidateAdminAndUser(ctx, true)
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
// TODO 检查权限
|
||||
// 检查权限
|
||||
if userId > 0 {
|
||||
err = models.SharedHTTPHeaderPolicyDAO.CheckUserHeaderPolicy(tx, userId, req.HttpHeaderPolicyId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
err = models.SharedHTTPHeaderPolicyDAO.UpdateReplacingHeaders(tx, req.HeaderPolicyId, req.HeadersJSON)
|
||||
err = models.SharedHTTPHeaderPolicyDAO.UpdateReplacingHeaders(tx, req.HttpHeaderPolicyId, req.HeadersJSON)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -132,16 +162,57 @@ func (this *HTTPHeaderPolicyService) UpdateHTTPHeaderPolicyReplacingHeaders(ctx
|
||||
|
||||
// UpdateHTTPHeaderPolicyDeletingHeaders 修改删除的Headers
|
||||
func (this *HTTPHeaderPolicyService) UpdateHTTPHeaderPolicyDeletingHeaders(ctx context.Context, req *pb.UpdateHTTPHeaderPolicyDeletingHeadersRequest) (*pb.RPCSuccess, error) {
|
||||
_, _, err := this.ValidateAdminAndUser(ctx, true)
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
// TODO 检查权限
|
||||
// 检查权限
|
||||
if userId > 0 {
|
||||
err = models.SharedHTTPHeaderPolicyDAO.CheckUserHeaderPolicy(tx, userId, req.HttpHeaderPolicyId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
err = models.SharedHTTPHeaderPolicyDAO.UpdateDeletingHeaders(tx, req.HeaderPolicyId, req.HeaderNames)
|
||||
err = models.SharedHTTPHeaderPolicyDAO.UpdateDeletingHeaders(tx, req.HttpHeaderPolicyId, req.HeaderNames)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// UpdateHTTPHeaderPolicyCORS 修改策略CORS设置
|
||||
func (this *HTTPHeaderPolicyService) UpdateHTTPHeaderPolicyCORS(ctx context.Context, req *pb.UpdateHTTPHeaderPolicyCORSRequest) (*pb.RPCSuccess, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
// 检查权限
|
||||
if userId > 0 {
|
||||
err = models.SharedHTTPHeaderPolicyDAO.CheckUserHeaderPolicy(tx, userId, req.HttpHeaderPolicyId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
var corsConfig = &shared.HTTPCORSHeaderConfig{}
|
||||
err = json.Unmarshal(req.CorsJSON, corsConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = corsConfig.Init()
|
||||
if err != nil {
|
||||
return nil, errors.New("validate CORS config failed: " + err.Error())
|
||||
}
|
||||
|
||||
err = models.SharedHTTPHeaderPolicyDAO.UpdateHeaderPolicyCORS(tx, req.HttpHeaderPolicyId, corsConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -822,3 +822,71 @@ func (this *HTTPWebService) FindHTTPWebReferers(ctx context.Context, req *pb.Fin
|
||||
ReferersJSON: configJSON,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// UpdateHTTPWebUserAgent 修改UserAgent设置
|
||||
func (this *HTTPWebService) UpdateHTTPWebUserAgent(ctx context.Context, req *pb.UpdateHTTPWebUserAgentRequest) (*pb.RPCSuccess, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
if userId > 0 {
|
||||
err = models.SharedHTTPWebDAO.CheckUserWeb(tx, userId, req.HttpWebId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
var config = &serverconfigs.UserAgentConfig{}
|
||||
if len(req.UserAgentJSON) > 0 {
|
||||
err = json.Unmarshal(req.UserAgentJSON, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = config.Init()
|
||||
if err != nil {
|
||||
return nil, errors.New("validate user-agent config failed: " + err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
err = models.SharedHTTPWebDAO.UpdateWebUserAgent(tx, req.HttpWebId, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// FindHTTPWebUserAgent 查找UserAgent设置
|
||||
func (this *HTTPWebService) FindHTTPWebUserAgent(ctx context.Context, req *pb.FindHTTPWebUserAgentRequest) (*pb.FindHTTPWebUserAgentResponse, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
if userId > 0 {
|
||||
err = models.SharedHTTPWebDAO.CheckUserWeb(tx, userId, req.HttpWebId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
config, err := models.SharedHTTPWebDAO.FindWebUserAgent(tx, req.HttpWebId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
configJSON, err := json.Marshal(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pb.FindHTTPWebUserAgentResponse{
|
||||
UserAgentJSON: configJSON,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
)
|
||||
|
||||
// MessageMediaService 消息媒介服务
|
||||
type MessageMediaService struct {
|
||||
BaseService
|
||||
}
|
||||
|
||||
// FindAllMessageMedias 获取所有支持的媒介
|
||||
func (this *MessageMediaService) FindAllMessageMedias(ctx context.Context, req *pb.FindAllMessageMediasRequest) (*pb.FindAllMessageMediasResponse, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var tx = this.NullTx()
|
||||
medias, err := models.SharedMessageMediaDAO.FindAllEnabledMessageMedias(tx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pbMedias := []*pb.MessageMedia{}
|
||||
for _, media := range medias {
|
||||
pbMedias = append(pbMedias, &pb.MessageMedia{
|
||||
Id: int64(media.Id),
|
||||
Type: media.Type,
|
||||
Name: media.Name,
|
||||
Description: media.Description,
|
||||
UserDescription: media.UserDescription,
|
||||
IsOn: media.IsOn,
|
||||
})
|
||||
}
|
||||
return &pb.FindAllMessageMediasResponse{MessageMedias: pbMedias}, nil
|
||||
}
|
||||
|
||||
// UpdateMessageMedias 设置所有支持的媒介
|
||||
func (this *MessageMediaService) UpdateMessageMedias(ctx context.Context, req *pb.UpdateMessageMediasRequest) (*pb.RPCSuccess, error) {
|
||||
_, err := this.ValidateMonitorNode(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
mediaMaps := []maps.Map{}
|
||||
for _, media := range req.MessageMedias {
|
||||
mediaMaps = append(mediaMaps, maps.Map{
|
||||
"name": media.Name,
|
||||
"type": media.Type,
|
||||
"description": media.Description,
|
||||
"userDescription": media.UserDescription,
|
||||
"isOn": media.IsOn,
|
||||
})
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
err = models.SharedMessageMediaDAO.UpdateMessageMedias(tx, mediaMaps)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return this.Success()
|
||||
}
|
||||
@@ -6,11 +6,13 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models/clients"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models/dns"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models/regions"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
"github.com/iwind/TeaGo/lists"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
@@ -769,7 +771,9 @@ func (this *ServerService) ListEnabledServersMatch(ctx context.Context, req *pb.
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
var fromUser = false
|
||||
if userId > 0 {
|
||||
fromUser = true
|
||||
req.UserId = userId
|
||||
}
|
||||
|
||||
@@ -816,15 +820,17 @@ func (this *ServerService) ListEnabledServersMatch(ctx context.Context, req *pb.
|
||||
}
|
||||
|
||||
// 用户
|
||||
user, err := models.SharedUserDAO.FindEnabledBasicUser(tx, int64(server.UserId))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var pbUser *pb.User = nil
|
||||
if user != nil {
|
||||
pbUser = &pb.User{
|
||||
Id: int64(user.Id),
|
||||
Fullname: user.Fullname,
|
||||
if !fromUser {
|
||||
user, err := models.SharedUserDAO.FindEnabledBasicUser(tx, int64(server.UserId))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if user != nil {
|
||||
pbUser = &pb.User{
|
||||
Id: int64(user.Id),
|
||||
Fullname: user.Fullname,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -840,7 +846,7 @@ func (this *ServerService) ListEnabledServersMatch(ctx context.Context, req *pb.
|
||||
}
|
||||
|
||||
// 配置
|
||||
config, err := models.SharedServerDAO.ComposeServerConfig(tx, server, nil, false, true)
|
||||
config, err := models.SharedServerDAO.ComposeServerConfig(tx, server, req.IgnoreSSLCerts, nil, false, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -963,9 +969,9 @@ func (this *ServerService) FindEnabledServer(ctx context.Context, req *pb.FindEn
|
||||
}
|
||||
|
||||
// 分组信息
|
||||
pbGroups := []*pb.ServerGroup{}
|
||||
var pbGroups = []*pb.ServerGroup{}
|
||||
if len(server.GroupIds) > 0 {
|
||||
groupIds := []int64{}
|
||||
var groupIds = []int64{}
|
||||
err = json.Unmarshal(server.GroupIds, &groupIds)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -1003,7 +1009,7 @@ func (this *ServerService) FindEnabledServer(ctx context.Context, req *pb.FindEn
|
||||
}
|
||||
|
||||
// 配置
|
||||
config, err := models.SharedServerDAO.ComposeServerConfig(tx, server, nil, userId > 0, false)
|
||||
config, err := models.SharedServerDAO.ComposeServerConfig(tx, server, req.IgnoreSSLCerts, nil, userId > 0, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1063,7 +1069,7 @@ func (this *ServerService) FindEnabledServerConfig(ctx context.Context, req *pb.
|
||||
}
|
||||
}
|
||||
|
||||
config, err := models.SharedServerDAO.ComposeServerConfigWithServerId(tx, req.ServerId, false)
|
||||
config, err := models.SharedServerDAO.ComposeServerConfigWithServerId(tx, req.ServerId, false, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1514,7 +1520,7 @@ func (this *ServerService) ComposeAllUserServersConfig(ctx context.Context, req
|
||||
var configs = []*serverconfigs.ServerConfig{}
|
||||
var cacheMap = utils.NewCacheMap()
|
||||
for _, server := range servers {
|
||||
config, err := models.SharedServerDAO.ComposeServerConfig(tx, server, cacheMap, true, false)
|
||||
config, err := models.SharedServerDAO.ComposeServerConfig(tx, server, false, cacheMap, true, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1714,7 +1720,7 @@ func (this *ServerService) UploadServerHTTPRequestStat(ctx context.Context, req
|
||||
return err
|
||||
}
|
||||
if systemId == 0 {
|
||||
err = models.SharedClientSystemDAO.CreateSystemIfNotExists(tx, result.Name)
|
||||
err = clients.SharedClientSystemDAO.CreateSystemIfNotExists(tx, result.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1745,7 +1751,7 @@ func (this *ServerService) UploadServerHTTPRequestStat(ctx context.Context, req
|
||||
return err
|
||||
}
|
||||
if browserId == 0 {
|
||||
err = models.SharedClientBrowserDAO.CreateBrowserIfNotExists(tx, result.Name)
|
||||
err = clients.SharedClientBrowserDAO.CreateBrowserIfNotExists(tx, result.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -2221,7 +2227,7 @@ func (this *ServerService) ComposeServerConfig(ctx context.Context, req *pb.Comp
|
||||
return &pb.ComposeServerConfigResponse{ServerConfigJSON: nil}, nil
|
||||
}
|
||||
|
||||
serverConfig, err := models.SharedServerDAO.ComposeServerConfigWithServerId(tx, req.ServerId, true)
|
||||
serverConfig, err := models.SharedServerDAO.ComposeServerConfigWithServerId(tx, req.ServerId, false, true)
|
||||
if err != nil {
|
||||
if err == models.ErrNotFound {
|
||||
return &pb.ComposeServerConfigResponse{ServerConfigJSON: nil}, nil
|
||||
@@ -2238,3 +2244,28 @@ func (this *ServerService) ComposeServerConfig(ctx context.Context, req *pb.Comp
|
||||
}
|
||||
return &pb.ComposeServerConfigResponse{ServerConfigJSON: configJSON}, nil
|
||||
}
|
||||
|
||||
// UpdateServerUser 修改服务所属用户
|
||||
func (this *ServerService) UpdateServerUser(ctx context.Context, req *pb.UpdateServerUserRequest) (*pb.RPCSuccess, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if req.ServerId <= 0 {
|
||||
return nil, errors.New("invalid serverId")
|
||||
}
|
||||
|
||||
if req.UserId <= 0 {
|
||||
return nil, errors.New("invalid userId")
|
||||
}
|
||||
|
||||
err = this.RunTx(func(tx *dbs.Tx) error {
|
||||
return models.SharedServerDAO.UpdateServerUserId(tx, req.ServerId, req.UserId)
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ func (this *SSLCertService) FindEnabledSSLCertConfig(ctx context.Context, req *p
|
||||
}
|
||||
}
|
||||
|
||||
config, err := models.SharedSSLCertDAO.ComposeCertConfig(tx, req.SslCertId, nil)
|
||||
config, err := models.SharedSSLCertDAO.ComposeCertConfig(tx, req.SslCertId, false, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -179,7 +179,7 @@ func (this *SSLCertService) ListSSLCerts(ctx context.Context, req *pb.ListSSLCer
|
||||
|
||||
certConfigs := []*sslconfigs.SSLCertConfig{}
|
||||
for _, certId := range certIds {
|
||||
certConfig, err := models.SharedSSLCertDAO.ComposeCertConfig(tx, certId, nil)
|
||||
certConfig, err := models.SharedSSLCertDAO.ComposeCertConfig(tx, certId, false, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ func (this *SSLPolicyService) FindEnabledSSLPolicyConfig(ctx context.Context, re
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
config, err := models.SharedSSLPolicyDAO.ComposePolicyConfig(tx, req.SslPolicyId, nil)
|
||||
config, err := models.SharedSSLPolicyDAO.ComposePolicyConfig(tx, req.SslPolicyId, req.IgnoreData, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
//go:build !plus
|
||||
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
)
|
||||
|
||||
// FindUserPriceInfo 读取用户计费信息
|
||||
func (this *UserService) FindUserPriceInfo(ctx context.Context, req *pb.FindUserPriceInfoRequest) (*pb.FindUserPriceInfoResponse, error) {
|
||||
return nil, this.NotImplementedYet()
|
||||
}
|
||||
|
||||
// UpdateUserPriceType 修改用户计费方式
|
||||
func (this *UserService) UpdateUserPriceType(ctx context.Context, req *pb.UpdateUserPriceTypeRequest) (*pb.RPCSuccess, error) {
|
||||
return nil, this.NotImplementedYet()
|
||||
}
|
||||
|
||||
// UpdateUserPricePeriod 修改用户计费周期
|
||||
func (this *UserService) UpdateUserPricePeriod(ctx context.Context, req *pb.UpdateUserPricePeriodRequest) (*pb.RPCSuccess, error) {
|
||||
return nil, this.NotImplementedYet()
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package services
|
||||
package users
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
teaconst "github.com/TeaOSLab/EdgeAPI/internal/const"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/rpc/services"
|
||||
rpcutils "github.com/TeaOSLab/EdgeAPI/internal/rpc/utils"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
|
||||
@@ -13,15 +14,15 @@ import (
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/systemconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/userconfigs"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
timeutil "github.com/iwind/TeaGo/utils/time"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// UserService 用户相关服务
|
||||
type UserService struct {
|
||||
BaseService
|
||||
services.BaseService
|
||||
}
|
||||
|
||||
// CreateUser 创建用户
|
||||
@@ -40,59 +41,6 @@ func (this *UserService) CreateUser(ctx context.Context, req *pb.CreateUserReque
|
||||
return &pb.CreateUserResponse{UserId: userId}, nil
|
||||
}
|
||||
|
||||
// RegisterUser 注册用户
|
||||
func (this *UserService) RegisterUser(ctx context.Context, req *pb.RegisterUserRequest) (*pb.RPCSuccess, error) {
|
||||
userId, err := this.ValidateUserNode(ctx, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if userId > 0 {
|
||||
return nil, this.PermissionError()
|
||||
}
|
||||
|
||||
// 注册配置
|
||||
configJSON, err := models.SharedSysSettingDAO.ReadSetting(nil, systemconfigs.SettingCodeUserRegisterConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(configJSON) == 0 {
|
||||
return nil, errors.New("the registration has been disabled")
|
||||
}
|
||||
var config = userconfigs.DefaultUserRegisterConfig()
|
||||
err = json.Unmarshal(configJSON, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !config.IsOn {
|
||||
return nil, errors.New("the registration has been disabled")
|
||||
}
|
||||
|
||||
err = this.RunTx(func(tx *dbs.Tx) error {
|
||||
// 检查用户名
|
||||
exists, err := models.SharedUserDAO.ExistUser(tx, 0, req.Username)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if exists {
|
||||
return errors.New("the username exists already")
|
||||
}
|
||||
|
||||
// 创建用户
|
||||
_, err = models.SharedUserDAO.CreateUser(tx, req.Username, req.Password, req.Fullname, req.Mobile, "", req.Email, "", req.Source, config.ClusterId, config.Features, req.Ip, !config.RequireVerification)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// VerifyUser 审核用户
|
||||
func (this *UserService) VerifyUser(ctx context.Context, req *pb.VerifyUserRequest) (*pb.RPCSuccess, error) {
|
||||
_, err := this.ValidateAdmin(ctx)
|
||||
@@ -300,6 +248,7 @@ func (this *UserService) FindEnabledUser(ctx context.Context, req *pb.FindEnable
|
||||
Mobile: user.Mobile,
|
||||
Tel: user.Tel,
|
||||
Email: user.Email,
|
||||
VerifiedEmail: user.VerifiedEmail,
|
||||
Remark: user.Remark,
|
||||
IsOn: user.IsOn,
|
||||
CreatedAt: int64(user.CreatedAt),
|
||||
@@ -360,6 +309,28 @@ func (this *UserService) LoginUser(ctx context.Context, req *pb.LoginUserRequest
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
// 邮箱登录
|
||||
if strings.Contains(req.Username, "@") {
|
||||
// 是否允许
|
||||
registerConfig, err := models.SharedSysSettingDAO.ReadUserRegisterConfig(tx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if registerConfig != nil && registerConfig.EmailVerification.CanLogin {
|
||||
userId, err := models.SharedUserDAO.CheckUserEmailPassword(tx, req.Username, req.Password)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if userId > 0 {
|
||||
return &pb.LoginUserResponse{
|
||||
UserId: userId,
|
||||
IsOk: true,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 用户名登录
|
||||
userId, err := models.SharedUserDAO.CheckUserPassword(tx, req.Username, req.Password)
|
||||
if err != nil {
|
||||
utils.PrintError(err)
|
||||
@@ -474,10 +445,13 @@ func (this *UserService) ComposeUserDashboard(ctx context.Context, req *pb.Compo
|
||||
}
|
||||
|
||||
// 今日总流量
|
||||
dailyTrafficBytes, err := models.SharedServerDailyStatDAO.SumUserDaily(tx, req.UserId, 0, currentDay)
|
||||
dailyTrafficStat, err := models.SharedServerDailyStatDAO.SumUserDaily(tx, req.UserId, 0, currentDay)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if dailyTrafficStat == nil {
|
||||
dailyTrafficStat = &models.ServerDailyStat{}
|
||||
}
|
||||
|
||||
// 近 30 日流量带宽趋势
|
||||
var dailyTrafficStats = []*pb.ComposeUserDashboardResponse_DailyTrafficStat{}
|
||||
@@ -495,10 +469,13 @@ func (this *UserService) ComposeUserDashboard(ctx context.Context, req *pb.Compo
|
||||
}
|
||||
|
||||
// 流量
|
||||
trafficBytes, err := models.SharedServerDailyStatDAO.SumUserDaily(tx, req.UserId, 0, day)
|
||||
trafficStat, err := models.SharedServerDailyStatDAO.SumUserDaily(tx, req.UserId, 0, day)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if trafficStat == nil {
|
||||
trafficStat = &models.ServerDailyStat{}
|
||||
}
|
||||
|
||||
// 峰值带宽
|
||||
peekBandwidthBytesStat, err := models.SharedUserBandwidthStatDAO.FindUserPeekBandwidthInDay(tx, req.UserId, day)
|
||||
@@ -510,14 +487,22 @@ func (this *UserService) ComposeUserDashboard(ctx context.Context, req *pb.Compo
|
||||
peekBandwidthBytes = int64(peekBandwidthBytesStat.Bytes)
|
||||
}
|
||||
|
||||
dailyTrafficStats = append(dailyTrafficStats, &pb.ComposeUserDashboardResponse_DailyTrafficStat{Day: day, Bytes: trafficBytes})
|
||||
dailyTrafficStats = append(dailyTrafficStats, &pb.ComposeUserDashboardResponse_DailyTrafficStat{
|
||||
Day: day,
|
||||
Bytes: int64(trafficStat.Bytes),
|
||||
CachedBytes: int64(trafficStat.CachedBytes),
|
||||
AttackBytes: int64(trafficStat.AttackBytes),
|
||||
CountRequests: int64(trafficStat.CountRequests),
|
||||
CountCachedRequests: int64(trafficStat.CountCachedRequests),
|
||||
CountAttackRequests: int64(trafficStat.CountAttackRequests),
|
||||
})
|
||||
dailyPeekBandwidthStats = append(dailyPeekBandwidthStats, &pb.ComposeUserDashboardResponse_DailyPeekBandwidthStat{Day: day, Bytes: peekBandwidthBytes})
|
||||
}
|
||||
var result = &pb.ComposeUserDashboardResponse{
|
||||
CountServers: countServers,
|
||||
MonthlyTrafficBytes: monthlyTrafficBytes,
|
||||
MonthlyPeekBandwidthBytes: monthlyPeekBandwidthBytes,
|
||||
DailyTrafficBytes: dailyTrafficBytes,
|
||||
DailyTrafficBytes: int64(dailyTrafficStat.Bytes),
|
||||
DailyPeekBandwidthBytes: dailyPeekBandwidthBytes,
|
||||
DailyTrafficStats: dailyTrafficStats,
|
||||
DailyPeekBandwidthStats: dailyPeekBandwidthStats,
|
||||
@@ -825,3 +810,53 @@ func (this *UserService) RenewUserServersState(ctx context.Context, req *pb.Rene
|
||||
IsEnabled: isEnabled,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// CheckUserEmail 检查邮箱是否被使用
|
||||
func (this *UserService) CheckUserEmail(ctx context.Context, req *pb.CheckUserEmailRequest) (*pb.CheckUserEmailResponse, error) {
|
||||
userId, err := this.ValidateUserNode(ctx, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(req.Email) == 0 {
|
||||
return nil, errors.New("'email' required")
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
emailOwnerUserId, err := models.SharedUserDAO.FindUserIdWithVerifiedEmail(tx, req.Email)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if emailOwnerUserId > 0 && userId != emailOwnerUserId {
|
||||
return &pb.CheckUserEmailResponse{Exists: true}, nil
|
||||
}
|
||||
return &pb.CheckUserEmailResponse{Exists: false}, nil
|
||||
}
|
||||
|
||||
// FindUserVerifiedEmailWithUsername 根据用户名查询用户绑定的邮箱
|
||||
func (this *UserService) FindUserVerifiedEmailWithUsername(ctx context.Context, req *pb.FindUserVerifiedEmailWithUsernameRequest) (*pb.FindUserVerifiedEmailWithUsernameResponse, error) {
|
||||
_, err := this.ValidateUserNode(ctx, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
userId, err := models.SharedUserDAO.FindEnabledUserIdWithUsername(tx, req.Username)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if userId <= 0 {
|
||||
return &pb.FindUserVerifiedEmailWithUsernameResponse{
|
||||
Email: "",
|
||||
}, nil
|
||||
}
|
||||
|
||||
email, err := models.SharedUserDAO.FindUserVerifiedEmail(tx, userId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pb.FindUserVerifiedEmailWithUsernameResponse{
|
||||
Email: email,
|
||||
}, nil
|
||||
}
|
||||
91
internal/rpc/services/users/service_user_ext.go
Normal file
91
internal/rpc/services/users/service_user_ext.go
Normal file
@@ -0,0 +1,91 @@
|
||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
//go:build !plus
|
||||
|
||||
package users
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
)
|
||||
|
||||
// FindUserPriceInfo 读取用户计费信息
|
||||
func (this *UserService) FindUserPriceInfo(ctx context.Context, req *pb.FindUserPriceInfoRequest) (*pb.FindUserPriceInfoResponse, error) {
|
||||
return nil, this.NotImplementedYet()
|
||||
}
|
||||
|
||||
// UpdateUserPriceType 修改用户计费方式
|
||||
func (this *UserService) UpdateUserPriceType(ctx context.Context, req *pb.UpdateUserPriceTypeRequest) (*pb.RPCSuccess, error) {
|
||||
return nil, this.NotImplementedYet()
|
||||
}
|
||||
|
||||
// UpdateUserPricePeriod 修改用户计费周期
|
||||
func (this *UserService) UpdateUserPricePeriod(ctx context.Context, req *pb.UpdateUserPricePeriodRequest) (*pb.RPCSuccess, error) {
|
||||
return nil, this.NotImplementedYet()
|
||||
}
|
||||
|
||||
// RegisterUser 注册用户
|
||||
func (this *UserService) RegisterUser(ctx context.Context, req *pb.RegisterUserRequest) (*pb.RegisterUserResponse, error) {
|
||||
currentUserId, err := this.ValidateUserNode(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if currentUserId > 0 {
|
||||
return nil, this.PermissionError()
|
||||
}
|
||||
|
||||
var tx = this.NullTx()
|
||||
|
||||
// 检查邮箱是否已被使用
|
||||
if len(req.Email) > 0 {
|
||||
emailUserId, err := models.SharedUserDAO.FindUserIdWithVerifiedEmail(tx, req.Email)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if emailUserId > 0 {
|
||||
return nil, errors.New("the email address '" + req.Email + "' is using by other user")
|
||||
}
|
||||
}
|
||||
|
||||
// 注册配置
|
||||
registerConfig, err := models.SharedSysSettingDAO.ReadUserRegisterConfig(tx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if registerConfig == nil || !registerConfig.IsOn {
|
||||
return nil, errors.New("the registration has been disabled")
|
||||
}
|
||||
|
||||
var requireEmailVerification = false
|
||||
var createdUserId int64
|
||||
err = this.RunTx(func(tx *dbs.Tx) error {
|
||||
// 检查用户名
|
||||
exists, err := models.SharedUserDAO.ExistUser(tx, 0, req.Username)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if exists {
|
||||
return errors.New("the username exists already")
|
||||
}
|
||||
|
||||
// 创建用户
|
||||
userId, err := models.SharedUserDAO.CreateUser(tx, req.Username, req.Password, req.Fullname, req.Mobile, "", req.Email, "", req.Source, registerConfig.ClusterId, registerConfig.Features, req.Ip, !registerConfig.RequireVerification)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
createdUserId = userId
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &pb.RegisterUserResponse{
|
||||
UserId: createdUserId,
|
||||
RequireEmailVerification: requireEmailVerification,
|
||||
}, nil
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -49,6 +49,15 @@ var recordsTables = []*SQLRecordsTable{
|
||||
TableName: "edgeFormalClientBrowsers",
|
||||
UniqueFields: []string{"dataId"},
|
||||
},
|
||||
{
|
||||
TableName: "edgeClientAgents",
|
||||
UniqueFields: []string{"code"},
|
||||
ExceptFields: []string{"countIPs"},
|
||||
},
|
||||
{
|
||||
TableName: "edgeClientAgentIPs",
|
||||
UniqueFields: []string{"agentId", "ip"},
|
||||
},
|
||||
}
|
||||
|
||||
type sqlItem struct {
|
||||
@@ -426,7 +435,7 @@ func (this *SQLDump) applyQueue(db *dbs.DB, newResult *SQLDumpResult, showLog bo
|
||||
continue
|
||||
}
|
||||
|
||||
args = append(args, k+"=?")
|
||||
args = append(args, "`"+k+"`"+"=?")
|
||||
values = append(values, v)
|
||||
}
|
||||
values = append(values, one.GetInt("id"))
|
||||
|
||||
@@ -124,6 +124,12 @@ func (this *SQLExecutor) checkData(db *dbs.DB) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// 更新Agents
|
||||
err = this.checkClientAgents(db)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 更新版本号
|
||||
err = this.updateVersion(db, ComposeSQLVersion())
|
||||
if err != nil {
|
||||
@@ -471,6 +477,29 @@ func (this *SQLExecutor) checkMetricItems(db *dbs.DB) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 更新Agents表
|
||||
func (this *SQLExecutor) checkClientAgents(db *dbs.DB) error {
|
||||
ones, _, err := db.FindOnes("SELECT id FROM edgeClientAgents")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, one := range ones {
|
||||
var agentId = one.GetInt64("id")
|
||||
|
||||
countIPs, err := db.FindCol(0, "SELECT COUNT(*) FROM edgeClientAgentIPs WHERE agentId=?", agentId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = db.Exec("UPDATE edgeClientAgents SET countIPs=? WHERE id=?", countIPs, agentId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// 更新版本号
|
||||
func (this *SQLExecutor) updateVersion(db *dbs.DB, version string) error {
|
||||
stmt, err := db.Prepare("SELECT COUNT(*) FROM edgeVersions")
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
)
|
||||
|
||||
func TestSQLExecutor_Run(t *testing.T) {
|
||||
executor := NewSQLExecutor(&dbs.DBConfig{
|
||||
var executor = NewSQLExecutor(&dbs.DBConfig{
|
||||
Driver: "mysql",
|
||||
Prefix: "edge",
|
||||
Dsn: "root:123456@tcp(127.0.0.1:3306)/db_edge_new?charset=utf8mb4&multiStatements=true",
|
||||
@@ -19,7 +19,7 @@ func TestSQLExecutor_Run(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestSQLExecutor_checkCluster(t *testing.T) {
|
||||
executor := NewSQLExecutor(&dbs.DBConfig{
|
||||
var executor = NewSQLExecutor(&dbs.DBConfig{
|
||||
Driver: "mysql",
|
||||
Prefix: "edge",
|
||||
Dsn: "root:123456@tcp(127.0.0.1:3306)/db_edge_new?charset=utf8mb4&multiStatements=true",
|
||||
@@ -40,7 +40,7 @@ func TestSQLExecutor_checkCluster(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestSQLExecutor_checkMetricItems(t *testing.T) {
|
||||
executor := NewSQLExecutor(&dbs.DBConfig{
|
||||
var executor = NewSQLExecutor(&dbs.DBConfig{
|
||||
Driver: "mysql",
|
||||
Prefix: "edge",
|
||||
Dsn: "root:123456@tcp(127.0.0.1:3306)/db_edge_new?charset=utf8mb4&multiStatements=true",
|
||||
@@ -61,7 +61,7 @@ func TestSQLExecutor_checkMetricItems(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestSQLExecutor_checkNS(t *testing.T) {
|
||||
executor := NewSQLExecutor(&dbs.DBConfig{
|
||||
var executor = NewSQLExecutor(&dbs.DBConfig{
|
||||
Driver: "mysql",
|
||||
Prefix: "edge",
|
||||
Dsn: "root:123456@tcp(127.0.0.1:3306)/db_edge_new?charset=utf8mb4&multiStatements=true",
|
||||
@@ -80,3 +80,24 @@ func TestSQLExecutor_checkNS(t *testing.T) {
|
||||
}
|
||||
t.Log("ok")
|
||||
}
|
||||
|
||||
func TestSQLExecutor_checkClientAgents(t *testing.T) {
|
||||
var executor = NewSQLExecutor(&dbs.DBConfig{
|
||||
Driver: "mysql",
|
||||
Prefix: "edge",
|
||||
Dsn: "root:123456@tcp(127.0.0.1:3306)/db_edge?charset=utf8mb4&multiStatements=true",
|
||||
})
|
||||
db, err := dbs.NewInstanceFromConfig(executor.dbConfig)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer func() {
|
||||
_ = db.Close()
|
||||
}()
|
||||
|
||||
err = executor.checkClientAgents(db)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Log("ok")
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ func (this *DNSTaskExecutor) Start() {
|
||||
}
|
||||
|
||||
func (this *DNSTaskExecutor) Loop() error {
|
||||
if !models.SharedAPINodeDAO.CheckAPINodeIsPrimaryWithoutErr() {
|
||||
if !this.IsPrimaryNode() {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ func (this *EventLooper) Start() {
|
||||
}
|
||||
|
||||
func (this *EventLooper) Loop() error {
|
||||
if !models.SharedAPINodeDAO.CheckAPINodeIsPrimaryWithoutErr() {
|
||||
if !this.IsPrimaryNode() {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -92,7 +92,7 @@ func (this *HealthCheckClusterTask) Stop() {
|
||||
// Loop 单个循环任务
|
||||
func (this *HealthCheckClusterTask) Loop() error {
|
||||
// 检查是否为主节点
|
||||
if !models.SharedAPINodeDAO.CheckAPINodeIsPrimaryWithoutErr() {
|
||||
if !this.IsPrimaryNode() {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ func (this *LogTask) RunMonitor() {
|
||||
|
||||
func (this *LogTask) LoopMonitor() error {
|
||||
// 检查是否为主节点
|
||||
if !models.SharedAPINodeDAO.CheckAPINodeIsPrimaryWithoutErr() {
|
||||
if !this.IsPrimaryNode() {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ func (this *NodeMonitorTask) Start() {
|
||||
|
||||
func (this *NodeMonitorTask) Loop() error {
|
||||
// 检查是否为主节点
|
||||
if !models.SharedAPINodeDAO.CheckAPINodeIsPrimaryWithoutErr() {
|
||||
if !this.IsPrimaryNode() {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ func (this *NodeMonitorTask) MonitorCluster(cluster *models.NodeCluster) error {
|
||||
err = nodeQueue.StartNode(nodeId)
|
||||
if err != nil {
|
||||
if !installers.IsGrantError(err) {
|
||||
_ = models.SharedNodeLogDAO.CreateLog(nil, nodeconfigs.NodeRoleNode, nodeId, 0, 0, models.LevelError, "NODE", "start node from remote API failed: "+err.Error(), time.Now().Unix(), "", nil)
|
||||
_ = models.SharedNodeLogDAO.CreateLog(nil, nodeconfigs.NodeRoleNode, nodeId, 0, 0, models.LevelInfo, "NODE", "start node from remote API failed: "+err.Error(), time.Now().Unix(), "", nil)
|
||||
}
|
||||
} else {
|
||||
_ = models.SharedNodeLogDAO.CreateLog(nil, nodeconfigs.NodeRoleNode, nodeId, 0, 0, models.LevelSuccess, "NODE", "start node from remote API successfully", time.Now().Unix(), "", nil)
|
||||
|
||||
@@ -40,7 +40,7 @@ func (this *NodeTaskExtractor) Start() {
|
||||
|
||||
func (this *NodeTaskExtractor) Loop() error {
|
||||
// 检查是否为主节点
|
||||
if !models.SharedAPINodeDAO.CheckAPINodeIsPrimaryWithoutErr() {
|
||||
if !this.IsPrimaryNode() {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ import (
|
||||
func init() {
|
||||
dbs.OnReadyDone(func() {
|
||||
goman.New(func() {
|
||||
NewServerAccessLogCleaner(12 * time.Hour).Start()
|
||||
NewServerAccessLogCleaner(6 * time.Hour).Start()
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -52,7 +52,7 @@ func (this *ServerAccessLogCleaner) Loop() error {
|
||||
if len(configJSON) == 0 {
|
||||
return nil
|
||||
}
|
||||
config := &systemconfigs.DatabaseConfig{}
|
||||
var config = &systemconfigs.DatabaseConfig{}
|
||||
err = json.Unmarshal(configJSON, config)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -60,8 +60,8 @@ func (this *ServerAccessLogCleaner) Loop() error {
|
||||
if config.ServerAccessLog.Clean.Days <= 0 {
|
||||
return nil
|
||||
}
|
||||
days := config.ServerAccessLog.Clean.Days
|
||||
endDay := timeutil.Format("Ymd", time.Now().AddDate(0, 0, -days+1))
|
||||
var days = config.ServerAccessLog.Clean.Days
|
||||
var endDay = timeutil.Format("Ymd", time.Now().AddDate(0, 0, -days+1))
|
||||
|
||||
// 当前连接的数据库
|
||||
db, err := dbs.Default()
|
||||
@@ -113,7 +113,7 @@ func (this *ServerAccessLogCleaner) cleanDB(db *dbs.DB, endDay string) error {
|
||||
if len(columnNames) != 1 {
|
||||
return errors.New("invalid column names: " + strings.Join(columnNames, ", "))
|
||||
}
|
||||
columnName := columnNames[0]
|
||||
var columnName = columnNames[0]
|
||||
var reg = regexp.MustCompile(`^(?i)(edgeHTTPAccessLogs|edgeNSAccessLogs)_(\d{8})(_\d{4})?$`)
|
||||
for _, one := range ones {
|
||||
var tableName = one.GetString(columnName)
|
||||
|
||||
@@ -45,7 +45,7 @@ func (this *SSLCertExpireCheckExecutor) Start() {
|
||||
// Loop 单次执行
|
||||
func (this *SSLCertExpireCheckExecutor) Loop() error {
|
||||
// 检查是否为主节点
|
||||
if !models.SharedAPINodeDAO.CheckAPINodeIsPrimaryWithoutErr() {
|
||||
if !this.IsPrimaryNode() {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ func (this *SSLCertUpdateOCSPTask) Start() {
|
||||
|
||||
func (this *SSLCertUpdateOCSPTask) Loop() error {
|
||||
// 检查是否为主节点
|
||||
if !models.SharedAPINodeDAO.CheckAPINodeIsPrimaryWithoutErr() {
|
||||
if !this.IsPrimaryNode() {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,10 @@
|
||||
|
||||
package tasks
|
||||
|
||||
import "github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
||||
)
|
||||
|
||||
type BaseTask struct {
|
||||
}
|
||||
@@ -10,3 +13,7 @@ type BaseTask struct {
|
||||
func (this *BaseTask) logErr(taskType string, errString string) {
|
||||
remotelogs.Error("TASK", "run '"+taskType+"' failed: "+errString)
|
||||
}
|
||||
|
||||
func (this *BaseTask) IsPrimaryNode() bool {
|
||||
return models.SharedAPINodeDAO.CheckAPINodeIsPrimaryWithoutErr()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user