Commit 13c85103 authored by brent's avatar brent

Initial commit

parents
Pipeline #680 canceled with stages
File added
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="Go" enabled="true" />
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/ai_developer_admin.iml" filepath="$PROJECT_DIR$/.idea/ai_developer_admin.iml" />
</modules>
</component>
</project>
\ No newline at end of file
appname = ai_developer_admin
httpport = 8087
runmode = dev
copyrequestbody = true
sessionon = true
sessiongcmaxlifetime = 127800
; SessionProvider = "redis"
; SessionProviderConfig = "192.168.1.10:6379,1000"
web3ClientId = "BHciicCbodMasHsyVfcdPYCaCokJMK5wGs2H4IRCaseqNJlcb1Li4kExaf5gF5DoUx-m_77epCrRPq4XmQzzdRk"
include "mysql.conf"
include "kong.conf"
include "redis.conf"
include "postgres.conf"
\ No newline at end of file
[dev]
kongadminurl = "http://192.168.1.10:8001"
[prod]
kongadminurl = "http://192.168.1.10:8001"
\ No newline at end of file
[dev]
mysqluser = "root"
mysqlpass = "12345678"
mysqlhost = "192.168.1.211"
mysqlport = 3306
mysqldb = "liuxuzhong"
[prod]
mysqluser = "root"
mysqlpass = "12345678"
mysqlhost = "192.168.1.211"
mysqlport = 3306
mysqldb = "liuxuzhong"
\ No newline at end of file
[dev]
postgresuser = "admin"
postgrespass = "quest"
postgreshost = "192.168.1.10"
postgresport = 8812
postgresdb = "qdb"
[prod]
postgresuser = "admin"
postgrespass = "quest"
postgreshost = "192.168.1.10"
postgresport = 8812
postgresdb = "qdb"
\ No newline at end of file
[dev]
tokenhost = "192.168.1.10:6379"
tokendb = 0
tokenpass = ""
balancehost = "192.168.1.10:6379"
balancedb = 0
balancepass = ""
[prod]
tokenhost = "192.168.1.10:6379"
tokendb = 0
tokenpass = ""
balancehost = "192.168.1.10:6379"
balancedb = 0
balancepass = ""
package controllers
import (
"ai_developer_admin/libs/kong"
"ai_developer_admin/libs/mysql"
"ai_developer_admin/libs/utils"
"ai_developer_admin/models"
"encoding/json"
"github.com/beego/beego/v2/core/logs"
"net/http"
"strings"
"time"
)
type AppController struct {
MainController
}
func (server *AppController) CreateApiKey() {
info, err := server.Check()
if err != nil {
server.respond(http.StatusUnauthorized, err.Error())
return
}
body := server.Ctx.Input.RequestBody
appRequest := models.AppRequest{}
err = json.Unmarshal(body, &appRequest) //解析body中数据
logs.Debug("appRequest", appRequest)
if err != nil {
server.respond(models.NoRequestBody, err.Error())
return
}
if appRequest.Name == "" {
server.respond(models.MissingParameter, "名称不能为空")
return
}
checkUser := &models.User{Id: info.UserID}
err = mysql.GetMysqlInstace().Ormer.Read(checkUser)
if err != nil {
server.respond(models.BusinessFailed, "用户不存在")
return
}
data, err := kong.CreateApiKey(checkUser)
if err != nil {
server.respond(models.BusinessFailed, err.Error())
return
}
if data.Id == "" {
server.respond(models.BusinessFailed, data.Message)
return
}
timestamp := time.Now()
app := models.ApiKey{
Name: appRequest.Name,
ApiKey: data.Key,
UserId: checkUser.Id,
CreatedTime: timestamp,
UpdatedTime: timestamp,
Deleted: 0,
ApiKeyId: data.Id,
}
mysql.GetMysqlInstace().Ormer.Insert(&app)
server.respond(http.StatusOK, "")
}
func (server *AppController) ApiKeys() {
info, err := server.Check()
if err != nil {
server.respond(http.StatusUnauthorized, err.Error())
return
}
qs := mysql.GetMysqlInstace().Ormer.QueryTable("api_key")
keyQs := qs.Filter("user_id", info.UserID)
count, err := keyQs.Count()
logs.Debug("Count = ", count)
var keys []*models.ApiKey
if count > 0 {
keyQs.All(&keys)
}
server.respond(http.StatusOK, "", keys)
}
func (server *AppController) UpdateApikey() {
_, err := server.Check()
if err != nil {
server.respond(http.StatusUnauthorized, err.Error())
return
}
body := server.Ctx.Input.RequestBody
appRequest := models.AppRequest{}
err = json.Unmarshal(body, &appRequest) //解析body中数据
logs.Debug("appRequest", appRequest)
if err != nil {
server.respond(models.NoRequestBody, err.Error())
return
}
if appRequest.Id == 0 {
server.respond(models.MissingParameter, "ID不能为空")
return
}
if appRequest.Name == "" {
server.respond(models.MissingParameter, "名称不能为空")
return
}
apiKay := models.ApiKey{Id: appRequest.Id}
err = mysql.GetMysqlInstace().Ormer.Read(&apiKay)
if err != nil {
server.respond(models.BusinessFailed, "api-key 不存在")
return
}
apiKay.Name = appRequest.Name
_, err = mysql.GetMysqlInstace().Ormer.Update(&apiKay)
if err != nil {
server.respond(models.BusinessFailed, err.Error())
return
}
server.respond(http.StatusOK, "修改成功")
}
func (server *AppController) DelApiKey() {
info, err := server.Check()
if err != nil {
server.respond(http.StatusUnauthorized, err.Error())
return
}
body := server.Ctx.Input.RequestBody
appRequest := models.AppRequest{}
err = json.Unmarshal(body, &appRequest) //解析body中数据
logs.Debug("appRequest", appRequest)
if err != nil {
server.respond(models.NoRequestBody, err.Error())
return
}
if appRequest.Id == 0 {
server.respond(models.MissingParameter, "id 不能为空")
return
}
apiKay := models.ApiKey{Id: appRequest.Id}
err = mysql.GetMysqlInstace().Ormer.Read(&apiKay)
if err != nil {
server.respond(models.BusinessFailed, "api-key 不存在")
return
}
data, err := kong.ListApikeys(info.Username)
if err != nil {
server.respond(models.BusinessFailed, err.Error())
return
}
found := false
for _, value := range data {
if strings.Compare(value.Id, apiKay.ApiKeyId) == 0 {
found = true
break
}
}
if found {
err = kong.DelateApiKey(info.Username, apiKay.ApiKeyId)
if err != nil {
server.respond(models.BusinessFailed, "删除 api-key 失败")
return
}
}
//if found {
_, err = mysql.GetMysqlInstace().Ormer.Delete(&apiKay)
if err != nil {
server.respond(models.BusinessFailed, "删除 api-key 失败")
return
}
//}
server.respond(http.StatusOK, "删除 api-key 成功")
}
func (server *AppController) CreateJWTToken() {
info, err := server.Check()
if err != nil {
server.respond(http.StatusUnauthorized, err.Error())
return
}
body := server.Ctx.Input.RequestBody
appRequest := models.AppRequest{}
err = json.Unmarshal(body, &appRequest) //解析body中数据
logs.Debug("appRequest", appRequest)
if err != nil {
server.respond(models.NoRequestBody, err.Error())
return
}
if appRequest.Name == "" {
server.respond(models.MissingParameter, "名称不能为空")
return
}
checkUser := &models.User{Id: info.UserID}
err = mysql.GetMysqlInstace().Ormer.Read(checkUser)
if err != nil {
server.respond(models.BusinessFailed, "用户不存在")
return
}
data, store, err := kong.CreateJwt(checkUser)
if err != nil {
server.respond(models.BusinessFailed, err.Error())
return
}
if data.Id == "" {
server.respond(models.BusinessFailed, data.Message)
return
}
jwtToken, err := utils.GenerateKongToken(data, "")
if err != nil {
jwtToken = ""
}
timestamp := time.Now()
app := models.JwtToken{
Name: appRequest.Name,
JwtCredential: string(store),
JwtToken: jwtToken,
UserId: checkUser.Id,
CreatedTime: timestamp,
UpdatedTime: timestamp,
Deleted: 0,
JwtId: data.Id,
}
mysql.GetMysqlInstace().Ormer.Insert(&app)
server.respond(http.StatusOK, "")
}
func (server *AppController) JwtTokens() {
info, err := server.Check()
if err != nil {
server.respond(http.StatusUnauthorized, err.Error())
return
}
qs := mysql.GetMysqlInstace().Ormer.QueryTable("jwt_token")
keyQs := qs.Filter("user_id", info.UserID)
count, err := keyQs.Count()
logs.Debug("Count = ", count)
var tokens []*models.JwtToken
if count > 0 {
keyQs.All(&tokens)
}
for _, value := range tokens {
value.JwtCredential = ""
}
server.respond(http.StatusOK, "", tokens)
}
func (server *AppController) UpdateJWT() {
_, err := server.Check()
if err != nil {
server.respond(http.StatusUnauthorized, err.Error())
return
}
body := server.Ctx.Input.RequestBody
appRequest := models.AppRequest{}
err = json.Unmarshal(body, &appRequest) //解析body中数据
logs.Debug("appRequest", appRequest)
if err != nil {
server.respond(models.NoRequestBody, err.Error())
return
}
if appRequest.Id == 0 {
server.respond(models.MissingParameter, "ID不能为空")
return
}
if appRequest.Name == "" {
server.respond(models.MissingParameter, "名称不能为空")
return
}
token := models.JwtToken{Id: appRequest.Id}
err = mysql.GetMysqlInstace().Ormer.Read(&token)
if err != nil {
server.respond(models.BusinessFailed, "JWT-token 不存在")
return
}
token.Name = appRequest.Name
_, err = mysql.GetMysqlInstace().Ormer.Update(&token)
if err != nil {
server.respond(models.BusinessFailed, err.Error())
return
}
server.respond(http.StatusOK, "修改成功")
}
func (server *AppController) DelJWT() {
info, err := server.Check()
if err != nil {
server.respond(http.StatusUnauthorized, err.Error())
return
}
body := server.Ctx.Input.RequestBody
appRequest := models.AppRequest{}
err = json.Unmarshal(body, &appRequest) //解析body中数据
logs.Debug("appRequest", appRequest)
if err != nil {
server.respond(models.NoRequestBody, err.Error())
return
}
if appRequest.Id == 0 {
server.respond(models.MissingParameter, "id 不能为空")
return
}
jwt := models.JwtToken{Id: appRequest.Id}
err = mysql.GetMysqlInstace().Ormer.Read(&jwt)
if err != nil {
server.respond(models.BusinessFailed, "jwt-token 不存在")
return
}
data, err := kong.ListJWT(info.Username)
if err != nil {
server.respond(models.BusinessFailed, err.Error())
return
}
found := false
for _, value := range data {
if strings.Compare(value.Id, jwt.JwtId) == 0 {
found = true
break
}
}
if found {
err = kong.DelateJWT(info.Username, jwt.JwtId)
if err != nil {
server.respond(models.BusinessFailed, "删除 jwt-token 失败")
return
}
}
//if found {
_, err = mysql.GetMysqlInstace().Ormer.Delete(&jwt)
if err != nil {
server.respond(models.BusinessFailed, "删除 jwt-token 失败")
return
}
//}
server.respond(http.StatusOK, "删除 jwt-token 成功")
}
package controllers
import (
"ai_developer_admin/libs/redis"
"ai_developer_admin/libs/utils"
"ai_developer_admin/models"
"errors"
beego "github.com/beego/beego/v2/server/web"
"strconv"
"time"
)
type MainController struct {
beego.Controller
}
func (server *MainController) Get() {
server.Data["Website"] = "beego.me"
server.Data["Email"] = "astaxie@gmail.com"
server.TplName = "index.tpl"
}
func (server *MainController) respond(code int, message string, data ...interface{}) {
status := 200
if code == 401 {
status = code
}
server.Ctx.Output.SetStatus(status)
var d interface{}
if len(data) > 0 {
d = data[0]
}
//reData := struct {
// Code int `json:"code"`
// Data interface{} `json:"data,omitempty"`
//}{
// Code: code,
// Data: d,
//}
server.Data["json"] = struct {
Code int `json:"code"`
Message string `json:"message"`
Data interface{} `json:"data,omitempty"`
}{
Code: code,
Message: message,
Data: d,
}
server.ServeJSON()
}
func (server *MainController) Check() (*models.JwtPayload, error) {
token := server.Ctx.Input.Header("Authorization")
if token == "" {
return nil, errors.New("error: 登陆失效")
}
// token := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwianNvbiI6ImdhbmdhbiIsImV4cCI6MTU3ODU1NDMyOCwiaWF0IjoxNTc4NTUzNzI4LCJpc3MiOiJnYW5nYW4ifQ.jOlMlfLMFBJvyrJTLagrwQx2931LzM7Z0EVMFZ75xYI"
info, err := utils.ValidateToken(token)
if err != nil {
return nil, err
// this.respond(401, "登陆失效")
}
key := "token:user-" + strconv.Itoa(info.UserID)
session, err := redis.GetDataToString(key)
if err != nil {
redis.DeleteKey(key)
return nil, errors.New("error: 登陆失效")
}
//session := c.GetSession(key)
if session == "" {
return nil, errors.New("error: 登陆失效")
}
if !(token == session) {
//c.DelSession(info.UserID)
redis.DeleteKey(key)
return nil, errors.New("error: 登陆失效")
}
if info.ExpiresAt <= time.Now().Unix() {
//c.DelSession(info.UserID)
redis.DeleteKey(key)
return nil, errors.New("error: 登陆已过期")
}
return info, err
}
func (server *MainController) StoreToken(name interface{}, value interface{}) error {
return server.SetSession("username", "liuxuzhong")
}
package controllers
import (
"ai_developer_admin/libs/kong"
"ai_developer_admin/libs/mysql"
"ai_developer_admin/libs/odysseus"
"ai_developer_admin/models"
"encoding/json"
"github.com/beego/beego/v2/core/logs"
"net/http"
"strconv"
"time"
)
type FundsController struct {
MainController
}
func (server *FundsController) Recharge() {
info, err := server.Check()
if err != nil {
server.respond(http.StatusUnauthorized, err.Error())
return
}
checkUser := &models.User{Id: info.UserID}
err = mysql.GetMysqlInstace().Ormer.Read(checkUser)
if err != nil {
server.respond(models.BusinessFailed, "用户不存在")
return
}
var chargeRequest models.ChargeRequest
body := server.Ctx.Input.RequestBody
err = json.Unmarshal(body, &chargeRequest) //解析body中数据
logs.Debug("charge", chargeRequest)
if err != nil {
server.respond(models.BusinessFailed, err.Error())
return
}
timestamp := time.Now()
amount := int64(chargeRequest.Amount * 1000000)
charge := models.ChargeRecord{
UserId: checkUser.Id,
Status: 1,
PayMethodDesc: chargeRequest.PaymentMethod.String(),
PayMethod: int(chargeRequest.PaymentMethod),
ChargeTime: timestamp,
CreatedTime: timestamp,
UpdatedTime: timestamp,
Amount: amount,
}
mysql.GetMysqlInstace().Ormer.Insert(&charge)
balance := int64((float64(checkUser.Balance/1000000) + chargeRequest.Amount) * 1000000)
//tempUser := models.User{
// Id: checkUser.Id,
// Balance: balance,
//}
checkUser.Balance = balance
checkUser.UpdatedTime = timestamp
flag, err := mysql.GetMysqlInstace().Ormer.Update(checkUser)
if err != nil {
server.respond(http.StatusOK, "充值失败")
}
logs.Debug("更新用户", flag)
//balanceKey := "balance:" + checkUser.CustomId
//chargeKey := "charge:user-" + checkUser.CustomId
//redis.SetKeyAndData(balanceKey, balance, 0)
//redis.SetKeyAndData(chargeKey, chargeRequest.Amount*1000000, 0)
userId := checkUser.CustomId
if userId == "" {
userId = strconv.Itoa(checkUser.Id)
}
//odysseus.SyncBanlace(userId, balance)
checkUserLevel := &models.UserLevel{Level: checkUser.Level}
err = mysql.GetMysqlInstace().Ormer.Read(checkUserLevel, "level")
if err != nil {
logs.Debug("Recharge 用户等级查找失败")
} else {
odysseus.SetUserInfo(checkUser)
//odysseus.GetUserInfo(int64(checkUser.Id))
//odysseus.GetUserInfo(int64(checkUser.Id + 1))
pluginId := checkUser.RateLimitPluginId
plugin, err := kong.SetRateLimit(checkUser, checkUserLevel, pluginId)
if err == nil && pluginId == "" {
checkUser.RateLimitPluginId = plugin.Id
mysql.GetMysqlInstace().Ormer.Update(checkUser)
}
}
server.respond(http.StatusOK, "充值成功")
}
func (server *FundsController) RechargeRecords() {
info, err := server.Check()
if err != nil {
server.respond(http.StatusUnauthorized, err.Error())
return
}
qs := mysql.GetMysqlInstace().Ormer.QueryTable("charge_record")
infoQs := qs.Filter("user_id", info.UserID)
count, err := infoQs.Count()
logs.Debug("Count = ", count)
var tokens []*models.ChargeRecord
if count > 0 {
infoQs.All(&tokens)
}
server.respond(http.StatusOK, "", tokens)
}
This diff is collapsed.
package controllers
import (
"ai_developer_admin/libs/jose"
"ai_developer_admin/libs/kong"
"ai_developer_admin/libs/mysql"
"ai_developer_admin/libs/redis"
"ai_developer_admin/libs/utils"
"ai_developer_admin/models"
"crypto/md5"
"encoding/hex"
"encoding/json"
"errors"
"github.com/beego/beego/v2/core/logs"
beego "github.com/beego/beego/v2/server/web"
"io"
"net/http"
"strconv"
"strings"
"time"
)
type UserController struct {
MainController
}
//func (u *UserController) respond(code int, message string, data ...interface{}) {
// u.Ctx.Output.SetStatus(code)
// var d interface{}
// if len(data) > 0 {
// d = data[0]
// }
// u.Data["json"] = struct {
// Code int `json:"code"`
// Message string `json:"message"`
// Data interface{} `json:"data,omitempty"`
// }{
// Code: code,
// Message: message,
// Data: d,
// }
// u.ServeJSON()
//}
//func (u *UserController) Test() {
// info, err := u.Check()
// if err != nil {
// u.respond(http.StatusUnauthorized, err.Error())
// return
// }
// u.respond(http.StatusOK, "", info)
//}
func (server *UserController) Login() {
var err error
body := server.Ctx.Input.RequestBody
loginRequest := models.LoginRequest{}
err = json.Unmarshal(body, &loginRequest) //解析body中数据
logs.Debug("loginRequest", loginRequest)
if err != nil {
server.respond(models.NoRequestBody, err.Error())
return
}
//if len(user.Username) == 0 {
// u.respond(http.StatusBadRequest, "用户名不能为空")
// return
//}
claims, err := jose.Verify("https://api-auth.web3auth.io/jwks", loginRequest.Web3AuthPublicKey, loginRequest.IdToken)
if err != nil {
server.respond(models.LoginFailed, "Web3Auth 验证失败")
return
}
if claims.Exp <= time.Now().Unix() {
server.respond(models.LoginFailed, "Web3Auth 登录已超时")
return
}
clientId, _ := beego.AppConfig.String("web3ClientId")
if strings.Compare(clientId, claims.Aud) != 0 {
server.respond(models.LoginFailed, "web3auth clientId 错误")
return
}
user := loginRequest.RequstUser
if len(user.VerifierId) == 0 {
user.VerifierId = claims.VerifierId
}
if len(user.Username) == 0 {
user.Username = "ai_" + generatorMD5(user.VerifierId)[0:8]
}
if len(user.ProfileImage) == 0 {
user.ProfileImage = claims.ProfileImage
}
checkUser := &models.User{VerifierId: user.VerifierId}
err = mysql.GetMysqlInstace().Ormer.Read(checkUser, "verifierId")
if err != nil {
checkUser, err = regisgerUser(user)
if err != nil {
server.respond(models.CreateUserFailed, err.Error())
return
}
}
duration := claims.Exp - claims.Iat
tokenString, err := utils.GenerateToken(checkUser, checkUser.Id, int(duration))
if err != nil {
server.respond(models.LoginFailed, "登录失败")
return
}
//checkUserLevel := &models.UserLevel{Id: checkUser.LevelId}
//err = mysql.GetMysqlInstace().Ormer.Read(checkUserLevel)
//if err != nil {
// logs.Debug("Recharge 用户等级查找失败")
//} else {
// odysseus.SyncCredit(strconv.Itoa(checkUser.Id), checkUserLevel.FreeQuota)
//}
key := "token:user-" + strconv.Itoa(checkUser.Id)
//u.SetSession(key, tokenString)
//lifetime, _ := beego.AppConfig.Int64("sessiongcmaxlifetime")
redis.SetKeyAndData(key, tokenString, time.Duration(duration)*time.Second)
server.Ctx.Output.Header("Authorization", tokenString) // set token into header
//session := u.GetSession(key)
//logs.Debug("login session", session)
server.respond(http.StatusOK, "")
}
func (server *UserController) Logout() {
info, err := server.Check()
if err != nil {
server.respond(http.StatusUnauthorized, err.Error())
return
}
key := "token:user-" + strconv.Itoa(info.UserID)
redis.DeleteKey(key)
server.respond(http.StatusUnauthorized, "")
}
func (server *UserController) Regisger() {
var err error
user := models.User{}
body := server.Ctx.Input.RequestBody
err = json.Unmarshal(body, &user) //解析body中数据
logs.Debug("user", user)
if err != nil {
server.respond(models.NoRequestBody, err.Error())
return
}
if len(user.Username) == 0 {
server.respond(models.MissingParameter, "用户名不能为空")
return
}
_, err = regisgerUser(user)
if err != nil {
server.respond(models.CreateUserFailed, err.Error())
return
}
server.respond(http.StatusOK, "")
}
func (server *UserController) UserInfo() {
info, err := server.Check()
if err != nil {
server.respond(http.StatusUnauthorized, err.Error())
return
}
checkUser := &models.User{Id: info.UserID}
err = mysql.GetMysqlInstace().Ormer.Read(checkUser)
if err != nil {
server.respond(models.BusinessFailed, err.Error())
return
}
server.respond(http.StatusOK, "", checkUser)
}
func regisgerUser(user models.User) (*models.User, error) {
var err error
qs := mysql.GetMysqlInstace().Ormer.QueryTable("user")
usernameQs := qs.Filter("username", user.Username)
var count int64
count, err = usernameQs.Count()
if count > 0 {
return nil, errors.New("用户名已存在")
}
//if len(user.CustomId) > 0 {
// customIdQs := qs.Filter("custom_id", user.CustomId)
// count, err = customIdQs.Count()
// if count > 0 {
// return nil, errors.New("您指定的客户id已存在")
// }
//}
user.CreatedTime = time.Now()
user.UpdatedTime = user.CreatedTime
user.Level = 0
_, err = mysql.GetMysqlInstace().Ormer.Insert(&user)
if err != nil {
return nil, errors.New("注册用户失败")
}
checkUser := &models.User{Username: user.Username}
err = mysql.GetMysqlInstace().Ormer.Read(checkUser, "username")
if err != nil {
return nil, errors.New("注册用户失败")
}
checkUser.CustomId = strconv.Itoa(checkUser.Id)
data, err := kong.CreateUser(checkUser)
if err != nil {
return nil, err
}
if data.Id == "" {
return nil, errors.New(data.Message)
}
checkUserLevel := &models.UserLevel{Level: checkUser.Level}
err = mysql.GetMysqlInstace().Ormer.Read(checkUserLevel, "level")
if err != nil {
logs.Debug("Recharge 用户等级查找失败")
} else {
plugin, err := kong.SetRateLimit(checkUser, checkUserLevel, "")
if err == nil {
checkUser.RateLimitPluginId = plugin.Id
}
}
mysql.GetMysqlInstace().Ormer.Update(checkUser)
return checkUser, nil
}
func generatorMD5(code string) string {
MD5 := md5.New()
_, _ = io.WriteString(MD5, code)
return hex.EncodeToString(MD5.Sum(nil))
}
package controllers
import (
"ai_developer_admin/libs/mysql"
"ai_developer_admin/models"
"encoding/json"
"github.com/beego/beego/v2/core/logs"
"net/http"
"time"
)
type UserLevelController struct {
MainController
}
func (server *UserLevelController) Levels() {
_, err := server.Check()
if err != nil {
server.respond(http.StatusUnauthorized, err.Error())
return
}
qs := mysql.GetMysqlInstace().Ormer.QueryTable("user_level")
count, err := qs.Count()
logs.Debug("Levels = ", count)
var levels []*models.UserLevel
if count > 0 {
qs.All(&levels)
}
server.respond(http.StatusOK, "", levels)
}
func (server *UserLevelController) AddLevel() {
_, err := server.Check()
if err != nil {
server.respond(http.StatusUnauthorized, err.Error())
return
}
body := server.Ctx.Input.RequestBody
logs.Debug("AddLevel body", string(body))
request := models.UserLevel{}
err = json.Unmarshal(body, &request) //解析body中数据
logs.Debug("request", request)
if err != nil {
server.respond(models.NoRequestBody, err.Error())
return
}
//if request.Level == 0 {
// u.respond(models.MissingParameter, "level 不能为空且必须大于0")
// return
//}
qs := mysql.GetMysqlInstace().Ormer.QueryTable("user_level")
usernameQs := qs.Filter("level", request.Level)
count, err := usernameQs.Count()
logs.Debug("Levels = ", count)
var levels []*models.UserLevel
if count > 0 {
server.respond(models.BusinessFailed, "该等级已存在")
return
}
timestamp := time.Now()
request.CreatedTime = timestamp
request.UpdatedTime = timestamp
request.Deleted = 0
mysql.GetMysqlInstace().Ormer.Insert(&request)
server.respond(http.StatusOK, "", levels)
}
func (server *UserLevelController) UpdateLevel() {
_, err := server.Check()
if err != nil {
server.respond(http.StatusUnauthorized, err.Error())
return
}
body := server.Ctx.Input.RequestBody
logs.Debug("AddLevel body", string(body))
request := models.UserLevel{}
err = json.Unmarshal(body, &request) //解析body中数据
logs.Debug("request", request)
if err != nil {
server.respond(models.NoRequestBody, err.Error())
return
}
if request.Id == 0 {
server.respond(models.MissingParameter, "id 不能为空")
return
}
checkLevel := models.UserLevel{Id: request.Id}
err = mysql.GetMysqlInstace().Ormer.Read(&checkLevel)
if err != nil {
server.respond(models.BusinessFailed, "level 不存在")
return
}
if checkLevel.Level != request.Level {
server.respond(models.BusinessFailed, "等级字段不能修改")
return
}
_, err = mysql.GetMysqlInstace().Ormer.Update(&request)
if err != nil {
server.respond(models.BusinessFailed, "更新失败")
return
}
server.respond(http.StatusOK, "更新成功")
}
func (server *UserLevelController) DelLevel() {
_, err := server.Check()
if err != nil {
server.respond(http.StatusUnauthorized, err.Error())
return
}
body := server.Ctx.Input.RequestBody
logs.Debug("AddLevel body", string(body))
request := models.UserLevel{}
err = json.Unmarshal(body, &request) //解析body中数据
logs.Debug("request", request)
if err != nil {
server.respond(models.NoRequestBody, err.Error())
return
}
if request.Id == 0 {
server.respond(models.MissingParameter, "id 不能为空")
return
}
if request.Level == 0 {
server.respond(models.MissingParameter, "默认等级不能删除")
return
}
mysql.GetMysqlInstace().Ormer.Delete(&request)
server.respond(http.StatusOK, "删除成功")
}
module ai_developer_admin
go 1.19
require github.com/beego/beego/v2 v2.0.1
require (
github.com/beego/beego v1.12.12
github.com/go-jose/go-jose/v3 v3.0.1
github.com/go-sql-driver/mysql v1.7.1
github.com/golang-jwt/jwt v3.2.2+incompatible
github.com/lib/pq v1.0.0
github.com/odysseus/payment v0.0.0-00010101000000-000000000000
github.com/smartystreets/goconvey v1.6.4
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad
gopkg.in/redis.v5 v5.2.9
)
require (
github.com/astaxie/beego v1.12.3 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/go-redis/redis/v7 v7.4.0 // indirect
github.com/golang/protobuf v1.4.2 // indirect
github.com/gomodule/redigo v2.0.0+incompatible // indirect
github.com/google/uuid v1.5.0 // indirect
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 // indirect
github.com/hashicorp/golang-lru v0.5.4 // indirect
github.com/jtolds/gls v4.20.0+incompatible // indirect
github.com/konsorten/go-windows-terminal-sequences v1.0.1 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
github.com/mitchellh/mapstructure v1.3.3 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/prometheus/client_golang v1.7.0 // indirect
github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.10.0 // indirect
github.com/prometheus/procfs v0.1.3 // indirect
github.com/redis/go-redis/v9 v9.4.0 // indirect
github.com/robfig/cron/v3 v3.0.1 // indirect
github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644 // indirect
github.com/sirupsen/logrus v1.4.2 // indirect
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d // indirect
golang.org/x/mod v0.3.0 // indirect
golang.org/x/net v0.0.0-20201021035429-f5854403a974 // indirect
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f // indirect
golang.org/x/text v0.3.3 // indirect
golang.org/x/tools v0.0.0-20201211185031-d93e913c1a58 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
google.golang.org/protobuf v1.23.0 // indirect
gopkg.in/yaml.v2 v2.2.8 // indirect
)
replace github.com/odysseus/payment => ../payment
This diff is collapsed.
{"/Users/brent/Documents/wubanWork/ai_developer_admin/controllers":1706860693667738264}
\ No newline at end of file
File added
package cronjob
import (
"ai_developer_admin/libs/odysseus"
"ai_developer_admin/libs/postgres"
"ai_developer_admin/libs/redis"
"ai_developer_admin/models"
"encoding/json"
"github.com/beego/beego/v2/core/logs"
"github.com/robfig/cron/v3"
"strconv"
)
var loopCronTask = cron.New(cron.WithSeconds())
func Start() {
//defer loopCronTask.Stop()
spec := "0 0 * * * ?" //"@every 1h"
loopCronTask.AddFunc(spec, func() {
logs.Debug("loopCronTask")
sql := "SELECT type,count(type) FROM bills GROUP BY type ORDER BY count DESC;"
tasks, err := postgres.CountTasks(sql)
if err != nil {
return
}
var response []models.TaskHeat
for _, value := range tasks {
taskId, err := strconv.Atoi(value.Type)
if err != nil {
continue
}
taskType, err1 := odysseus.GetTaskType(int64(taskId))
if err1 != nil {
continue
}
var hardwareRequire models.Hardware
eer := json.Unmarshal([]byte(taskType.HardwareRequire), &hardwareRequire)
if eer != nil {
}
count, _ := strconv.Atoi(value.Count)
retask := models.TaskHeat{
TaskId: taskId,
User: taskType.Username,
Pwd: taskType.Password,
Repository: taskType.ImageUrl,
SignUrl: taskType.SignUrl,
ImageName: taskType.ImageName,
ImageId: taskType.ImageId,
HardwareRequire: hardwareRequire,
Count: int64(count),
}
response = append(response, retask)
}
data, err := json.Marshal(response)
if err == nil {
redis.SetKeyAndData("task:heat", string(data), 0)
}
})
loopCronTask.Start()
}
package jose
import (
"encoding/json"
"errors"
"github.com/beego/beego/v2/core/logs"
josev3 "github.com/go-jose/go-jose/v3"
"github.com/go-jose/go-jose/v3/jwt"
"io"
"net/http"
"strings"
)
type JWKResponse struct {
Kty string `json:"kty"`
Crv string `json:"crv"`
X string `json:"x"`
Y string `json:"y"`
Kid string `json:"kid"`
}
type JWKS struct {
Keys []JWKResponse `json:"keys"`
}
type AIClaims struct {
Iat int64 `json:"iat"`
Aud string `json:"aud"`
Nonce string `json:"nonce"`
Iss string `json:"iss"`
Wallets []struct {
PublicKey string `json:"public_key"`
Type string `json:"type"`
Curve string `json:"curve"`
} `json:"wallets"`
Email string `json:"email"`
Name string `json:"name"`
ProfileImage string `json:"profileImage"`
Verifier string `json:"verifier"`
VerifierId string `json:"verifierId"`
AggregateVerifier string `json:"aggregateVerifier"`
Exp int64 `json:"exp"`
}
func Verify(url string, publicKey string, idToken string) (*AIClaims, error) {
resp, err := http.Get(url)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
logs.Debug("Verify", string(body))
var response1 JWKS
var jwkTokens []josev3.JSONWebKey
if err = json.Unmarshal(body, &response1); err != nil {
return nil, err
}
for _, value := range response1.Keys {
logs.Debug("Verify value", value)
bytes, err := json.Marshal(value)
if err != nil {
continue
}
var jwk2 josev3.JSONWebKey
err = jwk2.UnmarshalJSON(bytes)
if err != nil {
continue
}
jwkTokens = append(jwkTokens, jwk2)
}
jwks := &josev3.JSONWebKeySet{
Keys: jwkTokens,
}
tok, err := jwt.ParseSigned(idToken)
if err != nil {
return nil, err
}
var cl AIClaims
err = tok.Claims(jwks, &cl)
if err != nil {
return nil, err
}
if len(cl.Wallets) > 0 {
if strings.Compare(cl.Wallets[0].PublicKey, publicKey) != 0 {
return nil, errors.New("公钥验证失败")
}
}
//err = tok.Claims(*jwks, &cl)
//if err != nil {
// return nil, err
//}
return &cl, nil
}
package kong
import (
"ai_developer_admin/models"
"bytes"
"encoding/json"
"errors"
"github.com/beego/beego/v2/core/logs"
beego "github.com/beego/beego/v2/server/web"
"io"
"net/http"
)
func kongApi(path string, method string, payload io.Reader, headers map[string]string) ([]byte, error) {
client := &http.Client{}
base_url, _ := beego.AppConfig.String("kongadminurl")
url := base_url + "/" + path
reqest, err := http.NewRequest(method, url, payload)
for key, value := range headers {
reqest.Header.Add(key, value)
}
//reqest.Header.Add("Content-Type", "application/json")
resp, err := client.Do(reqest)
if err != nil {
return nil, err
}
//fmt.Printf("resp status code: %s\n", resp.Body)
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return body, nil
}
func CreateUser(user *models.User) (*models.CreateUserResponse, error) {
createUser := models.CreateUserRequest{
Username: user.Username,
CustomId: user.CustomId,
}
payload := new(bytes.Buffer)
json.NewEncoder(payload).Encode(createUser)
var err error
var data []byte
headers := map[string]string{
"Content-Type": "application/json",
}
data, err = kongApi("consumers", "POST", payload, headers)
if err != nil {
return nil, err
}
logs.Debug("kong CreateUser", string(data))
var response models.CreateUserResponse
if err = json.Unmarshal(data, &response); err != nil {
return nil, err
}
return &response, err
}
func CreateApiKey(user *models.User) (*models.CreateApiKeyResponse, error) {
var err error
var data []byte
path := "consumers/" + user.Username + "/key-auth"
data, err = kongApi(path, "POST", nil, nil)
if err != nil {
return nil, err
}
logs.Debug("kong CreateApiKey", string(data))
var response models.CreateApiKeyResponse
if err = json.Unmarshal(data, &response); err != nil {
return nil, err
}
return &response, err
}
func DelateApiKey(username string, id string) error {
var err error
var data []byte
path := "consumers/" + username + "/key-auth" + "/" + id
headers := map[string]string{
"Content-Type": "application/json",
}
data, err = kongApi(path, "DELETE", nil, headers)
if err != nil {
return err
}
logs.Debug("kong DelateApiKey", string(data))
return nil
}
func ListApikeys(username string) ([]models.CreateApiKeyResponse, error) {
var err error
var data []byte
path := "consumers/" + username + "/key-auth"
data, err = kongApi(path, "GET", nil, nil)
if err != nil {
return nil, err
}
logs.Debug("kong ListApikeys", string(data))
var response models.APIKeys
if err = json.Unmarshal(data, &response); err != nil {
return nil, err
}
return response.Data, err
}
func CreateJwt(user *models.User) (*models.JWTResponse, []byte, error) {
var err error
var data []byte
path := "consumers/" + user.Username + "/jwt"
headers := map[string]string{}
data, err = kongApi(path, "POST", nil, headers)
if err != nil {
return nil, nil, err
}
logs.Debug("kong CreateJwt", string(data))
var response models.JWTResponse
if err = json.Unmarshal(data, &response); err != nil {
return nil, nil, err
}
return &response, data, err
}
func DelateJWT(username string, id string) error {
var err error
var data []byte
path := "consumers/" + username + "/jwt" + "/" + id
data, err = kongApi(path, "DELETE", nil, nil)
if err != nil {
return err
}
logs.Debug("kong DelateApiKey", string(data))
return nil
}
func ListJWT(username string) ([]models.JWTResponse, error) {
var err error
var data []byte
path := "consumers/" + username + "/jwt"
data, err = kongApi(path, "GET", nil, nil)
if err != nil {
return nil, err
}
logs.Debug("kong ListJWT", string(data))
var response models.JWTS
if err = json.Unmarshal(data, &response); err != nil {
return nil, err
}
return response.Data, err
}
func SetRateLimit(user *models.User, level *models.UserLevel, pluginId string) (*models.Plugin, error) {
var err error
var data []byte
path := "consumers/" + user.Username + "/plugins" + "/" + pluginId
headers := map[string]string{
"Content-Type": "application/json",
}
method := "POST"
if pluginId != "" {
method = "PATCH"
}
configData := struct {
Second int `json:"second,omitempty"`
Minute int `json:"minute,omitempty"`
Hour int `json:"hour,omitempty"`
Day int `json:"day,omitempty"`
Month int `json:"month,omitempty"`
Year int64 `json:"year,omitempty"`
}{}
if level.RateLimitSecond > 0 {
configData.Second = level.RateLimitSecond
}
if level.RateLimitMinute > 0 {
configData.Minute = level.RateLimitMinute
}
if level.RateLimitHour > 0 {
configData.Hour = level.RateLimitHour
}
if level.RateLimitDay > 0 {
configData.Day = level.RateLimitDay
}
if level.RateLimitMonth > 0 {
configData.Month = level.RateLimitMonth
}
if level.RateLimitYear > 0 {
configData.Year = level.RateLimitYear
}
jsonData := struct {
Name string `json:"name"`
Config interface{} `json:"config"`
}{
Name: "rate-limiting",
Config: configData,
}
payload := new(bytes.Buffer)
json.NewEncoder(payload).Encode(jsonData)
logs.Debug("SetRateLimit = ", payload.String())
data, err = kongApi(path, method, payload, headers)
if err != nil {
logs.Debug("kong SetRateLimit", err.Error())
return nil, err
}
logs.Debug("kong SetRateLimit", string(data))
var response models.Plugin
if err = json.Unmarshal(data, &response); err != nil {
return nil, err
}
if response.Code != 0 {
return nil, errors.New(response.Message)
}
return &response, nil
}
func ListPlugins(user *models.User) ([]models.Plugin, error) {
var err error
var data []byte
path := "consumers/" + user.Username + "/plugins"
headers := map[string]string{
"Content-Type": "application/json",
}
var response models.Plugins
data, err = kongApi(path, "GET", nil, headers)
if err != nil {
logs.Debug("kong SetRateLimit", err.Error())
return response.Data, err
}
logs.Debug("kong CreateJwt", string(data))
if err = json.Unmarshal(data, &response); err != nil {
return response.Data, err
}
return response.Data, nil
}
package mysql
import (
"ai_developer_admin/models"
"fmt"
"github.com/beego/beego/orm"
"github.com/beego/beego/v2/core/logs"
beego "github.com/beego/beego/v2/server/web"
_ "github.com/go-sql-driver/mysql"
"sync"
)
type Singleton struct {
Ormer orm.Ormer
}
var instance *Singleton
var once sync.Once
func GetMysqlInstace() *Singleton {
once.Do(func() {
instance = &Singleton{
Ormer: orm.NewOrm(),
}
})
return instance
}
func init() {
logs.Debug("mysql lib init")
orm.Debug = true
if err := orm.RegisterDriver("mysql", orm.DRMySQL); err != nil {
logs.Error(err.Error())
}
orm.RegisterModel(new(models.User))
//orm.RegisterModel(new(models.App))
orm.RegisterModel(new(models.ChargeRecord))
orm.RegisterModel(new(models.UserLevel))
orm.RegisterModel(new(models.ApiKey))
orm.RegisterModel(new(models.JwtToken))
orm.RegisterModel(new(models.TaskType))
orm.RegisterModel(new(models.UserLevelTaskType))
logs.Debug("AppConfig", beego.AppConfig)
dbuser, _ := beego.AppConfig.String("mysqluser")
dbpass, _ := beego.AppConfig.String("mysqlpass")
dbhost, _ := beego.AppConfig.String("mysqlhost")
dbport, _ := beego.AppConfig.String("mysqlport")
dbname, _ := beego.AppConfig.String("mysqldb")
logs.Debug("mysql info", dbuser, dbpass, dbhost, dbport, dbname)
dbURL := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=true", dbuser, dbpass, dbhost, dbport, dbname)
logs.Debug("Will connect to mysql url", dbURL)
if err := orm.RegisterDataBase("default", "mysql", dbURL); err != nil {
logs.Error(err.Error())
panic(err.Error())
}
orm.SetMaxIdleConns("default", 10)
orm.SetMaxOpenConns("default", 100)
}
package odysseus
import (
"ai_developer_admin/models"
"context"
"github.com/beego/beego/v2/core/logs"
"github.com/odysseus/payment/cachedata"
"github.com/odysseus/payment/model"
)
import (
beego "github.com/beego/beego/v2/server/web"
)
var syncinfo *cachedata.CacheData
func init() {
host, _ := beego.AppConfig.String("balancehost")
db, _ := beego.AppConfig.Int("balancedb")
pass, _ := beego.AppConfig.String("balancepass")
//syncinfo = payment.NewPayment(payment.RedisConnParam{
// Addr: host,
// Password: pass,
// DbIndex: db,
//})
dbuser, _ := beego.AppConfig.String("mysqluser")
dbpass, _ := beego.AppConfig.String("mysqlpass")
dbhost, _ := beego.AppConfig.String("mysqlhost")
dbport, _ := beego.AppConfig.Int("mysqlport")
dbname, _ := beego.AppConfig.String("mysqldb")
syncinfo = cachedata.NewCacheData(context.Background(), cachedata.RedisConnParam{
Addr: host,
Password: pass,
DbIndex: db,
}, model.DbConfig{
User: dbuser,
Host: dbhost,
Port: dbport,
DbName: dbname,
Passwd: dbpass,
})
}
func SetUserInfo(user *models.User) error {
data := &model.User{
ID: int64(user.Id),
Level: int64(user.Level),
Balance: user.Balance,
Deleted: int64(user.Deleted),
}
return syncinfo.SetUserInfo(data)
}
func GetUserBalance(id int64) (int64, error) {
user, err := syncinfo.GetUserInfo(id)
logs.Debug("GetUserInfo = ", user, err)
return user.Balance, err
}
func GetTaskType(id int64) (*model.TaskType, error) {
return syncinfo.GetTaskWithId(id)
}
package postgres
import (
"ai_developer_admin/models"
"encoding/json"
"fmt"
"github.com/beego/beego/orm"
"github.com/beego/beego/v2/core/logs"
beego "github.com/beego/beego/v2/server/web"
_ "github.com/lib/pq"
)
var ormpost orm.Ormer
func init() {
logs.Debug("postgres lib init")
orm.Debug = true
if err := orm.RegisterDriver("postgres", orm.DRPostgres); err != nil {
logs.Error(err.Error())
}
//orm.RegisterModel(new(models.Bills))
//orm.RegisterModel(new(models.Tasks))
//orm.RegisterModel(new(models.ChargeRecord))
//orm.RegisterModel(new(models.UserLevel))
//orm.RegisterModel(new(models.ApiKey))
//orm.RegisterModel(new(models.JwtToken))
logs.Debug("AppConfig", beego.AppConfig)
dbuser, _ := beego.AppConfig.String("postgresuser")
dbpass, _ := beego.AppConfig.String("postgrespass")
dbhost, _ := beego.AppConfig.String("postgreshost")
dbport, _ := beego.AppConfig.Int("postgresport")
dbname, _ := beego.AppConfig.String("postgresdb")
logs.Debug("postgres info", dbuser, dbpass, dbhost, dbport, dbname)
dbURL := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=disable", dbhost, dbport, dbuser, dbpass, dbname)
logs.Debug("Will connect to postgres url", dbURL)
if err := orm.RegisterDataBase(dbname, "postgres", dbURL); err != nil {
logs.Error(err.Error())
panic(err.Error())
}
orm.SetMaxIdleConns(dbname, 10)
orm.SetMaxOpenConns(dbname, 100)
db, err := orm.GetDB(dbname)
if err != nil {
panic(err)
}
ormpost, err = orm.NewOrmWithDB("postgres", dbname, db)
if err != nil {
panic(err)
}
}
func QueryBills(sql string) ([]models.Bills, error) {
logs.Debug("QueryBills = ", sql)
qs := ormpost.Raw(sql)
var params []orm.Params
_, err := qs.Values(&params)
if err != nil {
return nil, err
}
arr, err := json.Marshal(params)
if err != nil {
return nil, err
}
var containers []models.Bills
logs.Debug("QueryBills = ", string(arr))
err = json.Unmarshal(arr, &containers)
if err != nil {
return nil, err
}
return containers, nil
}
func CountTasks(sql string) ([]models.TaskCount, error) {
logs.Debug("CountTasks = ", sql)
qs := ormpost.Raw(sql)
var params []orm.Params
_, err := qs.Values(&params)
if err != nil {
return nil, err
}
arr, err := json.Marshal(params)
if err != nil {
return nil, err
}
var containers []models.TaskCount
err = json.Unmarshal(arr, &containers)
if err != nil {
return nil, err
}
return containers, nil
}
package redis
import (
"github.com/beego/beego/v2/core/logs"
beego "github.com/beego/beego/v2/server/web"
"gopkg.in/redis.v5"
"time"
)
var redisCache *redis.Client
func init() {
host, _ := beego.AppConfig.String("tokenhost")
db, _ := beego.AppConfig.Int("tokendb")
pass, _ := beego.AppConfig.String("tokenpass")
redisCache = createClient(host, pass, db)
}
func createClient(redisHost string, password string, dataBase int) *redis.Client {
client := redis.NewClient(&redis.Options{
Addr: redisHost,
Password: password,
DB: dataBase,
})
_, err := client.Ping().Result()
if err != nil {
logs.Error("连接失败,", err)
}
return client
}
func SetKeyAndData(key string, value interface{}, time time.Duration) error {
err := redisCache.Set(key, value, time).Err()
if err != nil {
logs.Error("set key:", key, ",value:", value, err)
return err
}
return nil
}
func GetDataToString(key string) (string, error) {
v, err := redisCache.Get(key).Result()
if err != nil {
return "", err
}
return v, nil
}
func GetDataToBytes(key string) ([]byte, error) {
v, err := redisCache.Get(key).Bytes()
if err != nil {
return nil, err
}
return v, nil
}
func DeleteKey(key string) error {
err := redisCache.Del(key).Err()
return err
}
package utils
import (
"ai_developer_admin/models"
"crypto/rand"
"errors"
"fmt"
"io"
"time"
"github.com/beego/beego/logs"
"github.com/golang-jwt/jwt"
"golang.org/x/crypto/scrypt"
)
const (
SecretKEY string = "JWT-Secret-Key"
DEFAULT_EXPIRE_SECONDS int = 6000 // default expired 10 minutes
PasswordHashBytes = 16
)
type MyCustomClaims struct {
UserID int `json:"userID"`
jwt.StandardClaims
}
// generate token
//func GenerateToken(user *models.User, userID int, issuedAt int64, expireAt int64) (tokenString string, err error) {
//
// // Create the Claims
// mySigningKey := []byte(SecretKEY)
// logs.Info("Token will be expired at ", time.Unix(expireAt, 0))
//
// claims := MyCustomClaims{
// userID,
// jwt.StandardClaims{
// Issuer: user.Username,
// IssuedAt: issuedAt,
// ExpiresAt: expireAt,
// },
// }
//
// // Create the token using your claims
// token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
// // Signs the token with a secret
// tokenStr, err := token.SignedString(mySigningKey)
// if err != nil {
// return "", errors.New("error: failed to generate token")
// }
//
// return tokenStr, nil
//}
func GenerateToken(user *models.User, userID int, expiredSeconds int) (tokenString string, err error) {
if expiredSeconds == 0 {
expiredSeconds = DEFAULT_EXPIRE_SECONDS
}
// Create the Claims
mySigningKey := []byte(SecretKEY)
expireAt := time.Now().Add(time.Second * time.Duration(expiredSeconds)).Unix()
logs.Info("Token will be expired at ", time.Unix(expireAt, 0))
claims := MyCustomClaims{
userID,
jwt.StandardClaims{
Issuer: user.Username,
IssuedAt: time.Now().Unix(),
ExpiresAt: expireAt,
},
}
// Create the token using your claims
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
// Signs the token with a secret
tokenStr, err := token.SignedString(mySigningKey)
if err != nil {
return "", errors.New("error: failed to generate token")
}
return tokenStr, nil
}
// validate token
func ValidateToken(tokenString string) (*models.JwtPayload, error) {
token, err := jwt.ParseWithClaims(tokenString, &MyCustomClaims{},
func(token *jwt.Token) (interface{}, error) {
return []byte(SecretKEY), nil
})
claims, ok := token.Claims.(*MyCustomClaims)
if ok && token.Valid {
logs.Info("%v %v", claims.UserID, claims.StandardClaims.ExpiresAt)
logs.Info("Token will be expired at ", time.Unix(claims.StandardClaims.ExpiresAt, 0))
return &models.JwtPayload{
Username: claims.StandardClaims.Issuer,
UserID: claims.UserID,
IssuedAt: claims.StandardClaims.IssuedAt,
ExpiresAt: claims.StandardClaims.ExpiresAt,
}, nil
} else {
logs.Info(err.Error())
return nil, errors.New("error: failed to validate token")
}
}
// update token
func RefreshToken(tokenString string) (newTokenString string, err error) {
// get previous token
token, err := jwt.ParseWithClaims(tokenString, &MyCustomClaims{},
func(token *jwt.Token) (interface{}, error) {
return []byte(SecretKEY), nil
})
claims, ok := token.Claims.(*MyCustomClaims)
if !ok || !token.Valid {
return "", err
}
mySigningKey := []byte(SecretKEY)
expireAt := time.Now().Add(time.Second * time.Duration(DEFAULT_EXPIRE_SECONDS)).Unix() //new expired
newClaims := MyCustomClaims{
claims.UserID,
jwt.StandardClaims{
Issuer: claims.StandardClaims.Issuer, //name of token issue
IssuedAt: time.Now().Unix(), //time of token issue
ExpiresAt: expireAt,
},
}
// generate new token with new claims
newToken := jwt.NewWithClaims(jwt.SigningMethodHS256, newClaims)
// sign the token with a secret
tokenStr, err := newToken.SignedString(mySigningKey)
if err != nil {
return "", errors.New("error: failed to generate new fresh json web token")
}
return tokenStr, nil
}
// generate salt
func GenerateSalt() (salt string, err error) {
buf := make([]byte, PasswordHashBytes)
if _, err := io.ReadFull(rand.Reader, buf); err != nil {
return "", errors.New("error: failed to generate user's salt")
}
return fmt.Sprintf("%x", buf), nil
}
// generate password hash
func GeneratePassHash(password string, salt string) (hash string, err error) {
h, err := scrypt.Key([]byte(password), []byte(salt), 16384, 8, 1, PasswordHashBytes)
if err != nil {
return "", errors.New("error: failed to generate password hash")
}
return fmt.Sprintf("%x", h), nil
}
func GenerateKongToken(jwtCredential *models.JWTResponse, custom_id string) (tokenString string, err error) {
// Create the Claims
mySigningKey := []byte(jwtCredential.Secret)
claims := &jwt.StandardClaims{
Issuer: jwtCredential.Key,
}
// Create the token using your claims
method := jwt.SigningMethodHS256
if jwtCredential.Algorithm == "HS384" {
method = jwt.SigningMethodHS384
}
if jwtCredential.Algorithm == "HS512" {
method = jwt.SigningMethodHS512
}
if jwtCredential.Algorithm == "HS256" {
method = jwt.SigningMethodHS256
}
token := jwt.NewWithClaims(method, claims)
// Signs the token with a secret
tokenStr, err := token.SignedString(mySigningKey)
if err != nil {
return "", errors.New("error: failed to generate token")
}
return tokenStr, nil
}
package main
import (
"ai_developer_admin/libs/cronjob"
"ai_developer_admin/libs/mysql"
_ "ai_developer_admin/routers"
beego "github.com/beego/beego/v2/server/web"
"github.com/beego/beego/v2/server/web/filter/cors"
_ "github.com/beego/beego/v2/server/web/session/redis"
)
func init() {
beego.InsertFilter("*", beego.BeforeRouter, cors.Allow(&cors.Options{
AllowAllOrigins: true,
AllowMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
AllowHeaders: []string{"Origin", "Authorization", "Access-Control-Allow-Origin", "Access-Control-Allow-Headers", "Content-Type", "X-Xsrf-Token"},
ExposeHeaders: []string{"Content-Length", "Access-Control-Allow-Origin", "Access-Control-Allow-Headers", "Content-Type", "X-Xsrf-Token", "Authorization"},
AllowCredentials: true,
}))
}
func main() {
//t := time.Now()
//temp := fmt.Sprintf(t.Format("2006-01-02T15:04:05.000000Z"))
//logs.Debug("temp = ", temp)
cronjob.Start()
mysql.GetMysqlInstace()
//postgres.Query("")
beego.Run()
}
package models
import (
"time"
)
//type App struct {
// Id int `orm:"column(id);auto"`
// ApiKey string `json:"api_key";orm:"column(api_key);size(255)"`
// JwtCredential string `json:"jwt_credential";orm:"column(jwt_credential)"`
// JwtToken string `json:"jwt_token";orm:"column(jwt_token)"`
// UserId int `json:"user_id";orm:"column(user_id)"`
// CreatedTime time.Time `json:"created_time";orm:"column(created_time);type(datetime)"`
// UpdatedTime time.Time `json:"updated_time";orm:"column(updated_time);type(datetime)"`
// Deleted int `json:"deleted";orm:"column(deleted);size(1)"`
//}
type ApiKey struct {
Id int `orm:"column(id);auto"`
Name string `json:"name,omitempty";orm:"column(name)"`
ApiKey string `json:"api_key";orm:"column(api_key);size(255)"`
ApiKeyId string `json:"api_key_id";orm:"column(api_key_id);size(255)"`
UserId int `json:"user_id";orm:"column(user_id)"`
CreatedTime time.Time `json:"created_time";orm:"column(created_time);type(datetime)"`
UpdatedTime time.Time `json:"updated_time";orm:"column(updated_time);type(datetime)"`
Deleted int `json:"deleted";orm:"column(deleted);size(1)"`
}
type JwtToken struct {
Id int `orm:"column(id);auto"`
Name string `json:"name,omitempty";orm:"column(name)"`
JwtCredential string `json:"jwt_credential,omitempty";orm:"column(jwt_credential)"`
JwtToken string `json:"jwt_token";orm:"column(jwt_token)"`
JwtId string `json:"jwt_id";orm:"column(jwt_id)"`
UserId int `json:"user_id";orm:"column(user_id)"`
CreatedTime time.Time `json:"created_time";orm:"column(created_time);type(datetime)"`
UpdatedTime time.Time `json:"updated_time";orm:"column(updated_time);type(datetime)"`
Deleted int `json:"deleted";orm:"column(deleted);size(1)"`
}
type AppRequest struct {
Id int `json:"id,omitempty"`
Name string `json:"name,omitempty"`
Page int64 `json:"page,omitempty"`
Size int64 `json:"size,omitempty"`
StartTime *time.Time `json:"start_time,omitempty"`
EndTime *time.Time `json:"end_time,omitempty"`
ProfitAcc string `json:"profit_acc,omitempty"`
WorkerAcc string `json:"worker_acc,omitempty"`
}
package models
const (
NoRequestBody = iota + 5000
MissingParameter
CreateUserFailed
LoginFailed
BusinessFailed
Web3VerifyFailed
Web3LoginTimeout
Web3ClinetIdError
)
package models
import "time"
type PayMethodType int
const (
WeixinPay PayMethodType = iota + 1
AliPay
UnionPay
PayPal
ApplePay
ManualPay
)
func (m PayMethodType) String() string {
switch m {
case WeixinPay:
return "微信支付"
case AliPay:
return "支付宝"
case UnionPay:
return "银联支付"
case PayPal:
return "PayPal"
case ApplePay:
return "苹果支付"
case ManualPay:
return "手动充值"
default:
return "未知支付方式"
}
}
type ChargeRequest struct {
Amount float64 `json:"amount"`
PaymentMethod PayMethodType `json:"pay_method"`
}
type ChargeRecord struct {
Id int `orm:"column(id);auto"`
UserId int `json:"user_id";orm:"column(user_id)"`
Amount int64 `json:"amount";orm:"column(amount);size(7)"`
PayMethod int `json:"pay_method";orm:"column(pay_method);size(1)"`
PayMethodDesc string `json:"pay_method_desc";orm:"column(pay_method_desc);size(20)"`
Status int `json:"status";orm:"column(status);size(1)"`
ChargeTime time.Time `json:"charge_time";orm:"column(charge_time);type(datetime)"`
CreatedTime time.Time `json:"created_time";orm:"column(created_time);type(datetime)"`
UpdatedTime time.Time `json:"updated_time";orm:"column(updated_time);type(datetime)"`
Deleted int `json:"deleted";orm:"column(deleted);size(1)"`
}
package models
type JwtPayload struct {
Username string `json:"username"`
UserID int `json:"userID"`
IssuedAt int64 `json:"iat"`
ExpiresAt int64 `json:"exp"`
}
package models
type CreateUserRequest struct {
Username string `json:"username"`
CustomId string `json:"custom_id"`
}
type CreateUserResponse struct {
Id string `json:"id"`
CreatedAt int `json:"created_at"`
Username string `json:"username"`
Tags interface{} `json:"tags"`
CustomId string `json:"custom_id"`
UpdatedAt int `json:"updated_at"`
Fields struct {
Username string `json:"username"`
} `json:"fields"`
Code int `json:"code"`
Message string `json:"message"`
Name string `json:"name"`
}
type CreateApiKeyResponse struct {
Key string `json:"key"`
CreatedAt int `json:"created_at"`
Ttl interface{} `json:"ttl"`
Tags interface{} `json:"tags"`
Consumer struct {
Id string `json:"id"`
} `json:"consumer"`
Id string `json:"id"`
Code int `json:"code,omitempty"`
Message string `json:"message,omitempty"`
}
type APIKeys struct {
Next interface{} `json:"next"`
Data []CreateApiKeyResponse `json:"data"`
}
type JWTResponse struct {
Algorithm string `json:"algorithm"`
Consumer struct {
Id string `json:"id"`
} `json:"consumer"`
CreatedAt int `json:"created_at"`
Id string `json:"id"`
Key string `json:"key"`
RsaPublicKey interface{} `json:"rsa_public_key"`
Secret string `json:"secret"`
Tags interface{} `json:"tags"`
Code int `json:"code,omitempty"`
Message string `json:"message,omitempty"`
}
type JWTS struct {
Next interface{} `json:"next"`
Data []JWTResponse `json:"data"`
}
type Plugin struct {
Id string `json:"id"`
Name string `json:"name"`
CreatedAt int `json:"created_at"`
UpdatedAt int `json:"updated_at"`
Route interface{} `json:"route"`
Service interface{} `json:"service"`
Consumer interface{} `json:"consumer"`
InstanceName interface{} `json:"instance_name"`
Config struct {
Hour int `json:"hour"`
Minute int `json:"minute"`
} `json:"config"`
Protocols []string `json:"protocols"`
Enabled bool `json:"enabled"`
Tags []string `json:"tags"`
Ordering struct {
Before []string `json:"before"`
} `json:"ordering"`
Code int `json:"code,omitempty"`
Message string `json:"message,omitempty"`
}
type Plugins struct {
Next interface{} `json:"next"`
Data []Plugin `json:"data"`
}
package models
import (
"time"
)
type Hardware struct {
DiskSize int64 `json:"disk_size,omitempty"`
MemorySize int64 `json:"memory_size,omitempty"`
Gpus []string `json:"gpus,omitempty"`
}
type CMD struct {
ImageName string `json:"image_name"`
DockerCmd struct {
ContainerPort string `json:"container_port"`
} `json:"docker_cmd"`
ApiUrl string `json:"api_url"`
}
type TaskType struct {
Id int `orm:"column(id);auto"`
Desc string `json:"desc";orm:"column(desc);size(20)"`
Price int64 `json:"price";orm:"column(price)"`
PublicKey string `json:"public_key";orm:"column(public_key)"`
Complexity int `json:"complexity";orm:"column(complexity)"`
HardwareRequire string `json:"hardware_require";orm:"column(hardware_require)"`
ImageId string `json:"image_id";orm:"column(image_id)"`
ImageUrl string `json:"image_url";orm:"column(image_url)"`
Cmd string `json:"cmd";orm:"column(cmd)"`
Workload int `json:"workload";orm:"column(workload)"`
ApiPath string `json:"api_path";orm:"column(api_path)"`
ImageName string `json:"image_name";orm:"column(image_name)"`
SignUrl string `json:"sign_url";orm:"column(sign_url)"`
Username string `json:"username";orm:"column(username)"`
Password string `json:"password";orm:"column(password)"`
CreatedTime time.Time `json:"created_time";orm:"column(created_time);type(datetime)"`
UpdatedTime time.Time `json:"updated_time";orm:"column(updated_time);type(datetime)"`
Deleted int `json:"deleted";orm:"column(deleted);size(1)"`
}
type NewTaskType struct {
Id int `orm:"column(id);auto"`
Desc string `json:"desc";orm:"column(desc);size(20)"`
Price int64 `json:"price";orm:"column(price)"`
PublicKey string `json:"public_key";orm:"column(public_key)"`
Complexity int `json:"complexity";orm:"column(complexity)"`
HardwareRequire Hardware `json:"hardware_require";orm:"column(hardware_require)"`
ImageId string `json:"image_id";orm:"column(image_id)"`
ImageUrl string `json:"image_url";orm:"column(image_url)"`
Cmd CMD `json:"cmd";orm:"column(cmd)"`
Workload int `json:"workload";orm:"column(workload)"`
ApiPath string `json:"api_path";orm:"column(api_path)"`
ImageName string `json:"image_name";orm:"column(image_name)"`
SignUrl string `json:"sign_url";orm:"column(sign_url)"`
Username string `json:"username";orm:"column(username)"`
Password string `json:"password";orm:"column(password)"`
CreatedTime time.Time `json:"created_time";orm:"column(created_time);type(datetime)"`
UpdatedTime time.Time `json:"updated_time";orm:"column(updated_time);type(datetime)"`
Deleted int `json:"deleted";orm:"column(deleted);size(1)"`
}
type Bills struct {
//Key int `orm:"column(key);auto"`
Id string `json:"id";orm:"column(id)"`
Type string `json:"type";orm:"column(type)"`
Uid string `json:"uid";orm:"column(uid)"`
ProfitAcc string `json:"profit_acc";orm:"column(profit_acc)"`
Fee string `json:"fee";orm:"column(fee)"`
WorkerAcc string `json:"worker_acc";orm:"column(worker_acc)"`
Result string `json:"result";orm:"column(result)"`
Workload string `json:"workload";orm:"column(workload)"`
//ApiPath string `json:"api_path";orm:"column(api_path)"`
Time time.Time `json:"time";orm:"column(time);type(datetime)"`
TaskDuration string `json:"task_duration";orm:"column(task_duration)"`
OutLen string `json:"out_len";orm:"column(out_len)"`
InLen string `json:"in_len";orm:"column(in_len)"`
ApiPath string `json:"api_path,omitempty"`
Desc string `json:"desc,omitempty"`
TaskType string `json:"task_type,omitempty"`
Balance int64 `json:"balance,omitempty"`
}
type TaskCount struct {
Time time.Time `json:"time,omitempty"`
Count string `json:"count,omitempty"`
Fee string `json:"fee,omitempty"`
Type string `json:"type,omitempty"`
ApiPath string `json:"api_path,omitempty"`
HardwareRequire string `json:"hardware_require,omitempty"`
ImageId string `json:"image_id,omitempty"`
Repository string `json:"repository,omitempty"`
ImageName string `json:"image_name,omitempty"`
SignUrl string `json:"sign_url,omitempty"`
User string `json:"user,omitempty"`
Pwd string `json:"pwd,omitempty"`
TaskId int `json:"task_id,omitempty"`
}
type TaskHeat struct {
Time time.Time `json:"time,omitempty"`
Count int64 `json:"count,omitempty"`
ApiPath string `json:"api_path,omitempty"`
HardwareRequire Hardware `json:"hardware_require,omitempty"`
ImageId string `json:"image_id,omitempty"`
Repository string `json:"repository,omitempty"`
ImageName string `json:"image_name,omitempty"`
SignUrl string `json:"sign_url,omitempty"`
User string `json:"user,omitempty"`
Pwd string `json:"pwd,omitempty"`
TaskId int `json:"task_id,omitempty"`
}
//type Tasks struct {
// //Key int `orm:"column(key);auto"`
// Id string `json:"id";orm:"column(id)"`
// Type string `json:"type";orm:"column(type)"`
// Uid string `json:"uid";orm:"column(uid)"`
// Fee int `json:"fee";orm:"column(fee)"`
// //ApiPath string `json:"api_path";orm:"column(api_path)"`
// Time time.Time `json:"time";orm:"column(time);type(datetime)"`
// InLen int `json:"in_len";orm:"column(in_len)"`
//}
type AddTaskType struct {
Type NewTaskType `json:"type"`
Levels []UserLevelTaskType `json:"levels"`
}
package models
import "time"
//type User struct {
// Id int `json:"id" orm:"column(id);auto"`
// Username string `json:"username" orm:"column(username);size(128)"`
// Password string `json:"password" orm:"column(password);size(128)"`
// Phone string `json:"phone" orm:"column(phone);size(128)"`
// CustomId string `json:"custom_id" orm:"column(custom_id);size(128)"`
//}
type User struct {
Id int `orm:"column(id);auto"`
Name string `json:"name";orm:"column(name);size(20)"`
Username string `json:"user_name";orm:"column(user_name);size(20)"`
Mail string `json:"mail";orm:"column(mail);size(120)"`
Phone string `json:"phone";orm:"column(phone);size(15)"`
CustomId string `json:"custom_id";orm:"column(custom_id);size(120)"`
ChainAccount string `json:"chain_account";orm:"column(chain_account);size(42)"`
Type int `json:"type";orm:"column(type);size(1)"`
IsAuthed int `json:"is_authed";orm:"column(is_authed);size(1)"`
RegisterFrom int `json:"register_from";orm:"column(register_from);size(1)"`
RegisterFromDesc string `json:"register_from_desc";orm:"column(register_from_desc);size(16)"`
Balance int64 `json:"balance";orm:"column(balance)"`
Level int `json:"level";orm:"column(level);size(1)"`
VerifierId string `json:"verifier_id";orm:"column(verifier_id);size(255)"`
RateLimitPluginId string `json:"rate_limit_plugin_id";orm:"column(rate_limit_plugin_id);size(255)"`
ProfileImage string `json:"profile_image";orm:"column(profile_image);size(255)"`
Role int `json:"role";orm:"column(role);size(1)"`
CreatedTime time.Time `json:"created_time";orm:"column(created_time);type(datetime)"`
UpdatedTime time.Time `json:"updated_time";orm:"column(updated_time);type(datetime)"`
Deleted int `json:"deleted";orm:"column(deleted);size(1)"`
}
type LoginRequest struct {
RequstUser User `json:"user"`
IdToken string `json:"id_token"`
Web3AuthPublicKey string `json:"web3auth_public_key"`
}
type UserLevel struct {
Id int `orm:"column(id);auto"`
Desc string `json:"desc";orm:"column(desc);size(20)"`
CreditQuota int64 `json:"credit_quota";orm:"column(credit_quota)"`
FreeCallCountDay int `json:"free_call_count_day";orm:"column(free_call_count_day)"`
FreeCallCountMonth int `json:"free_call_count_month";orm:"column(free_call_count_month)"`
FreeCallCountYear int `json:"free_call_count_year";orm:"column(free_call_count_year)"`
FreeCallCountTotal int `json:"free_call_count_total";orm:"column(free_call_count_total)"`
RateLimitSecond int `json:"rate_limit_second";orm:"column(rate_limit_second)"`
RateLimitMinute int `json:"rate_limit_minute";orm:"column(rate_limit_minute)"`
RateLimitHour int `json:"rate_limit_hour";orm:"column(rate_limit_hour)"`
RateLimitDay int `json:"rate_limit_day";orm:"column(rate_limit_day)"`
RateLimitMonth int `json:"rate_limit_month";orm:"column(rate_limit_month)"`
RateLimitYear int64 `json:"rate_limit_year";orm:"column(rate_limit_year)"`
Level int `json:"level";orm:"column(level);size(1)"`
CreatedTime time.Time `json:"created_time";orm:"column(created_time);type(datetime)"`
UpdatedTime time.Time `json:"updated_time";orm:"column(updated_time);type(datetime)"`
Deleted int `json:"deleted";orm:"column(deleted);size(1)"`
}
type UserLevelTaskType struct {
ID int `orm:"column(id);auto"`
FreeCallCountDay int `json:"free_call_count_day"orm:"column(free_call_count_day)"`
FreeCallCountMonth int `json:"free_call_count_month"orm:"column(free_call_count_month)"`
FreeCallCountYear int `json:"free_call_count_year"orm:"column(free_call_count_year)"`
FreeCallCountTotal int `json:"free_call_count_total"orm:"column(free_call_count_total)"`
UserLevel int `json:"user_level"orm:"column(user_level)"`
TaskTypeId int `json:"task_type_id"orm:"column(task_type_id)"`
CreatedTime time.Time `json:"created_time";orm:"column(created_time);type(datetime)"`
UpdatedTime time.Time `json:"updated_time";orm:"column(updated_time);type(datetime)"`
Deleted int `json:"deleted";orm:"column(deleted);size(1)"`
}
package routers
import (
"ai_developer_admin/controllers"
beego "github.com/beego/beego/v2/server/web"
)
func init() {
beego.Router("/", &controllers.MainController{})
beego.AutoPrefix("api", &controllers.UserController{})
beego.AutoPrefix("api", &controllers.AppController{})
beego.AutoPrefix("api", &controllers.FundsController{})
beego.AutoPrefix("api", &controllers.UserLevelController{})
beego.AutoPrefix("api", &controllers.TaskController{})
}
function b(a){var c=new WebSocket(a);c.onclose=function(){setTimeout(function(){b(a)},2E3)};c.onmessage=function(){location.reload()}}try{if(window.WebSocket)try{b("ws://localhost:12450/reload")}catch(a){console.error(a)}else console.log("Your browser does not support WebSockets.")}catch(a){console.error("Exception during connecting to Reload:",a)};
package test
import (
"net/http"
"net/http/httptest"
"testing"
"runtime"
"path/filepath"
"github.com/beego/beego/v2/core/logs"
_ "ai_developer_admin/routers"
beego "github.com/beego/beego/v2/server/web"
. "github.com/smartystreets/goconvey/convey"
)
func init() {
_, file, _, _ := runtime.Caller(0)
apppath, _ := filepath.Abs(filepath.Dir(filepath.Join(file, ".." + string(filepath.Separator))))
beego.TestBeegoInit(apppath)
}
// TestBeego is a sample to run an endpoint test
func TestBeego(t *testing.T) {
r, _ := http.NewRequest("GET", "/", nil)
w := httptest.NewRecorder()
beego.BeeApp.Handlers.ServeHTTP(w, r)
logs.Trace("testing", "TestBeego", "Code[%d]\n%s", w.Code, w.Body.String())
Convey("Subject: Test Station Endpoint\n", t, func() {
Convey("Status Code Should Be 200", func() {
So(w.Code, ShouldEqual, 200)
})
Convey("The Result Should Not Be Empty", func() {
So(w.Body.Len(), ShouldBeGreaterThan, 0)
})
})
}
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment