serv_rpc.go 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. // package serv_rpc -- сервер RPC-запросов
  2. package serv_rpc
  3. import (
  4. "encoding/json"
  5. "fmt"
  6. "log"
  7. "net"
  8. "net/http"
  9. "net/rpc"
  10. "os"
  11. "wartank/pkg/types"
  12. )
  13. type ServRpc struct {
  14. serv types.IServer
  15. }
  16. // NewServRpc -- возвращает новый сервер RPC-запросов
  17. func NewServRpc(serv types.IServer) (*ServRpc, error) {
  18. if serv == nil {
  19. return nil, fmt.Errorf("NewServRpc(): IServer==nil")
  20. }
  21. sf := &ServRpc{
  22. serv: serv,
  23. }
  24. return sf, nil
  25. }
  26. // Run -- запускает сервис в работу
  27. func (sf *ServRpc) Run() {
  28. rpc.Register(sf)
  29. rpc.HandleHTTP()
  30. url := os.Getenv("SERVER_RPC_URL")
  31. if url == "" {
  32. log.Printf("ServRpc.Run(): env SERVER_RPC_URL not set\n")
  33. return
  34. }
  35. log.Printf("SERVER_RPC_URL=%v\n", url)
  36. lister, err := net.Listen("tcp", url)
  37. if err != nil {
  38. log.Printf("NewServRc(): listen error, err=\n\t%v\n", err)
  39. sf.serv.CancelApp()
  40. return
  41. }
  42. go http.Serve(lister, nil)
  43. }
  44. // EchoReq -- эхо запрос на сервер
  45. type EchoReq struct{}
  46. // EchoResp -- эхо ответ на запрос
  47. type EchoResp struct {
  48. Result string
  49. }
  50. // Echo -- эхо запрос для клиента
  51. func (sf *ServRpc) Echo(req *EchoReq, resp *EchoResp) error {
  52. log.Println("ServRpc.Echo()")
  53. resp.Result = "WarTank!"
  54. return nil
  55. }
  56. // LoginReq -- запрос на логин на сервер
  57. type LoginReq struct {
  58. Login string
  59. Pass string
  60. }
  61. // LoginResp -- ответ на запрос логина
  62. //
  63. // Вернёт ошибку если:
  64. // 1. Нужно создать админа
  65. // 2. Неверная пара логин/пароль
  66. type LoginResp struct {
  67. Result string
  68. }
  69. // Login -- запросвхода на сервер
  70. func (sf *ServRpc) Login(req *LoginReq, resp *LoginResp) error {
  71. log.Println("ServRpc.Login()")
  72. if !sf.checkUser(req.Login, req.Pass) {
  73. if err := sf.newUser(req.Login, req.Pass); err != nil {
  74. return fmt.Errorf("ServRpc.Login(): in create login(%q/%q), err=\n\t%w", req.Login, req.Pass, err)
  75. }
  76. }
  77. resp.Result = "ok"
  78. return nil
  79. }
  80. // Создаёт нового пользователя
  81. func (sf *ServRpc) newUser(login, pass string) error {
  82. log.Println("ServRpc.newUser()")
  83. if login == "" {
  84. return fmt.Errorf("ServRpc.newUser(): login is empty")
  85. }
  86. if pass == "" {
  87. return fmt.Errorf("ServRpc.newUser(): pass is empty")
  88. }
  89. store := sf.serv.Store()
  90. err := store.Put("/users/"+login, pass)
  91. if err != nil {
  92. return fmt.Errorf("ServRpc.newUser(): in create user, err=\n\t%w", err)
  93. }
  94. return nil
  95. }
  96. // AddBotReq -- запрос добавления бота на сервер
  97. type AddBotReq struct {
  98. Login string
  99. Pass string
  100. BotLogin string
  101. BotPass string
  102. }
  103. // AddBotResp -- ответ добавления бота на сервер
  104. type AddBotResp struct {
  105. Result string
  106. }
  107. // AddBot -- добавляет бота на сервер
  108. func (sf *ServRpc) AddBot(req *AddBotReq, resp *AddBotResp) error {
  109. log.Println("ServRpc.AddBot()")
  110. if !sf.checkUser(req.Login, req.Pass) {
  111. return fmt.Errorf("ServRpc.AddBot(): bad login/pass")
  112. }
  113. if !sf.checkBot(req.BotLogin, req.BotPass) {
  114. if err := sf.newBot(req.BotLogin, req.BotPass); err != nil {
  115. return fmt.Errorf("ServRpc.AddBot(): in save bot(%q/%q), err=\n\t%w", req.BotLogin, req.BotPass, err)
  116. }
  117. }
  118. resp.Result = "ok"
  119. return nil
  120. }
  121. // Создаёт нового бота по требованию
  122. func (sf *ServRpc) newBot(login, pass string) error {
  123. log.Println("ServRpc.newBot()")
  124. if login == "" {
  125. return fmt.Errorf("ServRpc.newBot(): login is empty")
  126. }
  127. if pass == "" {
  128. return fmt.Errorf("ServRpc.newBot(): pass is empty")
  129. }
  130. store := sf.serv.Store()
  131. err := store.Put("/bots/"+login, pass)
  132. if err != nil {
  133. return fmt.Errorf("ServRpc.newBot(): in create bot, err=\n\t%w", err)
  134. }
  135. strData, err := store.Get("/bots/list")
  136. if err != nil {
  137. return fmt.Errorf("ServRpc.newBot(): in get list bots, err=\n\t%w", err)
  138. }
  139. lstBots := make([]string, 0)
  140. err = json.Unmarshal([]byte(strData), &lstBots)
  141. if err != nil {
  142. return fmt.Errorf("ServRpc.newBot(): in unmarshall bots/list, err=\n\t%w", err)
  143. }
  144. lstBots = append(lstBots, login)
  145. binData, _ := json.Marshal(lstBots)
  146. err = store.Put("/bots/list", string(binData))
  147. if err != nil {
  148. return fmt.Errorf("ServRpc.newBot(): in save list bots, err=\n\t%w", err)
  149. }
  150. return nil
  151. }
  152. // Проверяет наличие бота в базе
  153. func (sf *ServRpc) checkBot(login, pass string) bool {
  154. log.Println("ServRpc.checkBot()")
  155. store := sf.serv.Store()
  156. binData, err := store.Get("/bots/" + login)
  157. if err != nil { // Нет такого логина бота
  158. return false
  159. }
  160. strPass := string(binData)
  161. return pass == strPass
  162. }
  163. // Проверяет пользователя по логину/паролю
  164. func (sf *ServRpc) checkUser(login, pass string) bool {
  165. log.Println("ServRpc.checkUser()")
  166. store := sf.serv.Store()
  167. binData, err := store.Get("/users/" + login)
  168. if err != nil { // Нет такого логина
  169. return false
  170. }
  171. strPass := string(binData)
  172. return pass == strPass
  173. }
  174. // BotStartReq -- запрос старта бота
  175. type BotStartReq struct {
  176. Login string
  177. Pass string
  178. BotLogin string
  179. }
  180. // BotStartResp -- ответ на запрос старта бота
  181. type BotStartResp struct {
  182. Result string
  183. }
  184. // BotStart -- стартует выбранного бота
  185. func (sf *ServRpc) BotStart(req *BotStartReq, resp *BotStartResp) error {
  186. log.Println("ServRpc.BotStart()")
  187. if !sf.checkUser(req.Login, req.Pass) {
  188. return fmt.Errorf("ServRpc.BotStart(): bad login/pass")
  189. }
  190. err := sf.serv.ServBots().BotStart(req.BotLogin)
  191. if err != nil {
  192. return fmt.Errorf("ServRpc.BotStart(): in run bot(%v), err=\n\t%w", req.BotLogin, err)
  193. }
  194. resp.Result = "ok"
  195. return nil
  196. }