PLT-4767 Implement MFA Enforcement (#4662)
* Create MFA setup page and remove MFA setup from account settings modal * Add enforce MFA to system console and force redirect * Lockdown mfa required API routes, add localization, other changes * Minor fixes * Fix typo * Fix some unit tests * Fix more unit tests * Minor fix * Updating UI for MFA screen (#4670) * Updating UI for MFA screen * Updating styles for MFA page * Add the ability to switch between email/sso with MFA enabled * Added mfa change email * Minor UI updates for MFA enforcement * Fix unit test * Fix client unit test * Allow switching email to ldap and back when MFA is enabled * Fix unit test * Revert config.json
Этот коммит содержится в:
коммит произвёл
enahum
родитель
f0d71d8789
Коммит
30a10d35a8
@@ -47,51 +47,55 @@ type Context struct {
|
||||
}
|
||||
|
||||
func ApiAppHandler(h func(*Context, http.ResponseWriter, *http.Request)) http.Handler {
|
||||
return &handler{h, false, false, true, false, false, false}
|
||||
return &handler{h, false, false, true, false, false, false, false}
|
||||
}
|
||||
|
||||
func AppHandler(h func(*Context, http.ResponseWriter, *http.Request)) http.Handler {
|
||||
return &handler{h, false, false, false, false, false, false}
|
||||
return &handler{h, false, false, false, false, false, false, false}
|
||||
}
|
||||
|
||||
func AppHandlerIndependent(h func(*Context, http.ResponseWriter, *http.Request)) http.Handler {
|
||||
return &handler{h, false, false, false, false, true, false}
|
||||
return &handler{h, false, false, false, false, true, false, false}
|
||||
}
|
||||
|
||||
func ApiUserRequired(h func(*Context, http.ResponseWriter, *http.Request)) http.Handler {
|
||||
return &handler{h, true, false, true, false, false, false}
|
||||
return &handler{h, true, false, true, false, false, false, true}
|
||||
}
|
||||
|
||||
func ApiUserRequiredActivity(h func(*Context, http.ResponseWriter, *http.Request), isUserActivity bool) http.Handler {
|
||||
return &handler{h, true, false, true, isUserActivity, false, false}
|
||||
return &handler{h, true, false, true, isUserActivity, false, false, true}
|
||||
}
|
||||
|
||||
func ApiUserRequiredMfa(h func(*Context, http.ResponseWriter, *http.Request)) http.Handler {
|
||||
return &handler{h, true, false, true, false, false, false, false}
|
||||
}
|
||||
|
||||
func UserRequired(h func(*Context, http.ResponseWriter, *http.Request)) http.Handler {
|
||||
return &handler{h, true, false, false, false, false, false}
|
||||
return &handler{h, true, false, false, false, false, false, true}
|
||||
}
|
||||
|
||||
func AppHandlerTrustRequester(h func(*Context, http.ResponseWriter, *http.Request)) http.Handler {
|
||||
return &handler{h, false, false, false, false, false, true}
|
||||
return &handler{h, false, false, false, false, false, true, false}
|
||||
}
|
||||
|
||||
func ApiAdminSystemRequired(h func(*Context, http.ResponseWriter, *http.Request)) http.Handler {
|
||||
return &handler{h, true, true, true, false, false, false}
|
||||
return &handler{h, true, true, true, false, false, false, true}
|
||||
}
|
||||
|
||||
func ApiAdminSystemRequiredTrustRequester(h func(*Context, http.ResponseWriter, *http.Request)) http.Handler {
|
||||
return &handler{h, true, true, true, false, false, true}
|
||||
return &handler{h, true, true, true, false, false, true, true}
|
||||
}
|
||||
|
||||
func ApiAppHandlerTrustRequester(h func(*Context, http.ResponseWriter, *http.Request)) http.Handler {
|
||||
return &handler{h, false, false, true, false, false, true}
|
||||
return &handler{h, false, false, true, false, false, true, false}
|
||||
}
|
||||
|
||||
func ApiUserRequiredTrustRequester(h func(*Context, http.ResponseWriter, *http.Request)) http.Handler {
|
||||
return &handler{h, true, false, true, false, false, true}
|
||||
return &handler{h, true, false, true, false, false, true, true}
|
||||
}
|
||||
|
||||
func ApiAppHandlerTrustRequesterIndependent(h func(*Context, http.ResponseWriter, *http.Request)) http.Handler {
|
||||
return &handler{h, false, false, true, false, true, true}
|
||||
return &handler{h, false, false, true, false, true, true, false}
|
||||
}
|
||||
|
||||
type handler struct {
|
||||
@@ -102,6 +106,7 @@ type handler struct {
|
||||
isUserActivity bool
|
||||
isTeamIndependent bool
|
||||
trustRequester bool
|
||||
requireMfa bool
|
||||
}
|
||||
|
||||
func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -204,6 +209,10 @@ func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
c.UserRequired()
|
||||
}
|
||||
|
||||
if c.Err == nil && h.requireMfa {
|
||||
c.MfaRequired()
|
||||
}
|
||||
|
||||
if c.Err == nil && h.requireSystemAdmin {
|
||||
c.SystemAdminRequired()
|
||||
}
|
||||
@@ -331,6 +340,39 @@ func (c *Context) UserRequired() {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Context) MfaRequired() {
|
||||
// Must be licensed for MFA and have it configured for enforcement
|
||||
if !utils.IsLicensed || !*utils.License.Features.MFA || !*utils.Cfg.ServiceSettings.EnableMultifactorAuthentication || !*utils.Cfg.ServiceSettings.EnforceMultifactorAuthentication {
|
||||
return
|
||||
}
|
||||
|
||||
// OAuth integrations are excepted
|
||||
if c.Session.IsOAuth {
|
||||
return
|
||||
}
|
||||
|
||||
if result := <-Srv.Store.User().Get(c.Session.UserId); result.Err != nil {
|
||||
c.Err = model.NewLocAppError("", "api.context.session_expired.app_error", nil, "MfaRequired")
|
||||
c.Err.StatusCode = http.StatusUnauthorized
|
||||
return
|
||||
} else {
|
||||
user := result.Data.(*model.User)
|
||||
|
||||
// Only required for email and ldap accounts
|
||||
if user.AuthService != "" &&
|
||||
user.AuthService != model.USER_AUTH_SERVICE_EMAIL &&
|
||||
user.AuthService != model.USER_AUTH_SERVICE_LDAP {
|
||||
return
|
||||
}
|
||||
|
||||
if !user.MfaActive {
|
||||
c.Err = model.NewLocAppError("", "api.context.mfa_required.app_error", nil, "MfaRequired")
|
||||
c.Err.StatusCode = http.StatusUnauthorized
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Context) SystemAdminRequired() {
|
||||
if len(c.Session.UserId) == 0 {
|
||||
c.Err = model.NewLocAppError("", "api.context.session_expired.app_error", nil, "SystemAdminRequired")
|
||||
|
||||
Ссылка в новой задаче
Block a user