apimain.go 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. package main
  2. import (
  3. "Gwen/config"
  4. "Gwen/global"
  5. "Gwen/http"
  6. "Gwen/lib/cache"
  7. "Gwen/lib/lock"
  8. "Gwen/lib/logger"
  9. "Gwen/lib/orm"
  10. "Gwen/lib/upload"
  11. "Gwen/model"
  12. "Gwen/service"
  13. "fmt"
  14. "github.com/go-redis/redis/v8"
  15. "github.com/nicksnyder/go-i18n/v2/i18n"
  16. "github.com/spf13/cobra"
  17. "os"
  18. "strconv"
  19. )
  20. // @title 管理系统API
  21. // @version 1.0
  22. // @description 接口
  23. // @basePath /api
  24. // @securityDefinitions.apikey token
  25. // @in header
  26. // @name api-token
  27. // @securitydefinitions.apikey BearerAuth
  28. // @in header
  29. // @name Authorization
  30. var rootCmd = &cobra.Command{
  31. Use: "apimain",
  32. Short: "RUSTDESK API SERVER",
  33. PersistentPreRun: func(cmd *cobra.Command, args []string) {
  34. InitGlobal()
  35. },
  36. Run: func(cmd *cobra.Command, args []string) {
  37. //gin
  38. http.ApiInit()
  39. },
  40. }
  41. var resetPwdCmd = &cobra.Command{
  42. Use: "reset-admin-pwd [pwd]",
  43. Example: "reset-admin-pwd 123456",
  44. Short: "Reset Admin Password",
  45. Args: cobra.ExactArgs(1),
  46. Run: func(cmd *cobra.Command, args []string) {
  47. pwd := args[0]
  48. admin := service.AllService.UserService.InfoById(1)
  49. err := service.AllService.UserService.UpdatePassword(admin, pwd)
  50. if err != nil {
  51. fmt.Printf("reset password fail! %v \n", err)
  52. return
  53. }
  54. fmt.Printf("reset password success! \n")
  55. },
  56. }
  57. var resetUserPwdCmd = &cobra.Command{
  58. Use: "reset-pwd [userId] [pwd]",
  59. Example: "reset-pwd 2 123456",
  60. Short: "Reset User Password",
  61. Args: cobra.ExactArgs(2),
  62. Run: func(cmd *cobra.Command, args []string) {
  63. userId := args[0]
  64. pwd := args[1]
  65. uid, err := strconv.Atoi(userId)
  66. if err != nil {
  67. fmt.Printf("userId must be int! \n")
  68. return
  69. }
  70. if uid <= 0 {
  71. fmt.Printf("userId must be greater than 0! \n")
  72. return
  73. }
  74. u := service.AllService.UserService.InfoById(uint(uid))
  75. err = service.AllService.UserService.UpdatePassword(u, pwd)
  76. if err != nil {
  77. fmt.Printf("reset password fail! %v \n", err)
  78. return
  79. }
  80. fmt.Printf("reset password success! \n")
  81. },
  82. }
  83. func init() {
  84. rootCmd.PersistentFlags().StringVarP(&global.ConfigPath, "config", "c", "./conf/config.yaml", "choose config file")
  85. rootCmd.AddCommand(resetPwdCmd, resetUserPwdCmd)
  86. }
  87. func main() {
  88. if err := rootCmd.Execute(); err != nil {
  89. fmt.Println(err)
  90. os.Exit(1)
  91. }
  92. }
  93. func InitGlobal() {
  94. //配置解析
  95. global.Viper = config.Init(&global.Config, global.ConfigPath)
  96. //从配置文件中加载密钥
  97. config.LoadKeyFile(&global.Config.Rustdesk)
  98. //日志
  99. global.Logger = logger.New(&logger.Config{
  100. Path: global.Config.Logger.Path,
  101. Level: global.Config.Logger.Level,
  102. ReportCaller: global.Config.Logger.ReportCaller,
  103. })
  104. global.InitI18n()
  105. //redis
  106. global.Redis = redis.NewClient(&redis.Options{
  107. Addr: global.Config.Redis.Addr,
  108. Password: global.Config.Redis.Password,
  109. DB: global.Config.Redis.Db,
  110. })
  111. //cache
  112. if global.Config.Cache.Type == cache.TypeFile {
  113. fc := cache.NewFileCache()
  114. fc.SetDir(global.Config.Cache.FileDir)
  115. global.Cache = fc
  116. } else if global.Config.Cache.Type == cache.TypeRedis {
  117. global.Cache = cache.NewRedis(&redis.Options{
  118. Addr: global.Config.Cache.RedisAddr,
  119. Password: global.Config.Cache.RedisPwd,
  120. DB: global.Config.Cache.RedisDb,
  121. })
  122. }
  123. //gorm
  124. if global.Config.Gorm.Type == config.TypeMysql {
  125. dns := global.Config.Mysql.Username + ":" + global.Config.Mysql.Password + "@(" + global.Config.Mysql.Addr + ")/" + global.Config.Mysql.Dbname + "?charset=utf8mb4&parseTime=True&loc=Local"
  126. global.DB = orm.NewMysql(&orm.MysqlConfig{
  127. Dns: dns,
  128. MaxIdleConns: global.Config.Gorm.MaxIdleConns,
  129. MaxOpenConns: global.Config.Gorm.MaxOpenConns,
  130. })
  131. } else {
  132. //sqlite
  133. global.DB = orm.NewSqlite(&orm.SqliteConfig{
  134. MaxIdleConns: global.Config.Gorm.MaxIdleConns,
  135. MaxOpenConns: global.Config.Gorm.MaxOpenConns,
  136. })
  137. }
  138. DatabaseAutoUpdate()
  139. //validator
  140. global.ApiInitValidator()
  141. //oss
  142. global.Oss = &upload.Oss{
  143. AccessKeyId: global.Config.Oss.AccessKeyId,
  144. AccessKeySecret: global.Config.Oss.AccessKeySecret,
  145. Host: global.Config.Oss.Host,
  146. CallbackUrl: global.Config.Oss.CallbackUrl,
  147. ExpireTime: global.Config.Oss.ExpireTime,
  148. MaxByte: global.Config.Oss.MaxByte,
  149. }
  150. //jwt
  151. //fmt.Println(global.Config.Jwt.PrivateKey)
  152. //global.Jwt = jwt.NewJwt(global.Config.Jwt.PrivateKey, global.Config.Jwt.ExpireDuration*time.Second)
  153. //locker
  154. global.Lock = lock.NewLocal()
  155. }
  156. func DatabaseAutoUpdate() {
  157. version := 251
  158. db := global.DB
  159. if global.Config.Gorm.Type == config.TypeMysql {
  160. //检查存不存在数据库,不存在则创建
  161. dbName := db.Migrator().CurrentDatabase()
  162. fmt.Println("dbName", dbName)
  163. if dbName == "" {
  164. dbName = global.Config.Mysql.Dbname
  165. // 移除 DSN 中的数据库名称,以便初始连接时不指定数据库
  166. dsnWithoutDB := global.Config.Mysql.Username + ":" + global.Config.Mysql.Password + "@(" + global.Config.Mysql.Addr + ")/?charset=utf8mb4&parseTime=True&loc=Local"
  167. //新链接
  168. dbWithoutDB := orm.NewMysql(&orm.MysqlConfig{
  169. Dns: dsnWithoutDB,
  170. })
  171. // 获取底层的 *sql.DB 对象,并确保在程序退出时关闭连接
  172. sqlDBWithoutDB, err := dbWithoutDB.DB()
  173. if err != nil {
  174. fmt.Printf("获取底层 *sql.DB 对象失败: %v\n", err)
  175. return
  176. }
  177. defer func() {
  178. if err := sqlDBWithoutDB.Close(); err != nil {
  179. fmt.Printf("关闭连接失败: %v\n", err)
  180. }
  181. }()
  182. err = dbWithoutDB.Exec("CREATE DATABASE IF NOT EXISTS " + dbName + " DEFAULT CHARSET utf8mb4").Error
  183. if err != nil {
  184. fmt.Println(err)
  185. return
  186. }
  187. }
  188. }
  189. if !db.Migrator().HasTable(&model.Version{}) {
  190. Migrate(uint(version))
  191. } else {
  192. //查找最后一个version
  193. var v model.Version
  194. db.Last(&v)
  195. if v.Version < uint(version) {
  196. Migrate(uint(version))
  197. }
  198. // 245迁移
  199. if v.Version < 245 {
  200. //oauths 表的 oauth_type 字段设置为 op同样的值
  201. db.Exec("update oauths set oauth_type = op")
  202. db.Exec("update oauths set issuer = 'https://accounts.google.com' where op = 'google'")
  203. db.Exec("update user_thirds set oauth_type = third_type, op = third_type")
  204. //通过email迁移旧的google授权
  205. uts := make([]model.UserThird, 0)
  206. db.Where("oauth_type = ?", "google").Find(&uts)
  207. for _, ut := range uts {
  208. if ut.UserId > 0 {
  209. db.Model(&model.User{}).Where("id = ?", ut.UserId).Update("email", ut.OpenId)
  210. }
  211. }
  212. }
  213. if v.Version < 246 {
  214. db.Exec("update oauths set issuer = 'https://accounts.google.com' where op = 'google' and issuer is null")
  215. }
  216. }
  217. }
  218. func Migrate(version uint) {
  219. fmt.Println("migrating....", version)
  220. err := global.DB.AutoMigrate(
  221. &model.Version{},
  222. &model.User{},
  223. &model.UserToken{},
  224. &model.Tag{},
  225. &model.AddressBook{},
  226. &model.Peer{},
  227. &model.Group{},
  228. &model.UserThird{},
  229. &model.Oauth{},
  230. &model.LoginLog{},
  231. &model.ShareRecord{},
  232. &model.AuditConn{},
  233. &model.AuditFile{},
  234. &model.AddressBookCollection{},
  235. &model.AddressBookCollectionRule{},
  236. &model.ServerCmd{},
  237. )
  238. if err != nil {
  239. fmt.Println("migrate err :=>", err)
  240. }
  241. global.DB.Create(&model.Version{Version: version})
  242. //如果是初次则创建一个默认用户
  243. var vc int64
  244. global.DB.Model(&model.Version{}).Count(&vc)
  245. if vc == 1 {
  246. localizer := global.Localizer("")
  247. defaultGroup, _ := localizer.LocalizeMessage(&i18n.Message{
  248. ID: "DefaultGroup",
  249. })
  250. group := &model.Group{
  251. Name: defaultGroup,
  252. Type: model.GroupTypeDefault,
  253. }
  254. service.AllService.GroupService.Create(group)
  255. shareGroup, _ := localizer.LocalizeMessage(&i18n.Message{
  256. ID: "ShareGroup",
  257. })
  258. groupShare := &model.Group{
  259. Name: shareGroup,
  260. Type: model.GroupTypeShare,
  261. }
  262. service.AllService.GroupService.Create(groupShare)
  263. //是true
  264. is_admin := true
  265. admin := &model.User{
  266. Username: "admin",
  267. Nickname: "Admin",
  268. Status: model.COMMON_STATUS_ENABLE,
  269. IsAdmin: &is_admin,
  270. GroupId: 1,
  271. }
  272. admin.Password = service.AllService.UserService.EncryptPassword("admin")
  273. global.DB.Create(admin)
  274. }
  275. }