[MM-56340] Add audit events for OAuth logins (#25859)
* Add audit events for OAuth logins * Fix test * Fix auth record --------- Co-authored-by: Mattermost Build <build@mattermost.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
0a3a55bb80
Коммит
31015a971e
@@ -76,7 +76,7 @@ func authorizeOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auditRec.Success()
|
auditRec.Success()
|
||||||
c.LogAudit("")
|
c.LogAudit("success")
|
||||||
|
|
||||||
w.Write([]byte(model.MapToJSON(map[string]string{"redirect": redirectURL})))
|
w.Write([]byte(model.MapToJSON(map[string]string{"redirect": redirectURL})))
|
||||||
}
|
}
|
||||||
@@ -91,6 +91,7 @@ func deauthorizeOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auditRec := c.MakeAuditRecord("deauthorizeOAuthApp", audit.Fail)
|
auditRec := c.MakeAuditRecord("deauthorizeOAuthApp", audit.Fail)
|
||||||
|
auditRec.AddMeta("client_id", clientId)
|
||||||
defer c.LogAuditRec(auditRec)
|
defer c.LogAuditRec(auditRec)
|
||||||
|
|
||||||
err := c.App.DeauthorizeOAuthAppForUser(c.AppContext, c.AppContext.Session().UserId, clientId)
|
err := c.App.DeauthorizeOAuthAppForUser(c.AppContext, c.AppContext.Session().UserId, clientId)
|
||||||
@@ -131,6 +132,11 @@ func authorizeOAuthPage(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auditRec := c.MakeAuditRecord("authorizeOAuthPage", audit.Fail)
|
||||||
|
auditRec.AddMeta("client_id", authRequest.ClientId)
|
||||||
|
auditRec.AddMeta("scope", authRequest.Scope)
|
||||||
|
defer c.LogAuditRec(auditRec)
|
||||||
|
|
||||||
oauthApp, err := c.App.GetOAuthApp(authRequest.ClientId)
|
oauthApp, err := c.App.GetOAuthApp(authRequest.ClientId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.RenderWebAppError(c.App.Config(), w, r, err, c.App.AsymmetricSigningKey())
|
utils.RenderWebAppError(c.App.Config(), w, r, err, c.App.AsymmetricSigningKey())
|
||||||
@@ -139,6 +145,9 @@ func authorizeOAuthPage(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
// here we should check if the user is logged in
|
// here we should check if the user is logged in
|
||||||
if c.AppContext.Session().UserId == "" {
|
if c.AppContext.Session().UserId == "" {
|
||||||
|
auditRec.Success()
|
||||||
|
c.LogAudit("success")
|
||||||
|
|
||||||
if loginHint == model.UserAuthServiceSaml {
|
if loginHint == model.UserAuthServiceSaml {
|
||||||
http.Redirect(w, r, c.GetSiteURLHeader()+"/login/sso/saml?redirect_to="+url.QueryEscape(r.RequestURI), http.StatusFound)
|
http.Redirect(w, r, c.GetSiteURLHeader()+"/login/sso/saml?redirect_to="+url.QueryEscape(r.RequestURI), http.StatusFound)
|
||||||
} else {
|
} else {
|
||||||
@@ -167,16 +176,21 @@ func authorizeOAuthPage(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
// Automatically allow if the app is trusted
|
// Automatically allow if the app is trusted
|
||||||
if oauthApp.IsTrusted || isAuthorized {
|
if oauthApp.IsTrusted || isAuthorized {
|
||||||
redirectURL, err := c.App.AllowOAuthAppAccessToUser(c.AppContext, c.AppContext.Session().UserId, authRequest)
|
redirectURL, err := c.App.AllowOAuthAppAccessToUser(c.AppContext, c.AppContext.Session().UserId, authRequest)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.RenderWebAppError(c.App.Config(), w, r, err, c.App.AsymmetricSigningKey())
|
utils.RenderWebAppError(c.App.Config(), w, r, err, c.App.AsymmetricSigningKey())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auditRec.Success()
|
||||||
|
c.LogAudit("success")
|
||||||
|
|
||||||
http.Redirect(w, r, redirectURL, http.StatusFound)
|
http.Redirect(w, r, redirectURL, http.StatusFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auditRec.Success()
|
||||||
|
c.LogAudit("success")
|
||||||
|
|
||||||
w.Header().Set("X-Frame-Options", "SAMEORIGIN")
|
w.Header().Set("X-Frame-Options", "SAMEORIGIN")
|
||||||
w.Header().Set("Content-Security-Policy", fmt.Sprintf("frame-ancestors %s", frameAncestors))
|
w.Header().Set("Content-Security-Policy", fmt.Sprintf("frame-ancestors %s", frameAncestors))
|
||||||
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||||
@@ -255,6 +269,10 @@ func completeOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
service := c.Params.Service
|
service := c.Params.Service
|
||||||
|
|
||||||
|
auditRec := c.MakeAuditRecord("completeOAuth", audit.Fail)
|
||||||
|
defer c.LogAuditRec(auditRec)
|
||||||
|
audit.AddEventParameter(auditRec, "service", service)
|
||||||
|
|
||||||
oauthError := r.URL.Query().Get("error")
|
oauthError := r.URL.Query().Get("error")
|
||||||
if oauthError == "access_denied" {
|
if oauthError == "access_denied" {
|
||||||
utils.RenderWebError(c.App.Config(), w, r, http.StatusTemporaryRedirect, url.Values{
|
utils.RenderWebError(c.App.Config(), w, r, http.StatusTemporaryRedirect, url.Values{
|
||||||
@@ -333,6 +351,10 @@ func completeOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
// Old mobile version
|
// Old mobile version
|
||||||
if isMobile && !hasRedirectURL {
|
if isMobile && !hasRedirectURL {
|
||||||
c.App.AttachSessionCookies(c.AppContext, w, r)
|
c.App.AttachSessionCookies(c.AppContext, w, r)
|
||||||
|
|
||||||
|
auditRec.Success()
|
||||||
|
c.LogAudit("success")
|
||||||
|
|
||||||
return
|
return
|
||||||
} else
|
} else
|
||||||
// New mobile version
|
// New mobile version
|
||||||
@@ -342,6 +364,10 @@ func completeOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
model.SessionCookieCsrf: c.AppContext.Session().GetCSRF(),
|
model.SessionCookieCsrf: c.AppContext.Session().GetCSRF(),
|
||||||
})
|
})
|
||||||
utils.RenderMobileAuthComplete(w, redirectURL)
|
utils.RenderMobileAuthComplete(w, redirectURL)
|
||||||
|
|
||||||
|
auditRec.Success()
|
||||||
|
c.LogAudit("success")
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// For web
|
// For web
|
||||||
@@ -376,6 +402,9 @@ func completeOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auditRec.Success()
|
||||||
|
c.LogAudit("success")
|
||||||
|
|
||||||
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||||
http.Redirect(w, r, redirectURL, http.StatusTemporaryRedirect)
|
http.Redirect(w, r, redirectURL, http.StatusTemporaryRedirect)
|
||||||
}
|
}
|
||||||
@@ -395,6 +424,10 @@ func loginWithOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auditRec := c.MakeAuditRecord("loginWithOAuth", audit.Fail)
|
||||||
|
auditRec.AddMeta("service", c.Params.Service)
|
||||||
|
defer c.LogAuditRec(auditRec)
|
||||||
|
|
||||||
teamId, err := c.App.GetTeamIdFromQuery(c.AppContext, r.URL.Query())
|
teamId, err := c.App.GetTeamIdFromQuery(c.AppContext, r.URL.Query())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Err = err
|
c.Err = err
|
||||||
@@ -407,6 +440,9 @@ func loginWithOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auditRec.Success()
|
||||||
|
c.LogAudit("success")
|
||||||
|
|
||||||
http.Redirect(w, r, authURL, http.StatusFound)
|
http.Redirect(w, r, authURL, http.StatusFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -424,6 +460,10 @@ func mobileLoginWithOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auditRec := c.MakeAuditRecord("mobileLoginWithOAuth", audit.Fail)
|
||||||
|
auditRec.AddMeta("service", c.Params.Service)
|
||||||
|
defer c.LogAuditRec(auditRec)
|
||||||
|
|
||||||
teamId, err := c.App.GetTeamIdFromQuery(c.AppContext, r.URL.Query())
|
teamId, err := c.App.GetTeamIdFromQuery(c.AppContext, r.URL.Query())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Err = err
|
c.Err = err
|
||||||
@@ -436,6 +476,9 @@ func mobileLoginWithOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auditRec.Success()
|
||||||
|
c.LogAudit("success")
|
||||||
|
|
||||||
http.Redirect(w, r, authURL, http.StatusFound)
|
http.Redirect(w, r, authURL, http.StatusFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -452,6 +495,10 @@ func signupWithOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auditRec := c.MakeAuditRecord("signupWithOAuth", audit.Fail)
|
||||||
|
auditRec.AddMeta("service", c.Params.Service)
|
||||||
|
defer c.LogAuditRec(auditRec)
|
||||||
|
|
||||||
teamId, err := c.App.GetTeamIdFromQuery(c.AppContext, r.URL.Query())
|
teamId, err := c.App.GetTeamIdFromQuery(c.AppContext, r.URL.Query())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Err = err
|
c.Err = err
|
||||||
@@ -466,6 +513,9 @@ func signupWithOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auditRec.Success()
|
||||||
|
c.LogAudit("success")
|
||||||
|
|
||||||
http.Redirect(w, r, authURL, http.StatusFound)
|
http.Redirect(w, r, authURL, http.StatusFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ func TestOAuthComplete_AccessDenied(t *testing.T) {
|
|||||||
Params: &Params{
|
Params: &Params{
|
||||||
Service: "TestService",
|
Service: "TestService",
|
||||||
},
|
},
|
||||||
|
AppContext: request.EmptyContext(th.TestLogger),
|
||||||
}
|
}
|
||||||
responseWriter := httptest.NewRecorder()
|
responseWriter := httptest.NewRecorder()
|
||||||
request, _ := http.NewRequest(http.MethodGet, th.App.GetSiteURL()+"/signup/TestService/complete?error=access_denied", nil)
|
request, _ := http.NewRequest(http.MethodGet, th.App.GetSiteURL()+"/signup/TestService/complete?error=access_denied", nil)
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user