Auth: Reduce restriction with non-user accounts (#74397)

* Reduce restrictions with non-user accounts

* Revert restrictions on anonymous accounts

* Change log level from warning to debug

* Change log messages to upper case
This commit is contained in:
linoman
2023-09-06 13:37:54 +02:00
committed by GitHub
parent a2c93bb8bc
commit 0e8f19ca6a
5 changed files with 53 additions and 47 deletions
+26 -21
View File
@@ -422,14 +422,15 @@ func (hs *HTTPServer) postDashboard(c *contextmodel.ReqContext, cmd dashboards.S
ctx := c.Req.Context() ctx := c.Req.Context()
var err error var err error
userID := int64(0)
namespaceID, userIDstr := c.SignedInUser.GetNamespacedID() namespaceID, userIDstr := c.SignedInUser.GetNamespacedID()
if namespaceID != identity.NamespaceUser && namespaceID != identity.NamespaceServiceAccount { if namespaceID != identity.NamespaceUser && namespaceID != identity.NamespaceServiceAccount {
hs.log.Warn("User does not belong to a user or service account namespace", "namespaceID", namespaceID, "userID", userIDstr) hs.log.Debug("User does not belong to a user or service account namespace", "namespaceID", namespaceID, "userID", userIDstr)
return response.Error(http.StatusBadRequest, "User does not belong to a user or service account namespace", nil) } else {
} userID, err = identity.IntIdentifier(namespaceID, userIDstr)
userID, err := identity.IntIdentifier(namespaceID, userIDstr) if err != nil {
if err != nil { hs.log.Debug("Error while parsing user ID", "namespaceID", namespaceID, "userID", userIDstr)
hs.log.Warn("Error while parsing user ID", "namespaceID", namespaceID, "userID", userIDstr) }
} }
cmd.OrgID = c.SignedInUser.GetOrgID() cmd.OrgID = c.SignedInUser.GetOrgID()
@@ -454,7 +455,7 @@ func (hs *HTTPServer) postDashboard(c *contextmodel.ReqContext, cmd dashboards.S
if newDashboard { if newDashboard {
limitReached, err := hs.QuotaService.QuotaReached(c, dashboards.QuotaTargetSrv) limitReached, err := hs.QuotaService.QuotaReached(c, dashboards.QuotaTargetSrv)
if err != nil { if err != nil {
return response.Error(http.StatusInternalServerError, "failed to get quota", err) return response.Error(http.StatusInternalServerError, "Failed to get quota", err)
} }
if limitReached { if limitReached {
return response.Error(http.StatusForbidden, "Quota reached", nil) return response.Error(http.StatusForbidden, "Quota reached", nil)
@@ -516,7 +517,7 @@ func (hs *HTTPServer) postDashboard(c *contextmodel.ReqContext, cmd dashboards.S
} }
if liveerr != nil { if liveerr != nil {
hs.log.Warn("unable to broadcast save event", "uid", dashboard.UID, "error", liveerr) hs.log.Warn("Unable to broadcast save event", "uid", dashboard.UID, "error", liveerr)
} }
} }
@@ -556,16 +557,18 @@ func (hs *HTTPServer) postDashboard(c *contextmodel.ReqContext, cmd dashboards.S
// 401: unauthorisedError // 401: unauthorisedError
// 500: internalServerError // 500: internalServerError
func (hs *HTTPServer) GetHomeDashboard(c *contextmodel.ReqContext) response.Response { func (hs *HTTPServer) GetHomeDashboard(c *contextmodel.ReqContext) response.Response {
userID := int64(0)
var err error
namespaceID, userIDstr := c.SignedInUser.GetNamespacedID() namespaceID, userIDstr := c.SignedInUser.GetNamespacedID()
if namespaceID != identity.NamespaceUser && namespaceID != identity.NamespaceServiceAccount {
if namespaceID != identity.NamespaceUser { hs.log.Debug("User does not belong to a user or service account namespace", "namespaceID", namespaceID, "userID", userIDstr)
return response.Error(http.StatusBadRequest, "User does not belong to a user namespace", nil) } else {
userID, err = identity.IntIdentifier(namespaceID, userIDstr)
if err != nil {
hs.log.Debug("Error while parsing user ID", "namespaceID", namespaceID, "userID", userIDstr)
}
} }
userID, err := identity.IntIdentifier(namespaceID, userIDstr)
if err != nil {
hs.log.Warn("Error while parsing user ID", "namespaceID", namespaceID, "userID", userIDstr, "err", err)
}
prefsQuery := pref.GetPreferenceWithDefaultsQuery{OrgID: c.SignedInUser.GetOrgID(), UserID: userID, Teams: c.SignedInUser.GetTeams()} prefsQuery := pref.GetPreferenceWithDefaultsQuery{OrgID: c.SignedInUser.GetOrgID(), UserID: userID, Teams: c.SignedInUser.GetTeams()}
homePage := hs.Cfg.HomePage homePage := hs.Cfg.HomePage
@@ -864,7 +867,7 @@ func (hs *HTTPServer) ValidateDashboard(c *contextmodel.ReqContext) response.Res
cmd := dashboards.ValidateDashboardCommand{} cmd := dashboards.ValidateDashboardCommand{}
if err := web.Bind(c.Req, &cmd); err != nil { if err := web.Bind(c.Req, &cmd); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err) return response.Error(http.StatusBadRequest, "Bad request data", err)
} }
dk := hs.Kinds.Dashboard() dk := hs.Kinds.Dashboard()
@@ -1074,13 +1077,15 @@ func (hs *HTTPServer) RestoreDashboardVersion(c *contextmodel.ReqContext) respon
return response.Error(http.StatusNotFound, "Dashboard version not found", nil) return response.Error(http.StatusNotFound, "Dashboard version not found", nil)
} }
userID := int64(0)
namespaceID, userIDstr := c.SignedInUser.GetNamespacedID() namespaceID, userIDstr := c.SignedInUser.GetNamespacedID()
if namespaceID != identity.NamespaceUser && namespaceID != identity.NamespaceServiceAccount { if namespaceID != identity.NamespaceUser && namespaceID != identity.NamespaceServiceAccount {
return response.Error(http.StatusBadRequest, "User does not belong to a user or service namespace", nil) hs.log.Warn("User does not belong to a user or service account namespace", "namespaceID", namespaceID, "userID", userIDstr)
} } else {
userID, err := identity.IntIdentifier(namespaceID, userIDstr) userID, err = identity.IntIdentifier(namespaceID, userIDstr)
if err != nil { if err != nil {
return response.Error(http.StatusInternalServerError, "failed to get user id", err) hs.log.Warn("Error while parsing user ID", "namespaceID", namespaceID, "userID", userIDstr)
}
} }
saveCmd := dashboards.SaveDashboardCommand{} saveCmd := dashboards.SaveDashboardCommand{}
@@ -22,7 +22,6 @@ import (
"github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util" "github.com/grafana/grafana/pkg/util"
"github.com/grafana/grafana/pkg/util/errutil"
) )
var ( var (
@@ -207,15 +206,16 @@ func (dr *DashboardServiceImpl) BuildSaveDashboardCommand(ctx context.Context, d
} }
func resolveUserID(user identity.Requester, log log.Logger) (int64, error) { func resolveUserID(user identity.Requester, log log.Logger) (int64, error) {
userID := int64(0)
namespaceID, identifier := user.GetNamespacedID() namespaceID, identifier := user.GetNamespacedID()
if namespaceID != identity.NamespaceUser && namespaceID != identity.NamespaceServiceAccount { if namespaceID != identity.NamespaceUser && namespaceID != identity.NamespaceServiceAccount {
return 0, errutil.BadRequest("account doesn't belong to the user or service namespace") log.Debug("User does not belong to a user or service account namespace", "namespaceID", namespaceID, "userID", identifier)
} }
userID, err := identity.IntIdentifier(namespaceID, identifier) userID, err := identity.IntIdentifier(namespaceID, identifier)
if err != nil { if err != nil {
log.Warn("failed to parse user ID", "namespaceID", namespaceID, "userID", identifier, "error", err) log.Debug("failed to parse user ID", "namespaceID", namespaceID, "userID", identifier, "error", err)
} }
return userID, nil return userID, nil
} }
+18 -14
View File
@@ -281,14 +281,17 @@ func (s *Service) Create(ctx context.Context, cmd *folder.CreateFolderCommand) (
dashFolder.SetUID(trimmedUID) dashFolder.SetUID(trimmedUID)
user := cmd.SignedInUser user := cmd.SignedInUser
userID := int64(0)
var err error
namespaceID, userIDstr := user.GetNamespacedID() namespaceID, userIDstr := user.GetNamespacedID()
if namespaceID == identity.NamespaceAPIKey { if namespaceID != identity.NamespaceUser && namespaceID != identity.NamespaceServiceAccount {
s.log.Warn("namespace API key detected, using 0 as user ID", "namespaceID", namespaceID, "userID", userIDstr) s.log.Debug("User does not belong to a user or service account namespace, using 0 as user ID", "namespaceID", namespaceID, "userID", userIDstr)
userIDstr = "0" } else {
} userID, err = identity.IntIdentifier(namespaceID, userIDstr)
userID, err := identity.IntIdentifier(namespaceID, userIDstr) if err != nil {
if err != nil { s.log.Debug("failed to parse user ID", "namespaceID", namespaceID, "userID", userIDstr, "error", err)
s.log.Warn("failed to parse user ID", "namespaceID", namespaceID, "userID", userIDstr, "error", err) }
} }
if userID == 0 { if userID == 0 {
@@ -773,14 +776,15 @@ func (s *Service) BuildSaveDashboardCommand(ctx context.Context, dto *dashboards
} }
} }
userID := int64(0)
namespaceID, userIDstr := dto.User.GetNamespacedID() namespaceID, userIDstr := dto.User.GetNamespacedID()
if namespaceID == identity.NamespaceAPIKey { if namespaceID != identity.NamespaceUser && namespaceID != identity.NamespaceServiceAccount {
s.log.Warn("namespace API key detected, using 0 as user ID", "namespaceID", namespaceID, "userID", userIDstr) s.log.Warn("User does not belong to a user or service account namespace, using 0 as user ID", "namespaceID", namespaceID, "userID", userIDstr)
userIDstr = "0" } else {
} userID, err = identity.IntIdentifier(namespaceID, userIDstr)
userID, err := identity.IntIdentifier(namespaceID, userIDstr) if err != nil {
if err != nil { s.log.Warn("failed to parse user ID", "namespaceID", namespaceID, "userID", userIDstr, "error", err)
s.log.Warn("failed to parse user ID", "namespaceID", namespaceID, "userID", userIDstr, "error", err) }
} }
cmd := &dashboards.SaveDashboardCommand{ cmd := &dashboards.SaveDashboardCommand{
+2 -6
View File
@@ -300,15 +300,11 @@ func ProvideService(plugCtxProvider *plugincontext.Provider, cfg *setting.Cfg, r
g.websocketHandler = func(ctx *contextmodel.ReqContext) { g.websocketHandler = func(ctx *contextmodel.ReqContext) {
user := ctx.SignedInUser user := ctx.SignedInUser
namespaceID, userID := user.GetNamespacedID() _, identifier := user.GetNamespacedID()
if namespaceID != identity.NamespaceUser {
return // Only users can connect to Live
}
// Centrifuge expects Credentials in context with a current user ID. // Centrifuge expects Credentials in context with a current user ID.
cred := &centrifuge.Credentials{ cred := &centrifuge.Credentials{
UserID: userID, UserID: identifier,
} }
newCtx := centrifuge.SetCredentials(ctx.Req.Context(), cred) newCtx := centrifuge.SetCredentials(ctx.Req.Context(), cred)
newCtx = livecontext.SetContextSignedUser(newCtx, user) newCtx = livecontext.SetContextSignedUser(newCtx, user)
+4 -3
View File
@@ -59,11 +59,12 @@ func (u *SignedInUser) ToUserDisplayDTO() *UserDisplayDTO {
// Static function to parse a requester into a UserDisplayDTO // Static function to parse a requester into a UserDisplayDTO
func NewUserDisplayDTOFromRequester(requester identity.Requester) (*UserDisplayDTO, error) { func NewUserDisplayDTOFromRequester(requester identity.Requester) (*UserDisplayDTO, error) {
userID := int64(0)
namespaceID, identifier := requester.GetNamespacedID() namespaceID, identifier := requester.GetNamespacedID()
if namespaceID != identity.NamespaceUser && namespaceID != identity.NamespaceServiceAccount { if namespaceID == identity.NamespaceUser || namespaceID == identity.NamespaceServiceAccount {
identifier = "0" userID, _ = identity.IntIdentifier(namespaceID, identifier)
} }
userID, _ := identity.IntIdentifier(namespaceID, identifier)
return &UserDisplayDTO{ return &UserDisplayDTO{
ID: userID, ID: userID,
Login: requester.GetLogin(), Login: requester.GetLogin(),