main.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. package main
  2. import (
  3. "flag"
  4. "fmt"
  5. "log/slog"
  6. "net"
  7. "os"
  8. "sync"
  9. "github.com/joho/godotenv"
  10. "github.com/kelseyhightower/envconfig"
  11. "github.com/mk6i/retro-aim-server/config"
  12. "github.com/mk6i/retro-aim-server/foodgroup"
  13. "github.com/mk6i/retro-aim-server/server/http"
  14. "github.com/mk6i/retro-aim-server/server/oscar"
  15. "github.com/mk6i/retro-aim-server/server/oscar/handler"
  16. "github.com/mk6i/retro-aim-server/server/oscar/middleware"
  17. "github.com/mk6i/retro-aim-server/state"
  18. )
  19. // Default build fields are populated by GoReleaser
  20. var (
  21. version = "dev"
  22. commit = "none"
  23. date = "unknown"
  24. )
  25. func init() {
  26. cfgFile := flag.String("config", "settings.env", "Path to config file")
  27. showHelp := flag.Bool("help", false, "Display help")
  28. showVersion := flag.Bool("version", false, "Display build information")
  29. flag.Parse()
  30. switch {
  31. case *showVersion:
  32. fmt.Printf("%-10s %s\n", "version:", version)
  33. fmt.Printf("%-10s %s\n", "commit:", commit)
  34. fmt.Printf("%-10s %s\n", "date:", date)
  35. os.Exit(0)
  36. case *showHelp:
  37. flag.PrintDefaults()
  38. os.Exit(0)
  39. }
  40. // Optionally populate environment variables with config file
  41. if err := godotenv.Load(*cfgFile); err != nil {
  42. fmt.Printf("Config file (%s) not found, defaulting to env vars for app config...\n", *cfgFile)
  43. } else {
  44. fmt.Printf("Successfully loaded config file (%s)\n", *cfgFile)
  45. }
  46. }
  47. func main() {
  48. var cfg config.Config
  49. err := envconfig.Process("", &cfg)
  50. if err != nil {
  51. _, _ = fmt.Fprintf(os.Stderr, "unable to process app config: %s\n", err.Error())
  52. os.Exit(1)
  53. }
  54. feedbagStore, err := state.NewSQLiteUserStore(cfg.DBPath)
  55. if err != nil {
  56. _, _ = fmt.Fprintf(os.Stderr, "unable to create feedbag store: %s\n", err.Error())
  57. os.Exit(1)
  58. }
  59. cookieBaker, err := state.NewHMACCookieBaker()
  60. if err != nil {
  61. _, _ = fmt.Fprintf(os.Stderr, "unable to create HMAC cookie baker: %s\n", err.Error())
  62. os.Exit(1)
  63. }
  64. logger := middleware.NewLogger(cfg)
  65. sessionManager := state.NewInMemorySessionManager(logger)
  66. chatSessionManager := state.NewInMemoryChatSessionManager(logger)
  67. adjListBuddyListStore := state.NewAdjListBuddyListStore()
  68. wg := sync.WaitGroup{}
  69. wg.Add(7)
  70. go func() {
  71. bld := config.Build{
  72. Version: version,
  73. Commit: commit,
  74. Date: date,
  75. }
  76. http.StartManagementAPI(bld, cfg, feedbagStore, sessionManager, feedbagStore, feedbagStore, chatSessionManager,
  77. feedbagStore, sessionManager, feedbagStore, feedbagStore, feedbagStore, feedbagStore, logger)
  78. wg.Done()
  79. }()
  80. go func(logger *slog.Logger) {
  81. logger = logger.With("svc", "BOS")
  82. authService := foodgroup.NewAuthService(cfg, sessionManager, chatSessionManager, feedbagStore, adjListBuddyListStore, cookieBaker, sessionManager, feedbagStore, chatSessionManager, feedbagStore)
  83. bartService := foodgroup.NewBARTService(logger, feedbagStore, sessionManager, feedbagStore, adjListBuddyListStore)
  84. buddyService := foodgroup.NewBuddyService(sessionManager, feedbagStore, adjListBuddyListStore)
  85. chatNavService := foodgroup.NewChatNavService(logger, feedbagStore)
  86. feedbagService := foodgroup.NewFeedbagService(logger, sessionManager, feedbagStore, feedbagStore, adjListBuddyListStore)
  87. foodgroupService := foodgroup.NewPermitDenyService()
  88. icbmService := foodgroup.NewICBMService(sessionManager, feedbagStore, adjListBuddyListStore, feedbagStore)
  89. icqService := foodgroup.NewICQService(sessionManager, feedbagStore, feedbagStore, logger, sessionManager, feedbagStore)
  90. locateService := foodgroup.NewLocateService(sessionManager, feedbagStore, feedbagStore, adjListBuddyListStore)
  91. oServiceService := foodgroup.NewOServiceServiceForBOS(cfg, sessionManager, adjListBuddyListStore, logger, cookieBaker, feedbagStore, feedbagStore)
  92. oscar.BOSServer{
  93. AuthService: authService,
  94. Config: cfg,
  95. Handler: handler.NewBOSRouter(handler.Handlers{
  96. AlertHandler: handler.NewAlertHandler(logger),
  97. BARTHandler: handler.NewBARTHandler(logger, bartService),
  98. BuddyHandler: handler.NewBuddyHandler(logger, buddyService),
  99. ChatNavHandler: handler.NewChatNavHandler(chatNavService, logger),
  100. FeedbagHandler: handler.NewFeedbagHandler(logger, feedbagService),
  101. ICQHandler: handler.NewICQHandler(logger, icqService),
  102. ICBMHandler: handler.NewICBMHandler(logger, icbmService),
  103. LocateHandler: handler.NewLocateHandler(locateService, logger),
  104. OServiceHandler: handler.NewOServiceHandler(logger, oServiceService),
  105. PermitDenyHandler: handler.NewPermitDenyHandler(logger, foodgroupService),
  106. }),
  107. Logger: logger,
  108. OnlineNotifier: oServiceService,
  109. ListenAddr: net.JoinHostPort("", cfg.BOSPort),
  110. }.Start()
  111. wg.Done()
  112. }(logger)
  113. go func(logger *slog.Logger) {
  114. logger = logger.With("svc", "CHAT")
  115. sessionManager := state.NewInMemorySessionManager(logger)
  116. authService := foodgroup.NewAuthService(cfg, sessionManager, chatSessionManager, feedbagStore, adjListBuddyListStore, cookieBaker, sessionManager, feedbagStore, chatSessionManager, feedbagStore)
  117. chatService := foodgroup.NewChatService(chatSessionManager)
  118. oServiceService := foodgroup.NewOServiceServiceForChat(cfg, logger, sessionManager, adjListBuddyListStore, feedbagStore, feedbagStore, chatSessionManager)
  119. oscar.ChatServer{
  120. AuthService: authService,
  121. Config: cfg,
  122. Handler: handler.NewChatRouter(handler.Handlers{
  123. ChatHandler: handler.NewChatHandler(logger, chatService),
  124. OServiceHandler: handler.NewOServiceHandler(logger, oServiceService),
  125. }),
  126. Logger: logger,
  127. OnlineNotifier: oServiceService,
  128. }.Start()
  129. wg.Done()
  130. }(logger)
  131. go func(logger *slog.Logger) {
  132. logger = logger.With("svc", "CHAT_NAV")
  133. sessionManager := state.NewInMemorySessionManager(logger)
  134. authService := foodgroup.NewAuthService(cfg, sessionManager, chatSessionManager, feedbagStore, adjListBuddyListStore, cookieBaker, sessionManager, feedbagStore, chatSessionManager, feedbagStore)
  135. chatNavService := foodgroup.NewChatNavService(logger, feedbagStore)
  136. oServiceService := foodgroup.NewOServiceServiceForChatNav(cfg, logger, sessionManager, adjListBuddyListStore, feedbagStore)
  137. oscar.BOSServer{
  138. AuthService: authService,
  139. Config: cfg,
  140. Handler: handler.NewChatNavRouter(handler.Handlers{
  141. ChatNavHandler: handler.NewChatNavHandler(chatNavService, logger),
  142. OServiceHandler: handler.NewOServiceHandler(logger, oServiceService),
  143. }),
  144. Logger: logger,
  145. OnlineNotifier: oServiceService,
  146. ListenAddr: net.JoinHostPort("", cfg.ChatNavPort),
  147. }.Start()
  148. wg.Done()
  149. }(logger)
  150. go func(logger *slog.Logger) {
  151. logger = logger.With("svc", "ALERT")
  152. sessionManager := state.NewInMemorySessionManager(logger)
  153. authService := foodgroup.NewAuthService(cfg, sessionManager, chatSessionManager, feedbagStore, adjListBuddyListStore, cookieBaker, sessionManager, feedbagStore, chatSessionManager, feedbagStore)
  154. oServiceService := foodgroup.NewOServiceServiceForAlert(cfg, logger, sessionManager, adjListBuddyListStore, feedbagStore)
  155. oscar.BOSServer{
  156. AuthService: authService,
  157. Config: cfg,
  158. Handler: handler.NewAlertRouter(handler.Handlers{
  159. AlertHandler: handler.NewAlertHandler(logger),
  160. OServiceHandler: handler.NewOServiceHandler(logger, oServiceService),
  161. }),
  162. Logger: logger,
  163. OnlineNotifier: oServiceService,
  164. ListenAddr: net.JoinHostPort("", cfg.AlertPort),
  165. }.Start()
  166. wg.Done()
  167. }(logger)
  168. go func(logger *slog.Logger) {
  169. logger = logger.With("svc", "ADMIN")
  170. buddyService := foodgroup.NewBuddyService(sessionManager, feedbagStore, adjListBuddyListStore)
  171. adminService := foodgroup.NewAdminService(sessionManager, feedbagStore, buddyService, sessionManager)
  172. authService := foodgroup.NewAuthService(cfg, sessionManager, chatSessionManager, feedbagStore, adjListBuddyListStore, cookieBaker, sessionManager, feedbagStore, chatSessionManager, feedbagStore)
  173. oServiceService := foodgroup.NewOServiceServiceForAdmin(cfg, logger, buddyService)
  174. oscar.AdminServer{
  175. AuthService: authService,
  176. Config: cfg,
  177. Handler: handler.NewAdminRouter(handler.Handlers{
  178. AdminHandler: handler.NewAdminHandler(logger, adminService),
  179. OServiceHandler: handler.NewOServiceHandler(logger, oServiceService),
  180. }),
  181. Logger: logger,
  182. OnlineNotifier: oServiceService,
  183. ListenAddr: net.JoinHostPort("", cfg.AdminPort),
  184. }.Start()
  185. wg.Done()
  186. }(logger)
  187. go func(logger *slog.Logger) {
  188. logger = logger.With("svc", "BART")
  189. sessionManager := state.NewInMemorySessionManager(logger)
  190. bartService := foodgroup.NewBARTService(logger, feedbagStore, sessionManager, feedbagStore, adjListBuddyListStore)
  191. authService := foodgroup.NewAuthService(cfg, sessionManager, chatSessionManager, feedbagStore, adjListBuddyListStore, cookieBaker, sessionManager, feedbagStore, chatSessionManager, feedbagStore)
  192. oServiceService := foodgroup.NewOServiceServiceForBART(cfg, logger, sessionManager, adjListBuddyListStore, feedbagStore)
  193. oscar.BOSServer{
  194. AuthService: authService,
  195. Config: cfg,
  196. Handler: handler.NewBARTRouter(handler.Handlers{
  197. BARTHandler: handler.NewBARTHandler(logger, bartService),
  198. OServiceHandler: handler.NewOServiceHandler(logger, oServiceService),
  199. }),
  200. ListenAddr: net.JoinHostPort("", cfg.BARTPort),
  201. Logger: logger,
  202. OnlineNotifier: oServiceService,
  203. }.Start()
  204. wg.Done()
  205. }(logger)
  206. go func(logger *slog.Logger) {
  207. logger = logger.With("svc", "AUTH")
  208. authHandler := foodgroup.NewAuthService(cfg, sessionManager, chatSessionManager, feedbagStore, adjListBuddyListStore, cookieBaker, nil, nil, chatSessionManager, feedbagStore)
  209. oscar.AuthServer{
  210. AuthService: authHandler,
  211. Config: cfg,
  212. Logger: logger,
  213. }.Start()
  214. wg.Done()
  215. }(logger)
  216. go func(logger *slog.Logger) {
  217. logger = logger.With("svc", "ODIR")
  218. sessionManager := state.NewInMemorySessionManager(logger)
  219. authService := foodgroup.NewAuthService(cfg, sessionManager, chatSessionManager, feedbagStore, adjListBuddyListStore, cookieBaker, sessionManager, feedbagStore, chatSessionManager, feedbagStore)
  220. oServiceService := foodgroup.NewOServiceServiceForODir(cfg, logger)
  221. oDirService := foodgroup.NewODirService(logger, feedbagStore)
  222. oscar.BOSServer{
  223. AuthService: authService,
  224. Config: cfg,
  225. Handler: handler.NewODirRouter(handler.Handlers{
  226. OServiceHandler: handler.NewOServiceHandler(logger, oServiceService),
  227. ODirHandler: handler.NewODirHandler(logger, oDirService),
  228. }),
  229. Logger: logger,
  230. OnlineNotifier: oServiceService,
  231. ListenAddr: net.JoinHostPort("", cfg.ODirPort),
  232. }.Start()
  233. wg.Done()
  234. }(logger)
  235. wg.Wait()
  236. }