From 93c0a20935a4cfa551791a46b00aa5b6c8098368 Mon Sep 17 00:00:00 2001 From: Gabe Kangas Date: Mon, 1 Jul 2024 21:44:37 -0700 Subject: [PATCH] chore(api): reorganize handlers into webserver package --- controllers/admin.go | 13 - controllers/config.go | 155 ------ go.mod | 2 +- go.sum | 32 +- webserver/handlers/admin.go | 14 +- .../handlers}/admin/appearance.go | 8 +- .../handlers}/admin/chat.go | 96 ++-- .../handlers}/admin/config.go | 226 ++++---- .../handlers}/admin/connectedClients.go | 4 +- .../handlers}/admin/disconnect.go | 6 +- .../handlers}/admin/emoji.go | 24 +- .../handlers}/admin/externalAPIUsers.go | 28 +- .../handlers}/admin/federation.go | 42 +- .../handlers}/admin/followers.go | 22 +- .../handlers}/admin/hardware.go | 0 .../handlers}/admin/logs.go | 0 .../handlers}/admin/notifications.go | 14 +- .../handlers}/admin/serverConfig.go | 0 .../handlers}/admin/status.go | 0 .../handlers}/admin/update.go | 10 +- .../handlers}/admin/video.go | 0 .../handlers}/admin/viewers.go | 6 +- .../handlers}/admin/webhooks.go | 24 +- .../handlers}/admin/yp.go | 6 +- webserver/handlers/auth.go | 4 +- .../handlers}/auth/fediverse/fediverse.go | 22 +- .../handlers}/auth/indieauth/client.go | 16 +- .../handlers}/auth/indieauth/server.go | 12 +- {controllers => webserver/handlers}/chat.go | 13 +- webserver/handlers/config.go | 506 +++++------------- webserver/handlers/configInterface.go | 368 +++++++++++++ .../handlers}/constants.go | 2 +- .../handlers}/customJavascript.go | 2 +- {controllers => webserver/handlers}/emoji.go | 5 +- .../handlers}/followers.go | 9 +- webserver/handlers/handler.go | 29 +- {controllers => webserver/handlers}/hls.go | 2 +- {controllers => webserver/handlers}/images.go | 2 +- {controllers => webserver/handlers}/index.go | 2 +- webserver/handlers/integrations.go | 7 +- {controllers => webserver/handlers}/logo.go | 2 +- webserver/handlers/moderation.go | 2 +- .../handlers}/moderation/moderation.go | 4 +- .../handlers}/notifications.go | 11 +- {controllers => webserver/handlers}/ping.go | 2 +- .../handlers}/playbackMetrics.go | 7 +- .../handlers}/remoteFollow.go | 13 +- {controllers => webserver/handlers}/robots.go | 2 +- {controllers => webserver/handlers}/status.go | 5 +- {controllers => webserver/handlers}/video.go | 5 +- {controllers => webserver/handlers}/web.go | 2 +- webserver/router/router.go | 39 +- .../utils}/pagination.go | 2 +- .../utils/responses.go | 8 +- 54 files changed, 904 insertions(+), 933 deletions(-) delete mode 100644 controllers/admin.go delete mode 100644 controllers/config.go rename {controllers => webserver/handlers}/admin/appearance.go (66%) rename {controllers => webserver/handlers}/admin/chat.go (75%) rename {controllers => webserver/handlers}/admin/config.go (69%) rename {controllers => webserver/handlers}/admin/connectedClients.go (87%) rename {controllers => webserver/handlers}/admin/disconnect.go (62%) rename {controllers => webserver/handlers}/admin/emoji.go (63%) rename {controllers => webserver/handlers}/admin/externalAPIUsers.go (75%) rename {controllers => webserver/handlers}/admin/federation.go (73%) rename {controllers => webserver/handlers}/admin/followers.go (73%) rename {controllers => webserver/handlers}/admin/hardware.go (100%) rename {controllers => webserver/handlers}/admin/logs.go (100%) rename {controllers => webserver/handlers}/admin/notifications.go (63%) rename {controllers => webserver/handlers}/admin/serverConfig.go (100%) rename {controllers => webserver/handlers}/admin/status.go (100%) rename {controllers => webserver/handlers}/admin/update.go (94%) rename {controllers => webserver/handlers}/admin/video.go (100%) rename {controllers => webserver/handlers}/admin/viewers.go (90%) rename {controllers => webserver/handlers}/admin/webhooks.go (70%) rename {controllers => webserver/handlers}/admin/yp.go (71%) rename {controllers => webserver/handlers}/auth/fediverse/fediverse.go (79%) rename {controllers => webserver/handlers}/auth/indieauth/client.go (86%) rename {controllers => webserver/handlers}/auth/indieauth/server.go (87%) rename {controllers => webserver/handlers}/chat.go (88%) create mode 100644 webserver/handlers/configInterface.go rename {controllers => webserver/handlers}/constants.go (83%) rename {controllers => webserver/handlers}/customJavascript.go (94%) rename {controllers => webserver/handlers}/emoji.go (87%) rename {controllers => webserver/handlers}/followers.go (65%) rename {controllers => webserver/handlers}/hls.go (98%) rename {controllers => webserver/handlers}/images.go (99%) rename {controllers => webserver/handlers}/index.go (99%) rename {controllers => webserver/handlers}/logo.go (99%) rename {controllers => webserver/handlers}/moderation/moderation.go (95%) rename {controllers => webserver/handlers}/notifications.go (75%) rename {controllers => webserver/handlers}/ping.go (94%) rename {controllers => webserver/handlers}/playbackMetrics.go (87%) rename {controllers => webserver/handlers}/remoteFollow.go (75%) rename {controllers => webserver/handlers}/robots.go (96%) rename {controllers => webserver/handlers}/status.go (92%) rename {controllers => webserver/handlers}/video.go (93%) rename {controllers => webserver/handlers}/web.go (92%) rename {controllers => webserver/utils}/pagination.go (90%) rename controllers/controllers.go => webserver/utils/responses.go (90%) diff --git a/controllers/admin.go b/controllers/admin.go deleted file mode 100644 index 47a400bc0..000000000 --- a/controllers/admin.go +++ /dev/null @@ -1,13 +0,0 @@ -package controllers - -import ( - "net/http" - - "github.com/owncast/owncast/core/rtmp" -) - -// DisconnectInboundConnection will force-disconnect an inbound stream. -func DisconnectInboundConnection(w http.ResponseWriter, r *http.Request) { - rtmp.Disconnect() - w.WriteHeader(http.StatusOK) -} diff --git a/controllers/config.go b/controllers/config.go deleted file mode 100644 index cd2fac3ce..000000000 --- a/controllers/config.go +++ /dev/null @@ -1,155 +0,0 @@ -package controllers - -import ( - "encoding/json" - "fmt" - "net/http" - "net/url" - - "github.com/owncast/owncast/activitypub" - "github.com/owncast/owncast/config" - "github.com/owncast/owncast/core/data" - "github.com/owncast/owncast/models" - "github.com/owncast/owncast/utils" - "github.com/owncast/owncast/webserver/router/middleware" - log "github.com/sirupsen/logrus" -) - -type webConfigResponse struct { - AppearanceVariables map[string]string `json:"appearanceVariables"` - Name string `json:"name"` - CustomStyles string `json:"customStyles"` - StreamTitle string `json:"streamTitle,omitempty"` // What's going on with the current stream - OfflineMessage string `json:"offlineMessage"` - Logo string `json:"logo"` - Version string `json:"version"` - SocketHostOverride string `json:"socketHostOverride,omitempty"` - ExtraPageContent string `json:"extraPageContent"` - Summary string `json:"summary"` - Tags []string `json:"tags"` - SocialHandles []models.SocialHandle `json:"socialHandles"` - ExternalActions []models.ExternalAction `json:"externalActions"` - Notifications notificationsConfigResponse `json:"notifications"` - Federation federationConfigResponse `json:"federation"` - MaxSocketPayloadSize int `json:"maxSocketPayloadSize"` - HideViewerCount bool `json:"hideViewerCount"` - ChatDisabled bool `json:"chatDisabled"` - ChatSpamProtectionDisabled bool `json:"chatSpamProtectionDisabled"` - NSFW bool `json:"nsfw"` - Authentication authenticationConfigResponse `json:"authentication"` -} - -type federationConfigResponse struct { - Account string `json:"account,omitempty"` - FollowerCount int `json:"followerCount,omitempty"` - Enabled bool `json:"enabled"` -} - -type browserNotificationsConfigResponse struct { - PublicKey string `json:"publicKey,omitempty"` - Enabled bool `json:"enabled"` -} - -type notificationsConfigResponse struct { - Browser browserNotificationsConfigResponse `json:"browser"` -} - -type authenticationConfigResponse struct { - IndieAuthEnabled bool `json:"indieAuthEnabled"` -} - -// GetWebConfig gets the status of the server. -func GetWebConfig(w http.ResponseWriter, r *http.Request) { - middleware.EnableCors(w) - middleware.DisableCache(w) - w.Header().Set("Content-Type", "application/json") - - configuration := getConfigResponse() - - if err := json.NewEncoder(w).Encode(configuration); err != nil { - BadRequestHandler(w, err) - } -} - -func getConfigResponse() webConfigResponse { - pageContent := utils.RenderPageContentMarkdown(data.GetExtraPageBodyContent()) - offlineMessage := utils.RenderSimpleMarkdown(data.GetCustomOfflineMessage()) - socialHandles := data.GetSocialHandles() - for i, handle := range socialHandles { - platform := models.GetSocialHandle(handle.Platform) - if platform != nil { - handle.Icon = platform.Icon - socialHandles[i] = handle - } - } - - serverSummary := data.GetServerSummary() - - var federationResponse federationConfigResponse - federationEnabled := data.GetFederationEnabled() - - followerCount, _ := activitypub.GetFollowerCount() - if federationEnabled { - serverURLString := data.GetServerURL() - serverURL, _ := url.Parse(serverURLString) - account := fmt.Sprintf("%s@%s", data.GetDefaultFederationUsername(), serverURL.Host) - federationResponse = federationConfigResponse{ - Enabled: federationEnabled, - FollowerCount: int(followerCount), - Account: account, - } - } - - browserPushEnabled := data.GetBrowserPushConfig().Enabled - browserPushPublicKey, err := data.GetBrowserPushPublicKey() - if err != nil { - log.Errorln("unable to fetch browser push notifications public key", err) - browserPushEnabled = false - } - - notificationsResponse := notificationsConfigResponse{ - Browser: browserNotificationsConfigResponse{ - Enabled: browserPushEnabled, - PublicKey: browserPushPublicKey, - }, - } - - authenticationResponse := authenticationConfigResponse{ - IndieAuthEnabled: data.GetServerURL() != "", - } - - return webConfigResponse{ - Name: data.GetServerName(), - Summary: serverSummary, - OfflineMessage: offlineMessage, - Logo: "/logo", - Tags: data.GetServerMetadataTags(), - Version: config.GetReleaseString(), - NSFW: data.GetNSFW(), - SocketHostOverride: data.GetWebsocketOverrideHost(), - ExtraPageContent: pageContent, - StreamTitle: data.GetStreamTitle(), - SocialHandles: socialHandles, - ChatDisabled: data.GetChatDisabled(), - ChatSpamProtectionDisabled: data.GetChatSpamProtectionEnabled(), - ExternalActions: data.GetExternalActions(), - CustomStyles: data.GetCustomStyles(), - MaxSocketPayloadSize: config.MaxSocketPayloadSize, - Federation: federationResponse, - Notifications: notificationsResponse, - Authentication: authenticationResponse, - AppearanceVariables: data.GetCustomColorVariableValues(), - HideViewerCount: data.GetHideViewerCount(), - } -} - -// GetAllSocialPlatforms will return a list of all social platform types. -func GetAllSocialPlatforms(w http.ResponseWriter, r *http.Request) { - middleware.EnableCors(w) - w.Header().Set("Content-Type", "application/json") - - platforms := models.GetAllSocialHandles() - if err := json.NewEncoder(w).Encode(platforms); err != nil { - InternalErrorHandler(w, err) - } -} diff --git a/go.mod b/go.mod index 016928796..2d70a46f0 100644 --- a/go.mod +++ b/go.mod @@ -31,7 +31,7 @@ require ( github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/numcpus v0.6.1 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect - golang.org/x/crypto v0.23.0 // indirect + golang.org/x/crypto v0.23.0 golang.org/x/net v0.25.0 golang.org/x/sys v0.20.0 // indirect ) diff --git a/go.sum b/go.sum index 2172c226b..1b165d564 100644 --- a/go.sum +++ b/go.sum @@ -11,12 +11,6 @@ github.com/andybalholm/cascadia v1.3.2 h1:3Xi6Dw5lHF15JtdcmAHD3i1+T8plmv7BQ/nsVi github.com/andybalholm/cascadia v1.3.2/go.mod h1:7gtRlve5FxPPgIgX36uWBX58OdBsSS6lUvCFb+h7KvU= github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ= github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk= -github.com/aws/aws-sdk-go v1.50.33 h1:/SKPJ7ZVPCFOYZyTKo5YdjeUEeOn2J2M0qfDTXWAoEU= -github.com/aws/aws-sdk-go v1.50.33/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= -github.com/aws/aws-sdk-go v1.51.17 h1:Cfa40lCdjv9OxC3X1Ks3a6O1Tu3gOANSyKHOSw/zuWU= -github.com/aws/aws-sdk-go v1.51.17/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= -github.com/aws/aws-sdk-go v1.51.23 h1:/3TEdsEE/aHmdKGw2NrOp7Sdea76zfffGkTTSXTsDxY= -github.com/aws/aws-sdk-go v1.51.23/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/aws/aws-sdk-go v1.53.5 h1:1OcVWMjGlwt7EU5OWmmEEXqaYfmX581EK317QJZXItM= github.com/aws/aws-sdk-go v1.53.5/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= @@ -111,8 +105,6 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= -github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU= -github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k= github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= @@ -127,10 +119,6 @@ github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjR github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/schollz/sqlite3dump v1.3.1 h1:QXizJ7XEJ7hggjqjZ3YRtF3+javm8zKtzNByYtEkPRA= github.com/schollz/sqlite3dump v1.3.1/go.mod h1:mzSTjZpJH4zAb1FN3iNlhWPbbdyeBpOaTW0hukyMHyI= -github.com/shirou/gopsutil/v3 v3.24.2 h1:kcR0erMbLg5/3LcInpw0X/rrPSqq4CDPyI6A6ZRC18Y= -github.com/shirou/gopsutil/v3 v3.24.2/go.mod h1:tSg/594BcA+8UdQU2XcW803GWYgdtauFFPgJCJKZlVk= -github.com/shirou/gopsutil/v3 v3.24.3 h1:eoUGJSmdfLzJ3mxIhmOAhgKEKgQkeOwKpz1NbhVnuPE= -github.com/shirou/gopsutil/v3 v3.24.3/go.mod h1:JpND7O217xa72ewWz9zN2eIIkPWsDN/3pl0H8Qt0uwg= github.com/shirou/gopsutil/v3 v3.24.4 h1:dEHgzZXt4LMNm+oYELpzl9YCqV65Yr/6SfrvgRBtXeU= github.com/shirou/gopsutil/v3 v3.24.4/go.mod h1:lTd2mdiOspcqLgAnr9/nGi71NkeMpWKdmhuxm9GusH8= github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= @@ -165,8 +153,6 @@ github.com/valyala/gozstd v1.20.1 h1:xPnnnvjmaDDitMFfDxmQ4vpx0+3CdTg2o3lALvXTU/g github.com/valyala/gozstd v1.20.1/go.mod h1:y5Ew47GLlP37EkTB+B4s7r6A5rdaeB7ftbl9zoYiIPQ= github.com/yuin/goldmark v1.3.7/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/yuin/goldmark v1.7.0 h1:EfOIvIMZIzHdB/R/zVrikYLPPwJlfMcNczJFMs1m6sA= -github.com/yuin/goldmark v1.7.0/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= github.com/yuin/goldmark v1.7.1 h1:3bajkSilaCbjdKVsKdZjZCLBNPL9pYzrCakKaf4U49U= github.com/yuin/goldmark v1.7.1/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= github.com/yuin/goldmark-emoji v1.0.2 h1:c/RgTShNgHTtc6xdz2KKI74jJr6rWi7FPgnP9GAsO5s= @@ -180,16 +166,10 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= -golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= -golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= -golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic= -golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -200,10 +180,6 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= -golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= -golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= -golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -225,8 +201,6 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= @@ -235,15 +209,13 @@ golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuX golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= -golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= +golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= +golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= diff --git a/webserver/handlers/admin.go b/webserver/handlers/admin.go index ed8e2922d..878544460 100644 --- a/webserver/handlers/admin.go +++ b/webserver/handlers/admin.go @@ -3,8 +3,8 @@ package handlers import ( "net/http" - "github.com/owncast/owncast/controllers" - "github.com/owncast/owncast/controllers/admin" + "github.com/owncast/owncast/core/rtmp" + "github.com/owncast/owncast/webserver/handlers/admin" "github.com/owncast/owncast/webserver/handlers/generated" "github.com/owncast/owncast/webserver/router/middleware" ) @@ -154,11 +154,11 @@ func (*ServerInterfaceImpl) GetWarningsOptions(w http.ResponseWriter, r *http.Re } func (*ServerInterfaceImpl) GetFollowersAdmin(w http.ResponseWriter, r *http.Request, params generated.GetFollowersAdminParams) { - middleware.RequireAdminAuth(middleware.HandlePagination(controllers.GetFollowers))(w, r) + middleware.RequireAdminAuth(middleware.HandlePagination(GetFollowers))(w, r) } func (*ServerInterfaceImpl) GetFollowersAdminOptions(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(middleware.HandlePagination(controllers.GetFollowers))(w, r) + middleware.RequireAdminAuth(middleware.HandlePagination(GetFollowers))(w, r) } func (*ServerInterfaceImpl) GetPendingFollowRequests(w http.ResponseWriter, r *http.Request) { @@ -304,3 +304,9 @@ func (*ServerInterfaceImpl) GetFederatedActions(w http.ResponseWriter, r *http.R func (*ServerInterfaceImpl) GetFederatedActionsOptions(w http.ResponseWriter, r *http.Request) { middleware.RequireAdminAuth(middleware.HandlePagination(admin.GetFederatedActions))(w, r) } + +// DisconnectInboundConnection will force-disconnect an inbound stream. +func DisconnectInboundConnection(w http.ResponseWriter, r *http.Request) { + rtmp.Disconnect() + w.WriteHeader(http.StatusOK) +} diff --git a/controllers/admin/appearance.go b/webserver/handlers/admin/appearance.go similarity index 66% rename from controllers/admin/appearance.go rename to webserver/handlers/admin/appearance.go index 4904ec325..6d920a903 100644 --- a/controllers/admin/appearance.go +++ b/webserver/handlers/admin/appearance.go @@ -4,8 +4,8 @@ import ( "encoding/json" "net/http" - "github.com/owncast/owncast/controllers" "github.com/owncast/owncast/core/data" + webutils "github.com/owncast/owncast/webserver/utils" ) // SetCustomColorVariableValues sets the custom color variables. @@ -22,14 +22,14 @@ func SetCustomColorVariableValues(w http.ResponseWriter, r *http.Request) { var values request if err := decoder.Decode(&values); err != nil { - controllers.WriteSimpleResponse(w, false, "unable to update appearance variable values") + webutils.WriteSimpleResponse(w, false, "unable to update appearance variable values") return } if err := data.SetCustomColorVariableValues(values.Value); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } - controllers.WriteSimpleResponse(w, true, "custom appearance variables updated") + webutils.WriteSimpleResponse(w, true, "custom appearance variables updated") } diff --git a/controllers/admin/chat.go b/webserver/handlers/admin/chat.go similarity index 75% rename from controllers/admin/chat.go rename to webserver/handlers/admin/chat.go index 81e1b714d..a4f536c97 100644 --- a/controllers/admin/chat.go +++ b/webserver/handlers/admin/chat.go @@ -9,13 +9,13 @@ import ( "net/http" "strconv" - "github.com/owncast/owncast/controllers" "github.com/owncast/owncast/core/chat" "github.com/owncast/owncast/core/chat/events" "github.com/owncast/owncast/core/data" "github.com/owncast/owncast/models" "github.com/owncast/owncast/persistence/userrepository" "github.com/owncast/owncast/utils" + webutils "github.com/owncast/owncast/webserver/utils" log "github.com/sirupsen/logrus" ) @@ -31,9 +31,9 @@ func UpdateMessageVisibility(w http.ResponseWriter, r *http.Request) { Visible bool `json:"visible"` } - if r.Method != controllers.POST { + if r.Method != http.MethodPost { // nolint:goconst - controllers.WriteSimpleResponse(w, false, r.Method+" not supported") + webutils.WriteSimpleResponse(w, false, r.Method+" not supported") return } @@ -42,16 +42,16 @@ func UpdateMessageVisibility(w http.ResponseWriter, r *http.Request) { if err := decoder.Decode(&request); err != nil { log.Errorln(err) - controllers.WriteSimpleResponse(w, false, "") + webutils.WriteSimpleResponse(w, false, "") return } if err := chat.SetMessagesVisibility(request.IDArray, request.Visible); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } - controllers.WriteSimpleResponse(w, true, "changed") + webutils.WriteSimpleResponse(w, true, "changed") } // BanIPAddress will manually ban an IP address. @@ -62,16 +62,16 @@ func BanIPAddress(w http.ResponseWriter, r *http.Request) { configValue, success := getValueFromRequest(w, r) if !success { - controllers.WriteSimpleResponse(w, false, "unable to ban IP address") + webutils.WriteSimpleResponse(w, false, "unable to ban IP address") return } if err := data.BanIPAddress(configValue.Value.(string), "manually added"); err != nil { - controllers.WriteSimpleResponse(w, false, "error saving IP address ban") + webutils.WriteSimpleResponse(w, false, "error saving IP address ban") return } - controllers.WriteSimpleResponse(w, true, "IP address banned") + webutils.WriteSimpleResponse(w, true, "IP address banned") } // UnBanIPAddress will remove an IP address ban. @@ -82,27 +82,27 @@ func UnBanIPAddress(w http.ResponseWriter, r *http.Request) { configValue, success := getValueFromRequest(w, r) if !success { - controllers.WriteSimpleResponse(w, false, "unable to unban IP address") + webutils.WriteSimpleResponse(w, false, "unable to unban IP address") return } if err := data.RemoveIPAddressBan(configValue.Value.(string)); err != nil { - controllers.WriteSimpleResponse(w, false, "error removing IP address ban") + webutils.WriteSimpleResponse(w, false, "error removing IP address ban") return } - controllers.WriteSimpleResponse(w, true, "IP address unbanned") + webutils.WriteSimpleResponse(w, true, "IP address unbanned") } // GetIPAddressBans will return all the banned IP addresses. func GetIPAddressBans(w http.ResponseWriter, r *http.Request) { bans, err := data.GetIPAddressBans() if err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } - controllers.WriteResponse(w, bans) + webutils.WriteResponse(w, bans) } // UpdateUserEnabled enable or disable a single user by ID. @@ -112,8 +112,8 @@ func UpdateUserEnabled(w http.ResponseWriter, r *http.Request) { Enabled bool `json:"enabled"` } - if r.Method != controllers.POST { - controllers.WriteSimpleResponse(w, false, r.Method+" not supported") + if r.Method != http.MethodPost { + webutils.WriteSimpleResponse(w, false, r.Method+" not supported") return } @@ -122,12 +122,12 @@ func UpdateUserEnabled(w http.ResponseWriter, r *http.Request) { if err := decoder.Decode(&request); err != nil { log.Errorln(err) - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } if request.UserID == "" { - controllers.WriteSimpleResponse(w, false, "must provide userId") + webutils.WriteSimpleResponse(w, false, "must provide userId") return } @@ -136,7 +136,7 @@ func UpdateUserEnabled(w http.ResponseWriter, r *http.Request) { // Disable/enable the user if err := userRepository.SetEnabled(request.UserID, request.Enabled); err != nil { log.Errorln("error changing user enabled status", err) - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } @@ -145,7 +145,7 @@ func UpdateUserEnabled(w http.ResponseWriter, r *http.Request) { if !request.Enabled { if err := chat.SetMessageVisibilityForUserID(request.UserID, request.Enabled); err != nil { log.Errorln("error changing user messages visibility", err) - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } } @@ -160,7 +160,7 @@ func UpdateUserEnabled(w http.ResponseWriter, r *http.Request) { if err != nil { log.Errorln("error fetching clients for user: ", err) - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } @@ -183,7 +183,7 @@ func UpdateUserEnabled(w http.ResponseWriter, r *http.Request) { } } - controllers.WriteSimpleResponse(w, true, fmt.Sprintf("%s enabled: %t", request.UserID, request.Enabled)) + webutils.WriteSimpleResponse(w, true, fmt.Sprintf("%s enabled: %t", request.UserID, request.Enabled)) } // GetDisabledUsers will return all the disabled users. @@ -193,7 +193,7 @@ func GetDisabledUsers(w http.ResponseWriter, r *http.Request) { userRepository := userrepository.Get() users := userRepository.GetDisabledUsers() - controllers.WriteResponse(w, users) + webutils.WriteResponse(w, users) } // UpdateUserModerator will set the moderator status for a user ID. @@ -204,7 +204,7 @@ func UpdateUserModerator(w http.ResponseWriter, r *http.Request) { } if r.Method != http.MethodPost { - controllers.WriteSimpleResponse(w, false, r.Method+" not supported") + webutils.WriteSimpleResponse(w, false, r.Method+" not supported") return } @@ -212,7 +212,7 @@ func UpdateUserModerator(w http.ResponseWriter, r *http.Request) { var req request if err := decoder.Decode(&req); err != nil { - controllers.WriteSimpleResponse(w, false, "") + webutils.WriteSimpleResponse(w, false, "") return } @@ -220,7 +220,7 @@ func UpdateUserModerator(w http.ResponseWriter, r *http.Request) { // Update the user object with new moderation access. if err := userRepository.SetModerator(req.UserID, req.IsModerator); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } @@ -229,7 +229,7 @@ func UpdateUserModerator(w http.ResponseWriter, r *http.Request) { log.Debugln(err) } - controllers.WriteSimpleResponse(w, true, fmt.Sprintf("%s is moderator: %t", req.UserID, req.IsModerator)) + webutils.WriteSimpleResponse(w, true, fmt.Sprintf("%s is moderator: %t", req.UserID, req.IsModerator)) } // GetModerators will return a list of moderator users. @@ -239,7 +239,7 @@ func GetModerators(w http.ResponseWriter, r *http.Request) { userRepository := userrepository.Get() users := userRepository.GetModeratorUsers() - controllers.WriteResponse(w, users) + webutils.WriteResponse(w, users) } // GetChatMessages returns all of the chat messages, unfiltered. @@ -247,7 +247,7 @@ func GetChatMessages(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") messages := chat.GetChatModerationHistory() - controllers.WriteResponse(w, messages) + webutils.WriteResponse(w, messages) } // SendSystemMessage will send an official "SYSTEM" message to chat on behalf of your server. @@ -256,15 +256,15 @@ func SendSystemMessage(integration models.ExternalAPIUser, w http.ResponseWriter var message events.SystemMessageEvent if err := json.NewDecoder(r.Body).Decode(&message); err != nil { - controllers.InternalErrorHandler(w, err) + webutils.InternalErrorHandler(w, err) return } if err := chat.SendSystemMessage(message.Body, false); err != nil { - controllers.BadRequestHandler(w, err) + webutils.BadRequestHandler(w, err) } - controllers.WriteSimpleResponse(w, true, "sent") + webutils.WriteSimpleResponse(w, true, "sent") } // SendSystemMessageToConnectedClient will handle incoming requests to send a single message to a single connected client by ID. @@ -272,30 +272,30 @@ func SendSystemMessageToConnectedClient(integration models.ExternalAPIUser, w ht w.Header().Set("Content-Type", "application/json") clientIDText, err := utils.GetURLParam(r, "clientId") if err != nil { - controllers.BadRequestHandler(w, err) + webutils.BadRequestHandler(w, err) return } clientIDNumeric, err := strconv.ParseUint(clientIDText, 10, 32) if err != nil { - controllers.BadRequestHandler(w, err) + webutils.BadRequestHandler(w, err) return } var message events.SystemMessageEvent if err := json.NewDecoder(r.Body).Decode(&message); err != nil { - controllers.InternalErrorHandler(w, err) + webutils.InternalErrorHandler(w, err) return } chat.SendSystemMessageToClient(uint(clientIDNumeric), message.Body) - controllers.WriteSimpleResponse(w, true, "sent") + webutils.WriteSimpleResponse(w, true, "sent") } // SendUserMessage will send a message to chat on behalf of a user. *Depreciated*. func SendUserMessage(integration models.ExternalAPIUser, w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") - controllers.BadRequestHandler(w, errors.New("no longer supported. see /api/integrations/chat/send")) + webutils.BadRequestHandler(w, errors.New("no longer supported. see /api/integrations/chat/send")) } // SendIntegrationChatMessage will send a chat message on behalf of an external chat integration. @@ -305,13 +305,13 @@ func SendIntegrationChatMessage(integration models.ExternalAPIUser, w http.Respo name := integration.DisplayName if name == "" { - controllers.BadRequestHandler(w, errors.New("unknown integration for provided access token")) + webutils.BadRequestHandler(w, errors.New("unknown integration for provided access token")) return } var event events.UserMessageEvent if err := json.NewDecoder(r.Body).Decode(&event); err != nil { - controllers.InternalErrorHandler(w, err) + webutils.InternalErrorHandler(w, err) return } event.SetDefaults() @@ -319,7 +319,7 @@ func SendIntegrationChatMessage(integration models.ExternalAPIUser, w http.Respo event.Type = "CHAT" if event.Empty() { - controllers.BadRequestHandler(w, errors.New("invalid message")) + webutils.BadRequestHandler(w, errors.New("invalid message")) return } @@ -332,13 +332,13 @@ func SendIntegrationChatMessage(integration models.ExternalAPIUser, w http.Respo } if err := chat.Broadcast(&event); err != nil { - controllers.BadRequestHandler(w, err) + webutils.BadRequestHandler(w, err) return } chat.SaveUserMessage(event) - controllers.WriteSimpleResponse(w, true, "sent") + webutils.WriteSimpleResponse(w, true, "sent") } // SendChatAction will send a generic chat action. @@ -347,7 +347,7 @@ func SendChatAction(integration models.ExternalAPIUser, w http.ResponseWriter, r var message events.SystemActionEvent if err := json.NewDecoder(r.Body).Decode(&message); err != nil { - controllers.InternalErrorHandler(w, err) + webutils.InternalErrorHandler(w, err) return } @@ -355,11 +355,11 @@ func SendChatAction(integration models.ExternalAPIUser, w http.ResponseWriter, r message.RenderBody() if err := chat.SendSystemAction(message.Body, false); err != nil { - controllers.BadRequestHandler(w, err) + webutils.BadRequestHandler(w, err) return } - controllers.WriteSimpleResponse(w, true, "sent") + webutils.WriteSimpleResponse(w, true, "sent") } // SetEnableEstablishedChatUserMode sets the requirement for a chat user @@ -371,14 +371,14 @@ func SetEnableEstablishedChatUserMode(w http.ResponseWriter, r *http.Request) { configValue, success := getValueFromRequest(w, r) if !success { - controllers.WriteSimpleResponse(w, false, "unable to update chat established user only mode") + webutils.WriteSimpleResponse(w, false, "unable to update chat established user only mode") return } if err := data.SetChatEstablishedUsersOnlyMode(configValue.Value.(bool)); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } - controllers.WriteSimpleResponse(w, true, "chat established users only mode updated") + webutils.WriteSimpleResponse(w, true, "chat established users only mode updated") } diff --git a/controllers/admin/config.go b/webserver/handlers/admin/config.go similarity index 69% rename from controllers/admin/config.go rename to webserver/handlers/admin/config.go index 1cc165be6..56b11e8d6 100644 --- a/controllers/admin/config.go +++ b/webserver/handlers/admin/config.go @@ -12,12 +12,12 @@ import ( "strings" "github.com/owncast/owncast/activitypub/outbox" - "github.com/owncast/owncast/controllers" "github.com/owncast/owncast/core/chat" "github.com/owncast/owncast/core/data" "github.com/owncast/owncast/core/webhooks" "github.com/owncast/owncast/models" "github.com/owncast/owncast/utils" + webutils "github.com/owncast/owncast/webserver/utils" log "github.com/sirupsen/logrus" "github.com/teris-io/shortid" ) @@ -44,17 +44,17 @@ func SetTags(w http.ResponseWriter, r *http.Request) { } if err := data.SetServerMetadataTags(tagStrings); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } // Update Fediverse followers about this change. if err := outbox.UpdateFollowersWithAccountUpdates(); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } - controllers.WriteSimpleResponse(w, true, "changed") + webutils.WriteSimpleResponse(w, true, "changed") } // SetStreamTitle will handle the web config request to set the current stream title. @@ -71,14 +71,14 @@ func SetStreamTitle(w http.ResponseWriter, r *http.Request) { value := configValue.Value.(string) if err := data.SetStreamTitle(value); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } if value != "" { sendSystemChatAction(fmt.Sprintf("Stream title changed to **%s**", value), true) go webhooks.SendStreamStatusEvent(models.StreamTitleUpdated) } - controllers.WriteSimpleResponse(w, true, "changed") + webutils.WriteSimpleResponse(w, true, "changed") } // ExternalSetStreamTitle will change the stream title on behalf of an external integration API request. @@ -104,17 +104,17 @@ func SetServerName(w http.ResponseWriter, r *http.Request) { } if err := data.SetServerName(configValue.Value.(string)); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } // Update Fediverse followers about this change. if err := outbox.UpdateFollowersWithAccountUpdates(); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } - controllers.WriteSimpleResponse(w, true, "changed") + webutils.WriteSimpleResponse(w, true, "changed") } // SetServerSummary will handle the web config request to set the about/summary text. @@ -129,17 +129,17 @@ func SetServerSummary(w http.ResponseWriter, r *http.Request) { } if err := data.SetServerSummary(configValue.Value.(string)); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } // Update Fediverse followers about this change. if err := outbox.UpdateFollowersWithAccountUpdates(); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } - controllers.WriteSimpleResponse(w, true, "changed") + webutils.WriteSimpleResponse(w, true, "changed") } // SetCustomOfflineMessage will set a message to display when the server is offline. @@ -154,11 +154,11 @@ func SetCustomOfflineMessage(w http.ResponseWriter, r *http.Request) { } if err := data.SetCustomOfflineMessage(strings.TrimSpace(configValue.Value.(string))); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } - controllers.WriteSimpleResponse(w, true, "changed") + webutils.WriteSimpleResponse(w, true, "changed") } // SetServerWelcomeMessage will handle the web config request to set the welcome message text. @@ -173,11 +173,11 @@ func SetServerWelcomeMessage(w http.ResponseWriter, r *http.Request) { } if err := data.SetServerWelcomeMessage(strings.TrimSpace(configValue.Value.(string))); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } - controllers.WriteSimpleResponse(w, true, "changed") + webutils.WriteSimpleResponse(w, true, "changed") } // SetExtraPageContent will handle the web config request to set the page markdown content. @@ -192,11 +192,11 @@ func SetExtraPageContent(w http.ResponseWriter, r *http.Request) { } if err := data.SetExtraPageBodyContent(configValue.Value.(string)); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } - controllers.WriteSimpleResponse(w, true, "changed") + webutils.WriteSimpleResponse(w, true, "changed") } // SetAdminPassword will handle the web config request to set the server admin password. @@ -211,11 +211,11 @@ func SetAdminPassword(w http.ResponseWriter, r *http.Request) { } if err := data.SetAdminPassword(configValue.Value.(string)); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } - controllers.WriteSimpleResponse(w, true, "changed") + webutils.WriteSimpleResponse(w, true, "changed") } // SetLogo will handle a new logo image file being uploaded. @@ -231,23 +231,23 @@ func SetLogo(w http.ResponseWriter, r *http.Request) { value, ok := configValue.Value.(string) if !ok { - controllers.WriteSimpleResponse(w, false, "unable to find image data") + webutils.WriteSimpleResponse(w, false, "unable to find image data") return } bytes, extension, err := utils.DecodeBase64Image(value) if err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } imgPath := filepath.Join("data", "logo"+extension) if err := os.WriteFile(imgPath, bytes, 0o600); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } if err := data.SetLogoPath("logo" + extension); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } @@ -257,11 +257,11 @@ func SetLogo(w http.ResponseWriter, r *http.Request) { // Update Fediverse followers about this change. if err := outbox.UpdateFollowersWithAccountUpdates(); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } - controllers.WriteSimpleResponse(w, true, "changed") + webutils.WriteSimpleResponse(w, true, "changed") } // SetNSFW will handle the web config request to set the NSFW flag. @@ -276,11 +276,11 @@ func SetNSFW(w http.ResponseWriter, r *http.Request) { } if err := data.SetNSFW(configValue.Value.(bool)); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } - controllers.WriteSimpleResponse(w, true, "changed") + webutils.WriteSimpleResponse(w, true, "changed") } // SetFfmpegPath will handle the web config request to validate and set an updated copy of ffmpg. @@ -296,16 +296,16 @@ func SetFfmpegPath(w http.ResponseWriter, r *http.Request) { path := configValue.Value.(string) if err := utils.VerifyFFMpegPath(path); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } if err := data.SetFfmpegPath(configValue.Value.(string)); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } - controllers.WriteSimpleResponse(w, true, "changed") + webutils.WriteSimpleResponse(w, true, "changed") } // SetWebServerPort will handle the web config request to set the server's HTTP port. @@ -321,19 +321,19 @@ func SetWebServerPort(w http.ResponseWriter, r *http.Request) { if port, ok := configValue.Value.(float64); ok { if (port < 1) || (port > 65535) { - controllers.WriteSimpleResponse(w, false, "Port number must be between 1 and 65535") + webutils.WriteSimpleResponse(w, false, "Port number must be between 1 and 65535") return } if err := data.SetHTTPPortNumber(port); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } - controllers.WriteSimpleResponse(w, true, "HTTP port set") + webutils.WriteSimpleResponse(w, true, "HTTP port set") return } - controllers.WriteSimpleResponse(w, false, "Invalid type or value, port must be a number") + webutils.WriteSimpleResponse(w, false, "Invalid type or value, port must be a number") } // SetWebServerIP will handle the web config request to set the server's HTTP listen address. @@ -350,18 +350,18 @@ func SetWebServerIP(w http.ResponseWriter, r *http.Request) { if input, ok := configValue.Value.(string); ok { if ip := net.ParseIP(input); ip != nil { if err := data.SetHTTPListenAddress(ip.String()); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } - controllers.WriteSimpleResponse(w, true, "HTTP listen address set") + webutils.WriteSimpleResponse(w, true, "HTTP listen address set") return } - controllers.WriteSimpleResponse(w, false, "Invalid IP address") + webutils.WriteSimpleResponse(w, false, "Invalid IP address") return } - controllers.WriteSimpleResponse(w, false, "Invalid type or value, IP address must be a string") + webutils.WriteSimpleResponse(w, false, "Invalid type or value, IP address must be a string") } // SetRTMPServerPort will handle the web config request to set the inbound RTMP port. @@ -376,11 +376,11 @@ func SetRTMPServerPort(w http.ResponseWriter, r *http.Request) { } if err := data.SetRTMPPortNumber(configValue.Value.(float64)); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } - controllers.WriteSimpleResponse(w, true, "rtmp port set") + webutils.WriteSimpleResponse(w, true, "rtmp port set") } // SetServerURL will handle the web config request to set the full server URL. @@ -396,13 +396,13 @@ func SetServerURL(w http.ResponseWriter, r *http.Request) { rawValue, ok := configValue.Value.(string) if !ok { - controllers.WriteSimpleResponse(w, false, "could not read server url") + webutils.WriteSimpleResponse(w, false, "could not read server url") return } serverHostString := utils.GetHostnameFromURLString(rawValue) if serverHostString == "" { - controllers.WriteSimpleResponse(w, false, "server url value invalid") + webutils.WriteSimpleResponse(w, false, "server url value invalid") return } @@ -410,7 +410,7 @@ func SetServerURL(w http.ResponseWriter, r *http.Request) { ipAddr, ipErr := netip.ParseAddr(utils.GetHostnameWithoutPortFromURLString(rawValue)) if ipErr == nil && ipAddr.IsPrivate() { - controllers.WriteSimpleResponse(w, false, "Server URL cannot be private") + webutils.WriteSimpleResponse(w, false, "Server URL cannot be private") return } @@ -418,11 +418,11 @@ func SetServerURL(w http.ResponseWriter, r *http.Request) { serverURL := strings.TrimRight(rawValue, "/") if err := data.SetServerURL(serverURL); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } - controllers.WriteSimpleResponse(w, true, "server url set") + webutils.WriteSimpleResponse(w, true, "server url set") } // SetSocketHostOverride will set the host override for the websocket. @@ -437,11 +437,11 @@ func SetSocketHostOverride(w http.ResponseWriter, r *http.Request) { } if err := data.SetWebsocketOverrideHost(configValue.Value.(string)); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } - controllers.WriteSimpleResponse(w, true, "websocket host override set") + webutils.WriteSimpleResponse(w, true, "websocket host override set") } // SetDirectoryEnabled will handle the web config request to enable or disable directory registration. @@ -456,10 +456,10 @@ func SetDirectoryEnabled(w http.ResponseWriter, r *http.Request) { } if err := data.SetDirectoryEnabled(configValue.Value.(bool)); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } - controllers.WriteSimpleResponse(w, true, "directory state changed") + webutils.WriteSimpleResponse(w, true, "directory state changed") } // SetStreamLatencyLevel will handle the web config request to set the stream latency level. @@ -474,11 +474,11 @@ func SetStreamLatencyLevel(w http.ResponseWriter, r *http.Request) { } if err := data.SetStreamLatencyLevel(configValue.Value.(float64)); err != nil { - controllers.WriteSimpleResponse(w, false, "error setting stream latency "+err.Error()) + webutils.WriteSimpleResponse(w, false, "error setting stream latency "+err.Error()) return } - controllers.WriteSimpleResponse(w, true, "set stream latency") + webutils.WriteSimpleResponse(w, true, "set stream latency") } // SetS3Configuration will handle the web config request to set the storage configuration. @@ -494,37 +494,37 @@ func SetS3Configuration(w http.ResponseWriter, r *http.Request) { decoder := json.NewDecoder(r.Body) var newS3Config s3ConfigurationRequest if err := decoder.Decode(&newS3Config); err != nil { - controllers.WriteSimpleResponse(w, false, "unable to update s3 config with provided values") + webutils.WriteSimpleResponse(w, false, "unable to update s3 config with provided values") return } if newS3Config.Value.Enabled { if newS3Config.Value.Endpoint == "" || !utils.IsValidURL((newS3Config.Value.Endpoint)) { - controllers.WriteSimpleResponse(w, false, "s3 support requires an endpoint") + webutils.WriteSimpleResponse(w, false, "s3 support requires an endpoint") return } if newS3Config.Value.AccessKey == "" || newS3Config.Value.Secret == "" { - controllers.WriteSimpleResponse(w, false, "s3 support requires an access key and secret") + webutils.WriteSimpleResponse(w, false, "s3 support requires an access key and secret") return } if newS3Config.Value.Region == "" { - controllers.WriteSimpleResponse(w, false, "s3 support requires a region and endpoint") + webutils.WriteSimpleResponse(w, false, "s3 support requires a region and endpoint") return } if newS3Config.Value.Bucket == "" { - controllers.WriteSimpleResponse(w, false, "s3 support requires a bucket created for storing public video segments") + webutils.WriteSimpleResponse(w, false, "s3 support requires a bucket created for storing public video segments") return } } if err := data.SetS3Config(newS3Config.Value); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } - controllers.WriteSimpleResponse(w, true, "storage configuration changed") + webutils.WriteSimpleResponse(w, true, "storage configuration changed") } // SetStreamOutputVariants will handle the web config request to set the video output stream variants. @@ -540,16 +540,16 @@ func SetStreamOutputVariants(w http.ResponseWriter, r *http.Request) { decoder := json.NewDecoder(r.Body) var videoVariants streamOutputVariantRequest if err := decoder.Decode(&videoVariants); err != nil { - controllers.WriteSimpleResponse(w, false, "unable to update video config with provided values "+err.Error()) + webutils.WriteSimpleResponse(w, false, "unable to update video config with provided values "+err.Error()) return } if err := data.SetStreamOutputVariants(videoVariants.Value); err != nil { - controllers.WriteSimpleResponse(w, false, "unable to update video config with provided values "+err.Error()) + webutils.WriteSimpleResponse(w, false, "unable to update video config with provided values "+err.Error()) return } - controllers.WriteSimpleResponse(w, true, "stream output variants updated") + webutils.WriteSimpleResponse(w, true, "stream output variants updated") } // SetSocialHandles will handle the web config request to set the external social profile links. @@ -565,22 +565,22 @@ func SetSocialHandles(w http.ResponseWriter, r *http.Request) { decoder := json.NewDecoder(r.Body) var socialHandles socialHandlesRequest if err := decoder.Decode(&socialHandles); err != nil { - controllers.WriteSimpleResponse(w, false, "unable to update social handles with provided values") + webutils.WriteSimpleResponse(w, false, "unable to update social handles with provided values") return } if err := data.SetSocialHandles(socialHandles.Value); err != nil { - controllers.WriteSimpleResponse(w, false, "unable to update social handles with provided values") + webutils.WriteSimpleResponse(w, false, "unable to update social handles with provided values") return } // Update Fediverse followers about this change. if err := outbox.UpdateFollowersWithAccountUpdates(); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } - controllers.WriteSimpleResponse(w, true, "social handles updated") + webutils.WriteSimpleResponse(w, true, "social handles updated") } // SetChatDisabled will disable chat functionality. @@ -591,16 +591,16 @@ func SetChatDisabled(w http.ResponseWriter, r *http.Request) { configValue, success := getValueFromRequest(w, r) if !success { - controllers.WriteSimpleResponse(w, false, "unable to update chat disabled") + webutils.WriteSimpleResponse(w, false, "unable to update chat disabled") return } if err := data.SetChatDisabled(configValue.Value.(bool)); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } - controllers.WriteSimpleResponse(w, true, "chat disabled status updated") + webutils.WriteSimpleResponse(w, true, "chat disabled status updated") } // SetVideoCodec will change the codec used for video encoding. @@ -611,16 +611,16 @@ func SetVideoCodec(w http.ResponseWriter, r *http.Request) { configValue, success := getValueFromRequest(w, r) if !success { - controllers.WriteSimpleResponse(w, false, "unable to change video codec") + webutils.WriteSimpleResponse(w, false, "unable to change video codec") return } if err := data.SetVideoCodec(configValue.Value.(string)); err != nil { - controllers.WriteSimpleResponse(w, false, "unable to update codec") + webutils.WriteSimpleResponse(w, false, "unable to update codec") return } - controllers.WriteSimpleResponse(w, true, "video codec updated") + webutils.WriteSimpleResponse(w, true, "video codec updated") } // SetExternalActions will set the 3rd party actions for the web interface. @@ -632,48 +632,48 @@ func SetExternalActions(w http.ResponseWriter, r *http.Request) { decoder := json.NewDecoder(r.Body) var actions externalActionsRequest if err := decoder.Decode(&actions); err != nil { - controllers.WriteSimpleResponse(w, false, "unable to update external actions with provided values") + webutils.WriteSimpleResponse(w, false, "unable to update external actions with provided values") return } if err := data.SetExternalActions(actions.Value); err != nil { - controllers.WriteSimpleResponse(w, false, "unable to update external actions with provided values") + webutils.WriteSimpleResponse(w, false, "unable to update external actions with provided values") return } - controllers.WriteSimpleResponse(w, true, "external actions update") + webutils.WriteSimpleResponse(w, true, "external actions update") } // SetCustomStyles will set the CSS string we insert into the page. func SetCustomStyles(w http.ResponseWriter, r *http.Request) { customStyles, success := getValueFromRequest(w, r) if !success { - controllers.WriteSimpleResponse(w, false, "unable to update custom styles") + webutils.WriteSimpleResponse(w, false, "unable to update custom styles") return } if err := data.SetCustomStyles(customStyles.Value.(string)); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } - controllers.WriteSimpleResponse(w, true, "custom styles updated") + webutils.WriteSimpleResponse(w, true, "custom styles updated") } // SetCustomJavascript will set the Javascript string we insert into the page. func SetCustomJavascript(w http.ResponseWriter, r *http.Request) { customJavascript, success := getValueFromRequest(w, r) if !success { - controllers.WriteSimpleResponse(w, false, "unable to update custom javascript") + webutils.WriteSimpleResponse(w, false, "unable to update custom javascript") return } if err := data.SetCustomJavascript(customJavascript.Value.(string)); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } - controllers.WriteSimpleResponse(w, true, "custom styles updated") + webutils.WriteSimpleResponse(w, true, "custom styles updated") } // SetForbiddenUsernameList will set the list of usernames we do not allow to use. @@ -685,16 +685,16 @@ func SetForbiddenUsernameList(w http.ResponseWriter, r *http.Request) { decoder := json.NewDecoder(r.Body) var request forbiddenUsernameListRequest if err := decoder.Decode(&request); err != nil { - controllers.WriteSimpleResponse(w, false, "unable to update forbidden usernames with provided values") + webutils.WriteSimpleResponse(w, false, "unable to update forbidden usernames with provided values") return } if err := data.SetForbiddenUsernameList(request.Value); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } - controllers.WriteSimpleResponse(w, true, "forbidden username list updated") + webutils.WriteSimpleResponse(w, true, "forbidden username list updated") } // SetSuggestedUsernameList will set the list of suggested usernames that newly registered users are assigned if it isn't inferred otherwise (i.e. through a proxy). @@ -707,16 +707,16 @@ func SetSuggestedUsernameList(w http.ResponseWriter, r *http.Request) { var request suggestedUsernameListRequest if err := decoder.Decode(&request); err != nil { - controllers.WriteSimpleResponse(w, false, "unable to update suggested usernames with provided values") + webutils.WriteSimpleResponse(w, false, "unable to update suggested usernames with provided values") return } if err := data.SetSuggestedUsernamesList(request.Value); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } - controllers.WriteSimpleResponse(w, true, "suggested username list updated") + webutils.WriteSimpleResponse(w, true, "suggested username list updated") } // SetChatJoinMessagesEnabled will enable or disable the chat join messages. @@ -727,16 +727,16 @@ func SetChatJoinMessagesEnabled(w http.ResponseWriter, r *http.Request) { configValue, success := getValueFromRequest(w, r) if !success { - controllers.WriteSimpleResponse(w, false, "unable to update chat join messages enabled") + webutils.WriteSimpleResponse(w, false, "unable to update chat join messages enabled") return } if err := data.SetChatJoinMessagesEnabled(configValue.Value.(bool)); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } - controllers.WriteSimpleResponse(w, true, "chat join message status updated") + webutils.WriteSimpleResponse(w, true, "chat join message status updated") } // SetHideViewerCount will enable or disable hiding the viewer count. @@ -747,16 +747,16 @@ func SetHideViewerCount(w http.ResponseWriter, r *http.Request) { configValue, success := getValueFromRequest(w, r) if !success { - controllers.WriteSimpleResponse(w, false, "unable to update hiding viewer count") + webutils.WriteSimpleResponse(w, false, "unable to update hiding viewer count") return } if err := data.SetHideViewerCount(configValue.Value.(bool)); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } - controllers.WriteSimpleResponse(w, true, "hide viewer count setting updated") + webutils.WriteSimpleResponse(w, true, "hide viewer count setting updated") } // SetDisableSearchIndexing will set search indexing support. @@ -767,38 +767,38 @@ func SetDisableSearchIndexing(w http.ResponseWriter, r *http.Request) { configValue, success := getValueFromRequest(w, r) if !success { - controllers.WriteSimpleResponse(w, false, "unable to update search indexing") + webutils.WriteSimpleResponse(w, false, "unable to update search indexing") return } if err := data.SetDisableSearchIndexing(configValue.Value.(bool)); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } - controllers.WriteSimpleResponse(w, true, "search indexing support updated") + webutils.WriteSimpleResponse(w, true, "search indexing support updated") } // SetVideoServingEndpoint will save the video serving endpoint. func SetVideoServingEndpoint(w http.ResponseWriter, r *http.Request) { endpoint, success := getValueFromRequest(w, r) if !success { - controllers.WriteSimpleResponse(w, false, "unable to update custom video serving endpoint") + webutils.WriteSimpleResponse(w, false, "unable to update custom video serving endpoint") return } value, ok := endpoint.Value.(string) if !ok { - controllers.WriteSimpleResponse(w, false, "unable to update custom video serving endpoint") + webutils.WriteSimpleResponse(w, false, "unable to update custom video serving endpoint") return } if err := data.SetVideoServingEndpoint(value); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } - controllers.WriteSimpleResponse(w, true, "custom video serving endpoint updated") + webutils.WriteSimpleResponse(w, true, "custom video serving endpoint updated") } // SetChatSpamProtectionEnabled will enable or disable the chat spam protection. @@ -813,10 +813,10 @@ func SetChatSpamProtectionEnabled(w http.ResponseWriter, r *http.Request) { } if err := data.SetChatSpamProtectionEnabled(configValue.Value.(bool)); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } - controllers.WriteSimpleResponse(w, true, "chat spam protection changed") + webutils.WriteSimpleResponse(w, true, "chat spam protection changed") } // SetChatSlurFilterEnabled will enable or disable the chat slur filter. @@ -831,15 +831,15 @@ func SetChatSlurFilterEnabled(w http.ResponseWriter, r *http.Request) { } if err := data.SetChatSlurFilterEnabled(configValue.Value.(bool)); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } - controllers.WriteSimpleResponse(w, true, "chat message slur filter changed") + webutils.WriteSimpleResponse(w, true, "chat message slur filter changed") } func requirePOST(w http.ResponseWriter, r *http.Request) bool { - if r.Method != controllers.POST { - controllers.WriteSimpleResponse(w, false, r.Method+" not supported") + if r.Method != http.MethodPost { + webutils.WriteSimpleResponse(w, false, r.Method+" not supported") return false } @@ -851,7 +851,7 @@ func getValueFromRequest(w http.ResponseWriter, r *http.Request) (ConfigValue, b var configValue ConfigValue if err := decoder.Decode(&configValue); err != nil { log.Warnln(err) - controllers.WriteSimpleResponse(w, false, "unable to parse new value") + webutils.WriteSimpleResponse(w, false, "unable to parse new value") return configValue, false } @@ -864,7 +864,7 @@ func getValuesFromRequest(w http.ResponseWriter, r *http.Request) ([]ConfigValue decoder := json.NewDecoder(r.Body) var configValue ConfigValue if err := decoder.Decode(&configValue); err != nil { - controllers.WriteSimpleResponse(w, false, "unable to parse array of values") + webutils.WriteSimpleResponse(w, false, "unable to parse array of values") return values, false } @@ -890,26 +890,26 @@ func SetStreamKeys(w http.ResponseWriter, r *http.Request) { decoder := json.NewDecoder(r.Body) var streamKeys streamKeysRequest if err := decoder.Decode(&streamKeys); err != nil { - controllers.WriteSimpleResponse(w, false, "unable to update stream keys with provided values") + webutils.WriteSimpleResponse(w, false, "unable to update stream keys with provided values") return } if len(streamKeys.Value) == 0 { - controllers.WriteSimpleResponse(w, false, "must provide at least one valid stream key") + webutils.WriteSimpleResponse(w, false, "must provide at least one valid stream key") return } for _, streamKey := range streamKeys.Value { if streamKey.Key == "" { - controllers.WriteSimpleResponse(w, false, "stream key cannot be empty") + webutils.WriteSimpleResponse(w, false, "stream key cannot be empty") return } } if err := data.SetStreamKeys(streamKeys.Value); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } - controllers.WriteSimpleResponse(w, true, "changed") + webutils.WriteSimpleResponse(w, true, "changed") } diff --git a/controllers/admin/connectedClients.go b/webserver/handlers/admin/connectedClients.go similarity index 87% rename from controllers/admin/connectedClients.go rename to webserver/handlers/admin/connectedClients.go index 0b3b9b90a..a4e8811b7 100644 --- a/controllers/admin/connectedClients.go +++ b/webserver/handlers/admin/connectedClients.go @@ -4,9 +4,9 @@ import ( "encoding/json" "net/http" - "github.com/owncast/owncast/controllers" "github.com/owncast/owncast/core/chat" "github.com/owncast/owncast/models" + webutils "github.com/owncast/owncast/webserver/utils" ) // GetConnectedChatClients returns currently connected clients. @@ -15,7 +15,7 @@ func GetConnectedChatClients(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") if err := json.NewEncoder(w).Encode(clients); err != nil { - controllers.InternalErrorHandler(w, err) + webutils.InternalErrorHandler(w, err) } } diff --git a/controllers/admin/disconnect.go b/webserver/handlers/admin/disconnect.go similarity index 62% rename from controllers/admin/disconnect.go rename to webserver/handlers/admin/disconnect.go index d8bf93346..66a3deea2 100644 --- a/controllers/admin/disconnect.go +++ b/webserver/handlers/admin/disconnect.go @@ -3,8 +3,8 @@ package admin import ( "net/http" - "github.com/owncast/owncast/controllers" "github.com/owncast/owncast/core" + webutils "github.com/owncast/owncast/webserver/utils" "github.com/owncast/owncast/core/rtmp" ) @@ -12,10 +12,10 @@ import ( // DisconnectInboundConnection will force-disconnect an inbound stream. func DisconnectInboundConnection(w http.ResponseWriter, r *http.Request) { if !core.GetStatus().Online { - controllers.WriteSimpleResponse(w, false, "no inbound stream connected") + webutils.WriteSimpleResponse(w, false, "no inbound stream connected") return } rtmp.Disconnect() - controllers.WriteSimpleResponse(w, true, "inbound stream disconnected") + webutils.WriteSimpleResponse(w, true, "inbound stream disconnected") } diff --git a/controllers/admin/emoji.go b/webserver/handlers/admin/emoji.go similarity index 63% rename from controllers/admin/emoji.go rename to webserver/handlers/admin/emoji.go index 810b629d1..2c9f7e454 100644 --- a/controllers/admin/emoji.go +++ b/webserver/handlers/admin/emoji.go @@ -8,8 +8,8 @@ import ( "path/filepath" "github.com/owncast/owncast/config" - "github.com/owncast/owncast/controllers" "github.com/owncast/owncast/utils" + webutils "github.com/owncast/owncast/webserver/utils" ) // UploadCustomEmoji allows POSTing a new custom emoji to the server. @@ -26,13 +26,13 @@ func UploadCustomEmoji(w http.ResponseWriter, r *http.Request) { emoji := new(postEmoji) if err := json.NewDecoder(r.Body).Decode(emoji); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } bytes, _, err := utils.DecodeBase64Image(emoji.Data) if err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } @@ -42,21 +42,21 @@ func UploadCustomEmoji(w http.ResponseWriter, r *http.Request) { err = os.MkdirAll(config.CustomEmojiPath, 0o700) if err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } if utils.DoesFileExists(targetPath) { - controllers.WriteSimpleResponse(w, false, fmt.Sprintf("An emoji with the name %q already exists", emojiFileName)) + webutils.WriteSimpleResponse(w, false, fmt.Sprintf("An emoji with the name %q already exists", emojiFileName)) return } if err = os.WriteFile(targetPath, bytes, 0o600); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } - controllers.WriteSimpleResponse(w, true, fmt.Sprintf("Emoji %q has been uploaded", emojiFileName)) + webutils.WriteSimpleResponse(w, true, fmt.Sprintf("Emoji %q has been uploaded", emojiFileName)) } // DeleteCustomEmoji deletes a custom emoji. @@ -72,25 +72,25 @@ func DeleteCustomEmoji(w http.ResponseWriter, r *http.Request) { emoji := new(deleteEmoji) if err := json.NewDecoder(r.Body).Decode(emoji); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } targetPath := filepath.Join(config.CustomEmojiPath, emoji.Name) if !filepath.IsLocal(targetPath) { - controllers.WriteSimpleResponse(w, false, "Emoji path is not valid") + webutils.WriteSimpleResponse(w, false, "Emoji path is not valid") return } if err := os.Remove(targetPath); err != nil { if os.IsNotExist(err) { - controllers.WriteSimpleResponse(w, false, fmt.Sprintf("Emoji %q doesn't exist", emoji.Name)) + webutils.WriteSimpleResponse(w, false, fmt.Sprintf("Emoji %q doesn't exist", emoji.Name)) } else { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) } return } - controllers.WriteSimpleResponse(w, true, fmt.Sprintf("Emoji %q has been deleted", emoji.Name)) + webutils.WriteSimpleResponse(w, true, fmt.Sprintf("Emoji %q has been deleted", emoji.Name)) } diff --git a/controllers/admin/externalAPIUsers.go b/webserver/handlers/admin/externalAPIUsers.go similarity index 75% rename from controllers/admin/externalAPIUsers.go rename to webserver/handlers/admin/externalAPIUsers.go index 52e8f0f7e..016d61732 100644 --- a/controllers/admin/externalAPIUsers.go +++ b/webserver/handlers/admin/externalAPIUsers.go @@ -7,10 +7,10 @@ import ( "time" "github.com/owncast/owncast/config" - "github.com/owncast/owncast/controllers" "github.com/owncast/owncast/models" "github.com/owncast/owncast/persistence/userrepository" "github.com/owncast/owncast/utils" + webutils "github.com/owncast/owncast/webserver/utils" ) type deleteExternalAPIUserRequest struct { @@ -27,7 +27,7 @@ func CreateExternalAPIUser(w http.ResponseWriter, r *http.Request) { decoder := json.NewDecoder(r.Body) var request createExternalAPIUserRequest if err := decoder.Decode(&request); err != nil { - controllers.BadRequestHandler(w, err) + webutils.BadRequestHandler(w, err) return } @@ -35,25 +35,25 @@ func CreateExternalAPIUser(w http.ResponseWriter, r *http.Request) { // Verify all the scopes provided are valid if !userRepository.HasValidScopes(request.Scopes) { - controllers.BadRequestHandler(w, errors.New("one or more invalid scopes provided")) + webutils.BadRequestHandler(w, errors.New("one or more invalid scopes provided")) return } token, err := utils.GenerateAccessToken() if err != nil { - controllers.InternalErrorHandler(w, err) + webutils.InternalErrorHandler(w, err) return } color := utils.GenerateRandomDisplayColor(config.MaxUserColor) if err := userRepository.InsertExternalAPIUser(token, request.Name, color, request.Scopes); err != nil { - controllers.InternalErrorHandler(w, err) + webutils.InternalErrorHandler(w, err) return } w.Header().Set("Content-Type", "application/json") - controllers.WriteResponse(w, models.ExternalAPIUser{ + webutils.WriteResponse(w, models.ExternalAPIUser{ AccessToken: token, DisplayName: request.Name, DisplayColor: color, @@ -71,39 +71,39 @@ func GetExternalAPIUsers(w http.ResponseWriter, r *http.Request) { tokens, err := userRepository.GetExternalAPIUser() if err != nil { - controllers.InternalErrorHandler(w, err) + webutils.InternalErrorHandler(w, err) return } - controllers.WriteResponse(w, tokens) + webutils.WriteResponse(w, tokens) } // DeleteExternalAPIUser will return a single 3rd party access token. func DeleteExternalAPIUser(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") - if r.Method != controllers.POST { - controllers.WriteSimpleResponse(w, false, r.Method+" not supported") + if r.Method != http.MethodPost { + webutils.WriteSimpleResponse(w, false, r.Method+" not supported") return } decoder := json.NewDecoder(r.Body) var request deleteExternalAPIUserRequest if err := decoder.Decode(&request); err != nil { - controllers.BadRequestHandler(w, err) + webutils.BadRequestHandler(w, err) return } if request.Token == "" { - controllers.BadRequestHandler(w, errors.New("must provide a token")) + webutils.BadRequestHandler(w, errors.New("must provide a token")) return } userRepository := userrepository.Get() if err := userRepository.DeleteExternalAPIUser(request.Token); err != nil { - controllers.InternalErrorHandler(w, err) + webutils.InternalErrorHandler(w, err) return } - controllers.WriteSimpleResponse(w, true, "deleted token") + webutils.WriteSimpleResponse(w, true, "deleted token") } diff --git a/controllers/admin/federation.go b/webserver/handlers/admin/federation.go similarity index 73% rename from controllers/admin/federation.go rename to webserver/handlers/admin/federation.go index 46844c6e6..bd739a817 100644 --- a/controllers/admin/federation.go +++ b/webserver/handlers/admin/federation.go @@ -6,8 +6,8 @@ import ( "github.com/owncast/owncast/activitypub" "github.com/owncast/owncast/activitypub/outbox" "github.com/owncast/owncast/activitypub/persistence" - "github.com/owncast/owncast/controllers" "github.com/owncast/owncast/core/data" + webutils "github.com/owncast/owncast/webserver/utils" ) // SendFederatedMessage will send a manual message to the fediverse. @@ -23,16 +23,16 @@ func SendFederatedMessage(w http.ResponseWriter, r *http.Request) { message, ok := configValue.Value.(string) if !ok { - controllers.WriteSimpleResponse(w, false, "unable to send message") + webutils.WriteSimpleResponse(w, false, "unable to send message") return } if err := activitypub.SendPublicFederatedMessage(message); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } - controllers.WriteSimpleResponse(w, true, "sent") + webutils.WriteSimpleResponse(w, true, "sent") } // SetFederationEnabled will set if Federation features are enabled. @@ -47,10 +47,10 @@ func SetFederationEnabled(w http.ResponseWriter, r *http.Request) { } if err := data.SetFederationEnabled(configValue.Value.(bool)); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } - controllers.WriteSimpleResponse(w, true, "federation features saved") + webutils.WriteSimpleResponse(w, true, "federation features saved") } // SetFederationActivityPrivate will set if Federation features are private to followers. @@ -65,17 +65,17 @@ func SetFederationActivityPrivate(w http.ResponseWriter, r *http.Request) { } if err := data.SetFederationIsPrivate(configValue.Value.(bool)); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } // Update Fediverse followers about this change. if err := outbox.UpdateFollowersWithAccountUpdates(); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } - controllers.WriteSimpleResponse(w, true, "federation private saved") + webutils.WriteSimpleResponse(w, true, "federation private saved") } // SetFederationShowEngagement will set if Fedivese engagement shows in chat. @@ -90,10 +90,10 @@ func SetFederationShowEngagement(w http.ResponseWriter, r *http.Request) { } if err := data.SetFederationShowEngagement(configValue.Value.(bool)); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } - controllers.WriteSimpleResponse(w, true, "federation show engagement saved") + webutils.WriteSimpleResponse(w, true, "federation show engagement saved") } // SetFederationUsername will set the local actor username used for federation activities. @@ -108,11 +108,11 @@ func SetFederationUsername(w http.ResponseWriter, r *http.Request) { } if err := data.SetFederationUsername(configValue.Value.(string)); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } - controllers.WriteSimpleResponse(w, true, "username saved") + webutils.WriteSimpleResponse(w, true, "username saved") } // SetFederationGoLiveMessage will set the federated message sent when the streamer goes live. @@ -127,11 +127,11 @@ func SetFederationGoLiveMessage(w http.ResponseWriter, r *http.Request) { } if err := data.SetFederationGoLiveMessage(configValue.Value.(string)); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } - controllers.WriteSimpleResponse(w, true, "message saved") + webutils.WriteSimpleResponse(w, true, "message saved") } // SetFederationBlockDomains saves a list of domains to block on the Fediverse. @@ -142,7 +142,7 @@ func SetFederationBlockDomains(w http.ResponseWriter, r *http.Request) { configValues, success := getValuesFromRequest(w, r) if !success { - controllers.WriteSimpleResponse(w, false, "unable to handle provided domains") + webutils.WriteSimpleResponse(w, false, "unable to handle provided domains") return } @@ -152,11 +152,11 @@ func SetFederationBlockDomains(w http.ResponseWriter, r *http.Request) { } if err := data.SetBlockedFederatedDomains(domainStrings); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } - controllers.WriteSimpleResponse(w, true, "saved") + webutils.WriteSimpleResponse(w, true, "saved") } // GetFederatedActions will return the saved list of accepted inbound @@ -166,14 +166,14 @@ func GetFederatedActions(page int, pageSize int, w http.ResponseWriter, r *http. activities, total, err := persistence.GetInboundActivities(pageSize, offset) if err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } - response := controllers.PaginatedResponse{ + response := webutils.PaginatedResponse{ Total: total, Results: activities, } - controllers.WriteResponse(w, response) + webutils.WriteResponse(w, response) } diff --git a/controllers/admin/followers.go b/webserver/handlers/admin/followers.go similarity index 73% rename from controllers/admin/followers.go rename to webserver/handlers/admin/followers.go index dd144791c..e6ea0bcf0 100644 --- a/controllers/admin/followers.go +++ b/webserver/handlers/admin/followers.go @@ -6,8 +6,8 @@ import ( "github.com/owncast/owncast/activitypub/persistence" "github.com/owncast/owncast/activitypub/requests" - "github.com/owncast/owncast/controllers" "github.com/owncast/owncast/core/data" + webutils "github.com/owncast/owncast/webserver/utils" ) // ApproveFollower will approve a federated follow request. @@ -24,14 +24,14 @@ func ApproveFollower(w http.ResponseWriter, r *http.Request) { decoder := json.NewDecoder(r.Body) var approval approveFollowerRequest if err := decoder.Decode(&approval); err != nil { - controllers.WriteSimpleResponse(w, false, "unable to handle follower state with provided values") + webutils.WriteSimpleResponse(w, false, "unable to handle follower state with provided values") return } if approval.Approved { // Approve a follower if err := persistence.ApprovePreviousFollowRequest(approval.ActorIRI); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } @@ -39,44 +39,44 @@ func ApproveFollower(w http.ResponseWriter, r *http.Request) { followRequest, err := persistence.GetFollower(approval.ActorIRI) if err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } // Send the approval to the follow requestor. if err := requests.SendFollowAccept(followRequest.Inbox, followRequest.RequestObject, localAccountName); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } } else { // Remove/block a follower if err := persistence.BlockOrRejectFollower(approval.ActorIRI); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } } - controllers.WriteSimpleResponse(w, true, "follower updated") + webutils.WriteSimpleResponse(w, true, "follower updated") } // GetPendingFollowRequests will return a list of pending follow requests. func GetPendingFollowRequests(w http.ResponseWriter, r *http.Request) { requests, err := persistence.GetPendingFollowRequests() if err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } - controllers.WriteResponse(w, requests) + webutils.WriteResponse(w, requests) } // GetBlockedAndRejectedFollowers will return blocked and rejected followers. func GetBlockedAndRejectedFollowers(w http.ResponseWriter, r *http.Request) { rejections, err := persistence.GetBlockedAndRejectedFollowers() if err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } - controllers.WriteResponse(w, rejections) + webutils.WriteResponse(w, rejections) } diff --git a/controllers/admin/hardware.go b/webserver/handlers/admin/hardware.go similarity index 100% rename from controllers/admin/hardware.go rename to webserver/handlers/admin/hardware.go diff --git a/controllers/admin/logs.go b/webserver/handlers/admin/logs.go similarity index 100% rename from controllers/admin/logs.go rename to webserver/handlers/admin/logs.go diff --git a/controllers/admin/notifications.go b/webserver/handlers/admin/notifications.go similarity index 63% rename from controllers/admin/notifications.go rename to webserver/handlers/admin/notifications.go index 82bdb5f8c..b7f29c413 100644 --- a/controllers/admin/notifications.go +++ b/webserver/handlers/admin/notifications.go @@ -4,9 +4,9 @@ import ( "encoding/json" "net/http" - "github.com/owncast/owncast/controllers" "github.com/owncast/owncast/core/data" "github.com/owncast/owncast/models" + webutils "github.com/owncast/owncast/webserver/utils" ) // SetDiscordNotificationConfiguration will set the discord notification configuration. @@ -22,16 +22,16 @@ func SetDiscordNotificationConfiguration(w http.ResponseWriter, r *http.Request) decoder := json.NewDecoder(r.Body) var config request if err := decoder.Decode(&config); err != nil { - controllers.WriteSimpleResponse(w, false, "unable to update discord config with provided values") + webutils.WriteSimpleResponse(w, false, "unable to update discord config with provided values") return } if err := data.SetDiscordConfig(config.Value); err != nil { - controllers.WriteSimpleResponse(w, false, "unable to update discord config with provided values") + webutils.WriteSimpleResponse(w, false, "unable to update discord config with provided values") return } - controllers.WriteSimpleResponse(w, true, "updated discord config with provided values") + webutils.WriteSimpleResponse(w, true, "updated discord config with provided values") } // SetBrowserNotificationConfiguration will set the browser notification configuration. @@ -47,14 +47,14 @@ func SetBrowserNotificationConfiguration(w http.ResponseWriter, r *http.Request) decoder := json.NewDecoder(r.Body) var config request if err := decoder.Decode(&config); err != nil { - controllers.WriteSimpleResponse(w, false, "unable to update browser push config with provided values") + webutils.WriteSimpleResponse(w, false, "unable to update browser push config with provided values") return } if err := data.SetBrowserPushConfig(config.Value); err != nil { - controllers.WriteSimpleResponse(w, false, "unable to update browser push config with provided values") + webutils.WriteSimpleResponse(w, false, "unable to update browser push config with provided values") return } - controllers.WriteSimpleResponse(w, true, "updated browser push config with provided values") + webutils.WriteSimpleResponse(w, true, "updated browser push config with provided values") } diff --git a/controllers/admin/serverConfig.go b/webserver/handlers/admin/serverConfig.go similarity index 100% rename from controllers/admin/serverConfig.go rename to webserver/handlers/admin/serverConfig.go diff --git a/controllers/admin/status.go b/webserver/handlers/admin/status.go similarity index 100% rename from controllers/admin/status.go rename to webserver/handlers/admin/status.go diff --git a/controllers/admin/update.go b/webserver/handlers/admin/update.go similarity index 94% rename from controllers/admin/update.go rename to webserver/handlers/admin/update.go index 8f93fa37b..d690a8301 100644 --- a/controllers/admin/update.go +++ b/webserver/handlers/admin/update.go @@ -10,7 +10,7 @@ import ( "strings" "github.com/owncast/owncast/config" - "github.com/owncast/owncast/controllers" + webutils "github.com/owncast/owncast/webserver/utils" log "github.com/sirupsen/logrus" ) @@ -47,7 +47,7 @@ func AutoUpdateOptions(w http.ResponseWriter, r *http.Request) { // Nothing is supported when running under "dev" or the feature is // explicitly disabled. if config.BuildPlatform == "dev" || !config.EnableAutoUpdate { - controllers.WriteResponse(w, updateOptions) + webutils.WriteResponse(w, updateOptions) return } @@ -58,7 +58,7 @@ func AutoUpdateOptions(w http.ResponseWriter, r *http.Request) { updateOptions.CanRestart = isRunningUnderSystemD() - controllers.WriteResponse(w, updateOptions) + webutils.WriteResponse(w, updateOptions) } // AutoUpdateStart will begin the auto update process. @@ -70,7 +70,7 @@ func AutoUpdateStart(w http.ResponseWriter, r *http.Request) { updater, err := downloadInstaller() if err != nil { log.Errorln(err) - controllers.WriteSimpleResponse(w, false, "failed to download and run installer") + webutils.WriteSimpleResponse(w, false, "failed to download and run installer") return } @@ -100,7 +100,7 @@ func AutoUpdateForceQuit(w http.ResponseWriter, r *http.Request) { go func() { os.Exit(0) }() - controllers.WriteSimpleResponse(w, true, "forcing quit") + webutils.WriteSimpleResponse(w, true, "forcing quit") } func downloadInstaller() (string, error) { diff --git a/controllers/admin/video.go b/webserver/handlers/admin/video.go similarity index 100% rename from controllers/admin/video.go rename to webserver/handlers/admin/video.go diff --git a/controllers/admin/viewers.go b/webserver/handlers/admin/viewers.go similarity index 90% rename from controllers/admin/viewers.go rename to webserver/handlers/admin/viewers.go index fa27c914f..b89dd715e 100644 --- a/controllers/admin/viewers.go +++ b/webserver/handlers/admin/viewers.go @@ -6,10 +6,10 @@ import ( "strconv" "time" - "github.com/owncast/owncast/controllers" "github.com/owncast/owncast/core" "github.com/owncast/owncast/metrics" "github.com/owncast/owncast/models" + webutils "github.com/owncast/owncast/webserver/utils" log "github.com/sirupsen/logrus" ) @@ -18,7 +18,7 @@ func GetViewersOverTime(w http.ResponseWriter, r *http.Request) { windowStartAtStr := r.URL.Query().Get("windowStart") windowStartAtUnix, err := strconv.Atoi(windowStartAtStr) if err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } @@ -44,7 +44,7 @@ func GetActiveViewers(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") if err := json.NewEncoder(w).Encode(viewers); err != nil { - controllers.InternalErrorHandler(w, err) + webutils.InternalErrorHandler(w, err) } } diff --git a/controllers/admin/webhooks.go b/webserver/handlers/admin/webhooks.go similarity index 70% rename from controllers/admin/webhooks.go rename to webserver/handlers/admin/webhooks.go index 9407b1996..156b11299 100644 --- a/controllers/admin/webhooks.go +++ b/webserver/handlers/admin/webhooks.go @@ -6,9 +6,9 @@ import ( "net/http" "time" - "github.com/owncast/owncast/controllers" "github.com/owncast/owncast/core/data" "github.com/owncast/owncast/models" + webutils "github.com/owncast/owncast/webserver/utils" ) type deleteWebhookRequest struct { @@ -25,23 +25,23 @@ func CreateWebhook(w http.ResponseWriter, r *http.Request) { decoder := json.NewDecoder(r.Body) var request createWebhookRequest if err := decoder.Decode(&request); err != nil { - controllers.BadRequestHandler(w, err) + webutils.BadRequestHandler(w, err) return } // Verify all the scopes provided are valid if !models.HasValidEvents(request.Events) { - controllers.BadRequestHandler(w, errors.New("one or more invalid event provided")) + webutils.BadRequestHandler(w, errors.New("one or more invalid event provided")) return } newWebhookID, err := data.InsertWebhook(request.URL, request.Events) if err != nil { - controllers.InternalErrorHandler(w, err) + webutils.InternalErrorHandler(w, err) return } - controllers.WriteResponse(w, models.Webhook{ + webutils.WriteResponse(w, models.Webhook{ ID: newWebhookID, URL: request.URL, Events: request.Events, @@ -54,31 +54,31 @@ func CreateWebhook(w http.ResponseWriter, r *http.Request) { func GetWebhooks(w http.ResponseWriter, r *http.Request) { webhooks, err := data.GetWebhooks() if err != nil { - controllers.InternalErrorHandler(w, err) + webutils.InternalErrorHandler(w, err) return } - controllers.WriteResponse(w, webhooks) + webutils.WriteResponse(w, webhooks) } // DeleteWebhook will delete a single webhook. func DeleteWebhook(w http.ResponseWriter, r *http.Request) { - if r.Method != controllers.POST { - controllers.WriteSimpleResponse(w, false, r.Method+" not supported") + if r.Method != http.MethodPost { + webutils.WriteSimpleResponse(w, false, r.Method+" not supported") return } decoder := json.NewDecoder(r.Body) var request deleteWebhookRequest if err := decoder.Decode(&request); err != nil { - controllers.BadRequestHandler(w, err) + webutils.BadRequestHandler(w, err) return } if err := data.DeleteWebhook(request.ID); err != nil { - controllers.InternalErrorHandler(w, err) + webutils.InternalErrorHandler(w, err) return } - controllers.WriteSimpleResponse(w, true, "deleted webhook") + webutils.WriteSimpleResponse(w, true, "deleted webhook") } diff --git a/controllers/admin/yp.go b/webserver/handlers/admin/yp.go similarity index 71% rename from controllers/admin/yp.go rename to webserver/handlers/admin/yp.go index c6595b86e..530fbf00a 100644 --- a/controllers/admin/yp.go +++ b/webserver/handlers/admin/yp.go @@ -3,8 +3,8 @@ package admin import ( "net/http" - "github.com/owncast/owncast/controllers" "github.com/owncast/owncast/core/data" + webutils "github.com/owncast/owncast/webserver/utils" log "github.com/sirupsen/logrus" ) @@ -13,8 +13,8 @@ func ResetYPRegistration(w http.ResponseWriter, r *http.Request) { log.Traceln("Resetting YP registration key") if err := data.SetDirectoryRegistrationKey(""); err != nil { log.Errorln(err) - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } - controllers.WriteSimpleResponse(w, true, "reset") + webutils.WriteSimpleResponse(w, true, "reset") } diff --git a/webserver/handlers/auth.go b/webserver/handlers/auth.go index ffa9eb7d1..c69e9d8e1 100644 --- a/webserver/handlers/auth.go +++ b/webserver/handlers/auth.go @@ -3,8 +3,8 @@ package handlers import ( "net/http" - "github.com/owncast/owncast/controllers/auth/fediverse" - "github.com/owncast/owncast/controllers/auth/indieauth" + "github.com/owncast/owncast/webserver/handlers/auth/fediverse" + "github.com/owncast/owncast/webserver/handlers/auth/indieauth" "github.com/owncast/owncast/webserver/handlers/generated" "github.com/owncast/owncast/webserver/router/middleware" ) diff --git a/controllers/auth/fediverse/fediverse.go b/webserver/handlers/auth/fediverse/fediverse.go similarity index 79% rename from controllers/auth/fediverse/fediverse.go rename to webserver/handlers/auth/fediverse/fediverse.go index 1fd773a4e..b8e7026bd 100644 --- a/controllers/auth/fediverse/fediverse.go +++ b/webserver/handlers/auth/fediverse/fediverse.go @@ -7,11 +7,11 @@ import ( "github.com/owncast/owncast/activitypub" fediverseauth "github.com/owncast/owncast/auth/fediverse" - "github.com/owncast/owncast/controllers" "github.com/owncast/owncast/core/chat" "github.com/owncast/owncast/core/data" "github.com/owncast/owncast/models" "github.com/owncast/owncast/persistence/userrepository" + webutils "github.com/owncast/owncast/webserver/utils" log "github.com/sirupsen/logrus" ) @@ -23,29 +23,29 @@ func RegisterFediverseOTPRequest(u models.User, w http.ResponseWriter, r *http.R var req request decoder := json.NewDecoder(r.Body) if err := decoder.Decode(&req); err != nil { - controllers.WriteSimpleResponse(w, false, "Could not decode request: "+err.Error()) + webutils.WriteSimpleResponse(w, false, "Could not decode request: "+err.Error()) return } accessToken := r.URL.Query().Get("accessToken") reg, success, err := fediverseauth.RegisterFediverseOTP(accessToken, u.ID, u.DisplayName, req.FediverseAccount) if err != nil { - controllers.WriteSimpleResponse(w, false, "Could not register auth request: "+err.Error()) + webutils.WriteSimpleResponse(w, false, "Could not register auth request: "+err.Error()) return } if !success { - controllers.WriteSimpleResponse(w, false, "Could not register auth request. One may already be pending. Try again later.") + webutils.WriteSimpleResponse(w, false, "Could not register auth request. One may already be pending. Try again later.") return } msg := fmt.Sprintf("

One-time code from %s: %s. If you did not request this message please ignore or block.

", data.GetServerName(), reg.Code) if err := activitypub.SendDirectFederatedMessage(msg, reg.Account); err != nil { - controllers.WriteSimpleResponse(w, false, "Could not send code to fediverse: "+err.Error()) + webutils.WriteSimpleResponse(w, false, "Could not send code to fediverse: "+err.Error()) return } - controllers.WriteSimpleResponse(w, true, "") + webutils.WriteSimpleResponse(w, true, "") } // VerifyFediverseOTPRequest verifies the given OTP code for the given access token. @@ -57,7 +57,7 @@ func VerifyFediverseOTPRequest(w http.ResponseWriter, r *http.Request) { var req request decoder := json.NewDecoder(r.Body) if err := decoder.Decode(&req); err != nil { - controllers.WriteSimpleResponse(w, false, "Could not decode request: "+err.Error()) + webutils.WriteSimpleResponse(w, false, "Could not decode request: "+err.Error()) return } accessToken := r.URL.Query().Get("accessToken") @@ -77,7 +77,7 @@ func VerifyFediverseOTPRequest(w http.ResponseWriter, r *http.Request) { // Update the current user's access token to point to the existing user id. userID := u.ID if err := userRepository.SetAccessTokenToOwner(accessToken, userID); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } @@ -88,7 +88,7 @@ func VerifyFediverseOTPRequest(w http.ResponseWriter, r *http.Request) { } } - controllers.WriteSimpleResponse(w, true, "") + webutils.WriteSimpleResponse(w, true, "") return } @@ -96,7 +96,7 @@ func VerifyFediverseOTPRequest(w http.ResponseWriter, r *http.Request) { // Otherwise, save this as new auth. log.Debug("fediverse account does not already exist, saving it as a new one for the current user") if err := userRepository.AddAuth(authRegistration.UserID, authRegistration.Account, models.Fediverse); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } @@ -106,5 +106,5 @@ func VerifyFediverseOTPRequest(w http.ResponseWriter, r *http.Request) { log.Errorln(err) } - controllers.WriteSimpleResponse(w, true, "") + webutils.WriteSimpleResponse(w, true, "") } diff --git a/controllers/auth/indieauth/client.go b/webserver/handlers/auth/indieauth/client.go similarity index 86% rename from controllers/auth/indieauth/client.go rename to webserver/handlers/auth/indieauth/client.go index 24cdb8bb2..d52bf8a5e 100644 --- a/controllers/auth/indieauth/client.go +++ b/webserver/handlers/auth/indieauth/client.go @@ -7,10 +7,10 @@ import ( "net/http" ia "github.com/owncast/owncast/auth/indieauth" - "github.com/owncast/owncast/controllers" "github.com/owncast/owncast/core/chat" "github.com/owncast/owncast/models" "github.com/owncast/owncast/persistence/userrepository" + webutils "github.com/owncast/owncast/webserver/utils" log "github.com/sirupsen/logrus" ) @@ -27,12 +27,12 @@ func StartAuthFlow(u models.User, w http.ResponseWriter, r *http.Request) { var authRequest request p, err := io.ReadAll(r.Body) if err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } if err := json.Unmarshal(p, &authRequest); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } @@ -40,14 +40,14 @@ func StartAuthFlow(u models.User, w http.ResponseWriter, r *http.Request) { redirectURL, err := ia.StartAuthFlow(authRequest.AuthHost, u.ID, accessToken, u.DisplayName) if err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } redirectResponse := response{ Redirect: redirectURL.String(), } - controllers.WriteResponse(w, redirectResponse) + webutils.WriteResponse(w, redirectResponse) } // HandleRedirect will handle the redirect from an IndieAuth server to @@ -59,7 +59,7 @@ func HandleRedirect(w http.ResponseWriter, r *http.Request) { if err != nil { log.Debugln(err) msg := `Unable to complete authentication. Go back.
` - _ = controllers.WriteString(w, msg, http.StatusBadRequest) + _ = webutils.WriteString(w, msg, http.StatusBadRequest) return } @@ -74,7 +74,7 @@ func HandleRedirect(w http.ResponseWriter, r *http.Request) { accessToken := request.CurrentAccessToken userID := u.ID if err := userRepository.SetAccessTokenToOwner(accessToken, userID); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } @@ -93,7 +93,7 @@ func HandleRedirect(w http.ResponseWriter, r *http.Request) { // Otherwise, save this as new auth. log.Debug("indieauth token does not already exist, saving it as a new one for the current user") if err := userRepository.AddAuth(request.UserID, response.Me, models.IndieAuth); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } diff --git a/controllers/auth/indieauth/server.go b/webserver/handlers/auth/indieauth/server.go similarity index 87% rename from controllers/auth/indieauth/server.go rename to webserver/handlers/auth/indieauth/server.go index 15780543c..429db445f 100644 --- a/controllers/auth/indieauth/server.go +++ b/webserver/handlers/auth/indieauth/server.go @@ -5,8 +5,8 @@ import ( "net/url" ia "github.com/owncast/owncast/auth/indieauth" - "github.com/owncast/owncast/controllers" "github.com/owncast/owncast/webserver/router/middleware" + webutils "github.com/owncast/owncast/webserver/utils" ) // HandleAuthEndpoint will handle the IndieAuth auth endpoint. @@ -33,7 +33,7 @@ func HandleAuthEndpointGet(w http.ResponseWriter, r *http.Request) { request, err := ia.StartServerAuth(clientID, redirectURI, codeChallenge, state, me) if err != nil { - _ = controllers.WriteString(w, err.Error(), http.StatusInternalServerError) + _ = webutils.WriteString(w, err.Error(), http.StatusInternalServerError) return } @@ -42,7 +42,7 @@ func HandleAuthEndpointGet(w http.ResponseWriter, r *http.Request) { // If the URL is invalid then return with specific "invalid_request" error. u, err := url.Parse(redirectURI) if err != nil { - controllers.WriteResponse(w, ia.Response{ + webutils.WriteResponse(w, ia.Response{ Error: "invalid_request", ErrorDescription: err.Error(), }) @@ -59,7 +59,7 @@ func HandleAuthEndpointGet(w http.ResponseWriter, r *http.Request) { func HandleAuthEndpointPost(w http.ResponseWriter, r *http.Request) { if err := r.ParseForm(); err != nil { - controllers.WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } @@ -72,12 +72,12 @@ func HandleAuthEndpointPost(w http.ResponseWriter, r *http.Request) { // "invalid_client" error. response, err := ia.CompleteServerAuth(code, redirectURI, clientID, codeVerifier) if err != nil { - controllers.WriteResponse(w, ia.Response{ + webutils.WriteResponse(w, ia.Response{ Error: "invalid_client", ErrorDescription: err.Error(), }) return } - controllers.WriteResponse(w, response) + webutils.WriteResponse(w, response) } diff --git a/controllers/chat.go b/webserver/handlers/chat.go similarity index 88% rename from controllers/chat.go rename to webserver/handlers/chat.go index a4c983404..010fe5254 100644 --- a/controllers/chat.go +++ b/webserver/handlers/chat.go @@ -1,4 +1,4 @@ -package controllers +package handlers import ( "encoding/json" @@ -11,6 +11,7 @@ import ( "github.com/owncast/owncast/persistence/userrepository" "github.com/owncast/owncast/utils" "github.com/owncast/owncast/webserver/router/middleware" + webutils "github.com/owncast/owncast/webserver/utils" log "github.com/sirupsen/logrus" ) @@ -38,8 +39,8 @@ func getChatMessages(w http.ResponseWriter, r *http.Request) { } default: w.WriteHeader(http.StatusNotImplemented) - if err := json.NewEncoder(w).Encode(j{"error": "method not implemented (PRs are accepted)"}); err != nil { - InternalErrorHandler(w, err) + if err := json.NewEncoder(w).Encode(webutils.J{"error": "method not implemented (PRs are accepted)"}); err != nil { + webutils.InternalErrorHandler(w, err) } } } @@ -59,7 +60,7 @@ func RegisterAnonymousChatUser(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { // nolint:goconst - WriteSimpleResponse(w, false, r.Method+" not supported") + webutils.WriteSimpleResponse(w, false, r.Method+" not supported") return } @@ -90,7 +91,7 @@ func RegisterAnonymousChatUser(w http.ResponseWriter, r *http.Request) { proposedNewDisplayName = utils.MakeSafeStringOfLength(proposedNewDisplayName, config.MaxChatDisplayNameLength) newUser, accessToken, err := userRepository.CreateAnonymousUser(proposedNewDisplayName) if err != nil { - WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } @@ -103,7 +104,7 @@ func RegisterAnonymousChatUser(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") middleware.DisableCache(w) - WriteResponse(w, response) + webutils.WriteResponse(w, response) } func generateDisplayName() string { diff --git a/webserver/handlers/config.go b/webserver/handlers/config.go index f0bef91f9..d7487a954 100644 --- a/webserver/handlers/config.go +++ b/webserver/handlers/config.go @@ -1,368 +1,156 @@ package handlers import ( + "encoding/json" + "fmt" "net/http" + "net/url" - "github.com/owncast/owncast/controllers/admin" + "github.com/owncast/owncast/activitypub" + "github.com/owncast/owncast/config" + "github.com/owncast/owncast/core/data" + "github.com/owncast/owncast/models" + "github.com/owncast/owncast/utils" "github.com/owncast/owncast/webserver/router/middleware" + webutils "github.com/owncast/owncast/webserver/utils" + log "github.com/sirupsen/logrus" ) -func (*ServerInterfaceImpl) SetAdminPassword(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetAdminPassword)(w, r) -} - -func (*ServerInterfaceImpl) SetAdminPasswordOptions(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetAdminPassword)(w, r) -} - -func (*ServerInterfaceImpl) SetStreamKeys(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetStreamKeys)(w, r) -} - -func (*ServerInterfaceImpl) SetStreamKeysOptions(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetStreamKeys)(w, r) -} - -func (*ServerInterfaceImpl) SetExtraPageContent(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetExtraPageContent)(w, r) -} - -func (*ServerInterfaceImpl) SetExtraPageContentOptions(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetExtraPageContent)(w, r) -} - -func (*ServerInterfaceImpl) SetStreamTitle(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetStreamTitle)(w, r) -} - -func (*ServerInterfaceImpl) SetStreamTitleOptions(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetStreamTitle)(w, r) -} - -func (*ServerInterfaceImpl) SetServerName(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetServerName)(w, r) -} - -func (*ServerInterfaceImpl) SetServerNameOptions(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetServerName)(w, r) -} - -func (*ServerInterfaceImpl) SetServerSummary(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetServerSummary)(w, r) -} - -func (*ServerInterfaceImpl) SetServerSummaryOptions(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetServerSummary)(w, r) -} - -func (*ServerInterfaceImpl) SetCustomOfflineMessage(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetCustomOfflineMessage)(w, r) -} - -func (*ServerInterfaceImpl) SetCustomOfflineMessageOptions(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetCustomOfflineMessage)(w, r) -} - -func (*ServerInterfaceImpl) SetServerWelcomeMessage(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetServerWelcomeMessage)(w, r) -} - -func (*ServerInterfaceImpl) SetServerWelcomeMessageOptions(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetServerWelcomeMessage)(w, r) -} - -func (*ServerInterfaceImpl) SetChatDisabled(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetChatDisabled)(w, r) -} - -func (*ServerInterfaceImpl) SetChatDisabledOptions(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetChatDisabled)(w, r) -} - -func (*ServerInterfaceImpl) SetChatJoinMessagesEnabled(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetChatJoinMessagesEnabled)(w, r) -} - -func (*ServerInterfaceImpl) SetChatJoinMessagesEnabledOptions(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetChatJoinMessagesEnabled)(w, r) -} - -func (*ServerInterfaceImpl) SetEnableEstablishedChatUserMode(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetEnableEstablishedChatUserMode)(w, r) -} - -func (*ServerInterfaceImpl) SetEnableEstablishedChatUserModeOptions(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetEnableEstablishedChatUserMode)(w, r) -} - -func (*ServerInterfaceImpl) SetForbiddenUsernameList(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetForbiddenUsernameList)(w, r) -} - -func (*ServerInterfaceImpl) SetForbiddenUsernameListOptions(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetForbiddenUsernameList)(w, r) -} - -func (*ServerInterfaceImpl) SetSuggestedUsernameList(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetSuggestedUsernameList)(w, r) -} - -func (*ServerInterfaceImpl) SetSuggestedUsernameListOptions(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetSuggestedUsernameList)(w, r) -} - -func (*ServerInterfaceImpl) SetChatSpamProtectionEnabled(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetChatSpamProtectionEnabled)(w, r) -} - -func (*ServerInterfaceImpl) SetChatSpamProtectionEnabledOptions(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetChatSpamProtectionEnabled)(w, r) -} - -func (*ServerInterfaceImpl) SetChatSlurFilterEnabled(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetChatSlurFilterEnabled)(w, r) -} - -func (*ServerInterfaceImpl) SetChatSlurFilterEnabledOptions(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetChatSlurFilterEnabled)(w, r) -} - -func (*ServerInterfaceImpl) SetVideoCodec(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetVideoCodec)(w, r) -} - -func (*ServerInterfaceImpl) SetVideoCodecOptions(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetVideoCodec)(w, r) -} - -func (*ServerInterfaceImpl) SetStreamLatencyLevel(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetStreamLatencyLevel)(w, r) -} - -func (*ServerInterfaceImpl) SetStreamLatencyLevelOptions(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetStreamLatencyLevel)(w, r) -} - -func (*ServerInterfaceImpl) SetStreamOutputVariants(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetStreamOutputVariants)(w, r) -} - -func (*ServerInterfaceImpl) SetStreamOutputVariantsOptions(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetStreamOutputVariants)(w, r) -} - -func (*ServerInterfaceImpl) SetCustomColorVariableValues(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetCustomColorVariableValues)(w, r) -} - -func (*ServerInterfaceImpl) SetCustomColorVariableValuesOptions(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetCustomColorVariableValues)(w, r) -} - -func (*ServerInterfaceImpl) SetLogo(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetLogo)(w, r) -} - -func (*ServerInterfaceImpl) SetLogoOptions(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetLogo)(w, r) -} - -func (*ServerInterfaceImpl) SetTags(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetTags)(w, r) -} - -func (*ServerInterfaceImpl) SetTagsOptions(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetTags)(w, r) -} - -func (*ServerInterfaceImpl) SetFfmpegPath(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetFfmpegPath)(w, r) -} - -func (*ServerInterfaceImpl) SetFfmpegPathOptions(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetFfmpegPath)(w, r) -} - -func (*ServerInterfaceImpl) SetWebServerPort(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetWebServerPort)(w, r) -} - -func (*ServerInterfaceImpl) SetWebServerPortOptions(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetWebServerPort)(w, r) -} - -func (*ServerInterfaceImpl) SetWebServerIP(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetWebServerIP)(w, r) -} - -func (*ServerInterfaceImpl) SetWebServerIPOptions(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetWebServerIP)(w, r) -} - -func (*ServerInterfaceImpl) SetRTMPServerPort(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetRTMPServerPort)(w, r) -} - -func (*ServerInterfaceImpl) SetRTMPServerPortOptions(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetRTMPServerPort)(w, r) -} - -func (*ServerInterfaceImpl) SetSocketHostOverride(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetSocketHostOverride)(w, r) -} - -func (*ServerInterfaceImpl) SetSocketHostOverrideOptions(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetSocketHostOverride)(w, r) -} - -func (*ServerInterfaceImpl) SetVideoServingEndpoint(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetVideoServingEndpoint)(w, r) -} - -func (*ServerInterfaceImpl) SetVideoServingEndpointOptions(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetVideoServingEndpoint)(w, r) -} - -func (*ServerInterfaceImpl) SetNSFW(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetNSFW)(w, r) -} - -func (*ServerInterfaceImpl) SetNSFWOptions(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetNSFW)(w, r) -} - -func (*ServerInterfaceImpl) SetDirectoryEnabled(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetDirectoryEnabled)(w, r) -} - -func (*ServerInterfaceImpl) SetDirectoryEnabledOptions(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetDirectoryEnabled)(w, r) -} - -func (*ServerInterfaceImpl) SetSocialHandles(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetSocialHandles)(w, r) -} - -func (*ServerInterfaceImpl) SetSocialHandlesOptions(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetSocialHandles)(w, r) -} - -func (*ServerInterfaceImpl) SetS3Configuration(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetS3Configuration)(w, r) -} - -func (*ServerInterfaceImpl) SetS3ConfigurationOptions(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetS3Configuration)(w, r) -} - -func (*ServerInterfaceImpl) SetServerURL(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetServerURL)(w, r) -} - -func (*ServerInterfaceImpl) SetServerURLOptions(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetServerURL)(w, r) -} - -func (*ServerInterfaceImpl) SetExternalActions(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetExternalActions)(w, r) -} - -func (*ServerInterfaceImpl) SetExternalActionsOptions(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetExternalActions)(w, r) -} - -func (*ServerInterfaceImpl) SetCustomStyles(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetCustomStyles)(w, r) -} - -func (*ServerInterfaceImpl) SetCustomStylesOptions(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetCustomStyles)(w, r) -} - -func (*ServerInterfaceImpl) SetCustomJavascript(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetCustomJavascript)(w, r) -} - -func (*ServerInterfaceImpl) SetCustomJavascriptOptions(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetCustomJavascript)(w, r) -} - -func (*ServerInterfaceImpl) SetHideViewerCount(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetHideViewerCount)(w, r) -} - -func (*ServerInterfaceImpl) SetHideViewerCountOptions(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetHideViewerCount)(w, r) -} - -func (*ServerInterfaceImpl) SetDisableSearchIndexing(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetDisableSearchIndexing)(w, r) -} - -func (*ServerInterfaceImpl) SetDisableSearchIndexingOptions(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetDisableSearchIndexing)(w, r) -} - -func (*ServerInterfaceImpl) SetFederationEnabled(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetFederationEnabled)(w, r) -} - -func (*ServerInterfaceImpl) SetFederationEnabledOptions(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetFederationEnabled)(w, r) -} - -func (*ServerInterfaceImpl) SetFederationActivityPrivate(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetFederationActivityPrivate)(w, r) -} - -func (*ServerInterfaceImpl) SetFederationActivityPrivateOptions(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetFederationActivityPrivate)(w, r) -} - -func (*ServerInterfaceImpl) SetFederationShowEngagement(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetFederationShowEngagement)(w, r) -} - -func (*ServerInterfaceImpl) SetFederationShowEngagementOptions(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetFederationShowEngagement)(w, r) -} - -func (*ServerInterfaceImpl) SetFederationUsername(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetFederationUsername)(w, r) -} - -func (*ServerInterfaceImpl) SetFederationUsernameOptions(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetFederationUsername)(w, r) -} - -func (*ServerInterfaceImpl) SetFederationGoLiveMessage(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetFederationGoLiveMessage)(w, r) -} - -func (*ServerInterfaceImpl) SetFederationGoLiveMessageOptions(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetFederationGoLiveMessage)(w, r) -} - -func (*ServerInterfaceImpl) SetFederationBlockDomains(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetFederationBlockDomains)(w, r) -} - -func (*ServerInterfaceImpl) SetFederationBlockDomainsOptions(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetFederationBlockDomains)(w, r) -} - -func (*ServerInterfaceImpl) SetDiscordNotificationConfiguration(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetDiscordNotificationConfiguration)(w, r) -} - -func (*ServerInterfaceImpl) SetDiscordNotificationConfigurationOptions(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetDiscordNotificationConfiguration)(w, r) -} - -func (*ServerInterfaceImpl) SetBrowserNotificationConfiguration(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetBrowserNotificationConfiguration)(w, r) -} - -func (*ServerInterfaceImpl) SetBrowserNotificationConfigurationOptions(w http.ResponseWriter, r *http.Request) { - middleware.RequireAdminAuth(admin.SetBrowserNotificationConfiguration)(w, r) +type webConfigResponse struct { + AppearanceVariables map[string]string `json:"appearanceVariables"` + Name string `json:"name"` + CustomStyles string `json:"customStyles"` + StreamTitle string `json:"streamTitle,omitempty"` // What's going on with the current stream + OfflineMessage string `json:"offlineMessage"` + Logo string `json:"logo"` + Version string `json:"version"` + SocketHostOverride string `json:"socketHostOverride,omitempty"` + ExtraPageContent string `json:"extraPageContent"` + Summary string `json:"summary"` + Tags []string `json:"tags"` + SocialHandles []models.SocialHandle `json:"socialHandles"` + ExternalActions []models.ExternalAction `json:"externalActions"` + Notifications notificationsConfigResponse `json:"notifications"` + Federation federationConfigResponse `json:"federation"` + MaxSocketPayloadSize int `json:"maxSocketPayloadSize"` + HideViewerCount bool `json:"hideViewerCount"` + ChatDisabled bool `json:"chatDisabled"` + ChatSpamProtectionDisabled bool `json:"chatSpamProtectionDisabled"` + NSFW bool `json:"nsfw"` + Authentication authenticationConfigResponse `json:"authentication"` +} + +type federationConfigResponse struct { + Account string `json:"account,omitempty"` + FollowerCount int `json:"followerCount,omitempty"` + Enabled bool `json:"enabled"` +} + +type browserNotificationsConfigResponse struct { + PublicKey string `json:"publicKey,omitempty"` + Enabled bool `json:"enabled"` +} + +type notificationsConfigResponse struct { + Browser browserNotificationsConfigResponse `json:"browser"` +} + +type authenticationConfigResponse struct { + IndieAuthEnabled bool `json:"indieAuthEnabled"` +} + +// GetWebConfig gets the status of the server. +func GetWebConfig(w http.ResponseWriter, r *http.Request) { + middleware.EnableCors(w) + middleware.DisableCache(w) + w.Header().Set("Content-Type", "application/json") + + configuration := getConfigResponse() + + if err := json.NewEncoder(w).Encode(configuration); err != nil { + webutils.BadRequestHandler(w, err) + } +} + +func getConfigResponse() webConfigResponse { + pageContent := utils.RenderPageContentMarkdown(data.GetExtraPageBodyContent()) + offlineMessage := utils.RenderSimpleMarkdown(data.GetCustomOfflineMessage()) + socialHandles := data.GetSocialHandles() + for i, handle := range socialHandles { + platform := models.GetSocialHandle(handle.Platform) + if platform != nil { + handle.Icon = platform.Icon + socialHandles[i] = handle + } + } + + serverSummary := data.GetServerSummary() + + var federationResponse federationConfigResponse + federationEnabled := data.GetFederationEnabled() + + followerCount, _ := activitypub.GetFollowerCount() + if federationEnabled { + serverURLString := data.GetServerURL() + serverURL, _ := url.Parse(serverURLString) + account := fmt.Sprintf("%s@%s", data.GetDefaultFederationUsername(), serverURL.Host) + federationResponse = federationConfigResponse{ + Enabled: federationEnabled, + FollowerCount: int(followerCount), + Account: account, + } + } + + browserPushEnabled := data.GetBrowserPushConfig().Enabled + browserPushPublicKey, err := data.GetBrowserPushPublicKey() + if err != nil { + log.Errorln("unable to fetch browser push notifications public key", err) + browserPushEnabled = false + } + + notificationsResponse := notificationsConfigResponse{ + Browser: browserNotificationsConfigResponse{ + Enabled: browserPushEnabled, + PublicKey: browserPushPublicKey, + }, + } + + authenticationResponse := authenticationConfigResponse{ + IndieAuthEnabled: data.GetServerURL() != "", + } + + return webConfigResponse{ + Name: data.GetServerName(), + Summary: serverSummary, + OfflineMessage: offlineMessage, + Logo: "/logo", + Tags: data.GetServerMetadataTags(), + Version: config.GetReleaseString(), + NSFW: data.GetNSFW(), + SocketHostOverride: data.GetWebsocketOverrideHost(), + ExtraPageContent: pageContent, + StreamTitle: data.GetStreamTitle(), + SocialHandles: socialHandles, + ChatDisabled: data.GetChatDisabled(), + ChatSpamProtectionDisabled: data.GetChatSpamProtectionEnabled(), + ExternalActions: data.GetExternalActions(), + CustomStyles: data.GetCustomStyles(), + MaxSocketPayloadSize: config.MaxSocketPayloadSize, + Federation: federationResponse, + Notifications: notificationsResponse, + Authentication: authenticationResponse, + AppearanceVariables: data.GetCustomColorVariableValues(), + HideViewerCount: data.GetHideViewerCount(), + } +} + +// GetAllSocialPlatforms will return a list of all social platform types. +func GetAllSocialPlatforms(w http.ResponseWriter, r *http.Request) { + middleware.EnableCors(w) + w.Header().Set("Content-Type", "application/json") + + platforms := models.GetAllSocialHandles() + if err := json.NewEncoder(w).Encode(platforms); err != nil { + webutils.InternalErrorHandler(w, err) + } } diff --git a/webserver/handlers/configInterface.go b/webserver/handlers/configInterface.go new file mode 100644 index 000000000..626fd7a5e --- /dev/null +++ b/webserver/handlers/configInterface.go @@ -0,0 +1,368 @@ +package handlers + +import ( + "net/http" + + "github.com/owncast/owncast/webserver/handlers/admin" + "github.com/owncast/owncast/webserver/router/middleware" +) + +func (*ServerInterfaceImpl) SetAdminPassword(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetAdminPassword)(w, r) +} + +func (*ServerInterfaceImpl) SetAdminPasswordOptions(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetAdminPassword)(w, r) +} + +func (*ServerInterfaceImpl) SetStreamKeys(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetStreamKeys)(w, r) +} + +func (*ServerInterfaceImpl) SetStreamKeysOptions(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetStreamKeys)(w, r) +} + +func (*ServerInterfaceImpl) SetExtraPageContent(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetExtraPageContent)(w, r) +} + +func (*ServerInterfaceImpl) SetExtraPageContentOptions(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetExtraPageContent)(w, r) +} + +func (*ServerInterfaceImpl) SetStreamTitle(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetStreamTitle)(w, r) +} + +func (*ServerInterfaceImpl) SetStreamTitleOptions(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetStreamTitle)(w, r) +} + +func (*ServerInterfaceImpl) SetServerName(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetServerName)(w, r) +} + +func (*ServerInterfaceImpl) SetServerNameOptions(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetServerName)(w, r) +} + +func (*ServerInterfaceImpl) SetServerSummary(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetServerSummary)(w, r) +} + +func (*ServerInterfaceImpl) SetServerSummaryOptions(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetServerSummary)(w, r) +} + +func (*ServerInterfaceImpl) SetCustomOfflineMessage(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetCustomOfflineMessage)(w, r) +} + +func (*ServerInterfaceImpl) SetCustomOfflineMessageOptions(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetCustomOfflineMessage)(w, r) +} + +func (*ServerInterfaceImpl) SetServerWelcomeMessage(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetServerWelcomeMessage)(w, r) +} + +func (*ServerInterfaceImpl) SetServerWelcomeMessageOptions(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetServerWelcomeMessage)(w, r) +} + +func (*ServerInterfaceImpl) SetChatDisabled(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetChatDisabled)(w, r) +} + +func (*ServerInterfaceImpl) SetChatDisabledOptions(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetChatDisabled)(w, r) +} + +func (*ServerInterfaceImpl) SetChatJoinMessagesEnabled(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetChatJoinMessagesEnabled)(w, r) +} + +func (*ServerInterfaceImpl) SetChatJoinMessagesEnabledOptions(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetChatJoinMessagesEnabled)(w, r) +} + +func (*ServerInterfaceImpl) SetEnableEstablishedChatUserMode(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetEnableEstablishedChatUserMode)(w, r) +} + +func (*ServerInterfaceImpl) SetEnableEstablishedChatUserModeOptions(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetEnableEstablishedChatUserMode)(w, r) +} + +func (*ServerInterfaceImpl) SetForbiddenUsernameList(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetForbiddenUsernameList)(w, r) +} + +func (*ServerInterfaceImpl) SetForbiddenUsernameListOptions(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetForbiddenUsernameList)(w, r) +} + +func (*ServerInterfaceImpl) SetSuggestedUsernameList(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetSuggestedUsernameList)(w, r) +} + +func (*ServerInterfaceImpl) SetSuggestedUsernameListOptions(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetSuggestedUsernameList)(w, r) +} + +func (*ServerInterfaceImpl) SetChatSpamProtectionEnabled(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetChatSpamProtectionEnabled)(w, r) +} + +func (*ServerInterfaceImpl) SetChatSpamProtectionEnabledOptions(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetChatSpamProtectionEnabled)(w, r) +} + +func (*ServerInterfaceImpl) SetChatSlurFilterEnabled(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetChatSlurFilterEnabled)(w, r) +} + +func (*ServerInterfaceImpl) SetChatSlurFilterEnabledOptions(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetChatSlurFilterEnabled)(w, r) +} + +func (*ServerInterfaceImpl) SetVideoCodec(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetVideoCodec)(w, r) +} + +func (*ServerInterfaceImpl) SetVideoCodecOptions(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetVideoCodec)(w, r) +} + +func (*ServerInterfaceImpl) SetStreamLatencyLevel(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetStreamLatencyLevel)(w, r) +} + +func (*ServerInterfaceImpl) SetStreamLatencyLevelOptions(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetStreamLatencyLevel)(w, r) +} + +func (*ServerInterfaceImpl) SetStreamOutputVariants(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetStreamOutputVariants)(w, r) +} + +func (*ServerInterfaceImpl) SetStreamOutputVariantsOptions(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetStreamOutputVariants)(w, r) +} + +func (*ServerInterfaceImpl) SetCustomColorVariableValues(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetCustomColorVariableValues)(w, r) +} + +func (*ServerInterfaceImpl) SetCustomColorVariableValuesOptions(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetCustomColorVariableValues)(w, r) +} + +func (*ServerInterfaceImpl) SetLogo(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetLogo)(w, r) +} + +func (*ServerInterfaceImpl) SetLogoOptions(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetLogo)(w, r) +} + +func (*ServerInterfaceImpl) SetTags(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetTags)(w, r) +} + +func (*ServerInterfaceImpl) SetTagsOptions(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetTags)(w, r) +} + +func (*ServerInterfaceImpl) SetFfmpegPath(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetFfmpegPath)(w, r) +} + +func (*ServerInterfaceImpl) SetFfmpegPathOptions(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetFfmpegPath)(w, r) +} + +func (*ServerInterfaceImpl) SetWebServerPort(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetWebServerPort)(w, r) +} + +func (*ServerInterfaceImpl) SetWebServerPortOptions(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetWebServerPort)(w, r) +} + +func (*ServerInterfaceImpl) SetWebServerIP(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetWebServerIP)(w, r) +} + +func (*ServerInterfaceImpl) SetWebServerIPOptions(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetWebServerIP)(w, r) +} + +func (*ServerInterfaceImpl) SetRTMPServerPort(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetRTMPServerPort)(w, r) +} + +func (*ServerInterfaceImpl) SetRTMPServerPortOptions(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetRTMPServerPort)(w, r) +} + +func (*ServerInterfaceImpl) SetSocketHostOverride(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetSocketHostOverride)(w, r) +} + +func (*ServerInterfaceImpl) SetSocketHostOverrideOptions(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetSocketHostOverride)(w, r) +} + +func (*ServerInterfaceImpl) SetVideoServingEndpoint(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetVideoServingEndpoint)(w, r) +} + +func (*ServerInterfaceImpl) SetVideoServingEndpointOptions(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetVideoServingEndpoint)(w, r) +} + +func (*ServerInterfaceImpl) SetNSFW(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetNSFW)(w, r) +} + +func (*ServerInterfaceImpl) SetNSFWOptions(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetNSFW)(w, r) +} + +func (*ServerInterfaceImpl) SetDirectoryEnabled(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetDirectoryEnabled)(w, r) +} + +func (*ServerInterfaceImpl) SetDirectoryEnabledOptions(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetDirectoryEnabled)(w, r) +} + +func (*ServerInterfaceImpl) SetSocialHandles(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetSocialHandles)(w, r) +} + +func (*ServerInterfaceImpl) SetSocialHandlesOptions(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetSocialHandles)(w, r) +} + +func (*ServerInterfaceImpl) SetS3Configuration(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetS3Configuration)(w, r) +} + +func (*ServerInterfaceImpl) SetS3ConfigurationOptions(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetS3Configuration)(w, r) +} + +func (*ServerInterfaceImpl) SetServerURL(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetServerURL)(w, r) +} + +func (*ServerInterfaceImpl) SetServerURLOptions(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetServerURL)(w, r) +} + +func (*ServerInterfaceImpl) SetExternalActions(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetExternalActions)(w, r) +} + +func (*ServerInterfaceImpl) SetExternalActionsOptions(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetExternalActions)(w, r) +} + +func (*ServerInterfaceImpl) SetCustomStyles(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetCustomStyles)(w, r) +} + +func (*ServerInterfaceImpl) SetCustomStylesOptions(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetCustomStyles)(w, r) +} + +func (*ServerInterfaceImpl) SetCustomJavascript(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetCustomJavascript)(w, r) +} + +func (*ServerInterfaceImpl) SetCustomJavascriptOptions(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetCustomJavascript)(w, r) +} + +func (*ServerInterfaceImpl) SetHideViewerCount(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetHideViewerCount)(w, r) +} + +func (*ServerInterfaceImpl) SetHideViewerCountOptions(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetHideViewerCount)(w, r) +} + +func (*ServerInterfaceImpl) SetDisableSearchIndexing(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetDisableSearchIndexing)(w, r) +} + +func (*ServerInterfaceImpl) SetDisableSearchIndexingOptions(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetDisableSearchIndexing)(w, r) +} + +func (*ServerInterfaceImpl) SetFederationEnabled(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetFederationEnabled)(w, r) +} + +func (*ServerInterfaceImpl) SetFederationEnabledOptions(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetFederationEnabled)(w, r) +} + +func (*ServerInterfaceImpl) SetFederationActivityPrivate(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetFederationActivityPrivate)(w, r) +} + +func (*ServerInterfaceImpl) SetFederationActivityPrivateOptions(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetFederationActivityPrivate)(w, r) +} + +func (*ServerInterfaceImpl) SetFederationShowEngagement(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetFederationShowEngagement)(w, r) +} + +func (*ServerInterfaceImpl) SetFederationShowEngagementOptions(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetFederationShowEngagement)(w, r) +} + +func (*ServerInterfaceImpl) SetFederationUsername(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetFederationUsername)(w, r) +} + +func (*ServerInterfaceImpl) SetFederationUsernameOptions(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetFederationUsername)(w, r) +} + +func (*ServerInterfaceImpl) SetFederationGoLiveMessage(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetFederationGoLiveMessage)(w, r) +} + +func (*ServerInterfaceImpl) SetFederationGoLiveMessageOptions(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetFederationGoLiveMessage)(w, r) +} + +func (*ServerInterfaceImpl) SetFederationBlockDomains(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetFederationBlockDomains)(w, r) +} + +func (*ServerInterfaceImpl) SetFederationBlockDomainsOptions(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetFederationBlockDomains)(w, r) +} + +func (*ServerInterfaceImpl) SetDiscordNotificationConfiguration(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetDiscordNotificationConfiguration)(w, r) +} + +func (*ServerInterfaceImpl) SetDiscordNotificationConfigurationOptions(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetDiscordNotificationConfiguration)(w, r) +} + +func (*ServerInterfaceImpl) SetBrowserNotificationConfiguration(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetBrowserNotificationConfiguration)(w, r) +} + +func (*ServerInterfaceImpl) SetBrowserNotificationConfigurationOptions(w http.ResponseWriter, r *http.Request) { + middleware.RequireAdminAuth(admin.SetBrowserNotificationConfiguration)(w, r) +} diff --git a/controllers/constants.go b/webserver/handlers/constants.go similarity index 83% rename from controllers/constants.go rename to webserver/handlers/constants.go index 29b08442a..52741dac6 100644 --- a/controllers/constants.go +++ b/webserver/handlers/constants.go @@ -1,4 +1,4 @@ -package controllers +package handlers // POST is the HTTP POST method. const POST = "POST" diff --git a/controllers/customJavascript.go b/webserver/handlers/customJavascript.go similarity index 94% rename from controllers/customJavascript.go rename to webserver/handlers/customJavascript.go index dc6cf17a9..d2c2da79a 100644 --- a/controllers/customJavascript.go +++ b/webserver/handlers/customJavascript.go @@ -1,4 +1,4 @@ -package controllers +package handlers import ( "net/http" diff --git a/controllers/emoji.go b/webserver/handlers/emoji.go similarity index 87% rename from controllers/emoji.go rename to webserver/handlers/emoji.go index e12c68078..a6e661ab5 100644 --- a/controllers/emoji.go +++ b/webserver/handlers/emoji.go @@ -1,4 +1,4 @@ -package controllers +package handlers import ( "encoding/json" @@ -9,6 +9,7 @@ import ( "github.com/owncast/owncast/config" "github.com/owncast/owncast/core/data" "github.com/owncast/owncast/webserver/router/middleware" + webutils "github.com/owncast/owncast/webserver/utils" ) // GetCustomEmojiList returns a list of emoji via the API. @@ -17,7 +18,7 @@ func GetCustomEmojiList(w http.ResponseWriter, r *http.Request) { middleware.SetCachingHeaders(w, r) if err := json.NewEncoder(w).Encode(emojiList); err != nil { - InternalErrorHandler(w, err) + webutils.InternalErrorHandler(w, err) } } diff --git a/controllers/followers.go b/webserver/handlers/followers.go similarity index 65% rename from controllers/followers.go rename to webserver/handlers/followers.go index 0f9c98eaa..fb84735f8 100644 --- a/controllers/followers.go +++ b/webserver/handlers/followers.go @@ -1,22 +1,23 @@ -package controllers +package handlers import ( "net/http" "github.com/owncast/owncast/activitypub/persistence" + webutils "github.com/owncast/owncast/webserver/utils" ) // GetFollowers will handle an API request to fetch the list of followers (non-activitypub response). func GetFollowers(offset int, limit int, w http.ResponseWriter, r *http.Request) { followers, total, err := persistence.GetFederationFollowers(limit, offset) if err != nil { - WriteSimpleResponse(w, false, "unable to fetch followers") + webutils.WriteSimpleResponse(w, false, "unable to fetch followers") return } - response := PaginatedResponse{ + response := webutils.PaginatedResponse{ Total: total, Results: followers, } - WriteResponse(w, response) + webutils.WriteResponse(w, response) } diff --git a/webserver/handlers/handler.go b/webserver/handlers/handler.go index df83187f5..832b5ca88 100644 --- a/webserver/handlers/handler.go +++ b/webserver/handlers/handler.go @@ -3,8 +3,7 @@ package handlers import ( "net/http" - "github.com/owncast/owncast/controllers" - "github.com/owncast/owncast/controllers/admin" + "github.com/owncast/owncast/webserver/handlers/admin" "github.com/owncast/owncast/webserver/handlers/generated" "github.com/owncast/owncast/webserver/router/middleware" @@ -25,23 +24,23 @@ func (s *ServerInterfaceImpl) Handler() http.Handler { } func (*ServerInterfaceImpl) GetStatus(w http.ResponseWriter, r *http.Request) { - controllers.GetStatus(w, r) + GetStatus(w, r) } func (*ServerInterfaceImpl) GetCustomEmojiList(w http.ResponseWriter, r *http.Request) { - controllers.GetCustomEmojiList(w, r) + GetCustomEmojiList(w, r) } func (*ServerInterfaceImpl) GetChatMessages(w http.ResponseWriter, r *http.Request, params generated.GetChatMessagesParams) { - middleware.RequireUserAccessToken(controllers.GetChatMessages)(w, r) + middleware.RequireUserAccessToken(GetChatMessages)(w, r) } func (*ServerInterfaceImpl) RegisterAnonymousChatUser(w http.ResponseWriter, r *http.Request, params generated.RegisterAnonymousChatUserParams) { - controllers.RegisterAnonymousChatUser(w, r) + RegisterAnonymousChatUser(w, r) } func (*ServerInterfaceImpl) RegisterAnonymousChatUserOptions(w http.ResponseWriter, r *http.Request) { - controllers.RegisterAnonymousChatUser(w, r) + RegisterAnonymousChatUser(w, r) } func (*ServerInterfaceImpl) UpdateMessageVisibility(w http.ResponseWriter, r *http.Request, params generated.UpdateMessageVisibilityParams) { @@ -53,7 +52,7 @@ func (*ServerInterfaceImpl) UpdateUserEnabled(w http.ResponseWriter, r *http.Req } func (*ServerInterfaceImpl) GetWebConfig(w http.ResponseWriter, r *http.Request) { - controllers.GetWebConfig(w, r) + GetWebConfig(w, r) } func (*ServerInterfaceImpl) GetYPResponse(w http.ResponseWriter, r *http.Request) { @@ -61,29 +60,29 @@ func (*ServerInterfaceImpl) GetYPResponse(w http.ResponseWriter, r *http.Request } func (*ServerInterfaceImpl) GetAllSocialPlatforms(w http.ResponseWriter, r *http.Request) { - controllers.GetAllSocialPlatforms(w, r) + GetAllSocialPlatforms(w, r) } func (*ServerInterfaceImpl) GetVideoStreamOutputVariants(w http.ResponseWriter, r *http.Request) { - controllers.GetVideoStreamOutputVariants(w, r) + GetVideoStreamOutputVariants(w, r) } func (*ServerInterfaceImpl) Ping(w http.ResponseWriter, r *http.Request) { - controllers.Ping(w, r) + Ping(w, r) } func (*ServerInterfaceImpl) RemoteFollow(w http.ResponseWriter, r *http.Request) { - controllers.RemoteFollow(w, r) + RemoteFollow(w, r) } func (*ServerInterfaceImpl) GetFollowers(w http.ResponseWriter, r *http.Request, params generated.GetFollowersParams) { - middleware.HandlePagination(controllers.GetFollowers)(w, r) + middleware.HandlePagination(GetFollowers)(w, r) } func (*ServerInterfaceImpl) ReportPlaybackMetrics(w http.ResponseWriter, r *http.Request) { - controllers.ReportPlaybackMetrics(w, r) + ReportPlaybackMetrics(w, r) } func (*ServerInterfaceImpl) RegisterForLiveNotifications(w http.ResponseWriter, r *http.Request, params generated.RegisterForLiveNotificationsParams) { - middleware.RequireUserAccessToken(controllers.RegisterForLiveNotifications)(w, r) + middleware.RequireUserAccessToken(RegisterForLiveNotifications)(w, r) } diff --git a/controllers/hls.go b/webserver/handlers/hls.go similarity index 98% rename from controllers/hls.go rename to webserver/handlers/hls.go index e3df46fa9..bee58c95e 100644 --- a/controllers/hls.go +++ b/webserver/handlers/hls.go @@ -1,4 +1,4 @@ -package controllers +package handlers import ( "net/http" diff --git a/controllers/images.go b/webserver/handlers/images.go similarity index 99% rename from controllers/images.go rename to webserver/handlers/images.go index 86d37d5be..993b78917 100644 --- a/controllers/images.go +++ b/webserver/handlers/images.go @@ -1,4 +1,4 @@ -package controllers +package handlers import ( "net/http" diff --git a/controllers/index.go b/webserver/handlers/index.go similarity index 99% rename from controllers/index.go rename to webserver/handlers/index.go index e20cd6f6d..29f47508c 100644 --- a/controllers/index.go +++ b/webserver/handlers/index.go @@ -1,4 +1,4 @@ -package controllers +package handlers import ( "bytes" diff --git a/webserver/handlers/integrations.go b/webserver/handlers/integrations.go index 701c2e6a5..5855a883e 100644 --- a/webserver/handlers/integrations.go +++ b/webserver/handlers/integrations.go @@ -3,9 +3,8 @@ package handlers import ( "net/http" - "github.com/owncast/owncast/controllers" - "github.com/owncast/owncast/controllers/admin" "github.com/owncast/owncast/models" + "github.com/owncast/owncast/webserver/handlers/admin" "github.com/owncast/owncast/webserver/router/middleware" "github.com/prometheus/client_golang/prometheus/promhttp" ) @@ -69,11 +68,11 @@ func (*ServerInterfaceImpl) ExternalSetStreamTitleOptions(w http.ResponseWriter, } func (*ServerInterfaceImpl) ExternalGetChatMessages(w http.ResponseWriter, r *http.Request) { - middleware.RequireExternalAPIAccessToken(models.ScopeHasAdminAccess, controllers.ExternalGetChatMessages)(w, r) + middleware.RequireExternalAPIAccessToken(models.ScopeHasAdminAccess, ExternalGetChatMessages)(w, r) } func (*ServerInterfaceImpl) ExternalGetChatMessagesOptions(w http.ResponseWriter, r *http.Request) { - middleware.RequireExternalAPIAccessToken(models.ScopeHasAdminAccess, controllers.ExternalGetChatMessages)(w, r) + middleware.RequireExternalAPIAccessToken(models.ScopeHasAdminAccess, ExternalGetChatMessages)(w, r) } func (*ServerInterfaceImpl) ExternalGetConnectedChatClients(w http.ResponseWriter, r *http.Request) { diff --git a/controllers/logo.go b/webserver/handlers/logo.go similarity index 99% rename from controllers/logo.go rename to webserver/handlers/logo.go index 2bcda25b1..6dff20201 100644 --- a/controllers/logo.go +++ b/webserver/handlers/logo.go @@ -1,4 +1,4 @@ -package controllers +package handlers import ( "net/http" diff --git a/webserver/handlers/moderation.go b/webserver/handlers/moderation.go index 91c8c126e..55d9f07e7 100644 --- a/webserver/handlers/moderation.go +++ b/webserver/handlers/moderation.go @@ -3,8 +3,8 @@ package handlers import ( "net/http" - "github.com/owncast/owncast/controllers/moderation" "github.com/owncast/owncast/webserver/handlers/generated" + "github.com/owncast/owncast/webserver/handlers/moderation" "github.com/owncast/owncast/webserver/router/middleware" ) diff --git a/controllers/moderation/moderation.go b/webserver/handlers/moderation/moderation.go similarity index 95% rename from controllers/moderation/moderation.go rename to webserver/handlers/moderation/moderation.go index 7ff177120..baff24655 100644 --- a/controllers/moderation/moderation.go +++ b/webserver/handlers/moderation/moderation.go @@ -6,11 +6,11 @@ import ( "strings" "time" - "github.com/owncast/owncast/controllers" "github.com/owncast/owncast/core/chat" "github.com/owncast/owncast/core/chat/events" "github.com/owncast/owncast/models" "github.com/owncast/owncast/persistence/userrepository" + "github.com/owncast/owncast/webserver/utils" log "github.com/sirupsen/logrus" ) @@ -71,6 +71,6 @@ func GetUserDetails(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") if err := json.NewEncoder(w).Encode(res); err != nil { - controllers.InternalErrorHandler(w, err) + utils.InternalErrorHandler(w, err) } } diff --git a/controllers/notifications.go b/webserver/handlers/notifications.go similarity index 75% rename from controllers/notifications.go rename to webserver/handlers/notifications.go index fec4c10a9..4b9bf24a2 100644 --- a/controllers/notifications.go +++ b/webserver/handlers/notifications.go @@ -1,4 +1,4 @@ -package controllers +package handlers import ( "encoding/json" @@ -9,6 +9,7 @@ import ( "github.com/owncast/owncast/utils" + webutils "github.com/owncast/owncast/webserver/utils" log "github.com/sirupsen/logrus" ) @@ -16,7 +17,7 @@ import ( // notified when a stream goes live. func RegisterForLiveNotifications(u models.User, w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { - WriteSimpleResponse(w, false, r.Method+" not supported") + webutils.WriteSimpleResponse(w, false, r.Method+" not supported") return } @@ -31,7 +32,7 @@ func RegisterForLiveNotifications(u models.User, w http.ResponseWriter, r *http. var req request if err := decoder.Decode(&req); err != nil { log.Errorln(err) - WriteSimpleResponse(w, false, "unable to register for notifications") + webutils.WriteSimpleResponse(w, false, "unable to register for notifications") return } @@ -39,13 +40,13 @@ func RegisterForLiveNotifications(u models.User, w http.ResponseWriter, r *http. validTypes := []string{notifications.BrowserPushNotification} _, validChannel := utils.FindInSlice(validTypes, req.Channel) if !validChannel { - WriteSimpleResponse(w, false, "invalid notification channel: "+req.Channel) + webutils.WriteSimpleResponse(w, false, "invalid notification channel: "+req.Channel) return } if err := notifications.AddNotification(req.Channel, req.Destination); err != nil { log.Errorln(err) - WriteSimpleResponse(w, false, "unable to save notification") + webutils.WriteSimpleResponse(w, false, "unable to save notification") return } } diff --git a/controllers/ping.go b/webserver/handlers/ping.go similarity index 94% rename from controllers/ping.go rename to webserver/handlers/ping.go index 07d46552a..36da32df7 100644 --- a/controllers/ping.go +++ b/webserver/handlers/ping.go @@ -1,4 +1,4 @@ -package controllers +package handlers import ( "net/http" diff --git a/controllers/playbackMetrics.go b/webserver/handlers/playbackMetrics.go similarity index 87% rename from controllers/playbackMetrics.go rename to webserver/handlers/playbackMetrics.go index b18bc8fbf..6cd9660ee 100644 --- a/controllers/playbackMetrics.go +++ b/webserver/handlers/playbackMetrics.go @@ -1,4 +1,4 @@ -package controllers +package handlers import ( "encoding/json" @@ -6,6 +6,7 @@ import ( "github.com/owncast/owncast/metrics" "github.com/owncast/owncast/utils" + webutils "github.com/owncast/owncast/webserver/utils" log "github.com/sirupsen/logrus" ) @@ -13,7 +14,7 @@ import ( // them for future video health reporting. func ReportPlaybackMetrics(w http.ResponseWriter, r *http.Request) { if r.Method != POST { - WriteSimpleResponse(w, false, r.Method+" not supported") + webutils.WriteSimpleResponse(w, false, r.Method+" not supported") return } @@ -29,7 +30,7 @@ func ReportPlaybackMetrics(w http.ResponseWriter, r *http.Request) { var request reportPlaybackMetricsRequest if err := decoder.Decode(&request); err != nil { log.Errorln("error decoding playback metrics payload:", err) - WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } diff --git a/controllers/remoteFollow.go b/webserver/handlers/remoteFollow.go similarity index 75% rename from controllers/remoteFollow.go rename to webserver/handlers/remoteFollow.go index fdd012cce..6dbe62922 100644 --- a/controllers/remoteFollow.go +++ b/webserver/handlers/remoteFollow.go @@ -1,4 +1,4 @@ -package controllers +package handlers import ( "encoding/json" @@ -9,6 +9,7 @@ import ( "github.com/owncast/owncast/activitypub/webfinger" "github.com/owncast/owncast/core/data" + webutils "github.com/owncast/owncast/webserver/utils" ) // RemoteFollow handles a request to begin the remote follow redirect flow. @@ -24,12 +25,12 @@ func RemoteFollow(w http.ResponseWriter, r *http.Request) { var request followRequest decoder := json.NewDecoder(r.Body) if err := decoder.Decode(&request); err != nil { - WriteSimpleResponse(w, false, "unable to parse request") + webutils.WriteSimpleResponse(w, false, "unable to parse request") return } if request.Account == "" { - WriteSimpleResponse(w, false, "Remote Fediverse account is required to follow.") + webutils.WriteSimpleResponse(w, false, "Remote Fediverse account is required to follow.") return } @@ -38,7 +39,7 @@ func RemoteFollow(w http.ResponseWriter, r *http.Request) { var template string links, err := webfinger.GetWebfingerLinks(request.Account) if err != nil { - WriteSimpleResponse(w, false, err.Error()) + webutils.WriteSimpleResponse(w, false, err.Error()) return } @@ -52,7 +53,7 @@ func RemoteFollow(w http.ResponseWriter, r *http.Request) { } if localActorPath.String() == "" || template == "" { - WriteSimpleResponse(w, false, "unable to determine remote follow information for "+request.Account) + webutils.WriteSimpleResponse(w, false, "unable to determine remote follow information for "+request.Account) return } @@ -61,5 +62,5 @@ func RemoteFollow(w http.ResponseWriter, r *http.Request) { RedirectURL: redirectURL, } - WriteResponse(w, response) + webutils.WriteResponse(w, response) } diff --git a/controllers/robots.go b/webserver/handlers/robots.go similarity index 96% rename from controllers/robots.go rename to webserver/handlers/robots.go index 4605d3da4..69b702cf3 100644 --- a/controllers/robots.go +++ b/webserver/handlers/robots.go @@ -1,4 +1,4 @@ -package controllers +package handlers import ( "net/http" diff --git a/controllers/status.go b/webserver/handlers/status.go similarity index 92% rename from controllers/status.go rename to webserver/handlers/status.go index f074dafc3..63853bc98 100644 --- a/controllers/status.go +++ b/webserver/handlers/status.go @@ -1,4 +1,4 @@ -package controllers +package handlers import ( "encoding/json" @@ -9,6 +9,7 @@ import ( "github.com/owncast/owncast/core/data" "github.com/owncast/owncast/utils" "github.com/owncast/owncast/webserver/router/middleware" + webutils "github.com/owncast/owncast/webserver/utils" ) // GetStatus gets the status of the server. @@ -19,7 +20,7 @@ func GetStatus(w http.ResponseWriter, r *http.Request) { middleware.DisableCache(w) if err := json.NewEncoder(w).Encode(response); err != nil { - InternalErrorHandler(w, err) + webutils.InternalErrorHandler(w, err) } } diff --git a/controllers/video.go b/webserver/handlers/video.go similarity index 93% rename from controllers/video.go rename to webserver/handlers/video.go index a3e69c357..6e862319c 100644 --- a/controllers/video.go +++ b/webserver/handlers/video.go @@ -1,10 +1,11 @@ -package controllers +package handlers import ( "net/http" "sort" "github.com/owncast/owncast/core/data" + webutils "github.com/owncast/owncast/webserver/utils" ) type variantsSort struct { @@ -55,5 +56,5 @@ func GetVideoStreamOutputVariants(w http.ResponseWriter, r *http.Request) { response[i] = variantResponse } - WriteResponse(w, response) + webutils.WriteResponse(w, response) } diff --git a/controllers/web.go b/webserver/handlers/web.go similarity index 92% rename from controllers/web.go rename to webserver/handlers/web.go index 7b16fe74a..8042684ea 100644 --- a/controllers/web.go +++ b/webserver/handlers/web.go @@ -1,4 +1,4 @@ -package controllers +package handlers import ( "net/http" diff --git a/webserver/router/router.go b/webserver/router/router.go index 7fc947d59..deef650f4 100644 --- a/webserver/router/router.go +++ b/webserver/router/router.go @@ -14,9 +14,8 @@ import ( "golang.org/x/net/http2/h2c" "github.com/owncast/owncast/activitypub" - apControllers "github.com/owncast/owncast/activitypub/controllers" + aphandlers "github.com/owncast/owncast/activitypub/controllers" "github.com/owncast/owncast/config" - "github.com/owncast/owncast/controllers" "github.com/owncast/owncast/core/chat" "github.com/owncast/owncast/core/data" "github.com/owncast/owncast/webserver/handlers" @@ -44,19 +43,19 @@ func Start(enableVerboseLogging bool) error { r.Handle("/public/*", http.StripPrefix("/public/", fs)) // Return HLS video - r.HandleFunc("/hls/*", controllers.HandleHLSRequest) + r.HandleFunc("/hls/*", handlers.HandleHLSRequest) // The admin web app. - r.HandleFunc("/admin/*", middleware.RequireAdminAuth(controllers.IndexHandler)) + r.HandleFunc("/admin/*", middleware.RequireAdminAuth(handlers.IndexHandler)) // Single ActivityPub Actor - r.HandleFunc("/federation/user/*", middleware.RequireActivityPubOrRedirect(apControllers.ActorHandler)) + r.HandleFunc("/federation/user/*", middleware.RequireActivityPubOrRedirect(aphandlers.ActorHandler)) // Single AP object - r.HandleFunc("/federation/*", middleware.RequireActivityPubOrRedirect(apControllers.ObjectHandler)) + r.HandleFunc("/federation/*", middleware.RequireActivityPubOrRedirect(aphandlers.ObjectHandler)) // The primary web app. - r.HandleFunc("/*", controllers.IndexHandler) + r.HandleFunc("/*", handlers.IndexHandler) // mount the api r.Mount("/api/", handlers.New().Handler()) @@ -105,40 +104,40 @@ func Start(enableVerboseLogging bool) error { func addStaticFileEndpoints(r chi.Router) { // Images - r.HandleFunc("/thumbnail.jpg", controllers.GetThumbnail) - r.HandleFunc("/preview.gif", controllers.GetPreview) - r.HandleFunc("/logo", controllers.GetLogo) + r.HandleFunc("/thumbnail.jpg", handlers.GetThumbnail) + r.HandleFunc("/preview.gif", handlers.GetPreview) + r.HandleFunc("/logo", handlers.GetLogo) // return a logo that's compatible with external social networks - r.HandleFunc("/logo/external", controllers.GetCompatibleLogo) + r.HandleFunc("/logo/external", handlers.GetCompatibleLogo) // Custom Javascript - r.HandleFunc("/customjavascript", controllers.ServeCustomJavascript) + r.HandleFunc("/customjavascript", handlers.ServeCustomJavascript) // robots.txt - r.HandleFunc("/robots.txt", controllers.GetRobotsDotTxt) + r.HandleFunc("/robots.txt", handlers.GetRobotsDotTxt) // Return a single emoji image. emojiDir := config.EmojiDir if !strings.HasSuffix(emojiDir, "*") { emojiDir += "*" } - r.HandleFunc(emojiDir, controllers.GetCustomEmojiImage) + r.HandleFunc(emojiDir, handlers.GetCustomEmojiImage) // WebFinger - r.HandleFunc("/.well-known/webfinger", apControllers.WebfingerHandler) + r.HandleFunc("/.well-known/webfinger", aphandlers.WebfingerHandler) // Host Metadata - r.HandleFunc("/.well-known/host-meta", apControllers.HostMetaController) + r.HandleFunc("/.well-known/host-meta", aphandlers.HostMetaController) // Nodeinfo v1 - r.HandleFunc("/.well-known/nodeinfo", apControllers.NodeInfoController) + r.HandleFunc("/.well-known/nodeinfo", aphandlers.NodeInfoController) // x-nodeinfo v2 - r.HandleFunc("/.well-known/x-nodeinfo2", apControllers.XNodeInfo2Controller) + r.HandleFunc("/.well-known/x-nodeinfo2", aphandlers.XNodeInfo2Controller) // Nodeinfo v2 - r.HandleFunc("/nodeinfo/2.0", apControllers.NodeInfoV2Controller) + r.HandleFunc("/nodeinfo/2.0", aphandlers.NodeInfoV2Controller) // Instance details - r.HandleFunc("/api/v1/instance", apControllers.InstanceV1Controller) + r.HandleFunc("/api/v1/instance", aphandlers.InstanceV1Controller) } diff --git a/controllers/pagination.go b/webserver/utils/pagination.go similarity index 90% rename from controllers/pagination.go rename to webserver/utils/pagination.go index 103bdc23b..8acf204c3 100644 --- a/controllers/pagination.go +++ b/webserver/utils/pagination.go @@ -1,4 +1,4 @@ -package controllers +package utils // PaginatedResponse is a structure for returning a total count with results. type PaginatedResponse struct { diff --git a/controllers/controllers.go b/webserver/utils/responses.go similarity index 90% rename from controllers/controllers.go rename to webserver/utils/responses.go index 09f0311a1..368ca756e 100644 --- a/controllers/controllers.go +++ b/webserver/utils/responses.go @@ -1,4 +1,4 @@ -package controllers +package utils import ( "encoding/json" @@ -9,7 +9,7 @@ import ( log "github.com/sirupsen/logrus" ) -type j map[string]interface{} +type J map[string]interface{} // InternalErrorHandler will return an error message as an HTTP response. func InternalErrorHandler(w http.ResponseWriter, err error) { @@ -17,7 +17,7 @@ func InternalErrorHandler(w http.ResponseWriter, err error) { return } - if err := json.NewEncoder(w).Encode(j{"error": err.Error()}); err != nil { + if err := json.NewEncoder(w).Encode(J{"error": err.Error()}); err != nil { InternalErrorHandler(w, err) } } @@ -31,7 +31,7 @@ func BadRequestHandler(w http.ResponseWriter, err error) { log.Debugln(err) w.WriteHeader(http.StatusBadRequest) - if err := json.NewEncoder(w).Encode(j{"error": err.Error()}); err != nil { + if err := json.NewEncoder(w).Encode(J{"error": err.Error()}); err != nil { InternalErrorHandler(w, err) } }