mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Session: set authID and authenticatedBy (#85806)
* Authn: Resolve authenticate by and auth id when fethcing signed in user * Change logout client interface to only take Requester interface * Session: Fetch external auth info when authenticating sessions * Use authenticated by from identity * Move call to get auth-info into session client and use GetAuthenticatedBy in various places
This commit is contained in:
@@ -4,7 +4,6 @@ import (
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
@@ -20,7 +19,6 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/login"
|
||||
"github.com/grafana/grafana/pkg/services/org"
|
||||
pref "github.com/grafana/grafana/pkg/services/preference"
|
||||
"github.com/grafana/grafana/pkg/services/user"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
@@ -112,7 +110,7 @@ func (hs *HTTPServer) setIndexViewData(c *contextmodel.ReqContext) (*dtos.IndexV
|
||||
HelpFlags1: c.HelpFlags1,
|
||||
HasEditPermissionInFolders: hasEditPerm,
|
||||
Analytics: hs.buildUserAnalyticsSettings(c),
|
||||
AuthenticatedBy: hs.getUserAuthenticatedBy(c, userID),
|
||||
AuthenticatedBy: c.GetAuthenticatedBy(),
|
||||
},
|
||||
Settings: settings,
|
||||
ThemeType: theme.Type,
|
||||
@@ -168,7 +166,7 @@ func (hs *HTTPServer) setIndexViewData(c *contextmodel.ReqContext) (*dtos.IndexV
|
||||
}
|
||||
|
||||
func (hs *HTTPServer) buildUserAnalyticsSettings(c *contextmodel.ReqContext) dtos.AnalyticsSettings {
|
||||
namespace, id := c.SignedInUser.GetNamespacedID()
|
||||
namespace, _ := c.SignedInUser.GetNamespacedID()
|
||||
|
||||
// Anonymous users do not have an email or auth info
|
||||
if namespace != identity.NamespaceUser {
|
||||
@@ -179,21 +177,10 @@ func (hs *HTTPServer) buildUserAnalyticsSettings(c *contextmodel.ReqContext) dto
|
||||
return dtos.AnalyticsSettings{}
|
||||
}
|
||||
|
||||
userID, err := identity.IntIdentifier(namespace, id)
|
||||
if err != nil {
|
||||
hs.log.Error("Failed to parse user ID", "error", err)
|
||||
return dtos.AnalyticsSettings{Identifier: "@" + hs.Cfg.AppURL}
|
||||
}
|
||||
|
||||
identifier := c.SignedInUser.GetEmail() + "@" + hs.Cfg.AppURL
|
||||
|
||||
authInfo, err := hs.authInfoService.GetAuthInfo(c.Req.Context(), &login.GetAuthInfoQuery{UserId: userID})
|
||||
if err != nil && !errors.Is(err, user.ErrUserNotFound) {
|
||||
hs.log.Error("Failed to get auth info for analytics", "error", err)
|
||||
}
|
||||
|
||||
if authInfo != nil && authInfo.AuthModule == login.GrafanaComAuthModule {
|
||||
identifier = authInfo.AuthId
|
||||
if authenticatedBy := c.SignedInUser.GetAuthenticatedBy(); authenticatedBy == login.GrafanaComAuthModule {
|
||||
identifier = c.SignedInUser.GetAuthID()
|
||||
}
|
||||
|
||||
return dtos.AnalyticsSettings{
|
||||
@@ -216,32 +203,6 @@ func (hs *HTTPServer) getUserOrgCount(c *contextmodel.ReqContext, userID int64)
|
||||
return len(userOrgs)
|
||||
}
|
||||
|
||||
// getUserAuthenticatedBy returns external authentication method used for user.
|
||||
// If user does not have an external authentication method an empty string is returned
|
||||
func (hs *HTTPServer) getUserAuthenticatedBy(c *contextmodel.ReqContext, userID int64) string {
|
||||
if userID == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Special case for image renderer. Frontend relies on this information
|
||||
// to render dashboards in a bit different way.
|
||||
if c.IsRenderCall {
|
||||
return login.RenderModule
|
||||
}
|
||||
|
||||
info, err := hs.authInfoService.GetAuthInfo(c.Req.Context(), &login.GetAuthInfoQuery{UserId: userID})
|
||||
// we ignore errors where a user does not have external user auth
|
||||
if err != nil && !errors.Is(err, user.ErrUserNotFound) {
|
||||
hs.log.FromContext(c.Req.Context()).Error("Failed to fetch auth info", "userId", c.SignedInUser.UserID, "error", err)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return info.AuthModule
|
||||
}
|
||||
|
||||
func hashUserIdentifier(identifier string, secret string) string {
|
||||
if secret == "" {
|
||||
return ""
|
||||
|
||||
@@ -243,13 +243,7 @@ func (hs *HTTPServer) loginUserWithUser(user *user.User, c *contextmodel.ReqCont
|
||||
func (hs *HTTPServer) Logout(c *contextmodel.ReqContext) {
|
||||
// FIXME: restructure saml client to implement authn.LogoutClient
|
||||
if hs.samlSingleLogoutEnabled() {
|
||||
id, err := identity.UserIdentifier(c.SignedInUser.GetNamespacedID())
|
||||
if err != nil {
|
||||
hs.log.Error("failed to retrieve user ID", "error", err)
|
||||
}
|
||||
|
||||
authInfo, _ := hs.authInfoService.GetAuthInfo(c.Req.Context(), &loginservice.GetAuthInfoQuery{UserId: id})
|
||||
if authInfo != nil && authInfo.AuthModule == loginservice.SAMLAuthModule {
|
||||
if c.SignedInUser.GetAuthenticatedBy() == loginservice.SAMLAuthModule {
|
||||
c.Redirect(hs.Cfg.AppSubURL + "/logout/saml")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -670,7 +670,8 @@ func TestLogoutSaml(t *testing.T) {
|
||||
assert.Equal(t, true, hs.samlSingleLogoutEnabled())
|
||||
sc.defaultHandler = routing.Wrap(func(c *contextmodel.ReqContext) response.Response {
|
||||
c.SignedInUser = &user.SignedInUser{
|
||||
UserID: 1,
|
||||
UserID: 1,
|
||||
AuthenticatedBy: loginservice.SAMLAuthModule,
|
||||
}
|
||||
hs.Logout(c)
|
||||
return response.Empty(http.StatusOK)
|
||||
|
||||
Reference in New Issue
Block a user