router.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425
  1. package router
  2. import (
  3. "fmt"
  4. "net/http"
  5. "time"
  6. "github.com/nanmu42/gzip"
  7. "github.com/prometheus/client_golang/prometheus/promhttp"
  8. log "github.com/sirupsen/logrus"
  9. "golang.org/x/net/http2"
  10. "golang.org/x/net/http2/h2c"
  11. "github.com/owncast/owncast/activitypub"
  12. "github.com/owncast/owncast/config"
  13. "github.com/owncast/owncast/controllers"
  14. "github.com/owncast/owncast/controllers/admin"
  15. fediverseauth "github.com/owncast/owncast/controllers/auth/fediverse"
  16. "github.com/owncast/owncast/controllers/auth/indieauth"
  17. "github.com/owncast/owncast/controllers/moderation"
  18. "github.com/owncast/owncast/core/chat"
  19. "github.com/owncast/owncast/core/data"
  20. "github.com/owncast/owncast/core/user"
  21. "github.com/owncast/owncast/router/middleware"
  22. "github.com/owncast/owncast/utils"
  23. "github.com/owncast/owncast/yp"
  24. )
  25. // Start starts the router for the http, ws, and rtmp.
  26. func Start() error {
  27. // The primary web app.
  28. http.HandleFunc("/", controllers.IndexHandler)
  29. // The admin web app.
  30. http.HandleFunc("/admin", middleware.RequireAdminAuth(controllers.IndexHandler))
  31. // Images
  32. http.HandleFunc("/thumbnail.jpg", controllers.GetThumbnail)
  33. http.HandleFunc("/preview.gif", controllers.GetPreview)
  34. http.HandleFunc("/logo", controllers.GetLogo)
  35. // Custom Javascript
  36. http.HandleFunc("/customjavascript", controllers.ServeCustomJavascript)
  37. // Return a single emoji image.
  38. http.HandleFunc(config.EmojiDir, controllers.GetCustomEmojiImage)
  39. // return the logo
  40. // return a logo that's compatible with external social networks
  41. http.HandleFunc("/logo/external", controllers.GetCompatibleLogo)
  42. // status of the system
  43. http.HandleFunc("/api/status", controllers.GetStatus)
  44. // custom emoji supported in the chat
  45. http.HandleFunc("/api/emoji", controllers.GetCustomEmojiList)
  46. // chat rest api
  47. http.HandleFunc("/api/chat", middleware.RequireUserAccessToken(controllers.GetChatMessages))
  48. // web config api
  49. http.HandleFunc("/api/config", controllers.GetWebConfig)
  50. // return the YP protocol data
  51. http.HandleFunc("/api/yp", yp.GetYPResponse)
  52. // list of all social platforms
  53. http.HandleFunc("/api/socialplatforms", controllers.GetAllSocialPlatforms)
  54. // return the list of video variants available
  55. http.HandleFunc("/api/video/variants", controllers.GetVideoStreamOutputVariants)
  56. // tell the backend you're an active viewer
  57. http.HandleFunc("/api/ping", controllers.Ping)
  58. // register a new chat user
  59. http.HandleFunc("/api/chat/register", controllers.RegisterAnonymousChatUser)
  60. // return remote follow details
  61. http.HandleFunc("/api/remotefollow", controllers.RemoteFollow)
  62. // return followers
  63. http.HandleFunc("/api/followers", middleware.HandlePagination(controllers.GetFollowers))
  64. // save client video playback metrics
  65. http.HandleFunc("/api/metrics/playback", controllers.ReportPlaybackMetrics)
  66. // Register for notifications
  67. http.HandleFunc("/api/notifications/register", middleware.RequireUserAccessToken(controllers.RegisterForLiveNotifications))
  68. // Authenticated admin requests
  69. // Current inbound broadcaster
  70. http.HandleFunc("/api/admin/status", middleware.RequireAdminAuth(admin.Status))
  71. // Return HLS video
  72. http.HandleFunc("/hls/", controllers.HandleHLSRequest)
  73. // Disconnect inbound stream
  74. http.HandleFunc("/api/admin/disconnect", middleware.RequireAdminAuth(admin.DisconnectInboundConnection))
  75. // Server config
  76. http.HandleFunc("/api/admin/serverconfig", middleware.RequireAdminAuth(admin.GetServerConfig))
  77. // Get viewer count over time
  78. http.HandleFunc("/api/admin/viewersOverTime", middleware.RequireAdminAuth(admin.GetViewersOverTime))
  79. // Get active viewers
  80. http.HandleFunc("/api/admin/viewers", middleware.RequireAdminAuth(admin.GetActiveViewers))
  81. // Get hardware stats
  82. http.HandleFunc("/api/admin/hardwarestats", middleware.RequireAdminAuth(admin.GetHardwareStats))
  83. // Get a a detailed list of currently connected chat clients
  84. http.HandleFunc("/api/admin/chat/clients", middleware.RequireAdminAuth(admin.GetConnectedChatClients))
  85. // Get all logs
  86. http.HandleFunc("/api/admin/logs", middleware.RequireAdminAuth(admin.GetLogs))
  87. // Get warning/error logs
  88. http.HandleFunc("/api/admin/logs/warnings", middleware.RequireAdminAuth(admin.GetWarnings))
  89. // Get all chat messages for the admin, unfiltered.
  90. http.HandleFunc("/api/admin/chat/messages", middleware.RequireAdminAuth(admin.GetChatMessages))
  91. // Update chat message visibility
  92. http.HandleFunc("/api/admin/chat/messagevisibility", middleware.RequireAdminAuth(admin.UpdateMessageVisibility))
  93. // Enable/disable a user
  94. http.HandleFunc("/api/admin/chat/users/setenabled", middleware.RequireAdminAuth(admin.UpdateUserEnabled))
  95. // Ban/unban an IP address
  96. http.HandleFunc("/api/admin/chat/users/ipbans/create", middleware.RequireAdminAuth(admin.BanIPAddress))
  97. // Remove an IP address ban
  98. http.HandleFunc("/api/admin/chat/users/ipbans/remove", middleware.RequireAdminAuth(admin.UnBanIPAddress))
  99. // Return all the banned IP addresses
  100. http.HandleFunc("/api/admin/chat/users/ipbans", middleware.RequireAdminAuth(admin.GetIPAddressBans))
  101. // Get a list of disabled users
  102. http.HandleFunc("/api/admin/chat/users/disabled", middleware.RequireAdminAuth(admin.GetDisabledUsers))
  103. // Set moderator status for a user
  104. http.HandleFunc("/api/admin/chat/users/setmoderator", middleware.RequireAdminAuth(admin.UpdateUserModerator))
  105. // Get a list of moderator users
  106. http.HandleFunc("/api/admin/chat/users/moderators", middleware.RequireAdminAuth(admin.GetModerators))
  107. // return followers
  108. http.HandleFunc("/api/admin/followers", middleware.RequireAdminAuth(middleware.HandlePagination(controllers.GetFollowers)))
  109. // Get a list of pending follow requests
  110. http.HandleFunc("/api/admin/followers/pending", middleware.RequireAdminAuth(admin.GetPendingFollowRequests))
  111. // Get a list of rejected or blocked follows
  112. http.HandleFunc("/api/admin/followers/blocked", middleware.RequireAdminAuth(admin.GetBlockedAndRejectedFollowers))
  113. // Set the following state of a follower or follow request.
  114. http.HandleFunc("/api/admin/followers/approve", middleware.RequireAdminAuth(admin.ApproveFollower))
  115. // Upload custom emoji
  116. http.HandleFunc("/api/admin/emoji/upload", middleware.RequireAdminAuth(admin.UploadCustomEmoji))
  117. // Delete custom emoji
  118. http.HandleFunc("/api/admin/emoji/delete", middleware.RequireAdminAuth(admin.DeleteCustomEmoji))
  119. // Update config values
  120. // Change the current streaming key in memory
  121. http.HandleFunc("/api/admin/config/adminpass", middleware.RequireAdminAuth(admin.SetAdminPassword))
  122. // Set an array of valid stream keys
  123. http.HandleFunc("/api/admin/config/streamkeys", middleware.RequireAdminAuth(admin.SetStreamKeys))
  124. // Change the extra page content in memory
  125. http.HandleFunc("/api/admin/config/pagecontent", middleware.RequireAdminAuth(admin.SetExtraPageContent))
  126. // Stream title
  127. http.HandleFunc("/api/admin/config/streamtitle", middleware.RequireAdminAuth(admin.SetStreamTitle))
  128. // Server name
  129. http.HandleFunc("/api/admin/config/name", middleware.RequireAdminAuth(admin.SetServerName))
  130. // Server summary
  131. http.HandleFunc("/api/admin/config/serversummary", middleware.RequireAdminAuth(admin.SetServerSummary))
  132. // Offline message
  133. http.HandleFunc("/api/admin/config/offlinemessage", middleware.RequireAdminAuth(admin.SetCustomOfflineMessage))
  134. // Server welcome message
  135. http.HandleFunc("/api/admin/config/welcomemessage", middleware.RequireAdminAuth(admin.SetServerWelcomeMessage))
  136. // Disable chat
  137. http.HandleFunc("/api/admin/config/chat/disable", middleware.RequireAdminAuth(admin.SetChatDisabled))
  138. // Disable chat user join messages
  139. http.HandleFunc("/api/admin/config/chat/joinmessagesenabled", middleware.RequireAdminAuth(admin.SetChatJoinMessagesEnabled))
  140. // Enable/disable chat established user mode
  141. http.HandleFunc("/api/admin/config/chat/establishedusermode", middleware.RequireAdminAuth(admin.SetEnableEstablishedChatUserMode))
  142. // Set chat usernames that are not allowed
  143. http.HandleFunc("/api/admin/config/chat/forbiddenusernames", middleware.RequireAdminAuth(admin.SetForbiddenUsernameList))
  144. // Set the suggested chat usernames that will be assigned automatically
  145. http.HandleFunc("/api/admin/config/chat/suggestedusernames", middleware.RequireAdminAuth(admin.SetSuggestedUsernameList))
  146. // Set video codec
  147. http.HandleFunc("/api/admin/config/video/codec", middleware.RequireAdminAuth(admin.SetVideoCodec))
  148. // Set style/color/css values
  149. http.HandleFunc("/api/admin/config/appearance", middleware.RequireAdminAuth(admin.SetCustomColorVariableValues))
  150. // Return all webhooks
  151. http.HandleFunc("/api/admin/webhooks", middleware.RequireAdminAuth(admin.GetWebhooks))
  152. // Delete a single webhook
  153. http.HandleFunc("/api/admin/webhooks/delete", middleware.RequireAdminAuth(admin.DeleteWebhook))
  154. // Create a single webhook
  155. http.HandleFunc("/api/admin/webhooks/create", middleware.RequireAdminAuth(admin.CreateWebhook))
  156. // Get all access tokens
  157. http.HandleFunc("/api/admin/accesstokens", middleware.RequireAdminAuth(admin.GetExternalAPIUsers))
  158. // Delete a single access token
  159. http.HandleFunc("/api/admin/accesstokens/delete", middleware.RequireAdminAuth(admin.DeleteExternalAPIUser))
  160. // Create a single access token
  161. http.HandleFunc("/api/admin/accesstokens/create", middleware.RequireAdminAuth(admin.CreateExternalAPIUser))
  162. // Return the auto-update features that are supported for this instance.
  163. http.HandleFunc("/api/admin/update/options", middleware.RequireAdminAuth(admin.AutoUpdateOptions))
  164. // Begin the auto update
  165. http.HandleFunc("/api/admin/update/start", middleware.RequireAdminAuth(admin.AutoUpdateStart))
  166. // Force quit the service to restart it
  167. http.HandleFunc("/api/admin/update/forcequit", middleware.RequireAdminAuth(admin.AutoUpdateForceQuit))
  168. // Send a system message to chat
  169. http.HandleFunc("/api/integrations/chat/system", middleware.RequireExternalAPIAccessToken(user.ScopeCanSendSystemMessages, admin.SendSystemMessage))
  170. // Send a system message to a single client
  171. http.HandleFunc(utils.RestEndpoint("/api/integrations/chat/system/client/{clientId}", middleware.RequireExternalAPIAccessToken(user.ScopeCanSendSystemMessages, admin.SendSystemMessageToConnectedClient)))
  172. // Send a user message to chat *NO LONGER SUPPORTED
  173. http.HandleFunc("/api/integrations/chat/user", middleware.RequireExternalAPIAccessToken(user.ScopeCanSendChatMessages, admin.SendUserMessage))
  174. // Send a message to chat as a specific 3rd party bot/integration based on its access token
  175. http.HandleFunc("/api/integrations/chat/send", middleware.RequireExternalAPIAccessToken(user.ScopeCanSendChatMessages, admin.SendIntegrationChatMessage))
  176. // Send a user action to chat
  177. http.HandleFunc("/api/integrations/chat/action", middleware.RequireExternalAPIAccessToken(user.ScopeCanSendSystemMessages, admin.SendChatAction))
  178. // Hide chat message
  179. http.HandleFunc("/api/integrations/chat/messagevisibility", middleware.RequireExternalAPIAccessToken(user.ScopeHasAdminAccess, admin.ExternalUpdateMessageVisibility))
  180. // Stream title
  181. http.HandleFunc("/api/integrations/streamtitle", middleware.RequireExternalAPIAccessToken(user.ScopeHasAdminAccess, admin.ExternalSetStreamTitle))
  182. // Get chat history
  183. http.HandleFunc("/api/integrations/chat", middleware.RequireExternalAPIAccessToken(user.ScopeHasAdminAccess, controllers.ExternalGetChatMessages))
  184. // Connected clients
  185. http.HandleFunc("/api/integrations/clients", middleware.RequireExternalAPIAccessToken(user.ScopeHasAdminAccess, admin.ExternalGetConnectedChatClients))
  186. // Logo path
  187. http.HandleFunc("/api/admin/config/logo", middleware.RequireAdminAuth(admin.SetLogo))
  188. // Server tags
  189. http.HandleFunc("/api/admin/config/tags", middleware.RequireAdminAuth(admin.SetTags))
  190. // ffmpeg
  191. http.HandleFunc("/api/admin/config/ffmpegpath", middleware.RequireAdminAuth(admin.SetFfmpegPath))
  192. // Server http port
  193. http.HandleFunc("/api/admin/config/webserverport", middleware.RequireAdminAuth(admin.SetWebServerPort))
  194. // Server http listen address
  195. http.HandleFunc("/api/admin/config/webserverip", middleware.RequireAdminAuth(admin.SetWebServerIP))
  196. // Server rtmp port
  197. http.HandleFunc("/api/admin/config/rtmpserverport", middleware.RequireAdminAuth(admin.SetRTMPServerPort))
  198. // Websocket host override
  199. http.HandleFunc("/api/admin/config/sockethostoverride", middleware.RequireAdminAuth(admin.SetSocketHostOverride))
  200. // Is server marked as NSFW
  201. http.HandleFunc("/api/admin/config/nsfw", middleware.RequireAdminAuth(admin.SetNSFW))
  202. // directory enabled
  203. http.HandleFunc("/api/admin/config/directoryenabled", middleware.RequireAdminAuth(admin.SetDirectoryEnabled))
  204. // social handles
  205. http.HandleFunc("/api/admin/config/socialhandles", middleware.RequireAdminAuth(admin.SetSocialHandles))
  206. // set the number of video segments and duration per segment in a playlist
  207. http.HandleFunc("/api/admin/config/video/streamlatencylevel", middleware.RequireAdminAuth(admin.SetStreamLatencyLevel))
  208. // set an array of video output configurations
  209. http.HandleFunc("/api/admin/config/video/streamoutputvariants", middleware.RequireAdminAuth(admin.SetStreamOutputVariants))
  210. // set s3 configuration
  211. http.HandleFunc("/api/admin/config/s3", middleware.RequireAdminAuth(admin.SetS3Configuration))
  212. // set server url
  213. http.HandleFunc("/api/admin/config/serverurl", middleware.RequireAdminAuth(admin.SetServerURL))
  214. // reset the YP registration
  215. http.HandleFunc("/api/admin/yp/reset", middleware.RequireAdminAuth(admin.ResetYPRegistration))
  216. // set external action links
  217. http.HandleFunc("/api/admin/config/externalactions", middleware.RequireAdminAuth(admin.SetExternalActions))
  218. // set custom style css
  219. http.HandleFunc("/api/admin/config/customstyles", middleware.RequireAdminAuth(admin.SetCustomStyles))
  220. // set custom style javascript
  221. http.HandleFunc("/api/admin/config/customjavascript", middleware.RequireAdminAuth(admin.SetCustomJavascript))
  222. // Video playback metrics
  223. http.HandleFunc("/api/admin/metrics/video", middleware.RequireAdminAuth(admin.GetVideoPlaybackMetrics))
  224. // Is the viewer count hidden from viewers
  225. http.HandleFunc("/api/admin/config/hideviewercount", middleware.RequireAdminAuth(admin.SetHideViewerCount))
  226. // Inline chat moderation actions
  227. // Update chat message visibility
  228. http.HandleFunc("/api/chat/messagevisibility", middleware.RequireUserModerationScopeAccesstoken(admin.UpdateMessageVisibility))
  229. // Enable/disable a user
  230. http.HandleFunc("/api/chat/users/setenabled", middleware.RequireUserModerationScopeAccesstoken(admin.UpdateUserEnabled))
  231. // Get a user's details
  232. http.HandleFunc("/api/moderation/chat/user/", middleware.RequireUserModerationScopeAccesstoken(moderation.GetUserDetails))
  233. // Configure Federation features
  234. // enable/disable federation features
  235. http.HandleFunc("/api/admin/config/federation/enable", middleware.RequireAdminAuth(admin.SetFederationEnabled))
  236. // set if federation activities are private
  237. http.HandleFunc("/api/admin/config/federation/private", middleware.RequireAdminAuth(admin.SetFederationActivityPrivate))
  238. // set if fediverse engagement appears in chat
  239. http.HandleFunc("/api/admin/config/federation/showengagement", middleware.RequireAdminAuth(admin.SetFederationShowEngagement))
  240. // set local federated username
  241. http.HandleFunc("/api/admin/config/federation/username", middleware.RequireAdminAuth(admin.SetFederationUsername))
  242. // set federated go live message
  243. http.HandleFunc("/api/admin/config/federation/livemessage", middleware.RequireAdminAuth(admin.SetFederationGoLiveMessage))
  244. // Federation blocked domains
  245. http.HandleFunc("/api/admin/config/federation/blockdomains", middleware.RequireAdminAuth(admin.SetFederationBlockDomains))
  246. // send a public message to the Fediverse from the server's user
  247. http.HandleFunc("/api/admin/federation/send", middleware.RequireAdminAuth(admin.SendFederatedMessage))
  248. // Return federated activities
  249. http.HandleFunc("/api/admin/federation/actions", middleware.RequireAdminAuth(middleware.HandlePagination(admin.GetFederatedActions)))
  250. // Prometheus metrics
  251. http.Handle("/api/admin/prometheus", middleware.RequireAdminAuth(func(rw http.ResponseWriter, r *http.Request) {
  252. promhttp.Handler().ServeHTTP(rw, r)
  253. }))
  254. // Configure outbound notification channels.
  255. http.HandleFunc("/api/admin/config/notifications/discord", middleware.RequireAdminAuth(admin.SetDiscordNotificationConfiguration))
  256. http.HandleFunc("/api/admin/config/notifications/browser", middleware.RequireAdminAuth(admin.SetBrowserNotificationConfiguration))
  257. // Auth
  258. // Start auth flow
  259. http.HandleFunc("/api/auth/indieauth", middleware.RequireUserAccessToken(indieauth.StartAuthFlow))
  260. http.HandleFunc("/api/auth/indieauth/callback", indieauth.HandleRedirect)
  261. http.HandleFunc("/api/auth/provider/indieauth", indieauth.HandleAuthEndpoint)
  262. http.HandleFunc("/api/auth/fediverse", middleware.RequireUserAccessToken(fediverseauth.RegisterFediverseOTPRequest))
  263. http.HandleFunc("/api/auth/fediverse/verify", fediverseauth.VerifyFediverseOTPRequest)
  264. // ActivityPub has its own router
  265. activitypub.Start(data.GetDatastore())
  266. // websocket
  267. http.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) {
  268. chat.HandleClientConnection(w, r)
  269. })
  270. // Optional public static files
  271. http.Handle("/public/", http.StripPrefix("/public/", http.FileServer(http.Dir(config.PublicFilesPath))))
  272. port := config.WebServerPort
  273. ip := config.WebServerIP
  274. // Create a custom mux handler to intercept the /debug/vars endpoint.
  275. // This is a hack because Prometheus enables this endpoint by default
  276. // due to its use of expvar and we do not want this exposed.
  277. h2s := &http2.Server{}
  278. defaultMux := h2c.NewHandler(http.DefaultServeMux, h2s)
  279. m := http.NewServeMux()
  280. m.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
  281. if r.URL.Path == "/debug/vars" {
  282. w.WriteHeader(http.StatusNotFound)
  283. return
  284. } else {
  285. defaultMux.ServeHTTP(w, r)
  286. }
  287. })
  288. server := &http.Server{
  289. Addr: fmt.Sprintf("%s:%d", ip, port),
  290. ReadHeaderTimeout: 4 * time.Second,
  291. Handler: gzip.DefaultHandler().WrapHandler(m),
  292. }
  293. log.Infof("Web server is listening on IP %s port %d.", ip, port)
  294. log.Infoln("The web admin interface is available at /admin.")
  295. return server.ListenAndServe()
  296. }