[MM-29845] Add a new handler to allow authentication via CWS API Key (#16319)

* Add a new handler to allow authentication via CWS API Key

* Make error better

* Add tests and cases for new handler functions

* Move some code around

* Add test for GetCloudSession function

* unset the env after test completion

* Remove white space

* Change Info to Warn

Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
Этот коммит содержится в:
Nick Misasi
2020-11-23 14:34:10 -05:00
коммит произвёл GitHub
родитель 27462bbfc9
Коммит 3099128bbd
12 изменённых файлов: 144 добавлений и 4 удалений

Просмотреть файл

@@ -143,6 +143,13 @@ func (c *Context) SessionRequired() {
}
}
func (c *Context) CloudKeyRequired() {
if license := c.App.Srv().License(); license == nil || !*license.Features.Cloud || c.App.Session().Props[model.SESSION_PROP_TYPE] != model.SESSION_TYPE_CLOUD_KEY {
c.Err = model.NewAppError("", "api.context.session_expired.app_error", nil, "TokenRequired", http.StatusUnauthorized)
return
}
}
func (c *Context) MfaRequired() {
// Must be licensed for MFA and have it configured for enforcement
if license := c.App.Srv().License(); license == nil || !*license.Features.MFA || !*c.App.Config().ServiceSettings.EnableMultifactorAuthentication || !*c.App.Config().ServiceSettings.EnforceMultifactorAuthentication {

Просмотреть файл

@@ -32,6 +32,21 @@ func TestRequireHookId(t *testing.T) {
})
}
func TestCloudKeyRequired(t *testing.T) {
th := SetupWithStoreMock(t)
defer th.TearDown()
th.App.Srv().SetLicense(model.NewTestLicense("cloud"))
c := &Context{
App: th.App,
}
c.CloudKeyRequired()
assert.Equal(t, c.Err.Id, "api.context.session_expired.app_error")
}
func TestMfaRequired(t *testing.T) {
th := SetupWithStoreMock(t)
defer th.TearDown()

Просмотреть файл

@@ -72,6 +72,7 @@ type Handler struct {
HandleFunc func(*Context, http.ResponseWriter, *http.Request)
HandlerName string
RequireSession bool
RequireCloudKey bool
TrustRequester bool
RequireMfa bool
IsStatic bool
@@ -187,7 +188,7 @@ func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
token, tokenLocation := app.ParseAuthTokenFromRequest(r)
if len(token) != 0 {
if len(token) != 0 && tokenLocation != app.TokenLocationCloudHeader {
session, err := c.App.GetSession(token)
if err != nil {
c.Log.Info("Invalid session", mlog.Err(err))
@@ -209,6 +210,15 @@ func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}
h.checkCSRFToken(c, r, token, tokenLocation, session)
} else if len(token) != 0 && c.App.Srv().License() != nil && *c.App.Srv().License().Features.Cloud && tokenLocation == app.TokenLocationCloudHeader {
// Check to see if this provided token matches our CWS Token
session, err := c.App.GetCloudSession(token)
if err != nil {
c.Log.Warn("Invalid CWS token", mlog.Err(err))
c.Err = err
} else {
c.App.SetSession(session)
}
}
c.Log = c.App.Log().With(
@@ -231,6 +241,10 @@ func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
c.SetServerBusyError()
}
if c.Err == nil && h.RequireCloudKey {
c.CloudKeyRequired()
}
if c.Err == nil && h.IsLocal {
// if the connection is local, RemoteAddr shouldn't have the
// shape IP:PORT (it will be "@" in Linux, for example)