1// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2// See LICENSE.txt for license information.
3
4package api4
5
6import (
7	"net/http"
8
9	"github.com/mattermost/gziphandler"
10
11	"github.com/mattermost/mattermost-server/v6/web"
12)
13
14type Context = web.Context
15
16// APIHandler provides a handler for API endpoints which do not require the user to be logged in order for access to be
17// granted.
18func (api *API) APIHandler(h func(*Context, http.ResponseWriter, *http.Request)) http.Handler {
19	handler := &web.Handler{
20		App:            api.app,
21		HandleFunc:     h,
22		HandlerName:    web.GetHandlerName(h),
23		RequireSession: false,
24		TrustRequester: false,
25		RequireMfa:     false,
26		IsStatic:       false,
27		IsLocal:        false,
28	}
29	if *api.app.Config().ServiceSettings.WebserverMode == "gzip" {
30		return gziphandler.GzipHandler(handler)
31	}
32	return handler
33}
34
35// APISessionRequired provides a handler for API endpoints which require the user to be logged in in order for access to
36// be granted.
37func (api *API) APISessionRequired(h func(*Context, http.ResponseWriter, *http.Request)) http.Handler {
38	handler := &web.Handler{
39		App:            api.app,
40		HandleFunc:     h,
41		HandlerName:    web.GetHandlerName(h),
42		RequireSession: true,
43		TrustRequester: false,
44		RequireMfa:     true,
45		IsStatic:       false,
46		IsLocal:        false,
47	}
48	if *api.app.Config().ServiceSettings.WebserverMode == "gzip" {
49		return gziphandler.GzipHandler(handler)
50	}
51	return handler
52
53}
54
55// CloudAPIKeyRequired provides a handler for webhook endpoints to access Cloud installations from CWS
56func (api *API) CloudAPIKeyRequired(h func(*Context, http.ResponseWriter, *http.Request)) http.Handler {
57	handler := &web.Handler{
58		App:             api.app,
59		HandleFunc:      h,
60		HandlerName:     web.GetHandlerName(h),
61		RequireSession:  false,
62		RequireCloudKey: true,
63		TrustRequester:  false,
64		RequireMfa:      false,
65		IsStatic:        false,
66		IsLocal:         false,
67	}
68	if *api.app.Config().ServiceSettings.WebserverMode == "gzip" {
69		return gziphandler.GzipHandler(handler)
70	}
71	return handler
72
73}
74
75// RemoteClusterTokenRequired provides a handler for remote cluster requests to /remotecluster endpoints.
76func (api *API) RemoteClusterTokenRequired(h func(*Context, http.ResponseWriter, *http.Request)) http.Handler {
77	handler := &web.Handler{
78		App:                       api.app,
79		HandleFunc:                h,
80		HandlerName:               web.GetHandlerName(h),
81		RequireSession:            false,
82		RequireCloudKey:           false,
83		RequireRemoteClusterToken: true,
84		TrustRequester:            false,
85		RequireMfa:                false,
86		IsStatic:                  false,
87		IsLocal:                   false,
88	}
89	if *api.app.Config().ServiceSettings.WebserverMode == "gzip" {
90		return gziphandler.GzipHandler(handler)
91	}
92	return handler
93}
94
95// APISessionRequiredMfa provides a handler for API endpoints which require a logged-in user session  but when accessed,
96// if MFA is enabled, the MFA process is not yet complete, and therefore the requirement to have completed the MFA
97// authentication must be waived.
98func (api *API) APISessionRequiredMfa(h func(*Context, http.ResponseWriter, *http.Request)) http.Handler {
99	handler := &web.Handler{
100		App:            api.app,
101		HandleFunc:     h,
102		HandlerName:    web.GetHandlerName(h),
103		RequireSession: true,
104		TrustRequester: false,
105		RequireMfa:     false,
106		IsStatic:       false,
107		IsLocal:        false,
108	}
109	if *api.app.Config().ServiceSettings.WebserverMode == "gzip" {
110		return gziphandler.GzipHandler(handler)
111	}
112	return handler
113
114}
115
116// APIHandlerTrustRequester provides a handler for API endpoints which do not require the user to be logged in and are
117// allowed to be requested directly rather than via javascript/XMLHttpRequest, such as site branding images or the
118// websocket.
119func (api *API) APIHandlerTrustRequester(h func(*Context, http.ResponseWriter, *http.Request)) http.Handler {
120	handler := &web.Handler{
121		App:            api.app,
122		HandleFunc:     h,
123		HandlerName:    web.GetHandlerName(h),
124		RequireSession: false,
125		TrustRequester: true,
126		RequireMfa:     false,
127		IsStatic:       false,
128		IsLocal:        false,
129	}
130	if *api.app.Config().ServiceSettings.WebserverMode == "gzip" {
131		return gziphandler.GzipHandler(handler)
132	}
133	return handler
134
135}
136
137// APISessionRequiredTrustRequester provides a handler for API endpoints which do require the user to be logged in and
138// are allowed to be requested directly rather than via javascript/XMLHttpRequest, such as emoji or file uploads.
139func (api *API) APISessionRequiredTrustRequester(h func(*Context, http.ResponseWriter, *http.Request)) http.Handler {
140	handler := &web.Handler{
141		App:            api.app,
142		HandleFunc:     h,
143		HandlerName:    web.GetHandlerName(h),
144		RequireSession: true,
145		TrustRequester: true,
146		RequireMfa:     true,
147		IsStatic:       false,
148		IsLocal:        false,
149	}
150	if *api.app.Config().ServiceSettings.WebserverMode == "gzip" {
151		return gziphandler.GzipHandler(handler)
152	}
153	return handler
154
155}
156
157// DisableWhenBusy provides a handler for API endpoints which should be disabled when the server is under load,
158// responding with HTTP 503 (Service Unavailable).
159func (api *API) APISessionRequiredDisableWhenBusy(h func(*Context, http.ResponseWriter, *http.Request)) http.Handler {
160	handler := &web.Handler{
161		App:             api.app,
162		HandleFunc:      h,
163		HandlerName:     web.GetHandlerName(h),
164		RequireSession:  true,
165		TrustRequester:  false,
166		RequireMfa:      false,
167		IsStatic:        false,
168		IsLocal:         false,
169		DisableWhenBusy: true,
170	}
171	if *api.app.Config().ServiceSettings.WebserverMode == "gzip" {
172		return gziphandler.GzipHandler(handler)
173	}
174	return handler
175
176}
177
178// APILocal provides a handler for API endpoints to be used in local
179// mode, this is, through a UNIX socket and without an authenticated
180// session, but with one that has no user set and no permission
181// restrictions
182func (api *API) APILocal(h func(*Context, http.ResponseWriter, *http.Request)) http.Handler {
183	handler := &web.Handler{
184		App:            api.app,
185		HandleFunc:     h,
186		HandlerName:    web.GetHandlerName(h),
187		RequireSession: false,
188		TrustRequester: false,
189		RequireMfa:     false,
190		IsStatic:       false,
191		IsLocal:        true,
192	}
193
194	if *api.app.Config().ServiceSettings.WebserverMode == "gzip" {
195		return gziphandler.GzipHandler(handler)
196	}
197	return handler
198}
199