diff --git a/cmd/apimain.go b/cmd/apimain.go index db22194..4fafbc2 100644 --- a/cmd/apimain.go +++ b/cmd/apimain.go @@ -14,6 +14,9 @@ import ( "fmt" "github.com/go-redis/redis/v8" "github.com/nicksnyder/go-i18n/v2/i18n" + "github.com/spf13/cobra" + "os" + "strconv" ) // @title 管理系统API @@ -26,9 +29,79 @@ import ( // @securitydefinitions.apikey BearerAuth // @in header // @name Authorization + +var rootCmd = &cobra.Command{ + Use: "apimain", + Short: "RUSTDESK API SERVER", + PersistentPreRun: func(cmd *cobra.Command, args []string) { + InitGlobal() + }, + Run: func(cmd *cobra.Command, args []string) { + //gin + http.ApiInit() + }, +} + +var resetPwdCmd = &cobra.Command{ + Use: "reset-admin-pwd [pwd]", + Example: "reset-admin-pwd 123456", + Short: "Reset Admin Password", + Args: cobra.ExactArgs(1), + Run: func(cmd *cobra.Command, args []string) { + pwd := args[0] + admin := service.AllService.UserService.InfoById(1) + err := service.AllService.UserService.UpdatePassword(admin, pwd) + if err != nil { + fmt.Printf("reset password fail! %v \n", err) + return + } + fmt.Printf("reset password success! \n") + }, +} +var resetUserPwdCmd = &cobra.Command{ + Use: "reset-pwd [userId] [pwd]", + Example: "reset-pwd 2 123456", + Short: "Reset User Password", + Args: cobra.ExactArgs(2), + Run: func(cmd *cobra.Command, args []string) { + userId := args[0] + pwd := args[1] + uid, err := strconv.Atoi(userId) + if err != nil { + fmt.Printf("userId must be int! \n") + return + } + if uid <= 0 { + fmt.Printf("userId must be greater than 0! \n") + return + } + u := service.AllService.UserService.InfoById(uint(uid)) + err = service.AllService.UserService.UpdatePassword(u, pwd) + if err != nil { + fmt.Printf("reset password fail! %v \n", err) + return + } + fmt.Printf("reset password success! \n") + }, +} + +func init() { + rootCmd.PersistentFlags().StringVarP(&global.ConfigPath, "config", "c", "./conf/config.yaml", "choose config file") + rootCmd.AddCommand(resetPwdCmd, resetUserPwdCmd) +} func main() { + if err := rootCmd.Execute(); err != nil { + fmt.Println(err) + os.Exit(1) + } +} + +func InitGlobal() { //配置解析 - global.Viper = config.Init(&global.Config) + global.Viper = config.Init(&global.Config, global.ConfigPath) + + //从配置文件中加载密钥 + config.LoadKeyFile(&global.Config.Rustdesk) //日志 global.Logger = logger.New(&logger.Config{ @@ -94,12 +167,7 @@ func main() { //locker global.Lock = lock.NewLocal() - - //gin - http.ApiInit() - } - func DatabaseAutoUpdate() { version := 246 diff --git a/config/config.go b/config/config.go index 95a19e7..9362b0a 100644 --- a/config/config.go +++ b/config/config.go @@ -1,7 +1,6 @@ package config import ( - "flag" "fmt" "github.com/fsnotify/fsnotify" "github.com/spf13/viper" @@ -35,18 +34,15 @@ type Config struct { } // Init 初始化配置 -func Init(rowVal interface{}) *viper.Viper { - var config string - flag.StringVar(&config, "c", "", "choose config file.") - flag.Parse() - if config == "" { // 优先级: 命令行 > 默认值 - config = DefaultConfig +func Init(rowVal interface{}, path string) *viper.Viper { + if path == "" { + path = DefaultConfig } - v := viper.New() + v := viper.GetViper() v.AutomaticEnv() v.SetEnvKeyReplacer(strings.NewReplacer(".", "_", "-", "_")) v.SetEnvPrefix("RUSTDESK_API") - v.SetConfigFile(config) + v.SetConfigFile(path) v.SetConfigType("yaml") err := v.ReadInConfig() if err != nil { @@ -63,7 +59,7 @@ func Init(rowVal interface{}) *viper.Viper { if err := v.Unmarshal(rowVal); err != nil { fmt.Println(err) } - LoadKeyFile(&rowVal.(*Config).Rustdesk) + return v } diff --git a/docs/admin/admin_docs.go b/docs/admin/admin_docs.go index 5fbf514..4050cc5 100644 --- a/docs/admin/admin_docs.go +++ b/docs/admin/admin_docs.go @@ -3067,6 +3067,90 @@ const docTemplateadmin = `{ } } }, + "/admin/user/myPeer": { + "get": { + "security": [ + { + "token": [] + } + ], + "description": "设备列表", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "设备" + ], + "summary": "设备列表", + "parameters": [ + { + "type": "integer", + "description": "页码", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "页大小", + "name": "page_size", + "in": "query" + }, + { + "type": "integer", + "description": "时间", + "name": "time_ago", + "in": "query" + }, + { + "type": "string", + "description": "ID", + "name": "id", + "in": "query" + }, + { + "type": "string", + "description": "主机名", + "name": "hostname", + "in": "query" + }, + { + "type": "string", + "description": "uuids 用逗号分隔", + "name": "uuids", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/model.PeerList" + } + } + } + ] + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + } + }, "/admin/user/update": { "post": { "security": [ @@ -3407,6 +3491,12 @@ const docTemplateadmin = `{ "admin.LoginPayload": { "type": "object", "properties": { + "avatar": { + "type": "string" + }, + "email": { + "type": "string" + }, "nickname": { "type": "string" }, @@ -3429,7 +3519,7 @@ const docTemplateadmin = `{ "required": [ "client_id", "client_secret", - "op", + "oauth_type", "redirect_url" ], "properties": { @@ -3448,6 +3538,9 @@ const docTemplateadmin = `{ "issuer": { "type": "string" }, + "oauth_type": { + "type": "string" + }, "op": { "type": "string" }, @@ -3567,6 +3660,10 @@ const docTemplateadmin = `{ "avatar": { "type": "string" }, + "email": { + "description": "validate:\"required,email\" email不强制", + "type": "string" + }, "group_id": { "type": "integer" }, @@ -3591,18 +3688,18 @@ const docTemplateadmin = `{ "username": { "type": "string", "maxLength": 10, - "minLength": 4 + "minLength": 2 } } }, "admin.UserOauthItem": { "type": "object", "properties": { + "op": { + "type": "string" + }, "status": { "type": "integer" - }, - "third_type": { - "type": "string" } } }, @@ -3973,6 +4070,9 @@ const docTemplateadmin = `{ "created_at": { "type": "string" }, + "device_id": { + "type": "string" + }, "id": { "type": "integer" }, @@ -4042,6 +4142,9 @@ const docTemplateadmin = `{ "issuer": { "type": "string" }, + "oauth_type": { + "type": "string" + }, "op": { "type": "string" }, @@ -4220,6 +4323,9 @@ const docTemplateadmin = `{ "created_at": { "type": "string" }, + "email": { + "type": "string" + }, "group_id": { "type": "integer" }, @@ -4269,6 +4375,12 @@ const docTemplateadmin = `{ "created_at": { "type": "string" }, + "device_id": { + "type": "string" + }, + "device_uuid": { + "type": "string" + }, "expired_at": { "type": "integer" }, diff --git a/docs/admin/admin_swagger.json b/docs/admin/admin_swagger.json index 91f76ee..0a5ad74 100644 --- a/docs/admin/admin_swagger.json +++ b/docs/admin/admin_swagger.json @@ -3060,6 +3060,90 @@ } } }, + "/admin/user/myPeer": { + "get": { + "security": [ + { + "token": [] + } + ], + "description": "设备列表", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "设备" + ], + "summary": "设备列表", + "parameters": [ + { + "type": "integer", + "description": "页码", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "页大小", + "name": "page_size", + "in": "query" + }, + { + "type": "integer", + "description": "时间", + "name": "time_ago", + "in": "query" + }, + { + "type": "string", + "description": "ID", + "name": "id", + "in": "query" + }, + { + "type": "string", + "description": "主机名", + "name": "hostname", + "in": "query" + }, + { + "type": "string", + "description": "uuids 用逗号分隔", + "name": "uuids", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/model.PeerList" + } + } + } + ] + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + } + }, "/admin/user/update": { "post": { "security": [ @@ -3400,6 +3484,12 @@ "admin.LoginPayload": { "type": "object", "properties": { + "avatar": { + "type": "string" + }, + "email": { + "type": "string" + }, "nickname": { "type": "string" }, @@ -3422,7 +3512,7 @@ "required": [ "client_id", "client_secret", - "op", + "oauth_type", "redirect_url" ], "properties": { @@ -3441,6 +3531,9 @@ "issuer": { "type": "string" }, + "oauth_type": { + "type": "string" + }, "op": { "type": "string" }, @@ -3560,6 +3653,10 @@ "avatar": { "type": "string" }, + "email": { + "description": "validate:\"required,email\" email不强制", + "type": "string" + }, "group_id": { "type": "integer" }, @@ -3584,18 +3681,18 @@ "username": { "type": "string", "maxLength": 10, - "minLength": 4 + "minLength": 2 } } }, "admin.UserOauthItem": { "type": "object", "properties": { + "op": { + "type": "string" + }, "status": { "type": "integer" - }, - "third_type": { - "type": "string" } } }, @@ -3966,6 +4063,9 @@ "created_at": { "type": "string" }, + "device_id": { + "type": "string" + }, "id": { "type": "integer" }, @@ -4035,6 +4135,9 @@ "issuer": { "type": "string" }, + "oauth_type": { + "type": "string" + }, "op": { "type": "string" }, @@ -4213,6 +4316,9 @@ "created_at": { "type": "string" }, + "email": { + "type": "string" + }, "group_id": { "type": "integer" }, @@ -4262,6 +4368,12 @@ "created_at": { "type": "string" }, + "device_id": { + "type": "string" + }, + "device_uuid": { + "type": "string" + }, "expired_at": { "type": "integer" }, diff --git a/docs/admin/admin_swagger.yaml b/docs/admin/admin_swagger.yaml index 6e97a41..8a45943 100644 --- a/docs/admin/admin_swagger.yaml +++ b/docs/admin/admin_swagger.yaml @@ -84,6 +84,10 @@ definitions: type: object admin.LoginPayload: properties: + avatar: + type: string + email: + type: string nickname: type: string route_names: @@ -107,6 +111,8 @@ definitions: type: integer issuer: type: string + oauth_type: + type: string op: type: string redirect_url: @@ -116,7 +122,7 @@ definitions: required: - client_id - client_secret - - op + - oauth_type - redirect_url type: object admin.PeerBatchDeleteForm: @@ -188,6 +194,9 @@ definitions: properties: avatar: type: string + email: + description: validate:"required,email" email不强制 + type: string group_id: type: integer id: @@ -203,7 +212,7 @@ definitions: minimum: 0 username: maxLength: 10 - minLength: 4 + minLength: 2 type: string required: - group_id @@ -212,10 +221,10 @@ definitions: type: object admin.UserOauthItem: properties: + op: + type: string status: type: integer - third_type: - type: string type: object admin.UserPasswordForm: properties: @@ -462,6 +471,8 @@ definitions: type: string created_at: type: string + device_id: + type: string id: type: integer ip: @@ -508,6 +519,8 @@ definitions: type: integer issuer: type: string + oauth_type: + type: string op: type: string redirect_url: @@ -627,6 +640,8 @@ definitions: type: string created_at: type: string + email: + type: string group_id: type: integer id: @@ -659,6 +674,10 @@ definitions: properties: created_at: type: string + device_id: + type: string + device_uuid: + type: string expired_at: type: integer id: @@ -2519,6 +2538,57 @@ paths: summary: 我的授权 tags: - 用户 + /admin/user/myPeer: + get: + consumes: + - application/json + description: 设备列表 + parameters: + - description: 页码 + in: query + name: page + type: integer + - description: 页大小 + in: query + name: page_size + type: integer + - description: 时间 + in: query + name: time_ago + type: integer + - description: ID + in: query + name: id + type: string + - description: 主机名 + in: query + name: hostname + type: string + - description: uuids 用逗号分隔 + in: query + name: uuids + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + data: + $ref: '#/definitions/model.PeerList' + type: object + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.Response' + security: + - token: [] + summary: 设备列表 + tags: + - 设备 /admin/user/update: post: consumes: diff --git a/docs/api/api_docs.go b/docs/api/api_docs.go index 5f3e535..8f84e0f 100644 --- a/docs/api/api_docs.go +++ b/docs/api/api_docs.go @@ -1365,7 +1365,7 @@ const docTemplateapi = `{ "username": { "type": "string", "maxLength": 10, - "minLength": 4 + "minLength": 2 }, "uuid": { "type": "string" diff --git a/docs/api/api_swagger.json b/docs/api/api_swagger.json index 75feb4e..e15f81e 100644 --- a/docs/api/api_swagger.json +++ b/docs/api/api_swagger.json @@ -1358,7 +1358,7 @@ "username": { "type": "string", "maxLength": 10, - "minLength": 4 + "minLength": 2 }, "uuid": { "type": "string" diff --git a/docs/api/api_swagger.yaml b/docs/api/api_swagger.yaml index 49c1c70..5d0f25f 100644 --- a/docs/api/api_swagger.yaml +++ b/docs/api/api_swagger.yaml @@ -69,7 +69,7 @@ definitions: type: string username: maxLength: 10 - minLength: 4 + minLength: 2 type: string uuid: type: string diff --git a/global/global.go b/global/global.go index 8550a2b..ddbcbdc 100644 --- a/global/global.go +++ b/global/global.go @@ -17,13 +17,14 @@ import ( ) var ( - DB *gorm.DB - Logger *logrus.Logger - Config config.Config - Viper *viper.Viper - Redis *redis.Client - Cache cache.Handler - Validator struct { + DB *gorm.DB + Logger *logrus.Logger + ConfigPath string = "" + Config config.Config + Viper *viper.Viper + Redis *redis.Client + Cache cache.Handler + Validator struct { Validate *validator.Validate UT *ut.UniversalTranslator VTrans ut.Translator diff --git a/go.mod b/go.mod index e6c0b3f..ad874e8 100644 --- a/go.mod +++ b/go.mod @@ -16,6 +16,7 @@ require ( github.com/google/uuid v1.1.2 github.com/nicksnyder/go-i18n/v2 v2.4.0 github.com/sirupsen/logrus v1.8.1 + github.com/spf13/cobra v1.8.1 github.com/spf13/viper v1.9.0 github.com/swaggo/files v1.0.1 github.com/swaggo/gin-swagger v1.6.0 @@ -28,7 +29,6 @@ require ( ) require ( - cloud.google.com/go/compute/metadata v0.5.1 // indirect github.com/KyleBanks/depth v1.2.1 // indirect github.com/PuerkitoBio/purell v1.1.1 // indirect github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect @@ -44,6 +44,7 @@ require ( github.com/go-sql-driver/mysql v1.7.0 // indirect github.com/goccy/go-json v0.10.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect github.com/josharian/intern v1.0.0 // indirect