mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Identity: remove GetTypedID (#91745)
This commit is contained in:
parent
6061fdc8b9
commit
bcfb66b416
@ -43,13 +43,11 @@ func (hs *HTTPServer) isDashboardStarredByUser(c *contextmodel.ReqContext, dashI
|
|||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
namespaceID, userIDstr := c.SignedInUser.GetTypedID()
|
if !identity.IsIdentityType(c.SignedInUser.GetID(), identity.TypeUser) {
|
||||||
|
|
||||||
if namespaceID != identity.TypeUser {
|
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
userID, err := identity.IntIdentifier(namespaceID, userIDstr)
|
userID, err := identity.UserIdentifier(c.SignedInUser.GetID())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
@ -439,16 +437,13 @@ func (hs *HTTPServer) deleteDashboard(c *contextmodel.ReqContext) response.Respo
|
|||||||
return response.Error(http.StatusBadRequest, "Use folders endpoint for deleting folders.", nil)
|
return response.Error(http.StatusBadRequest, "Use folders endpoint for deleting folders.", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
namespaceID, userIDStr := c.SignedInUser.GetTypedID()
|
|
||||||
|
|
||||||
// disconnect all library elements for this dashboard
|
// disconnect all library elements for this dashboard
|
||||||
err = hs.LibraryElementService.DisconnectElementsFromDashboard(c.Req.Context(), dash.ID)
|
err = hs.LibraryElementService.DisconnectElementsFromDashboard(c.Req.Context(), dash.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
hs.log.Error(
|
hs.log.Error(
|
||||||
"Failed to disconnect library elements",
|
"Failed to disconnect library elements",
|
||||||
"dashboard", dash.ID,
|
"dashboard", dash.ID,
|
||||||
"namespaceID", namespaceID,
|
"identity", c.GetID(),
|
||||||
"user", userIDStr,
|
|
||||||
"error", err)
|
"error", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -515,15 +510,9 @@ 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)
|
var userID int64
|
||||||
namespaceID, userIDstr := c.SignedInUser.GetTypedID()
|
if id, err := identity.UserIdentifier(c.SignedInUser.GetID()); err == nil {
|
||||||
if namespaceID != identity.TypeUser && namespaceID != identity.TypeServiceAccount {
|
userID = id
|
||||||
hs.log.Debug("User does not belong to a user or service account namespace", "namespaceID", namespaceID, "userID", userIDstr)
|
|
||||||
} else {
|
|
||||||
userID, err = identity.IntIdentifier(namespaceID, userIDstr)
|
|
||||||
if err != nil {
|
|
||||||
hs.log.Debug("Error while parsing user ID", "namespaceID", namespaceID, "userID", userIDstr)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.OrgID = c.SignedInUser.GetOrgID()
|
cmd.OrgID = c.SignedInUser.GetOrgID()
|
||||||
@ -632,16 +621,9 @@ 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 userID int64
|
||||||
var err error
|
if id, err := identity.UserIdentifier(c.SignedInUser.GetID()); err == nil {
|
||||||
namespaceID, userIDstr := c.SignedInUser.GetTypedID()
|
userID = id
|
||||||
if namespaceID != identity.TypeUser && namespaceID != identity.TypeServiceAccount {
|
|
||||||
hs.log.Debug("User does not belong to a user or service account namespace", "namespaceID", namespaceID, "userID", userIDstr)
|
|
||||||
} else {
|
|
||||||
userID, err = identity.IntIdentifier(namespaceID, userIDstr)
|
|
||||||
if err != nil {
|
|
||||||
hs.log.Debug("Error while parsing user ID", "namespaceID", namespaceID, "userID", userIDstr)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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()}
|
||||||
@ -1085,15 +1067,9 @@ 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)
|
var userID int64
|
||||||
namespaceID, userIDstr := c.SignedInUser.GetTypedID()
|
if id, err := identity.UserIdentifier(c.SignedInUser.GetID()); err == nil {
|
||||||
if namespaceID != identity.TypeUser && namespaceID != identity.TypeServiceAccount {
|
userID = id
|
||||||
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)
|
|
||||||
if err != nil {
|
|
||||||
hs.log.Warn("Error while parsing user ID", "namespaceID", namespaceID, "userID", userIDstr)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
saveCmd := dashboards.SaveDashboardCommand{}
|
saveCmd := dashboards.SaveDashboardCommand{}
|
||||||
|
@ -442,11 +442,7 @@ func (hs *HTTPServer) AddDataSource(c *contextmodel.ReqContext) response.Respons
|
|||||||
return response.Error(http.StatusBadRequest, "bad request data", err)
|
return response.Error(http.StatusBadRequest, "bad request data", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
userID, err := identity.UserIdentifier(c.SignedInUser.GetTypedID())
|
userID, _ := identity.UserIdentifier(c.SignedInUser.GetID())
|
||||||
if err != nil {
|
|
||||||
return response.Error(http.StatusInternalServerError,
|
|
||||||
"Failed to add datasource", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
datasourcesLogger.Debug("Received command to add data source", "url", cmd.URL)
|
datasourcesLogger.Debug("Received command to add data source", "url", cmd.URL)
|
||||||
cmd.OrgID = c.SignedInUser.GetOrgID()
|
cmd.OrgID = c.SignedInUser.GetOrgID()
|
||||||
|
@ -191,15 +191,13 @@ func (hs *HTTPServer) setDefaultFolderPermissions(ctx context.Context, orgID int
|
|||||||
if !hs.Cfg.RBAC.PermissionsOnCreation("folder") {
|
if !hs.Cfg.RBAC.PermissionsOnCreation("folder") {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var permissions []accesscontrol.SetResourcePermissionCommand
|
|
||||||
var userID int64
|
|
||||||
|
|
||||||
namespace, id := user.GetTypedID()
|
var permissions []accesscontrol.SetResourcePermissionCommand
|
||||||
if namespace == identity.TypeUser {
|
|
||||||
var errID error
|
if identity.IsIdentityType(user.GetID(), identity.TypeUser) {
|
||||||
userID, errID = identity.IntIdentifier(namespace, id)
|
userID, err := identity.UserIdentifier(user.GetID())
|
||||||
if errID != nil {
|
if err != nil {
|
||||||
return errID
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
permissions = append(permissions, accesscontrol.SetResourcePermissionCommand{
|
permissions = append(permissions, accesscontrol.SetResourcePermissionCommand{
|
||||||
|
@ -31,7 +31,7 @@ func (hs *HTTPServer) setIndexViewData(c *contextmodel.ReqContext) (*dtos.IndexV
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
userID, _ := identity.UserIdentifier(c.SignedInUser.GetTypedID())
|
userID, _ := identity.UserIdentifier(c.SignedInUser.GetID())
|
||||||
|
|
||||||
prefsQuery := pref.GetPreferenceWithDefaultsQuery{UserID: userID, OrgID: c.SignedInUser.GetOrgID(), Teams: c.Teams}
|
prefsQuery := pref.GetPreferenceWithDefaultsQuery{UserID: userID, OrgID: c.SignedInUser.GetOrgID(), Teams: c.Teams}
|
||||||
prefs, err := hs.preferenceService.GetWithDefaults(c.Req.Context(), &prefsQuery)
|
prefs, err := hs.preferenceService.GetWithDefaults(c.Req.Context(), &prefsQuery)
|
||||||
@ -169,10 +169,8 @@ func (hs *HTTPServer) setIndexViewData(c *contextmodel.ReqContext) (*dtos.IndexV
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (hs *HTTPServer) buildUserAnalyticsSettings(c *contextmodel.ReqContext) dtos.AnalyticsSettings {
|
func (hs *HTTPServer) buildUserAnalyticsSettings(c *contextmodel.ReqContext) dtos.AnalyticsSettings {
|
||||||
namespace, _ := c.SignedInUser.GetTypedID()
|
|
||||||
|
|
||||||
// Anonymous users do not have an email or auth info
|
// Anonymous users do not have an email or auth info
|
||||||
if namespace != identity.TypeUser {
|
if !identity.IsIdentityType(c.SignedInUser.GetID(), identity.TypeUser) {
|
||||||
return dtos.AnalyticsSettings{Identifier: "@" + hs.Cfg.AppURL}
|
return dtos.AnalyticsSettings{Identifier: "@" + hs.Cfg.AppURL}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,8 +257,7 @@ func (hs *HTTPServer) Logout(c *contextmodel.ReqContext) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
_, id := c.SignedInUser.GetTypedID()
|
hs.log.Info("Successful Logout", "id", c.SignedInUser.GetID())
|
||||||
hs.log.Info("Successful Logout", "userID", id)
|
|
||||||
c.Redirect(redirect.URL)
|
c.Redirect(redirect.URL)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -305,7 +304,7 @@ func (hs *HTTPServer) redirectURLWithErrorCookie(c *contextmodel.ReqContext, err
|
|||||||
var userID int64
|
var userID int64
|
||||||
if c.SignedInUser != nil && !c.SignedInUser.IsNil() {
|
if c.SignedInUser != nil && !c.SignedInUser.IsNil() {
|
||||||
var errID error
|
var errID error
|
||||||
userID, errID = identity.UserIdentifier(c.SignedInUser.GetTypedID())
|
userID, errID = identity.UserIdentifier(c.SignedInUser.GetID())
|
||||||
if errID != nil {
|
if errID != nil {
|
||||||
hs.log.Error("failed to retrieve user ID", "error", errID)
|
hs.log.Error("failed to retrieve user ID", "error", errID)
|
||||||
}
|
}
|
||||||
|
@ -132,12 +132,11 @@ func (hs *HTTPServer) CreateOrg(c *contextmodel.ReqContext) response.Response {
|
|||||||
return response.Error(http.StatusBadRequest, "bad request data", err)
|
return response.Error(http.StatusBadRequest, "bad request data", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace, identifier := c.SignedInUser.GetTypedID()
|
if !identity.IsIdentityType(c.SignedInUser.GetID(), identity.TypeUser) {
|
||||||
if namespace != identity.TypeUser {
|
|
||||||
return response.Error(http.StatusForbidden, "Only users can create organizations", nil)
|
return response.Error(http.StatusForbidden, "Only users can create organizations", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
userID, err := identity.IntIdentifier(namespace, identifier)
|
userID, err := identity.UserIdentifier(c.SignedInUser.GetID())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return response.Error(http.StatusInternalServerError, "Failed to parse user id", err)
|
return response.Error(http.StatusInternalServerError, "Failed to parse user id", err)
|
||||||
}
|
}
|
||||||
|
@ -101,14 +101,9 @@ func (hs *HTTPServer) AddOrgInvite(c *contextmodel.ReqContext) response.Response
|
|||||||
cmd.Name = inviteDto.Name
|
cmd.Name = inviteDto.Name
|
||||||
cmd.Status = tempuser.TmpUserInvitePending
|
cmd.Status = tempuser.TmpUserInvitePending
|
||||||
|
|
||||||
namespace, identifier := c.SignedInUser.GetTypedID()
|
|
||||||
var userID int64
|
var userID int64
|
||||||
if namespace == identity.TypeUser || namespace == identity.TypeServiceAccount {
|
if id, err := identity.UserIdentifier(c.SignedInUser.GetID()); err == nil {
|
||||||
var err error
|
userID = id
|
||||||
userID, err = strconv.ParseInt(identifier, 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return response.Error(http.StatusInternalServerError, "Unrecognized user", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.InvitedByUserID = userID
|
cmd.InvitedByUserID = userID
|
||||||
|
@ -22,9 +22,9 @@ func (hs *HTTPServer) SetHomeDashboard(c *contextmodel.ReqContext) response.Resp
|
|||||||
return response.Error(http.StatusBadRequest, "bad request data", err)
|
return response.Error(http.StatusBadRequest, "bad request data", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
userID, errID := identity.UserIdentifier(c.SignedInUser.GetTypedID())
|
userID, err := identity.UserIdentifier(c.SignedInUser.GetID())
|
||||||
if errID != nil {
|
if err != nil {
|
||||||
return response.Error(http.StatusInternalServerError, "Failed to set home dashboard", errID)
|
return response.Error(http.StatusInternalServerError, "Failed to set home dashboard", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.UserID = userID
|
cmd.UserID = userID
|
||||||
@ -64,9 +64,9 @@ func (hs *HTTPServer) SetHomeDashboard(c *contextmodel.ReqContext) response.Resp
|
|||||||
// 401: unauthorisedError
|
// 401: unauthorisedError
|
||||||
// 500: internalServerError
|
// 500: internalServerError
|
||||||
func (hs *HTTPServer) GetUserPreferences(c *contextmodel.ReqContext) response.Response {
|
func (hs *HTTPServer) GetUserPreferences(c *contextmodel.ReqContext) response.Response {
|
||||||
userID, errID := identity.UserIdentifier(c.SignedInUser.GetTypedID())
|
userID, err := identity.UserIdentifier(c.SignedInUser.GetID())
|
||||||
if errID != nil {
|
if err != nil {
|
||||||
return response.Error(http.StatusInternalServerError, "Failed to get user preferences", errID)
|
return response.Error(http.StatusInternalServerError, "Failed to update user preferences", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return prefapi.GetPreferencesFor(c.Req.Context(), hs.DashboardService, hs.preferenceService, c.SignedInUser.GetOrgID(), userID, 0)
|
return prefapi.GetPreferencesFor(c.Req.Context(), hs.DashboardService, hs.preferenceService, c.SignedInUser.GetOrgID(), userID, 0)
|
||||||
@ -89,9 +89,9 @@ func (hs *HTTPServer) UpdateUserPreferences(c *contextmodel.ReqContext) response
|
|||||||
return response.Error(http.StatusBadRequest, "bad request data", err)
|
return response.Error(http.StatusBadRequest, "bad request data", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
userID, errID := identity.UserIdentifier(c.SignedInUser.GetTypedID())
|
userID, err := identity.UserIdentifier(c.SignedInUser.GetID())
|
||||||
if errID != nil {
|
if err != nil {
|
||||||
return response.Error(http.StatusInternalServerError, "Failed to update user preferences", errID)
|
return response.Error(http.StatusInternalServerError, "Failed to update user preferences", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return prefapi.UpdatePreferencesFor(c.Req.Context(), hs.DashboardService,
|
return prefapi.UpdatePreferencesFor(c.Req.Context(), hs.DashboardService,
|
||||||
@ -113,9 +113,9 @@ func (hs *HTTPServer) PatchUserPreferences(c *contextmodel.ReqContext) response.
|
|||||||
return response.Error(http.StatusBadRequest, "bad request data", err)
|
return response.Error(http.StatusBadRequest, "bad request data", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
userID, errID := identity.UserIdentifier(c.SignedInUser.GetTypedID())
|
userID, err := identity.UserIdentifier(c.SignedInUser.GetID())
|
||||||
if errID != nil {
|
if err != nil {
|
||||||
return response.Error(http.StatusInternalServerError, "Failed to update user preferences", errID)
|
return response.Error(http.StatusInternalServerError, "Failed to update user preferences", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return hs.patchPreferencesFor(c.Req.Context(), c.SignedInUser.GetOrgID(), userID, 0, &dtoCmd)
|
return hs.patchPreferencesFor(c.Req.Context(), c.SignedInUser.GetOrgID(), userID, 0, &dtoCmd)
|
||||||
|
@ -65,9 +65,9 @@ func (hs *HTTPServer) RenderHandler(c *contextmodel.ReqContext) {
|
|||||||
headers["Accept-Language"] = acceptLanguageHeader
|
headers["Accept-Language"] = acceptLanguageHeader
|
||||||
}
|
}
|
||||||
|
|
||||||
userID, errID := identity.UserIdentifier(c.SignedInUser.GetTypedID())
|
userID, err := identity.UserIdentifier(c.SignedInUser.GetID())
|
||||||
if errID != nil {
|
if err != nil {
|
||||||
hs.log.Error("Failed to parse user id", "err", errID)
|
hs.log.Debug("Failed to parse user id", "err", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
encoding := queryReader.Get("encoding", "")
|
encoding := queryReader.Get("encoding", "")
|
||||||
|
@ -47,9 +47,9 @@ func (hs *HTTPServer) SignUp(c *contextmodel.ReqContext) response.Response {
|
|||||||
return response.Error(http.StatusUnprocessableEntity, "User with same email address already exists", nil)
|
return response.Error(http.StatusUnprocessableEntity, "User with same email address already exists", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
userID, errID := identity.UserIdentifier(c.SignedInUser.GetTypedID())
|
userID, err := identity.UserIdentifier(c.SignedInUser.GetID())
|
||||||
if errID != nil {
|
if err != nil {
|
||||||
hs.log.Error("Failed to parse user id", "err", errID)
|
hs.log.Debug("Failed to parse user id", "err", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd := tempuser.CreateTempUserCommand{}
|
cmd := tempuser.CreateTempUserCommand{}
|
||||||
|
@ -31,8 +31,7 @@ import (
|
|||||||
// 404: notFoundError
|
// 404: notFoundError
|
||||||
// 500: internalServerError
|
// 500: internalServerError
|
||||||
func (hs *HTTPServer) GetSignedInUser(c *contextmodel.ReqContext) response.Response {
|
func (hs *HTTPServer) GetSignedInUser(c *contextmodel.ReqContext) response.Response {
|
||||||
namespace, identifier := c.SignedInUser.GetTypedID()
|
if !identity.IsIdentityType(c.GetID(), identity.TypeUser) {
|
||||||
if namespace != identity.TypeUser {
|
|
||||||
return response.JSON(http.StatusOK, user.UserProfileDTO{
|
return response.JSON(http.StatusOK, user.UserProfileDTO{
|
||||||
IsGrafanaAdmin: c.SignedInUser.GetIsGrafanaAdmin(),
|
IsGrafanaAdmin: c.SignedInUser.GetIsGrafanaAdmin(),
|
||||||
OrgID: c.SignedInUser.GetOrgID(),
|
OrgID: c.SignedInUser.GetOrgID(),
|
||||||
@ -43,7 +42,7 @@ func (hs *HTTPServer) GetSignedInUser(c *contextmodel.ReqContext) response.Respo
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
userID, err := identity.IntIdentifier(namespace, identifier)
|
userID, err := identity.UserIdentifier(c.GetID())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return response.Error(http.StatusInternalServerError, "Failed to parse user id", err)
|
return response.Error(http.StatusInternalServerError, "Failed to parse user id", err)
|
||||||
}
|
}
|
||||||
@ -278,8 +277,7 @@ func (hs *HTTPServer) handleUpdateUser(ctx context.Context, cmd user.UpdateUserC
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (hs *HTTPServer) StartEmailVerificaton(c *contextmodel.ReqContext) response.Response {
|
func (hs *HTTPServer) StartEmailVerificaton(c *contextmodel.ReqContext) response.Response {
|
||||||
namespace, id := c.SignedInUser.GetTypedID()
|
if !identity.IsIdentityType(c.SignedInUser.GetID(), identity.TypeUser) {
|
||||||
if !identity.IsIdentityType(namespace, identity.TypeUser) {
|
|
||||||
return response.Error(http.StatusBadRequest, "Only users can verify their email", nil)
|
return response.Error(http.StatusBadRequest, "Only users can verify their email", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -288,7 +286,7 @@ func (hs *HTTPServer) StartEmailVerificaton(c *contextmodel.ReqContext) response
|
|||||||
return response.Respond(http.StatusNotModified, nil)
|
return response.Respond(http.StatusNotModified, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
userID, err := strconv.ParseInt(id, 10, 64)
|
userID, err := identity.UserIdentifier(c.SignedInUser.GetID())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return response.Error(http.StatusInternalServerError, "Got invalid user id", err)
|
return response.Error(http.StatusInternalServerError, "Got invalid user id", err)
|
||||||
}
|
}
|
||||||
@ -506,13 +504,12 @@ func (hs *HTTPServer) ChangeActiveOrgAndRedirectToHome(c *contextmodel.ReqContex
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace, identifier := c.SignedInUser.GetTypedID()
|
if !identity.IsIdentityType(c.SignedInUser.GetID(), identity.TypeUser) {
|
||||||
if namespace != identity.TypeUser {
|
|
||||||
c.JsonApiErr(http.StatusForbidden, "Endpoint only available for users", nil)
|
c.JsonApiErr(http.StatusForbidden, "Endpoint only available for users", nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
userID, err := identity.IntIdentifier(namespace, identifier)
|
userID, err := identity.UserIdentifier(c.SignedInUser.GetID())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JsonApiErr(http.StatusInternalServerError, "Failed to parse user id", err)
|
c.JsonApiErr(http.StatusInternalServerError, "Failed to parse user id", err)
|
||||||
return
|
return
|
||||||
@ -632,12 +629,11 @@ func (hs *HTTPServer) ClearHelpFlags(c *contextmodel.ReqContext) response.Respon
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getUserID(c *contextmodel.ReqContext) (int64, *response.NormalResponse) {
|
func getUserID(c *contextmodel.ReqContext) (int64, *response.NormalResponse) {
|
||||||
namespace, identifier := c.SignedInUser.GetTypedID()
|
if !identity.IsIdentityType(c.SignedInUser.GetID(), identity.TypeUser) {
|
||||||
if namespace != identity.TypeUser {
|
|
||||||
return 0, response.Error(http.StatusForbidden, "Endpoint only available for users", nil)
|
return 0, response.Error(http.StatusForbidden, "Endpoint only available for users", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
userID, err := identity.IntIdentifier(namespace, identifier)
|
userID, err := identity.UserIdentifier(c.SignedInUser.GetID())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, response.Error(http.StatusInternalServerError, "Failed to parse user id", err)
|
return 0, response.Error(http.StatusInternalServerError, "Failed to parse user id", err)
|
||||||
}
|
}
|
||||||
|
@ -32,12 +32,11 @@ import (
|
|||||||
// 403: forbiddenError
|
// 403: forbiddenError
|
||||||
// 500: internalServerError
|
// 500: internalServerError
|
||||||
func (hs *HTTPServer) GetUserAuthTokens(c *contextmodel.ReqContext) response.Response {
|
func (hs *HTTPServer) GetUserAuthTokens(c *contextmodel.ReqContext) response.Response {
|
||||||
namespace, identifier := c.SignedInUser.GetTypedID()
|
if !identity.IsIdentityType(c.SignedInUser.GetID(), identity.TypeUser) {
|
||||||
if namespace != identity.TypeUser {
|
return response.Error(http.StatusForbidden, "entity not allowed to get tokens", nil)
|
||||||
return response.Error(http.StatusForbidden, "entity not allowed to revoke tokens", nil)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
userID, err := identity.IntIdentifier(namespace, identifier)
|
userID, err := identity.UserIdentifier(c.SignedInUser.GetID())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return response.Error(http.StatusInternalServerError, "failed to parse user id", err)
|
return response.Error(http.StatusInternalServerError, "failed to parse user id", err)
|
||||||
}
|
}
|
||||||
@ -63,12 +62,11 @@ func (hs *HTTPServer) RevokeUserAuthToken(c *contextmodel.ReqContext) response.R
|
|||||||
return response.Error(http.StatusBadRequest, "bad request data", err)
|
return response.Error(http.StatusBadRequest, "bad request data", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace, identifier := c.SignedInUser.GetTypedID()
|
if !identity.IsIdentityType(c.SignedInUser.GetID(), identity.TypeUser) {
|
||||||
if namespace != identity.TypeUser {
|
|
||||||
return response.Error(http.StatusForbidden, "entity not allowed to revoke tokens", nil)
|
return response.Error(http.StatusForbidden, "entity not allowed to revoke tokens", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
userID, err := identity.IntIdentifier(namespace, identifier)
|
userID, err := identity.UserIdentifier(c.SignedInUser.GetID())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return response.Error(http.StatusInternalServerError, "failed to parse user id", err)
|
return response.Error(http.StatusInternalServerError, "failed to parse user id", err)
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
ErrInvalidIDType = errutil.BadRequest("auth.identity.invalid-id-type")
|
||||||
ErrInvalidTypedID = errutil.BadRequest("auth.identity.invalid-typed-id")
|
ErrInvalidTypedID = errutil.BadRequest("auth.identity.invalid-typed-id")
|
||||||
ErrNotIntIdentifier = errors.New("identifier is not an int64")
|
ErrNotIntIdentifier = errors.New("identifier is not an int64")
|
||||||
ErrIdentifierNotInitialized = errors.New("identifier is not initialized")
|
ErrIdentifierNotInitialized = errors.New("identifier is not initialized")
|
||||||
|
@ -17,15 +17,9 @@ type Requester interface {
|
|||||||
GetRawIdentifier() string
|
GetRawIdentifier() string
|
||||||
// Deprecated: use GetUID instead
|
// Deprecated: use GetUID instead
|
||||||
GetInternalID() (int64, error)
|
GetInternalID() (int64, error)
|
||||||
|
|
||||||
// GetID returns namespaced internalID for the entity
|
// GetID returns namespaced internalID for the entity
|
||||||
// Deprecated: use GetUID instead
|
// Deprecated: use GetUID instead
|
||||||
GetID() TypedID
|
GetID() TypedID
|
||||||
// GetTypedID returns the namespace and ID of the active entity.
|
|
||||||
// The namespace is one of the constants defined in pkg/apimachinery/identity.
|
|
||||||
// Deprecated: use GetID instead
|
|
||||||
GetTypedID() (kind IdentityType, identifier string)
|
|
||||||
|
|
||||||
// GetDisplayName returns the display name of the active entity.
|
// GetDisplayName returns the display name of the active entity.
|
||||||
// The display name is the name if it is set, otherwise the login or email.
|
// The display name is the name if it is set, otherwise the login or email.
|
||||||
GetDisplayName() string
|
GetDisplayName() string
|
||||||
@ -82,14 +76,14 @@ type Requester interface {
|
|||||||
GetIDClaims() *authnlib.Claims[authnlib.IDTokenClaims]
|
GetIDClaims() *authnlib.Claims[authnlib.IDTokenClaims]
|
||||||
}
|
}
|
||||||
|
|
||||||
// IntIdentifier converts a string identifier to an int64.
|
// IntIdentifier converts a typeID to an int64.
|
||||||
// Applicable for users, service accounts, api keys and renderer service.
|
// Applicable for users, service accounts, api keys and renderer service.
|
||||||
// Errors if the identifier is not initialized or if namespace is not recognized.
|
// Errors if the identifier is not initialized or if type is not recognized.
|
||||||
func IntIdentifier(kind IdentityType, identifier string) (int64, error) {
|
func IntIdentifier(typedID TypedID) (int64, error) {
|
||||||
if IsIdentityType(kind, TypeUser, TypeAPIKey, TypeServiceAccount, TypeRenderService) {
|
if IsIdentityType(typedID, TypeUser, TypeAPIKey, TypeServiceAccount, TypeRenderService) {
|
||||||
id, err := strconv.ParseInt(identifier, 10, 64)
|
id, err := strconv.ParseInt(typedID.ID(), 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, fmt.Errorf("unrecognized format for valid type %s: %w", kind, err)
|
return 0, fmt.Errorf("unrecognized format for valid type %s: %w", typedID.Type(), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if id < 1 {
|
if id < 1 {
|
||||||
@ -102,19 +96,18 @@ func IntIdentifier(kind IdentityType, identifier string) (int64, error) {
|
|||||||
return 0, ErrNotIntIdentifier
|
return 0, ErrNotIntIdentifier
|
||||||
}
|
}
|
||||||
|
|
||||||
// UserIdentifier converts a string identifier to an int64.
|
// UserIdentifier converts a typeID to an int64.
|
||||||
// Errors if the identifier is not initialized or if namespace is not recognized.
|
// Errors if the identifier is not initialized or if namespace is not recognized.
|
||||||
// Returns 0 if the namespace is not user or service account
|
// Returns 0 if the type is not user or service account
|
||||||
func UserIdentifier(kind IdentityType, identifier string) (int64, error) {
|
func UserIdentifier(typedID TypedID) (int64, error) {
|
||||||
userID, err := IntIdentifier(kind, identifier)
|
userID, err := IntIdentifier(typedID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// FIXME: return this error once entity namespaces are handled by stores
|
return 0, err
|
||||||
return 0, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if IsIdentityType(kind, TypeUser, TypeServiceAccount) {
|
if IsIdentityType(typedID, TypeUser, TypeServiceAccount) {
|
||||||
return userID, nil
|
return userID, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0, nil
|
return 0, ErrInvalidIDType
|
||||||
}
|
}
|
||||||
|
@ -149,12 +149,6 @@ func (u *StaticRequester) GetID() TypedID {
|
|||||||
return NewTypedIDString(u.Type, fmt.Sprintf("%d", u.UserID))
|
return NewTypedIDString(u.Type, fmt.Sprintf("%d", u.UserID))
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTypedID returns the namespace and ID of the active entity
|
|
||||||
// The namespace is one of the constants defined in pkg/apimachinery/identity
|
|
||||||
func (u *StaticRequester) GetTypedID() (IdentityType, string) {
|
|
||||||
return u.Type, fmt.Sprintf("%d", u.UserID)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *StaticRequester) GetAuthID() string {
|
func (u *StaticRequester) GetAuthID() string {
|
||||||
return u.AuthID
|
return u.AuthID
|
||||||
}
|
}
|
||||||
|
@ -42,10 +42,10 @@ func ParseType(str string) (IdentityType, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsIdentityType returns true if type matches any expected identity type
|
// IsIdentityType returns true if typedID matches any expected identity type
|
||||||
func IsIdentityType(typ IdentityType, expected ...IdentityType) bool {
|
func IsIdentityType(typedID TypedID, expected ...IdentityType) bool {
|
||||||
for _, e := range expected {
|
for _, e := range expected {
|
||||||
if typ == e {
|
if typedID.Type() == e {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -128,7 +128,7 @@ func (ni TypedID) Type() IdentityType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ni TypedID) IsType(expected ...IdentityType) bool {
|
func (ni TypedID) IsType(expected ...IdentityType) bool {
|
||||||
return IsIdentityType(ni.t, expected...)
|
return IsIdentityType(ni, expected...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ni TypedID) String() string {
|
func (ni TypedID) String() string {
|
@ -192,6 +192,5 @@ func (a *AccessControl) RegisterScopeAttributeResolver(prefix string, resolver a
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *AccessControl) debug(ctx context.Context, ident identity.Requester, msg string, eval accesscontrol.Evaluator) {
|
func (a *AccessControl) debug(ctx context.Context, ident identity.Requester, msg string, eval accesscontrol.Evaluator) {
|
||||||
namespace, id := ident.GetTypedID()
|
a.log.FromContext(ctx).Debug(msg, "id", ident.GetID(), "orgID", ident.GetOrgID(), "permissions", eval.GoString())
|
||||||
a.log.FromContext(ctx).Debug(msg, "namespace", namespace, "id", id, "orgID", ident.GetOrgID(), "permissions", eval.GoString())
|
|
||||||
}
|
}
|
||||||
|
@ -128,7 +128,7 @@ func (s *Service) GetUserPermissions(ctx context.Context, user identity.Requeste
|
|||||||
return s.getCachedUserPermissions(ctx, user, options)
|
return s.getCachedUserPermissions(ctx, user, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) getUserPermissions(ctx context.Context, user identity.Requester, options accesscontrol.Options) ([]accesscontrol.Permission, error) {
|
func (s *Service) getUserPermissions(ctx context.Context, user identity.Requester, _ accesscontrol.Options) ([]accesscontrol.Permission, error) {
|
||||||
ctx, span := s.tracer.Start(ctx, "authz.getUserPermissions")
|
ctx, span := s.tracer.Start(ctx, "authz.getUserPermissions")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
@ -143,10 +143,9 @@ func (s *Service) getUserPermissions(ctx context.Context, user identity.Requeste
|
|||||||
permissions = append(permissions, SharedWithMeFolderPermission)
|
permissions = append(permissions, SharedWithMeFolderPermission)
|
||||||
}
|
}
|
||||||
|
|
||||||
userID, err := identity.UserIdentifier(user.GetTypedID())
|
// we don't care about the error here, if this fails we get 0 and no
|
||||||
if err != nil {
|
// permission assigned to user will be returned, only for org role.
|
||||||
return nil, err
|
userID, _ := identity.UserIdentifier(user.GetID())
|
||||||
}
|
|
||||||
|
|
||||||
dbPermissions, err := s.store.GetUserPermissions(ctx, accesscontrol.GetUserPermissionsQuery{
|
dbPermissions, err := s.store.GetUserPermissions(ctx, accesscontrol.GetUserPermissionsQuery{
|
||||||
OrgID: user.GetOrgID(),
|
OrgID: user.GetOrgID(),
|
||||||
@ -211,12 +210,10 @@ func (s *Service) getUserDirectPermissions(ctx context.Context, user identity.Re
|
|||||||
ctx, span := s.tracer.Start(ctx, "authz.getUserDirectPermissions")
|
ctx, span := s.tracer.Start(ctx, "authz.getUserDirectPermissions")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
namespace, identifier := user.GetTypedID()
|
|
||||||
|
|
||||||
var userID int64
|
var userID int64
|
||||||
if namespace == identity.TypeUser || namespace == identity.TypeServiceAccount {
|
if identity.IsIdentityType(user.GetID(), identity.TypeUser, identity.TypeServiceAccount) {
|
||||||
var err error
|
var err error
|
||||||
userID, err = strconv.ParseInt(identifier, 10, 64)
|
userID, err = identity.UserIdentifier(user.GetID())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -80,11 +80,9 @@ func deny(c *contextmodel.ReqContext, evaluator Evaluator, err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
c.Logger.Error("Error from access control system", "error", err, "accessErrorID", id)
|
c.Logger.Error("Error from access control system", "error", err, "accessErrorID", id)
|
||||||
} else {
|
} else {
|
||||||
namespace, identifier := c.SignedInUser.GetTypedID()
|
|
||||||
c.Logger.Info(
|
c.Logger.Info(
|
||||||
"Access denied",
|
"Access denied",
|
||||||
"namespace", namespace,
|
"id", c.SignedInUser.GetID(),
|
||||||
"userID", identifier,
|
|
||||||
"accessErrorID", id,
|
"accessErrorID", id,
|
||||||
"permissions", evaluator.GoString(),
|
"permissions", evaluator.GoString(),
|
||||||
)
|
)
|
||||||
|
@ -70,12 +70,10 @@ func (s *Service) SignIdentity(ctx context.Context, id identity.Requester) (stri
|
|||||||
idClaims *auth.IDClaims
|
idClaims *auth.IDClaims
|
||||||
}
|
}
|
||||||
result, err, _ := s.si.Do(cacheKey, func() (any, error) {
|
result, err, _ := s.si.Do(cacheKey, func() (any, error) {
|
||||||
namespace, identifier := id.GetTypedID()
|
|
||||||
|
|
||||||
cachedToken, err := s.cache.Get(ctx, cacheKey)
|
cachedToken, err := s.cache.Get(ctx, cacheKey)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
s.metrics.tokenSigningFromCacheCounter.Inc()
|
s.metrics.tokenSigningFromCacheCounter.Inc()
|
||||||
s.logger.FromContext(ctx).Debug("Cached token found", "namespace", namespace, "id", identifier)
|
s.logger.FromContext(ctx).Debug("Cached token found", "id", id.GetID())
|
||||||
|
|
||||||
tokenClaims, err := s.extractTokenClaims(string(cachedToken))
|
tokenClaims, err := s.extractTokenClaims(string(cachedToken))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -85,14 +83,14 @@ func (s *Service) SignIdentity(ctx context.Context, id identity.Requester) (stri
|
|||||||
}
|
}
|
||||||
|
|
||||||
s.metrics.tokenSigningCounter.Inc()
|
s.metrics.tokenSigningCounter.Inc()
|
||||||
s.logger.FromContext(ctx).Debug("Sign new id token", "namespace", namespace, "id", identifier)
|
s.logger.FromContext(ctx).Debug("Sign new id token", "id", id.GetID())
|
||||||
|
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
claims := &auth.IDClaims{
|
claims := &auth.IDClaims{
|
||||||
Claims: &jwt.Claims{
|
Claims: &jwt.Claims{
|
||||||
Issuer: s.cfg.AppURL,
|
Issuer: s.cfg.AppURL,
|
||||||
Audience: getAudience(id.GetOrgID()),
|
Audience: getAudience(id.GetOrgID()),
|
||||||
Subject: getSubject(namespace.String(), identifier),
|
Subject: id.GetID().String(),
|
||||||
Expiry: jwt.NewNumericDate(now.Add(tokenTTL)),
|
Expiry: jwt.NewNumericDate(now.Add(tokenTTL)),
|
||||||
IssuedAt: jwt.NewNumericDate(now),
|
IssuedAt: jwt.NewNumericDate(now),
|
||||||
},
|
},
|
||||||
@ -101,7 +99,7 @@ func (s *Service) SignIdentity(ctx context.Context, id identity.Requester) (stri
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
if identity.IsIdentityType(namespace, identity.TypeUser) {
|
if identity.IsIdentityType(id.GetID(), identity.TypeUser) {
|
||||||
claims.Rest.Email = id.GetEmail()
|
claims.Rest.Email = id.GetEmail()
|
||||||
claims.Rest.EmailVerified = id.IsEmailVerified()
|
claims.Rest.EmailVerified = id.IsEmailVerified()
|
||||||
claims.Rest.AuthenticatedBy = id.GetAuthenticatedBy()
|
claims.Rest.AuthenticatedBy = id.GetAuthenticatedBy()
|
||||||
@ -145,8 +143,7 @@ func (s *Service) hook(ctx context.Context, identity *authn.Identity, _ *authn.R
|
|||||||
token, claims, err := s.SignIdentity(ctx, identity)
|
token, claims, err := s.SignIdentity(ctx, identity)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if shouldLogErr(err) {
|
if shouldLogErr(err) {
|
||||||
namespace, id := identity.GetTypedID()
|
s.logger.FromContext(ctx).Error("Failed to sign id token", "err", err, "id", identity.GetID())
|
||||||
s.logger.FromContext(ctx).Error("Failed to sign id token", "err", err, "namespace", namespace, "id", id)
|
|
||||||
}
|
}
|
||||||
// for now don't return error so we don't break authentication from this hook
|
// for now don't return error so we don't break authentication from this hook
|
||||||
return nil
|
return nil
|
||||||
@ -179,10 +176,6 @@ func getAudience(orgID int64) jwt.Audience {
|
|||||||
return jwt.Audience{fmt.Sprintf("org:%d", orgID)}
|
return jwt.Audience{fmt.Sprintf("org:%d", orgID)}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getSubject(namespace, identifier string) string {
|
|
||||||
return fmt.Sprintf("%s:%s", namespace, identifier)
|
|
||||||
}
|
|
||||||
|
|
||||||
func prefixCacheKey(key string) string {
|
func prefixCacheKey(key string) string {
|
||||||
return fmt.Sprintf("%s-%s", cachePrefix, key)
|
return fmt.Sprintf("%s-%s", cachePrefix, key)
|
||||||
}
|
}
|
||||||
|
@ -248,10 +248,9 @@ func (c *OAuth) RedirectURL(ctx context.Context, r *authn.Request) (*authn.Redir
|
|||||||
func (c *OAuth) Logout(ctx context.Context, user identity.Requester) (*authn.Redirect, bool) {
|
func (c *OAuth) Logout(ctx context.Context, user identity.Requester) (*authn.Redirect, bool) {
|
||||||
token := c.oauthService.GetCurrentOAuthToken(ctx, user)
|
token := c.oauthService.GetCurrentOAuthToken(ctx, user)
|
||||||
|
|
||||||
namespace, id := user.GetTypedID()
|
userID, err := identity.UserIdentifier(user.GetID())
|
||||||
userID, err := identity.UserIdentifier(namespace, id)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.log.FromContext(ctx).Error("Failed to parse user id", "namespace", namespace, "id", id, "error", err)
|
c.log.FromContext(ctx).Error("Failed to parse user id", "id", user.GetID(), "error", err)
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -260,8 +259,7 @@ func (c *OAuth) Logout(ctx context.Context, user identity.Requester) (*authn.Red
|
|||||||
AuthId: user.GetAuthID(),
|
AuthId: user.GetAuthID(),
|
||||||
AuthModule: user.GetAuthenticatedBy(),
|
AuthModule: user.GetAuthenticatedBy(),
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
namespace, id := user.GetTypedID()
|
c.log.FromContext(ctx).Error("Failed to invalidate tokens", "id", user.GetID(), "error", err)
|
||||||
c.log.FromContext(ctx).Error("Failed to invalidate tokens", "namespace", namespace, "id", id, "error", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
oauthCfg := c.socialService.GetOAuthInfoProvider(c.providerName)
|
oauthCfg := c.socialService.GetOAuthInfoProvider(c.providerName)
|
||||||
|
@ -485,7 +485,7 @@ func TestOAuth_Logout(t *testing.T) {
|
|||||||
}
|
}
|
||||||
c := ProvideOAuth(authn.ClientWithPrefix("azuread"), tt.cfg, mockService, fakeSocialSvc, &setting.OSSImpl{Cfg: tt.cfg}, featuremgmt.WithFeatures())
|
c := ProvideOAuth(authn.ClientWithPrefix("azuread"), tt.cfg, mockService, fakeSocialSvc, &setting.OSSImpl{Cfg: tt.cfg}, featuremgmt.WithFeatures())
|
||||||
|
|
||||||
redirect, ok := c.Logout(context.Background(), &authn.Identity{})
|
redirect, ok := c.Logout(context.Background(), &authn.Identity{ID: identity.NewTypedIDString(identity.TypeUser, "1")})
|
||||||
|
|
||||||
assert.Equal(t, tt.expectedOK, ok)
|
assert.Equal(t, tt.expectedOK, ok)
|
||||||
if tt.expectedOK {
|
if tt.expectedOK {
|
||||||
|
@ -115,10 +115,6 @@ func (i *Identity) GetID() identity.TypedID {
|
|||||||
return i.ID
|
return i.ID
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Identity) GetTypedID() (namespace identity.IdentityType, identifier string) {
|
|
||||||
return i.ID.Type(), i.ID.ID()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i *Identity) GetUID() string {
|
func (i *Identity) GetUID() string {
|
||||||
return i.UID.String()
|
return i.UID.String()
|
||||||
}
|
}
|
||||||
@ -132,14 +128,14 @@ func (i *Identity) GetAuthenticatedBy() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (i *Identity) GetCacheKey() string {
|
func (i *Identity) GetCacheKey() string {
|
||||||
namespace, id := i.GetTypedID()
|
id := i.GetID().ID()
|
||||||
if !i.HasUniqueId() {
|
if !i.HasUniqueId() {
|
||||||
// Hack use the org role as id for identities that do not have a unique id
|
// Hack use the org role as id for identities that do not have a unique id
|
||||||
// e.g. anonymous and render key.
|
// e.g. anonymous and render key.
|
||||||
id = string(i.GetOrgRole())
|
id = string(i.GetOrgRole())
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Sprintf("%d-%s-%s", i.GetOrgID(), namespace, id)
|
return fmt.Sprintf("%d-%s-%s", i.GetOrgID(), i.GetID().Type(), id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Identity) GetDisplayName() string {
|
func (i *Identity) GetDisplayName() string {
|
||||||
@ -232,10 +228,10 @@ func (i *Identity) HasRole(role org.RoleType) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (i *Identity) HasUniqueId() bool {
|
func (i *Identity) HasUniqueId() bool {
|
||||||
namespace, _ := i.GetTypedID()
|
typ := i.GetID().Type()
|
||||||
return namespace == identity.TypeUser ||
|
return typ == identity.TypeUser ||
|
||||||
namespace == identity.TypeServiceAccount ||
|
typ == identity.TypeServiceAccount ||
|
||||||
namespace == identity.TypeAPIKey
|
typ == identity.TypeAPIKey
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Identity) IsAuthenticatedBy(providers ...string) bool {
|
func (i *Identity) IsAuthenticatedBy(providers ...string) bool {
|
||||||
|
@ -154,22 +154,22 @@ func (h *ContextHandler) addIDHeaderEndOfRequestFunc(ident identity.Requester) w
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace, id := ident.GetTypedID()
|
id := ident.GetID()
|
||||||
if !identity.IsIdentityType(
|
if !identity.IsIdentityType(
|
||||||
namespace,
|
id,
|
||||||
identity.TypeUser,
|
identity.TypeUser,
|
||||||
identity.TypeServiceAccount,
|
identity.TypeServiceAccount,
|
||||||
identity.TypeAPIKey,
|
identity.TypeAPIKey,
|
||||||
) || id == "0" {
|
) || id.ID() == "0" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := h.Cfg.IDResponseHeaderNamespaces[namespace.String()]; !ok {
|
if _, ok := h.Cfg.IDResponseHeaderNamespaces[id.Type().String()]; !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
headerName := fmt.Sprintf("%s-Identity-Id", h.Cfg.IDResponseHeaderPrefix)
|
headerName := fmt.Sprintf("%s-Identity-Id", h.Cfg.IDResponseHeaderPrefix)
|
||||||
w.Header().Add(headerName, fmt.Sprintf("%s:%s", namespace, id))
|
w.Header().Add(headerName, id.String())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,11 +109,9 @@ func (s *ImportDashboardService) ImportDashboard(ctx context.Context, req *dashb
|
|||||||
req.FolderUid = folder.UID
|
req.FolderUid = folder.UID
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace, identifier := req.User.GetTypedID()
|
var userID int64
|
||||||
userID := int64(0)
|
if id, err := identity.UserIdentifier(req.User.GetID()); err == nil {
|
||||||
|
userID = id
|
||||||
if namespace == identity.TypeUser || namespace == identity.TypeServiceAccount {
|
|
||||||
userID, _ = identity.IntIdentifier(namespace, identifier)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
saveCmd := dashboards.SaveDashboardCommand{
|
saveCmd := dashboards.SaveDashboardCommand{
|
||||||
|
@ -83,7 +83,7 @@ func TestImportDashboardService(t *testing.T) {
|
|||||||
require.NotNil(t, resp)
|
require.NotNil(t, resp)
|
||||||
require.Equal(t, "UDdpyzz7z", resp.UID)
|
require.Equal(t, "UDdpyzz7z", resp.UID)
|
||||||
|
|
||||||
userID, err := identity.IntIdentifier(importDashboardArg.User.GetTypedID())
|
userID, err := identity.IntIdentifier(importDashboardArg.User.GetID())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
require.NotNil(t, importDashboardArg)
|
require.NotNil(t, importDashboardArg)
|
||||||
@ -149,7 +149,7 @@ func TestImportDashboardService(t *testing.T) {
|
|||||||
require.NotNil(t, resp)
|
require.NotNil(t, resp)
|
||||||
require.Equal(t, "UDdpyzz7z", resp.UID)
|
require.Equal(t, "UDdpyzz7z", resp.UID)
|
||||||
|
|
||||||
userID, err := identity.IntIdentifier(importDashboardArg.User.GetTypedID())
|
userID, err := identity.IntIdentifier(importDashboardArg.User.GetID())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
require.NotNil(t, importDashboardArg)
|
require.NotNil(t, importDashboardArg)
|
||||||
|
@ -207,9 +207,11 @@ func (dr *DashboardServiceImpl) BuildSaveDashboardCommand(ctx context.Context, d
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
userID, err := resolveUserID(dto.User, dr.log)
|
var userID int64
|
||||||
if err != nil {
|
if id, err := identity.UserIdentifier(dto.User.GetID()); err == nil {
|
||||||
return nil, err
|
userID = id
|
||||||
|
} else {
|
||||||
|
dr.log.Debug("User does not belong to a user or service account namespace, using 0 as user ID", "id", dto.User.GetID())
|
||||||
}
|
}
|
||||||
|
|
||||||
metrics.MFolderIDsServiceCount.WithLabelValues(metrics.Dashboard).Inc()
|
metrics.MFolderIDsServiceCount.WithLabelValues(metrics.Dashboard).Inc()
|
||||||
@ -232,22 +234,6 @@ func (dr *DashboardServiceImpl) BuildSaveDashboardCommand(ctx context.Context, d
|
|||||||
return cmd, nil
|
return cmd, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func resolveUserID(user identity.Requester, log log.Logger) (int64, error) {
|
|
||||||
userID := int64(0)
|
|
||||||
namespaceID, identifier := user.GetTypedID()
|
|
||||||
if namespaceID != identity.TypeUser && namespaceID != identity.TypeServiceAccount {
|
|
||||||
log.Debug("User does not belong to a user or service account namespace", "namespaceID", namespaceID, "userID", identifier)
|
|
||||||
} else {
|
|
||||||
var err error
|
|
||||||
userID, err = identity.IntIdentifier(namespaceID, identifier)
|
|
||||||
if err != nil {
|
|
||||||
log.Debug("failed to parse user ID", "namespaceID", namespaceID, "userID", identifier, "error", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return userID, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (dr *DashboardServiceImpl) DeleteOrphanedProvisionedDashboards(ctx context.Context, cmd *dashboards.DeleteOrphanedProvisionedDashboardsCommand) error {
|
func (dr *DashboardServiceImpl) DeleteOrphanedProvisionedDashboards(ctx context.Context, cmd *dashboards.DeleteOrphanedProvisionedDashboardsCommand) error {
|
||||||
return dr.dashboardStore.DeleteOrphanedProvisionedDashboards(ctx, cmd)
|
return dr.dashboardStore.DeleteOrphanedProvisionedDashboards(ctx, cmd)
|
||||||
}
|
}
|
||||||
@ -503,12 +489,10 @@ func (dr *DashboardServiceImpl) setDefaultPermissions(ctx context.Context, dto *
|
|||||||
var permissions []accesscontrol.SetResourcePermissionCommand
|
var permissions []accesscontrol.SetResourcePermissionCommand
|
||||||
|
|
||||||
if !provisioned {
|
if !provisioned {
|
||||||
namespaceID, userIDstr := dto.User.GetTypedID()
|
userID, err := identity.IntIdentifier(dto.User.GetID())
|
||||||
userID, err := identity.IntIdentifier(namespaceID, userIDstr)
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
dr.log.Error("Could not make user admin", "dashboard", dash.Title, "namespaceID", namespaceID, "userID", userID, "error", err)
|
dr.log.Error("Could not make user admin", "dashboard", dash.Title, "id", dto.User.GetID(), "error", err)
|
||||||
} else if namespaceID == identity.TypeUser && userID > 0 {
|
} else if identity.IsIdentityType(dto.User.GetID(), identity.TypeUser) {
|
||||||
permissions = append(permissions, accesscontrol.SetResourcePermissionCommand{
|
permissions = append(permissions, accesscontrol.SetResourcePermissionCommand{
|
||||||
UserID: userID, Permission: dashboardaccess.PERMISSION_ADMIN.String(),
|
UserID: userID, Permission: dashboardaccess.PERMISSION_ADMIN.String(),
|
||||||
})
|
})
|
||||||
@ -541,12 +525,10 @@ func (dr *DashboardServiceImpl) setDefaultFolderPermissions(ctx context.Context,
|
|||||||
var permissions []accesscontrol.SetResourcePermissionCommand
|
var permissions []accesscontrol.SetResourcePermissionCommand
|
||||||
|
|
||||||
if !provisioned {
|
if !provisioned {
|
||||||
namespaceID, userIDstr := cmd.SignedInUser.GetTypedID()
|
userID, err := identity.IntIdentifier(cmd.SignedInUser.GetID())
|
||||||
userID, err := identity.IntIdentifier(namespaceID, userIDstr)
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
dr.log.Error("Could not make user admin", "folder", cmd.Title, "namespaceID", namespaceID, "userID", userID, "error", err)
|
dr.log.Error("Could not make user admin", "folder", cmd.Title, "id", cmd.SignedInUser.GetID())
|
||||||
} else if namespaceID == identity.TypeUser && userID > 0 {
|
} else if identity.IsIdentityType(cmd.SignedInUser.GetID(), identity.TypeUser) {
|
||||||
permissions = append(permissions, accesscontrol.SetResourcePermissionCommand{
|
permissions = append(permissions, accesscontrol.SetResourcePermissionCommand{
|
||||||
UserID: userID, Permission: dashboardaccess.PERMISSION_ADMIN.String(),
|
UserID: userID, Permission: dashboardaccess.PERMISSION_ADMIN.String(),
|
||||||
})
|
})
|
||||||
|
@ -116,7 +116,7 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) {
|
|||||||
err := callSaveWithError(t, cmd, sqlStore)
|
err := callSaveWithError(t, cmd, sqlStore)
|
||||||
assert.Equal(t, dashboards.ErrDashboardUpdateAccessDenied, err)
|
assert.Equal(t, dashboards.ErrDashboardUpdateAccessDenied, err)
|
||||||
|
|
||||||
userID, err := identity.IntIdentifier(sc.dashboardGuardianMock.User.GetTypedID())
|
userID, err := identity.IntIdentifier(sc.dashboardGuardianMock.User.GetID())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
assert.Equal(t, "", sc.dashboardGuardianMock.DashUID)
|
assert.Equal(t, "", sc.dashboardGuardianMock.DashUID)
|
||||||
@ -139,7 +139,7 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) {
|
|||||||
err := callSaveWithError(t, cmd, sc.sqlStore)
|
err := callSaveWithError(t, cmd, sc.sqlStore)
|
||||||
require.Equal(t, dashboards.ErrDashboardUpdateAccessDenied, err)
|
require.Equal(t, dashboards.ErrDashboardUpdateAccessDenied, err)
|
||||||
|
|
||||||
userID, err := identity.IntIdentifier(sc.dashboardGuardianMock.User.GetTypedID())
|
userID, err := identity.IntIdentifier(sc.dashboardGuardianMock.User.GetID())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
assert.Equal(t, sc.otherSavedFolder.ID, sc.dashboardGuardianMock.DashID)
|
assert.Equal(t, sc.otherSavedFolder.ID, sc.dashboardGuardianMock.DashID)
|
||||||
@ -162,7 +162,7 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) {
|
|||||||
err := callSaveWithError(t, cmd, sc.sqlStore)
|
err := callSaveWithError(t, cmd, sc.sqlStore)
|
||||||
require.Equal(t, dashboards.ErrDashboardUpdateAccessDenied, err)
|
require.Equal(t, dashboards.ErrDashboardUpdateAccessDenied, err)
|
||||||
|
|
||||||
userID, err := identity.IntIdentifier(sc.dashboardGuardianMock.User.GetTypedID())
|
userID, err := identity.IntIdentifier(sc.dashboardGuardianMock.User.GetID())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
assert.Equal(t, sc.savedDashInFolder.UID, sc.dashboardGuardianMock.DashUID)
|
assert.Equal(t, sc.savedDashInFolder.UID, sc.dashboardGuardianMock.DashUID)
|
||||||
@ -186,7 +186,7 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) {
|
|||||||
err := callSaveWithError(t, cmd, sc.sqlStore)
|
err := callSaveWithError(t, cmd, sc.sqlStore)
|
||||||
require.Equal(t, dashboards.ErrDashboardUpdateAccessDenied, err)
|
require.Equal(t, dashboards.ErrDashboardUpdateAccessDenied, err)
|
||||||
|
|
||||||
userID, err := identity.IntIdentifier(sc.dashboardGuardianMock.User.GetTypedID())
|
userID, err := identity.IntIdentifier(sc.dashboardGuardianMock.User.GetID())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
assert.Equal(t, sc.savedDashInFolder.UID, sc.dashboardGuardianMock.DashUID)
|
assert.Equal(t, sc.savedDashInFolder.UID, sc.dashboardGuardianMock.DashUID)
|
||||||
@ -210,7 +210,7 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) {
|
|||||||
err := callSaveWithError(t, cmd, sc.sqlStore)
|
err := callSaveWithError(t, cmd, sc.sqlStore)
|
||||||
assert.Equal(t, dashboards.ErrDashboardUpdateAccessDenied, err)
|
assert.Equal(t, dashboards.ErrDashboardUpdateAccessDenied, err)
|
||||||
|
|
||||||
userID, err := identity.IntIdentifier(sc.dashboardGuardianMock.User.GetTypedID())
|
userID, err := identity.IntIdentifier(sc.dashboardGuardianMock.User.GetID())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
assert.Equal(t, sc.savedDashInGeneralFolder.UID, sc.dashboardGuardianMock.DashUID)
|
assert.Equal(t, sc.savedDashInGeneralFolder.UID, sc.dashboardGuardianMock.DashUID)
|
||||||
@ -234,7 +234,7 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) {
|
|||||||
err := callSaveWithError(t, cmd, sc.sqlStore)
|
err := callSaveWithError(t, cmd, sc.sqlStore)
|
||||||
require.Equal(t, dashboards.ErrDashboardUpdateAccessDenied, err)
|
require.Equal(t, dashboards.ErrDashboardUpdateAccessDenied, err)
|
||||||
|
|
||||||
userID, err := identity.IntIdentifier(sc.dashboardGuardianMock.User.GetTypedID())
|
userID, err := identity.IntIdentifier(sc.dashboardGuardianMock.User.GetID())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
assert.Equal(t, sc.savedDashInFolder.UID, sc.dashboardGuardianMock.DashUID)
|
assert.Equal(t, sc.savedDashInFolder.UID, sc.dashboardGuardianMock.DashUID)
|
||||||
@ -258,7 +258,7 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) {
|
|||||||
err := callSaveWithError(t, cmd, sc.sqlStore)
|
err := callSaveWithError(t, cmd, sc.sqlStore)
|
||||||
require.Equal(t, dashboards.ErrDashboardUpdateAccessDenied, err)
|
require.Equal(t, dashboards.ErrDashboardUpdateAccessDenied, err)
|
||||||
|
|
||||||
userID, err := identity.IntIdentifier(sc.dashboardGuardianMock.User.GetTypedID())
|
userID, err := identity.IntIdentifier(sc.dashboardGuardianMock.User.GetID())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
assert.Equal(t, sc.savedDashInGeneralFolder.UID, sc.dashboardGuardianMock.DashUID)
|
assert.Equal(t, sc.savedDashInGeneralFolder.UID, sc.dashboardGuardianMock.DashUID)
|
||||||
@ -282,7 +282,7 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) {
|
|||||||
err := callSaveWithError(t, cmd, sc.sqlStore)
|
err := callSaveWithError(t, cmd, sc.sqlStore)
|
||||||
assert.Equal(t, dashboards.ErrDashboardUpdateAccessDenied, err)
|
assert.Equal(t, dashboards.ErrDashboardUpdateAccessDenied, err)
|
||||||
|
|
||||||
userID, err := identity.IntIdentifier(sc.dashboardGuardianMock.User.GetTypedID())
|
userID, err := identity.IntIdentifier(sc.dashboardGuardianMock.User.GetID())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
assert.Equal(t, sc.savedDashInFolder.UID, sc.dashboardGuardianMock.DashUID)
|
assert.Equal(t, sc.savedDashInFolder.UID, sc.dashboardGuardianMock.DashUID)
|
||||||
@ -306,7 +306,7 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) {
|
|||||||
err := callSaveWithError(t, cmd, sc.sqlStore)
|
err := callSaveWithError(t, cmd, sc.sqlStore)
|
||||||
require.Equal(t, dashboards.ErrDashboardUpdateAccessDenied, err)
|
require.Equal(t, dashboards.ErrDashboardUpdateAccessDenied, err)
|
||||||
|
|
||||||
userID, err := identity.IntIdentifier(sc.dashboardGuardianMock.User.GetTypedID())
|
userID, err := identity.IntIdentifier(sc.dashboardGuardianMock.User.GetID())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
assert.Equal(t, sc.savedDashInGeneralFolder.UID, sc.dashboardGuardianMock.DashUID)
|
assert.Equal(t, sc.savedDashInGeneralFolder.UID, sc.dashboardGuardianMock.DashUID)
|
||||||
@ -330,7 +330,7 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) {
|
|||||||
err := callSaveWithError(t, cmd, sc.sqlStore)
|
err := callSaveWithError(t, cmd, sc.sqlStore)
|
||||||
require.Equal(t, dashboards.ErrDashboardUpdateAccessDenied, err)
|
require.Equal(t, dashboards.ErrDashboardUpdateAccessDenied, err)
|
||||||
|
|
||||||
userID, err := identity.IntIdentifier(sc.dashboardGuardianMock.User.GetTypedID())
|
userID, err := identity.IntIdentifier(sc.dashboardGuardianMock.User.GetID())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
assert.Equal(t, sc.savedDashInFolder.UID, sc.dashboardGuardianMock.DashUID)
|
assert.Equal(t, sc.savedDashInFolder.UID, sc.dashboardGuardianMock.DashUID)
|
||||||
|
@ -122,12 +122,10 @@ func (d *DashboardSnapshotStore) SearchDashboardSnapshots(ctx context.Context, q
|
|||||||
sess.Where("name LIKE ?", query.Name)
|
sess.Where("name LIKE ?", query.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace, id := query.SignedInUser.GetTypedID()
|
|
||||||
var userID int64
|
var userID int64
|
||||||
|
if identity.IsIdentityType(query.SignedInUser.GetID(), identity.TypeUser, identity.TypeServiceAccount) {
|
||||||
if namespace == identity.TypeServiceAccount || namespace == identity.TypeUser {
|
|
||||||
var err error
|
var err error
|
||||||
userID, err = identity.IntIdentifier(namespace, id)
|
userID, err = identity.UserIdentifier(query.SignedInUser.GetID())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -137,7 +135,7 @@ func (d *DashboardSnapshotStore) SearchDashboardSnapshots(ctx context.Context, q
|
|||||||
switch {
|
switch {
|
||||||
case query.SignedInUser.GetOrgRole() == org.RoleAdmin:
|
case query.SignedInUser.GetOrgRole() == org.RoleAdmin:
|
||||||
sess.Where("org_id = ?", query.SignedInUser.GetOrgID())
|
sess.Where("org_id = ?", query.SignedInUser.GetOrgID())
|
||||||
case namespace != identity.TypeAnonymous:
|
case userID != 0:
|
||||||
sess.Where("org_id = ? AND user_id = ?", query.OrgID, userID)
|
sess.Where("org_id = ? AND user_id = ?", query.OrgID, userID)
|
||||||
default:
|
default:
|
||||||
queryResult = snapshots
|
queryResult = snapshots
|
||||||
|
@ -63,17 +63,10 @@ func CreateDashboardSnapshot(c *contextmodel.ReqContext, cfg dashboardsnapshot.S
|
|||||||
cmd.DashboardCreateCommand.Name = "Unnamed snapshot"
|
cmd.DashboardCreateCommand.Name = "Unnamed snapshot"
|
||||||
}
|
}
|
||||||
|
|
||||||
userID, err := identity.UserIdentifier(user.GetTypedID())
|
|
||||||
if err != nil {
|
|
||||||
c.JsonApiErr(http.StatusInternalServerError,
|
|
||||||
"Failed to create external snapshot", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var snapshotUrl string
|
var snapshotUrl string
|
||||||
cmd.ExternalURL = ""
|
cmd.ExternalURL = ""
|
||||||
cmd.OrgID = user.GetOrgID()
|
cmd.OrgID = user.GetOrgID()
|
||||||
cmd.UserID = userID
|
cmd.UserID, _ = identity.UserIdentifier(user.GetID())
|
||||||
originalDashboardURL, err := createOriginalDashboardURL(&cmd)
|
originalDashboardURL, err := createOriginalDashboardURL(&cmd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JsonApiErr(http.StatusInternalServerError, "Invalid app URL", err)
|
c.JsonApiErr(http.StatusInternalServerError, "Invalid app URL", err)
|
||||||
|
@ -592,21 +592,17 @@ func (s *Service) Create(ctx context.Context, cmd *folder.CreateFolderCommand) (
|
|||||||
|
|
||||||
user := cmd.SignedInUser
|
user := cmd.SignedInUser
|
||||||
|
|
||||||
userID := int64(0)
|
var userID int64
|
||||||
var err error
|
if id, err := identity.UserIdentifier(cmd.SignedInUser.GetID()); err == nil {
|
||||||
namespaceID, userIDstr := user.GetTypedID()
|
userID = id
|
||||||
if namespaceID != identity.TypeUser && namespaceID != identity.TypeServiceAccount {
|
|
||||||
s.log.Debug("User does not belong to a user or service account namespace, using 0 as user ID", "namespaceID", namespaceID, "userID", userIDstr)
|
|
||||||
} else {
|
} else {
|
||||||
userID, err = identity.IntIdentifier(namespaceID, userIDstr)
|
s.log.Warn("User does not belong to a user or service account namespace, using 0 as user ID", "id", cmd.SignedInUser.GetID())
|
||||||
if err != nil {
|
|
||||||
s.log.Debug("failed to parse user ID", "namespaceID", namespaceID, "userID", userIDstr, "error", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if userID == 0 {
|
if userID == 0 {
|
||||||
userID = -1
|
userID = -1
|
||||||
}
|
}
|
||||||
|
|
||||||
dashFolder.CreatedBy = userID
|
dashFolder.CreatedBy = userID
|
||||||
dashFolder.UpdatedBy = userID
|
dashFolder.UpdatedBy = userID
|
||||||
dashFolder.UpdateSlug()
|
dashFolder.UpdateSlug()
|
||||||
@ -682,8 +678,6 @@ func (s *Service) Update(ctx context.Context, cmd *folder.UpdateFolderCommand) (
|
|||||||
}
|
}
|
||||||
|
|
||||||
if cmd.NewTitle != nil {
|
if cmd.NewTitle != nil {
|
||||||
namespace, id := cmd.SignedInUser.GetTypedID()
|
|
||||||
|
|
||||||
metrics.MFolderIDsServiceCount.WithLabelValues(metrics.Folder).Inc()
|
metrics.MFolderIDsServiceCount.WithLabelValues(metrics.Folder).Inc()
|
||||||
if err := s.bus.Publish(ctx, &events.FolderTitleUpdated{
|
if err := s.bus.Publish(ctx, &events.FolderTitleUpdated{
|
||||||
Timestamp: foldr.Updated,
|
Timestamp: foldr.Updated,
|
||||||
@ -692,7 +686,7 @@ func (s *Service) Update(ctx context.Context, cmd *folder.UpdateFolderCommand) (
|
|||||||
UID: dashFolder.UID,
|
UID: dashFolder.UID,
|
||||||
OrgID: cmd.OrgID,
|
OrgID: cmd.OrgID,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
s.log.ErrorContext(ctx, "failed to publish FolderTitleUpdated event", "folder", foldr.Title, "user", id, "namespace", namespace, "error", err)
|
s.log.ErrorContext(ctx, "failed to publish FolderTitleUpdated event", "folder", foldr.Title, "user", cmd.SignedInUser.GetID(), "error", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -739,12 +733,10 @@ func (s *Service) legacyUpdate(ctx context.Context, cmd *folder.UpdateFolderComm
|
|||||||
}
|
}
|
||||||
|
|
||||||
var userID int64
|
var userID int64
|
||||||
namespace, id := cmd.SignedInUser.GetTypedID()
|
if id, err := identity.UserIdentifier(cmd.SignedInUser.GetID()); err == nil {
|
||||||
if namespace == identity.TypeUser || namespace == identity.TypeServiceAccount {
|
userID = id
|
||||||
userID, err = identity.IntIdentifier(namespace, id)
|
} else {
|
||||||
if err != nil {
|
s.log.Warn("User does not belong to a user or service account namespace, using 0 as user ID", "id", cmd.SignedInUser.GetID())
|
||||||
s.log.ErrorContext(ctx, "failed to parse user ID", "namespace", namespace, "userID", id, "error", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
prepareForUpdate(dashFolder, cmd.OrgID, userID, cmd)
|
prepareForUpdate(dashFolder, cmd.OrgID, userID, cmd)
|
||||||
@ -1163,15 +1155,11 @@ func (s *Service) buildSaveDashboardCommand(ctx context.Context, dto *dashboards
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
userID := int64(0)
|
var userID int64
|
||||||
namespaceID, userIDstr := dto.User.GetTypedID()
|
if id, err := identity.UserIdentifier(dto.User.GetID()); err == nil {
|
||||||
if namespaceID != identity.TypeUser && namespaceID != identity.TypeServiceAccount {
|
userID = id
|
||||||
s.log.Warn("User does not belong to a user or service account namespace, using 0 as user ID", "namespaceID", namespaceID, "userID", userIDstr)
|
|
||||||
} else {
|
} else {
|
||||||
userID, err = identity.IntIdentifier(namespaceID, userIDstr)
|
s.log.Warn("User does not belong to a user or service account namespace, using 0 as user ID", "id", dto.User.GetID())
|
||||||
if err != nil {
|
|
||||||
s.log.Warn("failed to parse user ID", "namespaceID", namespaceID, "userID", userIDstr, "error", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
metrics.MFolderIDsServiceCount.WithLabelValues(metrics.Folder).Inc()
|
metrics.MFolderIDsServiceCount.WithLabelValues(metrics.Folder).Inc()
|
||||||
|
@ -309,13 +309,12 @@ func (a *accessControlFolderGuardian) CanCreate(folderID int64, isFolder bool) (
|
|||||||
|
|
||||||
func (a *accessControlDashboardGuardian) evaluate(evaluator accesscontrol.Evaluator) (bool, error) {
|
func (a *accessControlDashboardGuardian) evaluate(evaluator accesscontrol.Evaluator) (bool, error) {
|
||||||
ok, err := a.ac.Evaluate(a.ctx, a.user, evaluator)
|
ok, err := a.ac.Evaluate(a.ctx, a.user, evaluator)
|
||||||
namespaceID, userID := a.user.GetTypedID()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
id := 0
|
id := 0
|
||||||
if a.dashboard != nil {
|
if a.dashboard != nil {
|
||||||
id = int(a.dashboard.ID)
|
id = int(a.dashboard.ID)
|
||||||
}
|
}
|
||||||
a.log.Debug("Failed to evaluate access control to dashboard", "error", err, "namespaceID", namespaceID, "userId", userID, "id", id)
|
a.log.Debug("Failed to evaluate access control to dashboard", "error", err, "identity", a.user.GetID(), "id", id)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ok && err == nil {
|
if !ok && err == nil {
|
||||||
@ -323,7 +322,7 @@ func (a *accessControlDashboardGuardian) evaluate(evaluator accesscontrol.Evalua
|
|||||||
if a.dashboard != nil {
|
if a.dashboard != nil {
|
||||||
id = int(a.dashboard.ID)
|
id = int(a.dashboard.ID)
|
||||||
}
|
}
|
||||||
a.log.Debug("Access denied to dashboard", "namespaceID", namespaceID, "userId", userID, "id", id, "permissions", evaluator.GoString())
|
a.log.Debug("Access denied to dashboard", "identity", a.user.GetID(), "id", id, "permissions", evaluator.GoString())
|
||||||
}
|
}
|
||||||
|
|
||||||
return ok, err
|
return ok, err
|
||||||
@ -331,7 +330,6 @@ func (a *accessControlDashboardGuardian) evaluate(evaluator accesscontrol.Evalua
|
|||||||
|
|
||||||
func (a *accessControlFolderGuardian) evaluate(evaluator accesscontrol.Evaluator) (bool, error) {
|
func (a *accessControlFolderGuardian) evaluate(evaluator accesscontrol.Evaluator) (bool, error) {
|
||||||
ok, err := a.ac.Evaluate(a.ctx, a.user, evaluator)
|
ok, err := a.ac.Evaluate(a.ctx, a.user, evaluator)
|
||||||
namespaceID, userID := a.user.GetTypedID()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
uid := ""
|
uid := ""
|
||||||
orgID := 0
|
orgID := 0
|
||||||
@ -339,7 +337,7 @@ func (a *accessControlFolderGuardian) evaluate(evaluator accesscontrol.Evaluator
|
|||||||
uid = a.folder.UID
|
uid = a.folder.UID
|
||||||
orgID = int(a.folder.OrgID)
|
orgID = int(a.folder.OrgID)
|
||||||
}
|
}
|
||||||
a.log.Debug("Failed to evaluate access control to folder", "error", err, "namespaceID", namespaceID, "userId", userID, "orgID", orgID, "uid", uid)
|
a.log.Debug("Failed to evaluate access control to folder", "error", err, "identity", a.user.GetID(), "orgID", orgID, "uid", uid)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ok && err == nil {
|
if !ok && err == nil {
|
||||||
@ -349,7 +347,7 @@ func (a *accessControlFolderGuardian) evaluate(evaluator accesscontrol.Evaluator
|
|||||||
uid = a.folder.UID
|
uid = a.folder.UID
|
||||||
orgID = int(a.folder.OrgID)
|
orgID = int(a.folder.OrgID)
|
||||||
}
|
}
|
||||||
a.log.Debug("Access denied to folder", "namespaceID", namespaceID, "userId", userID, "orgID", orgID, "uid", uid, "permissions", evaluator.GoString())
|
a.log.Debug("Access denied to folder", "identity", a.user.GetID(), "identity", a.user.GetID(), "orgID", orgID, "uid", uid, "permissions", evaluator.GoString())
|
||||||
}
|
}
|
||||||
|
|
||||||
return ok, err
|
return ok, err
|
||||||
|
@ -138,13 +138,9 @@ func (l *LibraryElementService) createLibraryElement(c context.Context, signedIn
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
userID := int64(0)
|
var userID int64
|
||||||
namespaceID, identifier := signedInUser.GetTypedID()
|
if id, err := identity.UserIdentifier(signedInUser.GetID()); err == nil {
|
||||||
if namespaceID == identity.TypeUser || namespaceID == identity.TypeServiceAccount {
|
userID = id
|
||||||
userID, err = identity.IntIdentifier(namespaceID, identifier)
|
|
||||||
if err != nil {
|
|
||||||
l.log.Warn("Error while parsing userID", "namespaceID", namespaceID, "userID", identifier)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
metrics.MFolderIDsServiceCount.WithLabelValues(metrics.LibraryElements).Inc()
|
metrics.MFolderIDsServiceCount.WithLabelValues(metrics.LibraryElements).Inc()
|
||||||
@ -593,13 +589,8 @@ func (l *LibraryElementService) patchLibraryElement(c context.Context, signedInU
|
|||||||
}
|
}
|
||||||
|
|
||||||
var userID int64
|
var userID int64
|
||||||
namespaceID, identifier := signedInUser.GetTypedID()
|
if id, err := identity.UserIdentifier(signedInUser.GetID()); err == nil {
|
||||||
if namespaceID == identity.TypeUser || namespaceID == identity.TypeServiceAccount {
|
userID = id
|
||||||
var errID error
|
|
||||||
userID, errID = identity.IntIdentifier(namespaceID, identifier)
|
|
||||||
if errID != nil {
|
|
||||||
l.log.Warn("Error while parsing userID", "namespaceID", namespaceID, "userID", identifier, "err", errID)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
metrics.MFolderIDsServiceCount.WithLabelValues(metrics.LibraryElements).Inc()
|
metrics.MFolderIDsServiceCount.WithLabelValues(metrics.LibraryElements).Inc()
|
||||||
@ -800,13 +791,9 @@ func (l *LibraryElementService) connectElementsToDashboardID(c context.Context,
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
namespaceID, identifier := signedInUser.GetTypedID()
|
var userID int64
|
||||||
userID := int64(0)
|
if id, err := identity.UserIdentifier(signedInUser.GetID()); err == nil {
|
||||||
if namespaceID == identity.TypeUser || namespaceID == identity.TypeServiceAccount {
|
userID = id
|
||||||
userID, err = identity.IntIdentifier(namespaceID, identifier)
|
|
||||||
if err != nil {
|
|
||||||
l.log.Warn("Failed to parse user ID from namespace identifier", "namespace", namespaceID, "identifier", identifier, "error", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
connection := model.LibraryElementConnection{
|
connection := model.LibraryElementConnection{
|
||||||
|
@ -284,11 +284,9 @@ 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
|
||||||
_, identifier := user.GetTypedID()
|
|
||||||
|
|
||||||
// Centrifuge expects Credentials in context with a current user ID.
|
// Centrifuge expects Credentials in context with a current user ID.
|
||||||
cred := ¢rifuge.Credentials{
|
cred := ¢rifuge.Credentials{
|
||||||
UserID: identifier,
|
UserID: user.GetID().ID(),
|
||||||
}
|
}
|
||||||
newCtx := centrifuge.SetCredentials(ctx.Req.Context(), cred)
|
newCtx := centrifuge.SetCredentials(ctx.Req.Context(), cred)
|
||||||
newCtx = livecontext.SetContextSignedUser(newCtx, user)
|
newCtx = livecontext.SetContextSignedUser(newCtx, user)
|
||||||
@ -955,8 +953,7 @@ func (g *GrafanaLive) HandleHTTPPublish(ctx *contextmodel.ReqContext) response.R
|
|||||||
return response.Error(http.StatusBadRequest, "invalid channel ID", nil)
|
return response.Error(http.StatusBadRequest, "invalid channel ID", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
namespaceID, userID := ctx.SignedInUser.GetTypedID()
|
logger.Debug("Publish API cmd", "identity", ctx.SignedInUser.GetID(), "channel", cmd.Channel)
|
||||||
logger.Debug("Publish API cmd", "namespaceID", namespaceID, "userID", userID, "channel", cmd.Channel)
|
|
||||||
user := ctx.SignedInUser
|
user := ctx.SignedInUser
|
||||||
channel := cmd.Channel
|
channel := cmd.Channel
|
||||||
|
|
||||||
@ -1013,7 +1010,7 @@ func (g *GrafanaLive) HandleHTTPPublish(ctx *contextmodel.ReqContext) response.R
|
|||||||
return response.Error(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError), nil)
|
return response.Error(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError), nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
logger.Debug("Publication successful", "namespaceID", namespaceID, "userID", userID, "channel", cmd.Channel)
|
logger.Debug("Publication successful", "identity", ctx.SignedInUser.GetID(), "channel", cmd.Channel)
|
||||||
return response.JSON(http.StatusOK, dtos.LivePublishResponse{})
|
return response.JSON(http.StatusOK, dtos.LivePublishResponse{})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ func TestStreamManager_SubmitStream_Send(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mockContextGetter.EXPECT().GetPluginContext(context.Background(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, user identity.Requester, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error) {
|
mockContextGetter.EXPECT().GetPluginContext(context.Background(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, user identity.Requester, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error) {
|
||||||
userID, err := identity.IntIdentifier(user.GetTypedID())
|
userID, err := identity.IntIdentifier(user.GetID())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, int64(2), userID)
|
require.Equal(t, int64(2), userID)
|
||||||
require.Equal(t, int64(1), user.GetOrgID())
|
require.Equal(t, int64(1), user.GetOrgID())
|
||||||
@ -258,7 +258,7 @@ func TestStreamManager_SubmitStream_ErrorRestartsRunStream(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mockContextGetter.EXPECT().GetPluginContext(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, user identity.Requester, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error) {
|
mockContextGetter.EXPECT().GetPluginContext(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, user identity.Requester, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error) {
|
||||||
userID, err := identity.IntIdentifier(user.GetTypedID())
|
userID, err := identity.IntIdentifier(user.GetID())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, int64(2), userID)
|
require.Equal(t, int64(2), userID)
|
||||||
require.Equal(t, int64(1), user.GetOrgID())
|
require.Equal(t, int64(1), user.GetOrgID())
|
||||||
@ -343,7 +343,7 @@ func TestStreamManager_HandleDatasourceUpdate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mockContextGetter.EXPECT().GetPluginContext(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, user identity.Requester, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error) {
|
mockContextGetter.EXPECT().GetPluginContext(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, user identity.Requester, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error) {
|
||||||
userID, err := identity.IntIdentifier(user.GetTypedID())
|
userID, err := identity.IntIdentifier(user.GetID())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
require.Equal(t, int64(2), userID)
|
require.Equal(t, int64(2), userID)
|
||||||
@ -412,7 +412,7 @@ func TestStreamManager_HandleDatasourceDelete(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mockContextGetter.EXPECT().GetPluginContext(context.Background(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, user identity.Requester, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error) {
|
mockContextGetter.EXPECT().GetPluginContext(context.Background(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, user identity.Requester, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error) {
|
||||||
userID, err := identity.IntIdentifier(user.GetTypedID())
|
userID, err := identity.IntIdentifier(user.GetID())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, int64(2), userID)
|
require.Equal(t, int64(2), userID)
|
||||||
require.Equal(t, int64(1), user.GetOrgID())
|
require.Equal(t, int64(1), user.GetOrgID())
|
||||||
|
@ -297,7 +297,7 @@ func (s *ServiceImpl) getProfileNode(c *contextmodel.ReqContext) *navtree.NavLin
|
|||||||
func (s *ServiceImpl) buildStarredItemsNavLinks(c *contextmodel.ReqContext) ([]*navtree.NavLink, error) {
|
func (s *ServiceImpl) buildStarredItemsNavLinks(c *contextmodel.ReqContext) ([]*navtree.NavLink, error) {
|
||||||
starredItemsChildNavs := []*navtree.NavLink{}
|
starredItemsChildNavs := []*navtree.NavLink{}
|
||||||
|
|
||||||
userID, _ := identity.UserIdentifier(c.SignedInUser.GetTypedID())
|
userID, _ := identity.UserIdentifier(c.SignedInUser.GetID())
|
||||||
query := star.GetUserStarsQuery{
|
query := star.GetUserStarsQuery{
|
||||||
UserID: userID,
|
UserID: userID,
|
||||||
}
|
}
|
||||||
|
@ -76,9 +76,9 @@ func (srv RulerSrv) RouteDeleteAlertRules(c *contextmodel.ReqContext, namespaceU
|
|||||||
return toNamespaceErrorResponse(err)
|
return toNamespaceErrorResponse(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
userNamespace, id := c.SignedInUser.GetTypedID()
|
userNamespace, id := c.SignedInUser.GetID().Type(), c.SignedInUser.GetID().ID()
|
||||||
var loggerCtx = []any{
|
var loggerCtx = []any{
|
||||||
"userId",
|
"identity",
|
||||||
id,
|
id,
|
||||||
"userNamespace",
|
"userNamespace",
|
||||||
userNamespace,
|
userNamespace,
|
||||||
@ -283,7 +283,7 @@ func (srv RulerSrv) RouteGetRulesConfig(c *contextmodel.ReqContext) response.Res
|
|||||||
for groupKey, rules := range configs {
|
for groupKey, rules := range configs {
|
||||||
folder, ok := namespaceMap[groupKey.NamespaceUID]
|
folder, ok := namespaceMap[groupKey.NamespaceUID]
|
||||||
if !ok {
|
if !ok {
|
||||||
userNamespace, id := c.SignedInUser.GetTypedID()
|
userNamespace, id := c.SignedInUser.GetID().Type(), c.SignedInUser.GetID().ID()
|
||||||
srv.log.Error("Namespace not visible to the user", "user", id, "userNamespace", userNamespace, "namespace", groupKey.NamespaceUID)
|
srv.log.Error("Namespace not visible to the user", "user", id, "userNamespace", userNamespace, "namespace", groupKey.NamespaceUID)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -359,7 +359,7 @@ func (srv RulerSrv) updateAlertRulesInGroup(c *contextmodel.ReqContext, groupKey
|
|||||||
var finalChanges *store.GroupDelta
|
var finalChanges *store.GroupDelta
|
||||||
var dbConfig *ngmodels.AlertConfiguration
|
var dbConfig *ngmodels.AlertConfiguration
|
||||||
err := srv.xactManager.InTransaction(c.Req.Context(), func(tranCtx context.Context) error {
|
err := srv.xactManager.InTransaction(c.Req.Context(), func(tranCtx context.Context) error {
|
||||||
userNamespace, id := c.SignedInUser.GetTypedID()
|
userNamespace, id := c.SignedInUser.GetID().Type(), c.SignedInUser.GetID().ID()
|
||||||
logger := srv.log.New("namespace_uid", groupKey.NamespaceUID, "group",
|
logger := srv.log.New("namespace_uid", groupKey.NamespaceUID, "group",
|
||||||
groupKey.RuleGroup, "org_id", groupKey.OrgID, "user_id", id, "userNamespace", userNamespace)
|
groupKey.RuleGroup, "org_id", groupKey.OrgID, "user_id", id, "userNamespace", userNamespace)
|
||||||
groupChanges, err := store.CalculateChanges(tranCtx, srv.store, groupKey, rules)
|
groupChanges, err := store.CalculateChanges(tranCtx, srv.store, groupKey, rules)
|
||||||
@ -454,7 +454,7 @@ func (srv RulerSrv) updateAlertRulesInGroup(c *contextmodel.ReqContext, groupKey
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(finalChanges.New) > 0 {
|
if len(finalChanges.New) > 0 {
|
||||||
userID, _ := identity.UserIdentifier(c.SignedInUser.GetTypedID())
|
userID, _ := identity.UserIdentifier(c.SignedInUser.GetID())
|
||||||
limitReached, err := srv.QuotaService.CheckQuotaReached(tranCtx, ngmodels.QuotaTargetSrv, "a.ScopeParameters{
|
limitReached, err := srv.QuotaService.CheckQuotaReached(tranCtx, ngmodels.QuotaTargetSrv, "a.ScopeParameters{
|
||||||
OrgID: c.SignedInUser.GetOrgID(),
|
OrgID: c.SignedInUser.GetOrgID(),
|
||||||
UserID: userID,
|
UserID: userID,
|
||||||
|
@ -659,12 +659,10 @@ func (service *AlertRuleService) DeleteAlertRule(ctx context.Context, user ident
|
|||||||
// checkLimitsTransactionCtx checks whether the current transaction (as identified by the ctx) breaches configured alert rule limits.
|
// checkLimitsTransactionCtx checks whether the current transaction (as identified by the ctx) breaches configured alert rule limits.
|
||||||
func (service *AlertRuleService) checkLimitsTransactionCtx(ctx context.Context, user identity.Requester) error {
|
func (service *AlertRuleService) checkLimitsTransactionCtx(ctx context.Context, user identity.Requester) error {
|
||||||
// default to 0 if there is no user
|
// default to 0 if there is no user
|
||||||
userID := int64(0)
|
var userID int64
|
||||||
u, err := identity.UserIdentifier(user.GetTypedID())
|
if id, err := identity.UserIdentifier(user.GetID()); err == nil {
|
||||||
if err != nil {
|
userID = id
|
||||||
return fmt.Errorf("failed to check alert rule quota: %w", err)
|
|
||||||
}
|
}
|
||||||
userID = u
|
|
||||||
|
|
||||||
limitReached, err := service.quotas.CheckQuotaReached(ctx, models.QuotaTargetSrv, "a.ScopeParameters{
|
limitReached, err := service.quotas.CheckQuotaReached(ctx, models.QuotaTargetSrv, "a.ScopeParameters{
|
||||||
OrgID: user.GetOrgID(),
|
OrgID: user.GetOrgID(),
|
||||||
|
@ -94,17 +94,14 @@ func (o *Service) HasOAuthEntry(ctx context.Context, usr identity.Requester) (*l
|
|||||||
return nil, false, nil
|
return nil, false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace, id := usr.GetTypedID()
|
if !identity.IsIdentityType(usr.GetID(), identity.TypeUser) {
|
||||||
if namespace != identity.TypeUser {
|
|
||||||
// Not a user, therefore no token.
|
|
||||||
return nil, false, nil
|
return nil, false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
ctxLogger := logger.FromContext(ctx)
|
ctxLogger := logger.FromContext(ctx)
|
||||||
|
userID, err := identity.UserIdentifier(usr.GetID())
|
||||||
userID, err := identity.IntIdentifier(namespace, id)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctxLogger.Error("Failed to convert user id to int", "namespace", namespace, "userID", id, "error", err)
|
ctxLogger.Error("Failed to convert user id to int", "id", usr.GetID(), "error", err)
|
||||||
return nil, false, err
|
return nil, false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,24 +127,22 @@ func (o *Service) HasOAuthEntry(ctx context.Context, usr identity.Requester) (*l
|
|||||||
// TryTokenRefresh returns an error in case the OAuth token refresh was unsuccessful
|
// TryTokenRefresh returns an error in case the OAuth token refresh was unsuccessful
|
||||||
// It uses a singleflight.Group to prevent getting the Refresh Token multiple times for a given User
|
// It uses a singleflight.Group to prevent getting the Refresh Token multiple times for a given User
|
||||||
func (o *Service) TryTokenRefresh(ctx context.Context, usr identity.Requester) error {
|
func (o *Service) TryTokenRefresh(ctx context.Context, usr identity.Requester) error {
|
||||||
|
ctxLogger := logger.FromContext(ctx)
|
||||||
|
|
||||||
if usr == nil || usr.IsNil() {
|
if usr == nil || usr.IsNil() {
|
||||||
logger.Warn("Can only refresh OAuth tokens for existing users", "user", "nil")
|
ctxLogger.Warn("Can only refresh OAuth tokens for existing users", "user", "nil")
|
||||||
// Not user, no token.
|
// Not user, no token.
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace, id := usr.GetTypedID()
|
if !identity.IsIdentityType(usr.GetID(), identity.TypeUser) {
|
||||||
if namespace != identity.TypeUser {
|
ctxLogger.Warn("Can only refresh OAuth tokens for users", "id", usr.GetID())
|
||||||
// Not a user, therefore no token.
|
|
||||||
logger.Warn("Can only refresh OAuth tokens for users", "namespace", namespace, "userId", id)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
ctxLogger := logger.FromContext(ctx)
|
userID, err := identity.UserIdentifier(usr.GetID())
|
||||||
|
|
||||||
userID, err := identity.IntIdentifier(namespace, id)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctxLogger.Warn("Failed to convert user id to int", "namespace", namespace, "userId", id, "error", err)
|
ctxLogger.Warn("Failed to convert user id to int", "id", usr.GetID(), "error", err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,8 +35,7 @@ func (m *UserHeaderMiddleware) applyUserHeader(ctx context.Context, h backend.Fo
|
|||||||
}
|
}
|
||||||
|
|
||||||
h.DeleteHTTPHeader(proxyutil.UserHeaderName)
|
h.DeleteHTTPHeader(proxyutil.UserHeaderName)
|
||||||
namespace, _ := reqCtx.SignedInUser.GetTypedID()
|
if !identity.IsIdentityType(reqCtx.SignedInUser.GetID(), identity.TypeAnonymous) {
|
||||||
if namespace != identity.TypeAnonymous {
|
|
||||||
h.SetHTTPHeader(proxyutil.UserHeaderName, reqCtx.SignedInUser.GetLogin())
|
h.SetHTTPHeader(proxyutil.UserHeaderName, reqCtx.SignedInUser.GetLogin())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,8 +99,7 @@ func (api *ServiceAccountsAPI) CreateServiceAccount(c *contextmodel.ReqContext)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if api.cfg.RBAC.PermissionsOnCreation("service-account") {
|
if api.cfg.RBAC.PermissionsOnCreation("service-account") {
|
||||||
t, _ := c.SignedInUser.GetTypedID()
|
if identity.IsIdentityType(c.SignedInUser.GetID(), identity.TypeUser) {
|
||||||
if t == identity.TypeUser {
|
|
||||||
userID, err := c.SignedInUser.GetID().ParseInt()
|
userID, err := c.SignedInUser.GetID().ParseInt()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return response.Error(http.StatusInternalServerError, "Failed to parse user id", err)
|
return response.Error(http.StatusInternalServerError, "Failed to parse user id", err)
|
||||||
|
@ -165,10 +165,9 @@ func (f *accessControlDashboardPermissionFilter) buildClauses() {
|
|||||||
dashWildcards := accesscontrol.WildcardsFromPrefix(dashboards.ScopeDashboardsPrefix)
|
dashWildcards := accesscontrol.WildcardsFromPrefix(dashboards.ScopeDashboardsPrefix)
|
||||||
folderWildcards := accesscontrol.WildcardsFromPrefix(dashboards.ScopeFoldersPrefix)
|
folderWildcards := accesscontrol.WildcardsFromPrefix(dashboards.ScopeFoldersPrefix)
|
||||||
|
|
||||||
userID := int64(0)
|
var userID int64
|
||||||
namespace, identifier := f.user.GetTypedID()
|
if id, err := identity.UserIdentifier(f.user.GetID()); err == nil {
|
||||||
if namespace == identity.TypeUser || namespace == identity.TypeServiceAccount {
|
userID = id
|
||||||
userID, _ = identity.IntIdentifier(namespace, identifier)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
orgID := f.user.GetOrgID()
|
orgID := f.user.GetOrgID()
|
||||||
|
@ -33,10 +33,9 @@ func (f *accessControlDashboardPermissionFilterNoFolderSubquery) buildClauses()
|
|||||||
dashWildcards := accesscontrol.WildcardsFromPrefix(dashboards.ScopeDashboardsPrefix)
|
dashWildcards := accesscontrol.WildcardsFromPrefix(dashboards.ScopeDashboardsPrefix)
|
||||||
folderWildcards := accesscontrol.WildcardsFromPrefix(dashboards.ScopeFoldersPrefix)
|
folderWildcards := accesscontrol.WildcardsFromPrefix(dashboards.ScopeFoldersPrefix)
|
||||||
|
|
||||||
userID := int64(0)
|
var userID int64
|
||||||
namespace, identifier := f.user.GetTypedID()
|
if id, err := identity.UserIdentifier(f.user.GetID()); err == nil {
|
||||||
if namespace == identity.TypeUser || namespace == identity.TypeServiceAccount {
|
userID = id
|
||||||
userID, _ = identity.IntIdentifier(namespace, identifier)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
orgID := f.user.GetOrgID()
|
orgID := f.user.GetOrgID()
|
||||||
|
@ -47,14 +47,9 @@ func (api *API) getDashboardHelper(ctx context.Context, orgID int64, id int64, u
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (api *API) GetStars(c *contextmodel.ReqContext) response.Response {
|
func (api *API) GetStars(c *contextmodel.ReqContext) response.Response {
|
||||||
namespace, identifier := c.SignedInUser.GetTypedID()
|
userID, err := identity.UserIdentifier(c.SignedInUser.GetID())
|
||||||
if namespace != identity.TypeUser && namespace != identity.TypeServiceAccount {
|
|
||||||
return response.Error(http.StatusBadRequest, "Only users and service accounts can star dashboards", nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
userID, err := identity.IntIdentifier(namespace, identifier)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return response.Error(http.StatusInternalServerError, "Invalid user ID", err)
|
return response.Error(http.StatusBadRequest, "Only users and service accounts get starred dashboards", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
query := star.GetUserStarsQuery{
|
query := star.GetUserStarsQuery{
|
||||||
@ -101,17 +96,12 @@ func (api *API) GetStars(c *contextmodel.ReqContext) response.Response {
|
|||||||
// 403: forbiddenError
|
// 403: forbiddenError
|
||||||
// 500: internalServerError
|
// 500: internalServerError
|
||||||
func (api *API) StarDashboard(c *contextmodel.ReqContext) response.Response {
|
func (api *API) StarDashboard(c *contextmodel.ReqContext) response.Response {
|
||||||
namespace, identifier := c.SignedInUser.GetTypedID()
|
userID, err := identity.UserIdentifier(c.SignedInUser.GetID())
|
||||||
if namespace != identity.TypeUser && namespace != identity.TypeServiceAccount {
|
if err != nil {
|
||||||
return response.Error(http.StatusBadRequest, "Only users and service accounts can star dashboards", nil)
|
return response.Error(http.StatusBadRequest, "Only users and service accounts can star dashboards", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
userID, err := identity.IntIdentifier(namespace, identifier)
|
id, err := strconv.ParseInt(web.Params(c.Req)[":id"], 10, 64)
|
||||||
if err != nil {
|
|
||||||
return response.Error(http.StatusInternalServerError, "Invalid user ID", err)
|
|
||||||
}
|
|
||||||
idString := web.Params(c.Req)[":id"]
|
|
||||||
id, err := strconv.ParseInt(idString, 10, 64)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return response.Error(http.StatusBadRequest, "Invalid dashboard ID", nil)
|
return response.Error(http.StatusBadRequest, "Invalid dashboard ID", nil)
|
||||||
}
|
}
|
||||||
@ -146,18 +136,12 @@ func (api *API) StarDashboardByUID(c *contextmodel.ReqContext) response.Response
|
|||||||
return response.Error(http.StatusBadRequest, "Invalid dashboard UID", nil)
|
return response.Error(http.StatusBadRequest, "Invalid dashboard UID", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace, identifier := c.SignedInUser.GetTypedID()
|
userID, err := identity.UserIdentifier(c.SignedInUser.GetID())
|
||||||
if namespace != identity.TypeUser && namespace != identity.TypeServiceAccount {
|
if err != nil {
|
||||||
return response.Error(http.StatusBadRequest, "Only users and service accounts can star dashboards", nil)
|
return response.Error(http.StatusBadRequest, "Only users and service accounts can star dashboards", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
userID, err := identity.IntIdentifier(namespace, identifier)
|
|
||||||
if err != nil {
|
|
||||||
return response.Error(http.StatusInternalServerError, "Invalid user ID", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
dash, rsp := api.getDashboardHelper(c.Req.Context(), c.SignedInUser.GetOrgID(), 0, uid)
|
dash, rsp := api.getDashboardHelper(c.Req.Context(), c.SignedInUser.GetOrgID(), 0, uid)
|
||||||
|
|
||||||
if rsp != nil {
|
if rsp != nil {
|
||||||
return rsp
|
return rsp
|
||||||
}
|
}
|
||||||
@ -193,14 +177,9 @@ func (api *API) UnstarDashboard(c *contextmodel.ReqContext) response.Response {
|
|||||||
return response.Error(http.StatusBadRequest, "Invalid dashboard ID", nil)
|
return response.Error(http.StatusBadRequest, "Invalid dashboard ID", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace, identifier := c.SignedInUser.GetTypedID()
|
userID, err := identity.UserIdentifier(c.SignedInUser.GetID())
|
||||||
if namespace != identity.TypeUser && namespace != identity.TypeServiceAccount {
|
|
||||||
return response.Error(http.StatusBadRequest, "Only users and service accounts can star dashboards", nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
userID, err := identity.IntIdentifier(namespace, identifier)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return response.Error(http.StatusInternalServerError, "Invalid user ID", err)
|
return response.Error(http.StatusBadRequest, "Only users and service accounts can star dashboards", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd := star.UnstarDashboardCommand{UserID: userID, DashboardID: id}
|
cmd := star.UnstarDashboardCommand{UserID: userID, DashboardID: id}
|
||||||
@ -233,14 +212,9 @@ func (api *API) UnstarDashboardByUID(c *contextmodel.ReqContext) response.Respon
|
|||||||
return response.Error(http.StatusBadRequest, "Invalid dashboard UID", nil)
|
return response.Error(http.StatusBadRequest, "Invalid dashboard UID", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace, identifier := c.SignedInUser.GetTypedID()
|
userID, err := identity.UserIdentifier(c.SignedInUser.GetID())
|
||||||
if namespace != identity.TypeUser && namespace != identity.TypeServiceAccount {
|
|
||||||
return response.Error(http.StatusBadRequest, "Only users and service accounts can star dashboards", nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
userID, err := identity.IntIdentifier(namespace, identifier)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return response.Error(http.StatusInternalServerError, "Invalid user ID", err)
|
return response.Error(http.StatusBadRequest, "Only users and service accounts can star dashboards", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
dash, rsp := api.getDashboardHelper(c.Req.Context(), c.SignedInUser.GetOrgID(), 0, uid)
|
dash, rsp := api.getDashboardHelper(c.Req.Context(), c.SignedInUser.GetOrgID(), 0, uid)
|
||||||
|
@ -49,7 +49,7 @@ func (tapi *TeamAPI) createTeam(c *contextmodel.ReqContext) response.Response {
|
|||||||
// if the request is authenticated using API tokens
|
// if the request is authenticated using API tokens
|
||||||
// the SignedInUser is an empty struct therefore
|
// the SignedInUser is an empty struct therefore
|
||||||
// an additional check whether it is an actual user is required
|
// an additional check whether it is an actual user is required
|
||||||
namespace, identifier := c.SignedInUser.GetTypedID()
|
namespace, identifier := c.SignedInUser.GetID().Type(), c.SignedInUser.GetID().ID()
|
||||||
switch namespace {
|
switch namespace {
|
||||||
case identity.TypeUser:
|
case identity.TypeUser:
|
||||||
userID, err := strconv.ParseInt(identifier, 10, 64)
|
userID, err := strconv.ParseInt(identifier, 10, 64)
|
||||||
|
@ -169,7 +169,7 @@ func (u *SignedInUser) GetAllowedKubernetesNamespace() string {
|
|||||||
// GetCacheKey returns a unique key for the entity.
|
// GetCacheKey returns a unique key for the entity.
|
||||||
// Add an extra prefix to avoid collisions with other caches
|
// Add an extra prefix to avoid collisions with other caches
|
||||||
func (u *SignedInUser) GetCacheKey() string {
|
func (u *SignedInUser) GetCacheKey() string {
|
||||||
namespace, id := u.GetTypedID()
|
typ, id := u.GetID().Type(), u.GetID().ID()
|
||||||
if !u.HasUniqueId() {
|
if !u.HasUniqueId() {
|
||||||
// Hack use the org role as id for identities that do not have a unique id
|
// Hack use the org role as id for identities that do not have a unique id
|
||||||
// e.g. anonymous and render key.
|
// e.g. anonymous and render key.
|
||||||
@ -181,7 +181,7 @@ func (u *SignedInUser) GetCacheKey() string {
|
|||||||
id = string(orgRole)
|
id = string(orgRole)
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Sprintf("%d-%s-%s", u.GetOrgID(), namespace, id)
|
return fmt.Sprintf("%d-%s-%s", u.GetOrgID(), typ, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetIsGrafanaAdmin returns true if the user is a server admin
|
// GetIsGrafanaAdmin returns true if the user is a server admin
|
||||||
@ -245,13 +245,11 @@ func (u *SignedInUser) GetOrgRole() identity.RoleType {
|
|||||||
|
|
||||||
// GetID returns namespaced id for the entity
|
// GetID returns namespaced id for the entity
|
||||||
func (u *SignedInUser) GetID() identity.TypedID {
|
func (u *SignedInUser) GetID() identity.TypedID {
|
||||||
ns, id := u.GetTypedID()
|
ns, id := u.getTypeAndID()
|
||||||
return identity.NewTypedIDString(ns, id)
|
return identity.NewTypedIDString(ns, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTypedID returns the namespace and ID of the active entity
|
func (u *SignedInUser) getTypeAndID() (identity.IdentityType, string) {
|
||||||
// The namespace is one of the constants defined in pkg/apimachinery/identity
|
|
||||||
func (u *SignedInUser) GetTypedID() (identity.IdentityType, string) {
|
|
||||||
switch {
|
switch {
|
||||||
case u.ApiKeyID != 0:
|
case u.ApiKeyID != 0:
|
||||||
return identity.TypeAPIKey, strconv.FormatInt(u.ApiKeyID, 10)
|
return identity.TypeAPIKey, strconv.FormatInt(u.ApiKeyID, 10)
|
||||||
|
@ -114,8 +114,7 @@ func ApplyUserHeader(sendUserHeader bool, req *http.Request, user identity.Reque
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace, _ := user.GetTypedID()
|
if identity.IsIdentityType(user.GetID(), identity.TypeUser) {
|
||||||
if namespace == identity.TypeUser || namespace == identity.TypeServiceAccount {
|
|
||||||
req.Header.Set(UserHeaderName, user.GetLogin())
|
req.Header.Set(UserHeaderName, user.GetLogin())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user