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
|
||||
}
|
||||
|
||||
namespaceID, userIDstr := c.SignedInUser.GetTypedID()
|
||||
|
||||
if namespaceID != identity.TypeUser {
|
||||
if !identity.IsIdentityType(c.SignedInUser.GetID(), identity.TypeUser) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
userID, err := identity.IntIdentifier(namespaceID, userIDstr)
|
||||
userID, err := identity.UserIdentifier(c.SignedInUser.GetID())
|
||||
if err != nil {
|
||||
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)
|
||||
}
|
||||
|
||||
namespaceID, userIDStr := c.SignedInUser.GetTypedID()
|
||||
|
||||
// disconnect all library elements for this dashboard
|
||||
err = hs.LibraryElementService.DisconnectElementsFromDashboard(c.Req.Context(), dash.ID)
|
||||
if err != nil {
|
||||
hs.log.Error(
|
||||
"Failed to disconnect library elements",
|
||||
"dashboard", dash.ID,
|
||||
"namespaceID", namespaceID,
|
||||
"user", userIDStr,
|
||||
"identity", c.GetID(),
|
||||
"error", err)
|
||||
}
|
||||
|
||||
@ -515,15 +510,9 @@ func (hs *HTTPServer) postDashboard(c *contextmodel.ReqContext, cmd dashboards.S
|
||||
ctx := c.Req.Context()
|
||||
var err error
|
||||
|
||||
userID := int64(0)
|
||||
namespaceID, userIDstr := c.SignedInUser.GetTypedID()
|
||||
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)
|
||||
}
|
||||
var userID int64
|
||||
if id, err := identity.UserIdentifier(c.SignedInUser.GetID()); err == nil {
|
||||
userID = id
|
||||
}
|
||||
|
||||
cmd.OrgID = c.SignedInUser.GetOrgID()
|
||||
@ -632,16 +621,9 @@ func (hs *HTTPServer) postDashboard(c *contextmodel.ReqContext, cmd dashboards.S
|
||||
// 401: unauthorisedError
|
||||
// 500: internalServerError
|
||||
func (hs *HTTPServer) GetHomeDashboard(c *contextmodel.ReqContext) response.Response {
|
||||
userID := int64(0)
|
||||
var err error
|
||||
namespaceID, userIDstr := c.SignedInUser.GetTypedID()
|
||||
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)
|
||||
}
|
||||
var userID int64
|
||||
if id, err := identity.UserIdentifier(c.SignedInUser.GetID()); err == nil {
|
||||
userID = id
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
userID := int64(0)
|
||||
namespaceID, userIDstr := c.SignedInUser.GetTypedID()
|
||||
if namespaceID != identity.TypeUser && namespaceID != identity.TypeServiceAccount {
|
||||
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)
|
||||
}
|
||||
var userID int64
|
||||
if id, err := identity.UserIdentifier(c.SignedInUser.GetID()); err == nil {
|
||||
userID = id
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
userID, err := identity.UserIdentifier(c.SignedInUser.GetTypedID())
|
||||
if err != nil {
|
||||
return response.Error(http.StatusInternalServerError,
|
||||
"Failed to add datasource", err)
|
||||
}
|
||||
userID, _ := identity.UserIdentifier(c.SignedInUser.GetID())
|
||||
|
||||
datasourcesLogger.Debug("Received command to add data source", "url", cmd.URL)
|
||||
cmd.OrgID = c.SignedInUser.GetOrgID()
|
||||
|
@ -191,15 +191,13 @@ func (hs *HTTPServer) setDefaultFolderPermissions(ctx context.Context, orgID int
|
||||
if !hs.Cfg.RBAC.PermissionsOnCreation("folder") {
|
||||
return nil
|
||||
}
|
||||
var permissions []accesscontrol.SetResourcePermissionCommand
|
||||
var userID int64
|
||||
|
||||
namespace, id := user.GetTypedID()
|
||||
if namespace == identity.TypeUser {
|
||||
var errID error
|
||||
userID, errID = identity.IntIdentifier(namespace, id)
|
||||
if errID != nil {
|
||||
return errID
|
||||
var permissions []accesscontrol.SetResourcePermissionCommand
|
||||
|
||||
if identity.IsIdentityType(user.GetID(), identity.TypeUser) {
|
||||
userID, err := identity.UserIdentifier(user.GetID())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
permissions = append(permissions, accesscontrol.SetResourcePermissionCommand{
|
||||
|
@ -31,7 +31,7 @@ func (hs *HTTPServer) setIndexViewData(c *contextmodel.ReqContext) (*dtos.IndexV
|
||||
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}
|
||||
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 {
|
||||
namespace, _ := c.SignedInUser.GetTypedID()
|
||||
|
||||
// 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}
|
||||
}
|
||||
|
||||
|
@ -257,8 +257,7 @@ func (hs *HTTPServer) Logout(c *contextmodel.ReqContext) {
|
||||
return
|
||||
}
|
||||
|
||||
_, id := c.SignedInUser.GetTypedID()
|
||||
hs.log.Info("Successful Logout", "userID", id)
|
||||
hs.log.Info("Successful Logout", "id", c.SignedInUser.GetID())
|
||||
c.Redirect(redirect.URL)
|
||||
}
|
||||
|
||||
@ -305,7 +304,7 @@ func (hs *HTTPServer) redirectURLWithErrorCookie(c *contextmodel.ReqContext, err
|
||||
var userID int64
|
||||
if c.SignedInUser != nil && !c.SignedInUser.IsNil() {
|
||||
var errID error
|
||||
userID, errID = identity.UserIdentifier(c.SignedInUser.GetTypedID())
|
||||
userID, errID = identity.UserIdentifier(c.SignedInUser.GetID())
|
||||
if errID != nil {
|
||||
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)
|
||||
}
|
||||
|
||||
namespace, identifier := c.SignedInUser.GetTypedID()
|
||||
if namespace != identity.TypeUser {
|
||||
if !identity.IsIdentityType(c.SignedInUser.GetID(), identity.TypeUser) {
|
||||
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 {
|
||||
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.Status = tempuser.TmpUserInvitePending
|
||||
|
||||
namespace, identifier := c.SignedInUser.GetTypedID()
|
||||
var userID int64
|
||||
if namespace == identity.TypeUser || namespace == identity.TypeServiceAccount {
|
||||
var err error
|
||||
userID, err = strconv.ParseInt(identifier, 10, 64)
|
||||
if err != nil {
|
||||
return response.Error(http.StatusInternalServerError, "Unrecognized user", err)
|
||||
}
|
||||
if id, err := identity.UserIdentifier(c.SignedInUser.GetID()); err == nil {
|
||||
userID = id
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
userID, errID := identity.UserIdentifier(c.SignedInUser.GetTypedID())
|
||||
if errID != nil {
|
||||
return response.Error(http.StatusInternalServerError, "Failed to set home dashboard", errID)
|
||||
userID, err := identity.UserIdentifier(c.SignedInUser.GetID())
|
||||
if err != nil {
|
||||
return response.Error(http.StatusInternalServerError, "Failed to set home dashboard", err)
|
||||
}
|
||||
|
||||
cmd.UserID = userID
|
||||
@ -64,9 +64,9 @@ func (hs *HTTPServer) SetHomeDashboard(c *contextmodel.ReqContext) response.Resp
|
||||
// 401: unauthorisedError
|
||||
// 500: internalServerError
|
||||
func (hs *HTTPServer) GetUserPreferences(c *contextmodel.ReqContext) response.Response {
|
||||
userID, errID := identity.UserIdentifier(c.SignedInUser.GetTypedID())
|
||||
if errID != nil {
|
||||
return response.Error(http.StatusInternalServerError, "Failed to get user preferences", errID)
|
||||
userID, err := identity.UserIdentifier(c.SignedInUser.GetID())
|
||||
if err != nil {
|
||||
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)
|
||||
@ -89,9 +89,9 @@ func (hs *HTTPServer) UpdateUserPreferences(c *contextmodel.ReqContext) response
|
||||
return response.Error(http.StatusBadRequest, "bad request data", err)
|
||||
}
|
||||
|
||||
userID, errID := identity.UserIdentifier(c.SignedInUser.GetTypedID())
|
||||
if errID != nil {
|
||||
return response.Error(http.StatusInternalServerError, "Failed to update user preferences", errID)
|
||||
userID, err := identity.UserIdentifier(c.SignedInUser.GetID())
|
||||
if err != nil {
|
||||
return response.Error(http.StatusInternalServerError, "Failed to update user preferences", err)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
userID, errID := identity.UserIdentifier(c.SignedInUser.GetTypedID())
|
||||
if errID != nil {
|
||||
return response.Error(http.StatusInternalServerError, "Failed to update user preferences", errID)
|
||||
userID, err := identity.UserIdentifier(c.SignedInUser.GetID())
|
||||
if err != nil {
|
||||
return response.Error(http.StatusInternalServerError, "Failed to update user preferences", err)
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
userID, errID := identity.UserIdentifier(c.SignedInUser.GetTypedID())
|
||||
if errID != nil {
|
||||
hs.log.Error("Failed to parse user id", "err", errID)
|
||||
userID, err := identity.UserIdentifier(c.SignedInUser.GetID())
|
||||
if err != nil {
|
||||
hs.log.Debug("Failed to parse user id", "err", err)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
userID, errID := identity.UserIdentifier(c.SignedInUser.GetTypedID())
|
||||
if errID != nil {
|
||||
hs.log.Error("Failed to parse user id", "err", errID)
|
||||
userID, err := identity.UserIdentifier(c.SignedInUser.GetID())
|
||||
if err != nil {
|
||||
hs.log.Debug("Failed to parse user id", "err", err)
|
||||
}
|
||||
|
||||
cmd := tempuser.CreateTempUserCommand{}
|
||||
|
@ -31,8 +31,7 @@ import (
|
||||
// 404: notFoundError
|
||||
// 500: internalServerError
|
||||
func (hs *HTTPServer) GetSignedInUser(c *contextmodel.ReqContext) response.Response {
|
||||
namespace, identifier := c.SignedInUser.GetTypedID()
|
||||
if namespace != identity.TypeUser {
|
||||
if !identity.IsIdentityType(c.GetID(), identity.TypeUser) {
|
||||
return response.JSON(http.StatusOK, user.UserProfileDTO{
|
||||
IsGrafanaAdmin: c.SignedInUser.GetIsGrafanaAdmin(),
|
||||
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 {
|
||||
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 {
|
||||
namespace, id := c.SignedInUser.GetTypedID()
|
||||
if !identity.IsIdentityType(namespace, identity.TypeUser) {
|
||||
if !identity.IsIdentityType(c.SignedInUser.GetID(), identity.TypeUser) {
|
||||
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)
|
||||
}
|
||||
|
||||
userID, err := strconv.ParseInt(id, 10, 64)
|
||||
userID, err := identity.UserIdentifier(c.SignedInUser.GetID())
|
||||
if err != nil {
|
||||
return response.Error(http.StatusInternalServerError, "Got invalid user id", err)
|
||||
}
|
||||
@ -506,13 +504,12 @@ func (hs *HTTPServer) ChangeActiveOrgAndRedirectToHome(c *contextmodel.ReqContex
|
||||
return
|
||||
}
|
||||
|
||||
namespace, identifier := c.SignedInUser.GetTypedID()
|
||||
if namespace != identity.TypeUser {
|
||||
if !identity.IsIdentityType(c.SignedInUser.GetID(), identity.TypeUser) {
|
||||
c.JsonApiErr(http.StatusForbidden, "Endpoint only available for users", nil)
|
||||
return
|
||||
}
|
||||
|
||||
userID, err := identity.IntIdentifier(namespace, identifier)
|
||||
userID, err := identity.UserIdentifier(c.SignedInUser.GetID())
|
||||
if err != nil {
|
||||
c.JsonApiErr(http.StatusInternalServerError, "Failed to parse user id", err)
|
||||
return
|
||||
@ -632,12 +629,11 @@ func (hs *HTTPServer) ClearHelpFlags(c *contextmodel.ReqContext) response.Respon
|
||||
}
|
||||
|
||||
func getUserID(c *contextmodel.ReqContext) (int64, *response.NormalResponse) {
|
||||
namespace, identifier := c.SignedInUser.GetTypedID()
|
||||
if namespace != identity.TypeUser {
|
||||
if !identity.IsIdentityType(c.SignedInUser.GetID(), identity.TypeUser) {
|
||||
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 {
|
||||
return 0, response.Error(http.StatusInternalServerError, "Failed to parse user id", err)
|
||||
}
|
||||
|
@ -32,12 +32,11 @@ import (
|
||||
// 403: forbiddenError
|
||||
// 500: internalServerError
|
||||
func (hs *HTTPServer) GetUserAuthTokens(c *contextmodel.ReqContext) response.Response {
|
||||
namespace, identifier := c.SignedInUser.GetTypedID()
|
||||
if namespace != identity.TypeUser {
|
||||
return response.Error(http.StatusForbidden, "entity not allowed to revoke tokens", nil)
|
||||
if !identity.IsIdentityType(c.SignedInUser.GetID(), identity.TypeUser) {
|
||||
return response.Error(http.StatusForbidden, "entity not allowed to get tokens", nil)
|
||||
}
|
||||
|
||||
userID, err := identity.IntIdentifier(namespace, identifier)
|
||||
userID, err := identity.UserIdentifier(c.SignedInUser.GetID())
|
||||
if err != nil {
|
||||
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)
|
||||
}
|
||||
|
||||
namespace, identifier := c.SignedInUser.GetTypedID()
|
||||
if namespace != identity.TypeUser {
|
||||
if !identity.IsIdentityType(c.SignedInUser.GetID(), identity.TypeUser) {
|
||||
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 {
|
||||
return response.Error(http.StatusInternalServerError, "failed to parse user id", err)
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
ErrInvalidIDType = errutil.BadRequest("auth.identity.invalid-id-type")
|
||||
ErrInvalidTypedID = errutil.BadRequest("auth.identity.invalid-typed-id")
|
||||
ErrNotIntIdentifier = errors.New("identifier is not an int64")
|
||||
ErrIdentifierNotInitialized = errors.New("identifier is not initialized")
|
||||
|
@ -17,15 +17,9 @@ type Requester interface {
|
||||
GetRawIdentifier() string
|
||||
// Deprecated: use GetUID instead
|
||||
GetInternalID() (int64, error)
|
||||
|
||||
// GetID returns namespaced internalID for the entity
|
||||
// Deprecated: use GetUID instead
|
||||
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.
|
||||
// The display name is the name if it is set, otherwise the login or email.
|
||||
GetDisplayName() string
|
||||
@ -82,14 +76,14 @@ type Requester interface {
|
||||
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.
|
||||
// Errors if the identifier is not initialized or if namespace is not recognized.
|
||||
func IntIdentifier(kind IdentityType, identifier string) (int64, error) {
|
||||
if IsIdentityType(kind, TypeUser, TypeAPIKey, TypeServiceAccount, TypeRenderService) {
|
||||
id, err := strconv.ParseInt(identifier, 10, 64)
|
||||
// Errors if the identifier is not initialized or if type is not recognized.
|
||||
func IntIdentifier(typedID TypedID) (int64, error) {
|
||||
if IsIdentityType(typedID, TypeUser, TypeAPIKey, TypeServiceAccount, TypeRenderService) {
|
||||
id, err := strconv.ParseInt(typedID.ID(), 10, 64)
|
||||
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 {
|
||||
@ -102,19 +96,18 @@ func IntIdentifier(kind IdentityType, identifier string) (int64, error) {
|
||||
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.
|
||||
// Returns 0 if the namespace is not user or service account
|
||||
func UserIdentifier(kind IdentityType, identifier string) (int64, error) {
|
||||
userID, err := IntIdentifier(kind, identifier)
|
||||
// Returns 0 if the type is not user or service account
|
||||
func UserIdentifier(typedID TypedID) (int64, error) {
|
||||
userID, err := IntIdentifier(typedID)
|
||||
if err != nil {
|
||||
// FIXME: return this error once entity namespaces are handled by stores
|
||||
return 0, nil
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if IsIdentityType(kind, TypeUser, TypeServiceAccount) {
|
||||
if IsIdentityType(typedID, TypeUser, TypeServiceAccount) {
|
||||
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))
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return u.AuthID
|
||||
}
|
||||
|
@ -42,10 +42,10 @@ func ParseType(str string) (IdentityType, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// IsIdentityType returns true if type matches any expected identity type
|
||||
func IsIdentityType(typ IdentityType, expected ...IdentityType) bool {
|
||||
// IsIdentityType returns true if typedID matches any expected identity type
|
||||
func IsIdentityType(typedID TypedID, expected ...IdentityType) bool {
|
||||
for _, e := range expected {
|
||||
if typ == e {
|
||||
if typedID.Type() == e {
|
||||
return true
|
||||
}
|
||||
}
|
||||
@ -128,7 +128,7 @@ func (ni TypedID) Type() IdentityType {
|
||||
}
|
||||
|
||||
func (ni TypedID) IsType(expected ...IdentityType) bool {
|
||||
return IsIdentityType(ni.t, expected...)
|
||||
return IsIdentityType(ni, expected...)
|
||||
}
|
||||
|
||||
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) {
|
||||
namespace, id := ident.GetTypedID()
|
||||
a.log.FromContext(ctx).Debug(msg, "namespace", namespace, "id", id, "orgID", ident.GetOrgID(), "permissions", eval.GoString())
|
||||
a.log.FromContext(ctx).Debug(msg, "id", ident.GetID(), "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)
|
||||
}
|
||||
|
||||
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")
|
||||
defer span.End()
|
||||
|
||||
@ -143,10 +143,9 @@ func (s *Service) getUserPermissions(ctx context.Context, user identity.Requeste
|
||||
permissions = append(permissions, SharedWithMeFolderPermission)
|
||||
}
|
||||
|
||||
userID, err := identity.UserIdentifier(user.GetTypedID())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// we don't care about the error here, if this fails we get 0 and no
|
||||
// permission assigned to user will be returned, only for org role.
|
||||
userID, _ := identity.UserIdentifier(user.GetID())
|
||||
|
||||
dbPermissions, err := s.store.GetUserPermissions(ctx, accesscontrol.GetUserPermissionsQuery{
|
||||
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")
|
||||
defer span.End()
|
||||
|
||||
namespace, identifier := user.GetTypedID()
|
||||
|
||||
var userID int64
|
||||
if namespace == identity.TypeUser || namespace == identity.TypeServiceAccount {
|
||||
if identity.IsIdentityType(user.GetID(), identity.TypeUser, identity.TypeServiceAccount) {
|
||||
var err error
|
||||
userID, err = strconv.ParseInt(identifier, 10, 64)
|
||||
userID, err = identity.UserIdentifier(user.GetID())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -80,11 +80,9 @@ func deny(c *contextmodel.ReqContext, evaluator Evaluator, err error) {
|
||||
if err != nil {
|
||||
c.Logger.Error("Error from access control system", "error", err, "accessErrorID", id)
|
||||
} else {
|
||||
namespace, identifier := c.SignedInUser.GetTypedID()
|
||||
c.Logger.Info(
|
||||
"Access denied",
|
||||
"namespace", namespace,
|
||||
"userID", identifier,
|
||||
"id", c.SignedInUser.GetID(),
|
||||
"accessErrorID", id,
|
||||
"permissions", evaluator.GoString(),
|
||||
)
|
||||
|
@ -70,12 +70,10 @@ func (s *Service) SignIdentity(ctx context.Context, id identity.Requester) (stri
|
||||
idClaims *auth.IDClaims
|
||||
}
|
||||
result, err, _ := s.si.Do(cacheKey, func() (any, error) {
|
||||
namespace, identifier := id.GetTypedID()
|
||||
|
||||
cachedToken, err := s.cache.Get(ctx, cacheKey)
|
||||
if err == nil {
|
||||
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))
|
||||
if err != nil {
|
||||
@ -85,14 +83,14 @@ func (s *Service) SignIdentity(ctx context.Context, id identity.Requester) (stri
|
||||
}
|
||||
|
||||
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()
|
||||
claims := &auth.IDClaims{
|
||||
Claims: &jwt.Claims{
|
||||
Issuer: s.cfg.AppURL,
|
||||
Audience: getAudience(id.GetOrgID()),
|
||||
Subject: getSubject(namespace.String(), identifier),
|
||||
Subject: id.GetID().String(),
|
||||
Expiry: jwt.NewNumericDate(now.Add(tokenTTL)),
|
||||
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.EmailVerified = id.IsEmailVerified()
|
||||
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)
|
||||
if err != nil {
|
||||
if shouldLogErr(err) {
|
||||
namespace, id := identity.GetTypedID()
|
||||
s.logger.FromContext(ctx).Error("Failed to sign id token", "err", err, "namespace", namespace, "id", id)
|
||||
s.logger.FromContext(ctx).Error("Failed to sign id token", "err", err, "id", identity.GetID())
|
||||
}
|
||||
// for now don't return error so we don't break authentication from this hook
|
||||
return nil
|
||||
@ -179,10 +176,6 @@ func getAudience(orgID int64) jwt.Audience {
|
||||
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 {
|
||||
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) {
|
||||
token := c.oauthService.GetCurrentOAuthToken(ctx, user)
|
||||
|
||||
namespace, id := user.GetTypedID()
|
||||
userID, err := identity.UserIdentifier(namespace, id)
|
||||
userID, err := identity.UserIdentifier(user.GetID())
|
||||
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
|
||||
}
|
||||
|
||||
@ -260,8 +259,7 @@ func (c *OAuth) Logout(ctx context.Context, user identity.Requester) (*authn.Red
|
||||
AuthId: user.GetAuthID(),
|
||||
AuthModule: user.GetAuthenticatedBy(),
|
||||
}); err != nil {
|
||||
namespace, id := user.GetTypedID()
|
||||
c.log.FromContext(ctx).Error("Failed to invalidate tokens", "namespace", namespace, "id", id, "error", err)
|
||||
c.log.FromContext(ctx).Error("Failed to invalidate tokens", "id", user.GetID(), "error", err)
|
||||
}
|
||||
|
||||
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())
|
||||
|
||||
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)
|
||||
if tt.expectedOK {
|
||||
|
@ -115,10 +115,6 @@ func (i *Identity) GetID() identity.TypedID {
|
||||
return i.ID
|
||||
}
|
||||
|
||||
func (i *Identity) GetTypedID() (namespace identity.IdentityType, identifier string) {
|
||||
return i.ID.Type(), i.ID.ID()
|
||||
}
|
||||
|
||||
func (i *Identity) GetUID() string {
|
||||
return i.UID.String()
|
||||
}
|
||||
@ -132,14 +128,14 @@ func (i *Identity) GetAuthenticatedBy() string {
|
||||
}
|
||||
|
||||
func (i *Identity) GetCacheKey() string {
|
||||
namespace, id := i.GetTypedID()
|
||||
id := i.GetID().ID()
|
||||
if !i.HasUniqueId() {
|
||||
// Hack use the org role as id for identities that do not have a unique id
|
||||
// e.g. anonymous and render key.
|
||||
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 {
|
||||
@ -232,10 +228,10 @@ func (i *Identity) HasRole(role org.RoleType) bool {
|
||||
}
|
||||
|
||||
func (i *Identity) HasUniqueId() bool {
|
||||
namespace, _ := i.GetTypedID()
|
||||
return namespace == identity.TypeUser ||
|
||||
namespace == identity.TypeServiceAccount ||
|
||||
namespace == identity.TypeAPIKey
|
||||
typ := i.GetID().Type()
|
||||
return typ == identity.TypeUser ||
|
||||
typ == identity.TypeServiceAccount ||
|
||||
typ == identity.TypeAPIKey
|
||||
}
|
||||
|
||||
func (i *Identity) IsAuthenticatedBy(providers ...string) bool {
|
||||
|
@ -154,22 +154,22 @@ func (h *ContextHandler) addIDHeaderEndOfRequestFunc(ident identity.Requester) w
|
||||
return
|
||||
}
|
||||
|
||||
namespace, id := ident.GetTypedID()
|
||||
id := ident.GetID()
|
||||
if !identity.IsIdentityType(
|
||||
namespace,
|
||||
id,
|
||||
identity.TypeUser,
|
||||
identity.TypeServiceAccount,
|
||||
identity.TypeAPIKey,
|
||||
) || id == "0" {
|
||||
) || id.ID() == "0" {
|
||||
return
|
||||
}
|
||||
|
||||
if _, ok := h.Cfg.IDResponseHeaderNamespaces[namespace.String()]; !ok {
|
||||
if _, ok := h.Cfg.IDResponseHeaderNamespaces[id.Type().String()]; !ok {
|
||||
return
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
namespace, identifier := req.User.GetTypedID()
|
||||
userID := int64(0)
|
||||
|
||||
if namespace == identity.TypeUser || namespace == identity.TypeServiceAccount {
|
||||
userID, _ = identity.IntIdentifier(namespace, identifier)
|
||||
var userID int64
|
||||
if id, err := identity.UserIdentifier(req.User.GetID()); err == nil {
|
||||
userID = id
|
||||
}
|
||||
|
||||
saveCmd := dashboards.SaveDashboardCommand{
|
||||
|
@ -83,7 +83,7 @@ func TestImportDashboardService(t *testing.T) {
|
||||
require.NotNil(t, resp)
|
||||
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.NotNil(t, importDashboardArg)
|
||||
@ -149,7 +149,7 @@ func TestImportDashboardService(t *testing.T) {
|
||||
require.NotNil(t, resp)
|
||||
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.NotNil(t, importDashboardArg)
|
||||
|
@ -207,9 +207,11 @@ func (dr *DashboardServiceImpl) BuildSaveDashboardCommand(ctx context.Context, d
|
||||
}
|
||||
}
|
||||
|
||||
userID, err := resolveUserID(dto.User, dr.log)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
var userID int64
|
||||
if id, err := identity.UserIdentifier(dto.User.GetID()); err == nil {
|
||||
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()
|
||||
@ -232,22 +234,6 @@ func (dr *DashboardServiceImpl) BuildSaveDashboardCommand(ctx context.Context, d
|
||||
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 {
|
||||
return dr.dashboardStore.DeleteOrphanedProvisionedDashboards(ctx, cmd)
|
||||
}
|
||||
@ -503,12 +489,10 @@ func (dr *DashboardServiceImpl) setDefaultPermissions(ctx context.Context, dto *
|
||||
var permissions []accesscontrol.SetResourcePermissionCommand
|
||||
|
||||
if !provisioned {
|
||||
namespaceID, userIDstr := dto.User.GetTypedID()
|
||||
userID, err := identity.IntIdentifier(namespaceID, userIDstr)
|
||||
|
||||
userID, err := identity.IntIdentifier(dto.User.GetID())
|
||||
if err != nil {
|
||||
dr.log.Error("Could not make user admin", "dashboard", dash.Title, "namespaceID", namespaceID, "userID", userID, "error", err)
|
||||
} else if namespaceID == identity.TypeUser && userID > 0 {
|
||||
dr.log.Error("Could not make user admin", "dashboard", dash.Title, "id", dto.User.GetID(), "error", err)
|
||||
} else if identity.IsIdentityType(dto.User.GetID(), identity.TypeUser) {
|
||||
permissions = append(permissions, accesscontrol.SetResourcePermissionCommand{
|
||||
UserID: userID, Permission: dashboardaccess.PERMISSION_ADMIN.String(),
|
||||
})
|
||||
@ -541,12 +525,10 @@ func (dr *DashboardServiceImpl) setDefaultFolderPermissions(ctx context.Context,
|
||||
var permissions []accesscontrol.SetResourcePermissionCommand
|
||||
|
||||
if !provisioned {
|
||||
namespaceID, userIDstr := cmd.SignedInUser.GetTypedID()
|
||||
userID, err := identity.IntIdentifier(namespaceID, userIDstr)
|
||||
|
||||
userID, err := identity.IntIdentifier(cmd.SignedInUser.GetID())
|
||||
if err != nil {
|
||||
dr.log.Error("Could not make user admin", "folder", cmd.Title, "namespaceID", namespaceID, "userID", userID, "error", err)
|
||||
} else if namespaceID == identity.TypeUser && userID > 0 {
|
||||
dr.log.Error("Could not make user admin", "folder", cmd.Title, "id", cmd.SignedInUser.GetID())
|
||||
} else if identity.IsIdentityType(cmd.SignedInUser.GetID(), identity.TypeUser) {
|
||||
permissions = append(permissions, accesscontrol.SetResourcePermissionCommand{
|
||||
UserID: userID, Permission: dashboardaccess.PERMISSION_ADMIN.String(),
|
||||
})
|
||||
|
@ -116,7 +116,7 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) {
|
||||
err := callSaveWithError(t, cmd, sqlStore)
|
||||
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)
|
||||
|
||||
assert.Equal(t, "", sc.dashboardGuardianMock.DashUID)
|
||||
@ -139,7 +139,7 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) {
|
||||
err := callSaveWithError(t, cmd, sc.sqlStore)
|
||||
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)
|
||||
|
||||
assert.Equal(t, sc.otherSavedFolder.ID, sc.dashboardGuardianMock.DashID)
|
||||
@ -162,7 +162,7 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) {
|
||||
err := callSaveWithError(t, cmd, sc.sqlStore)
|
||||
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)
|
||||
|
||||
assert.Equal(t, sc.savedDashInFolder.UID, sc.dashboardGuardianMock.DashUID)
|
||||
@ -186,7 +186,7 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) {
|
||||
err := callSaveWithError(t, cmd, sc.sqlStore)
|
||||
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)
|
||||
|
||||
assert.Equal(t, sc.savedDashInFolder.UID, sc.dashboardGuardianMock.DashUID)
|
||||
@ -210,7 +210,7 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) {
|
||||
err := callSaveWithError(t, cmd, sc.sqlStore)
|
||||
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)
|
||||
|
||||
assert.Equal(t, sc.savedDashInGeneralFolder.UID, sc.dashboardGuardianMock.DashUID)
|
||||
@ -234,7 +234,7 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) {
|
||||
err := callSaveWithError(t, cmd, sc.sqlStore)
|
||||
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)
|
||||
|
||||
assert.Equal(t, sc.savedDashInFolder.UID, sc.dashboardGuardianMock.DashUID)
|
||||
@ -258,7 +258,7 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) {
|
||||
err := callSaveWithError(t, cmd, sc.sqlStore)
|
||||
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)
|
||||
|
||||
assert.Equal(t, sc.savedDashInGeneralFolder.UID, sc.dashboardGuardianMock.DashUID)
|
||||
@ -282,7 +282,7 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) {
|
||||
err := callSaveWithError(t, cmd, sc.sqlStore)
|
||||
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)
|
||||
|
||||
assert.Equal(t, sc.savedDashInFolder.UID, sc.dashboardGuardianMock.DashUID)
|
||||
@ -306,7 +306,7 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) {
|
||||
err := callSaveWithError(t, cmd, sc.sqlStore)
|
||||
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)
|
||||
|
||||
assert.Equal(t, sc.savedDashInGeneralFolder.UID, sc.dashboardGuardianMock.DashUID)
|
||||
@ -330,7 +330,7 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) {
|
||||
err := callSaveWithError(t, cmd, sc.sqlStore)
|
||||
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)
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
namespace, id := query.SignedInUser.GetTypedID()
|
||||
var userID int64
|
||||
|
||||
if namespace == identity.TypeServiceAccount || namespace == identity.TypeUser {
|
||||
if identity.IsIdentityType(query.SignedInUser.GetID(), identity.TypeUser, identity.TypeServiceAccount) {
|
||||
var err error
|
||||
userID, err = identity.IntIdentifier(namespace, id)
|
||||
userID, err = identity.UserIdentifier(query.SignedInUser.GetID())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -137,7 +135,7 @@ func (d *DashboardSnapshotStore) SearchDashboardSnapshots(ctx context.Context, q
|
||||
switch {
|
||||
case query.SignedInUser.GetOrgRole() == org.RoleAdmin:
|
||||
sess.Where("org_id = ?", query.SignedInUser.GetOrgID())
|
||||
case namespace != identity.TypeAnonymous:
|
||||
case userID != 0:
|
||||
sess.Where("org_id = ? AND user_id = ?", query.OrgID, userID)
|
||||
default:
|
||||
queryResult = snapshots
|
||||
|
@ -63,17 +63,10 @@ func CreateDashboardSnapshot(c *contextmodel.ReqContext, cfg dashboardsnapshot.S
|
||||
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
|
||||
cmd.ExternalURL = ""
|
||||
cmd.OrgID = user.GetOrgID()
|
||||
cmd.UserID = userID
|
||||
cmd.UserID, _ = identity.UserIdentifier(user.GetID())
|
||||
originalDashboardURL, err := createOriginalDashboardURL(&cmd)
|
||||
if err != nil {
|
||||
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
|
||||
|
||||
userID := int64(0)
|
||||
var err error
|
||||
namespaceID, userIDstr := user.GetTypedID()
|
||||
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)
|
||||
var userID int64
|
||||
if id, err := identity.UserIdentifier(cmd.SignedInUser.GetID()); err == nil {
|
||||
userID = id
|
||||
} else {
|
||||
userID, err = identity.IntIdentifier(namespaceID, userIDstr)
|
||||
if err != nil {
|
||||
s.log.Debug("failed to parse user ID", "namespaceID", namespaceID, "userID", userIDstr, "error", err)
|
||||
}
|
||||
s.log.Warn("User does not belong to a user or service account namespace, using 0 as user ID", "id", cmd.SignedInUser.GetID())
|
||||
}
|
||||
|
||||
if userID == 0 {
|
||||
userID = -1
|
||||
}
|
||||
|
||||
dashFolder.CreatedBy = userID
|
||||
dashFolder.UpdatedBy = userID
|
||||
dashFolder.UpdateSlug()
|
||||
@ -682,8 +678,6 @@ func (s *Service) Update(ctx context.Context, cmd *folder.UpdateFolderCommand) (
|
||||
}
|
||||
|
||||
if cmd.NewTitle != nil {
|
||||
namespace, id := cmd.SignedInUser.GetTypedID()
|
||||
|
||||
metrics.MFolderIDsServiceCount.WithLabelValues(metrics.Folder).Inc()
|
||||
if err := s.bus.Publish(ctx, &events.FolderTitleUpdated{
|
||||
Timestamp: foldr.Updated,
|
||||
@ -692,7 +686,7 @@ func (s *Service) Update(ctx context.Context, cmd *folder.UpdateFolderCommand) (
|
||||
UID: dashFolder.UID,
|
||||
OrgID: cmd.OrgID,
|
||||
}); 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
|
||||
}
|
||||
}
|
||||
@ -739,12 +733,10 @@ func (s *Service) legacyUpdate(ctx context.Context, cmd *folder.UpdateFolderComm
|
||||
}
|
||||
|
||||
var userID int64
|
||||
namespace, id := cmd.SignedInUser.GetTypedID()
|
||||
if namespace == identity.TypeUser || namespace == identity.TypeServiceAccount {
|
||||
userID, err = identity.IntIdentifier(namespace, id)
|
||||
if err != nil {
|
||||
s.log.ErrorContext(ctx, "failed to parse user ID", "namespace", namespace, "userID", id, "error", err)
|
||||
}
|
||||
if id, err := identity.UserIdentifier(cmd.SignedInUser.GetID()); err == nil {
|
||||
userID = id
|
||||
} else {
|
||||
s.log.Warn("User does not belong to a user or service account namespace, using 0 as user ID", "id", cmd.SignedInUser.GetID())
|
||||
}
|
||||
|
||||
prepareForUpdate(dashFolder, cmd.OrgID, userID, cmd)
|
||||
@ -1163,15 +1155,11 @@ func (s *Service) buildSaveDashboardCommand(ctx context.Context, dto *dashboards
|
||||
}
|
||||
}
|
||||
|
||||
userID := int64(0)
|
||||
namespaceID, userIDstr := dto.User.GetTypedID()
|
||||
if namespaceID != identity.TypeUser && namespaceID != identity.TypeServiceAccount {
|
||||
s.log.Warn("User does not belong to a user or service account namespace, using 0 as user ID", "namespaceID", namespaceID, "userID", userIDstr)
|
||||
var userID int64
|
||||
if id, err := identity.UserIdentifier(dto.User.GetID()); err == nil {
|
||||
userID = id
|
||||
} else {
|
||||
userID, err = identity.IntIdentifier(namespaceID, userIDstr)
|
||||
if err != nil {
|
||||
s.log.Warn("failed to parse user ID", "namespaceID", namespaceID, "userID", userIDstr, "error", err)
|
||||
}
|
||||
s.log.Warn("User does not belong to a user or service account namespace, using 0 as user ID", "id", dto.User.GetID())
|
||||
}
|
||||
|
||||
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) {
|
||||
ok, err := a.ac.Evaluate(a.ctx, a.user, evaluator)
|
||||
namespaceID, userID := a.user.GetTypedID()
|
||||
if err != nil {
|
||||
id := 0
|
||||
if a.dashboard != nil {
|
||||
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 {
|
||||
@ -323,7 +322,7 @@ func (a *accessControlDashboardGuardian) evaluate(evaluator accesscontrol.Evalua
|
||||
if a.dashboard != nil {
|
||||
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
|
||||
@ -331,7 +330,6 @@ func (a *accessControlDashboardGuardian) evaluate(evaluator accesscontrol.Evalua
|
||||
|
||||
func (a *accessControlFolderGuardian) evaluate(evaluator accesscontrol.Evaluator) (bool, error) {
|
||||
ok, err := a.ac.Evaluate(a.ctx, a.user, evaluator)
|
||||
namespaceID, userID := a.user.GetTypedID()
|
||||
if err != nil {
|
||||
uid := ""
|
||||
orgID := 0
|
||||
@ -339,7 +337,7 @@ func (a *accessControlFolderGuardian) evaluate(evaluator accesscontrol.Evaluator
|
||||
uid = a.folder.UID
|
||||
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 {
|
||||
@ -349,7 +347,7 @@ func (a *accessControlFolderGuardian) evaluate(evaluator accesscontrol.Evaluator
|
||||
uid = a.folder.UID
|
||||
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
|
||||
|
@ -138,13 +138,9 @@ func (l *LibraryElementService) createLibraryElement(c context.Context, signedIn
|
||||
}
|
||||
}
|
||||
|
||||
userID := int64(0)
|
||||
namespaceID, identifier := signedInUser.GetTypedID()
|
||||
if namespaceID == identity.TypeUser || namespaceID == identity.TypeServiceAccount {
|
||||
userID, err = identity.IntIdentifier(namespaceID, identifier)
|
||||
if err != nil {
|
||||
l.log.Warn("Error while parsing userID", "namespaceID", namespaceID, "userID", identifier)
|
||||
}
|
||||
var userID int64
|
||||
if id, err := identity.UserIdentifier(signedInUser.GetID()); err == nil {
|
||||
userID = id
|
||||
}
|
||||
|
||||
metrics.MFolderIDsServiceCount.WithLabelValues(metrics.LibraryElements).Inc()
|
||||
@ -593,13 +589,8 @@ func (l *LibraryElementService) patchLibraryElement(c context.Context, signedInU
|
||||
}
|
||||
|
||||
var userID int64
|
||||
namespaceID, identifier := signedInUser.GetTypedID()
|
||||
if namespaceID == identity.TypeUser || namespaceID == identity.TypeServiceAccount {
|
||||
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)
|
||||
}
|
||||
if id, err := identity.UserIdentifier(signedInUser.GetID()); err == nil {
|
||||
userID = id
|
||||
}
|
||||
|
||||
metrics.MFolderIDsServiceCount.WithLabelValues(metrics.LibraryElements).Inc()
|
||||
@ -800,13 +791,9 @@ func (l *LibraryElementService) connectElementsToDashboardID(c context.Context,
|
||||
return err
|
||||
}
|
||||
|
||||
namespaceID, identifier := signedInUser.GetTypedID()
|
||||
userID := int64(0)
|
||||
if namespaceID == identity.TypeUser || namespaceID == identity.TypeServiceAccount {
|
||||
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)
|
||||
}
|
||||
var userID int64
|
||||
if id, err := identity.UserIdentifier(signedInUser.GetID()); err == nil {
|
||||
userID = id
|
||||
}
|
||||
|
||||
connection := model.LibraryElementConnection{
|
||||
|
@ -284,11 +284,9 @@ func ProvideService(plugCtxProvider *plugincontext.Provider, cfg *setting.Cfg, r
|
||||
|
||||
g.websocketHandler = func(ctx *contextmodel.ReqContext) {
|
||||
user := ctx.SignedInUser
|
||||
_, identifier := user.GetTypedID()
|
||||
|
||||
// Centrifuge expects Credentials in context with a current user ID.
|
||||
cred := ¢rifuge.Credentials{
|
||||
UserID: identifier,
|
||||
UserID: user.GetID().ID(),
|
||||
}
|
||||
newCtx := centrifuge.SetCredentials(ctx.Req.Context(), cred)
|
||||
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)
|
||||
}
|
||||
|
||||
namespaceID, userID := ctx.SignedInUser.GetTypedID()
|
||||
logger.Debug("Publish API cmd", "namespaceID", namespaceID, "userID", userID, "channel", cmd.Channel)
|
||||
logger.Debug("Publish API cmd", "identity", ctx.SignedInUser.GetID(), "channel", cmd.Channel)
|
||||
user := ctx.SignedInUser
|
||||
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)
|
||||
}
|
||||
}
|
||||
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{})
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
userID, err := identity.IntIdentifier(user.GetTypedID())
|
||||
userID, err := identity.IntIdentifier(user.GetID())
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, int64(2), userID)
|
||||
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) {
|
||||
userID, err := identity.IntIdentifier(user.GetTypedID())
|
||||
userID, err := identity.IntIdentifier(user.GetID())
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, int64(2), userID)
|
||||
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) {
|
||||
userID, err := identity.IntIdentifier(user.GetTypedID())
|
||||
userID, err := identity.IntIdentifier(user.GetID())
|
||||
require.NoError(t, err)
|
||||
|
||||
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) {
|
||||
userID, err := identity.IntIdentifier(user.GetTypedID())
|
||||
userID, err := identity.IntIdentifier(user.GetID())
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, int64(2), userID)
|
||||
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) {
|
||||
starredItemsChildNavs := []*navtree.NavLink{}
|
||||
|
||||
userID, _ := identity.UserIdentifier(c.SignedInUser.GetTypedID())
|
||||
userID, _ := identity.UserIdentifier(c.SignedInUser.GetID())
|
||||
query := star.GetUserStarsQuery{
|
||||
UserID: userID,
|
||||
}
|
||||
|
@ -76,9 +76,9 @@ func (srv RulerSrv) RouteDeleteAlertRules(c *contextmodel.ReqContext, namespaceU
|
||||
return toNamespaceErrorResponse(err)
|
||||
}
|
||||
|
||||
userNamespace, id := c.SignedInUser.GetTypedID()
|
||||
userNamespace, id := c.SignedInUser.GetID().Type(), c.SignedInUser.GetID().ID()
|
||||
var loggerCtx = []any{
|
||||
"userId",
|
||||
"identity",
|
||||
id,
|
||||
"userNamespace",
|
||||
userNamespace,
|
||||
@ -283,7 +283,7 @@ func (srv RulerSrv) RouteGetRulesConfig(c *contextmodel.ReqContext) response.Res
|
||||
for groupKey, rules := range configs {
|
||||
folder, ok := namespaceMap[groupKey.NamespaceUID]
|
||||
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)
|
||||
continue
|
||||
}
|
||||
@ -359,7 +359,7 @@ func (srv RulerSrv) updateAlertRulesInGroup(c *contextmodel.ReqContext, groupKey
|
||||
var finalChanges *store.GroupDelta
|
||||
var dbConfig *ngmodels.AlertConfiguration
|
||||
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",
|
||||
groupKey.RuleGroup, "org_id", groupKey.OrgID, "user_id", id, "userNamespace", userNamespace)
|
||||
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 {
|
||||
userID, _ := identity.UserIdentifier(c.SignedInUser.GetTypedID())
|
||||
userID, _ := identity.UserIdentifier(c.SignedInUser.GetID())
|
||||
limitReached, err := srv.QuotaService.CheckQuotaReached(tranCtx, ngmodels.QuotaTargetSrv, "a.ScopeParameters{
|
||||
OrgID: c.SignedInUser.GetOrgID(),
|
||||
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.
|
||||
func (service *AlertRuleService) checkLimitsTransactionCtx(ctx context.Context, user identity.Requester) error {
|
||||
// default to 0 if there is no user
|
||||
userID := int64(0)
|
||||
u, err := identity.UserIdentifier(user.GetTypedID())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to check alert rule quota: %w", err)
|
||||
var userID int64
|
||||
if id, err := identity.UserIdentifier(user.GetID()); err == nil {
|
||||
userID = id
|
||||
}
|
||||
userID = u
|
||||
|
||||
limitReached, err := service.quotas.CheckQuotaReached(ctx, models.QuotaTargetSrv, "a.ScopeParameters{
|
||||
OrgID: user.GetOrgID(),
|
||||
|
@ -94,17 +94,14 @@ func (o *Service) HasOAuthEntry(ctx context.Context, usr identity.Requester) (*l
|
||||
return nil, false, nil
|
||||
}
|
||||
|
||||
namespace, id := usr.GetTypedID()
|
||||
if namespace != identity.TypeUser {
|
||||
// Not a user, therefore no token.
|
||||
if !identity.IsIdentityType(usr.GetID(), identity.TypeUser) {
|
||||
return nil, false, nil
|
||||
}
|
||||
|
||||
ctxLogger := logger.FromContext(ctx)
|
||||
|
||||
userID, err := identity.IntIdentifier(namespace, id)
|
||||
userID, err := identity.UserIdentifier(usr.GetID())
|
||||
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
|
||||
}
|
||||
|
||||
@ -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
|
||||
// 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 {
|
||||
ctxLogger := logger.FromContext(ctx)
|
||||
|
||||
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.
|
||||
return nil
|
||||
}
|
||||
|
||||
namespace, id := usr.GetTypedID()
|
||||
if namespace != identity.TypeUser {
|
||||
// Not a user, therefore no token.
|
||||
logger.Warn("Can only refresh OAuth tokens for users", "namespace", namespace, "userId", id)
|
||||
if !identity.IsIdentityType(usr.GetID(), identity.TypeUser) {
|
||||
ctxLogger.Warn("Can only refresh OAuth tokens for users", "id", usr.GetID())
|
||||
return nil
|
||||
}
|
||||
|
||||
ctxLogger := logger.FromContext(ctx)
|
||||
|
||||
userID, err := identity.IntIdentifier(namespace, id)
|
||||
userID, err := identity.UserIdentifier(usr.GetID())
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -35,8 +35,7 @@ func (m *UserHeaderMiddleware) applyUserHeader(ctx context.Context, h backend.Fo
|
||||
}
|
||||
|
||||
h.DeleteHTTPHeader(proxyutil.UserHeaderName)
|
||||
namespace, _ := reqCtx.SignedInUser.GetTypedID()
|
||||
if namespace != identity.TypeAnonymous {
|
||||
if !identity.IsIdentityType(reqCtx.SignedInUser.GetID(), identity.TypeAnonymous) {
|
||||
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") {
|
||||
t, _ := c.SignedInUser.GetTypedID()
|
||||
if t == identity.TypeUser {
|
||||
if identity.IsIdentityType(c.SignedInUser.GetID(), identity.TypeUser) {
|
||||
userID, err := c.SignedInUser.GetID().ParseInt()
|
||||
if err != nil {
|
||||
return response.Error(http.StatusInternalServerError, "Failed to parse user id", err)
|
||||
|
@ -165,10 +165,9 @@ func (f *accessControlDashboardPermissionFilter) buildClauses() {
|
||||
dashWildcards := accesscontrol.WildcardsFromPrefix(dashboards.ScopeDashboardsPrefix)
|
||||
folderWildcards := accesscontrol.WildcardsFromPrefix(dashboards.ScopeFoldersPrefix)
|
||||
|
||||
userID := int64(0)
|
||||
namespace, identifier := f.user.GetTypedID()
|
||||
if namespace == identity.TypeUser || namespace == identity.TypeServiceAccount {
|
||||
userID, _ = identity.IntIdentifier(namespace, identifier)
|
||||
var userID int64
|
||||
if id, err := identity.UserIdentifier(f.user.GetID()); err == nil {
|
||||
userID = id
|
||||
}
|
||||
|
||||
orgID := f.user.GetOrgID()
|
||||
|
@ -33,10 +33,9 @@ func (f *accessControlDashboardPermissionFilterNoFolderSubquery) buildClauses()
|
||||
dashWildcards := accesscontrol.WildcardsFromPrefix(dashboards.ScopeDashboardsPrefix)
|
||||
folderWildcards := accesscontrol.WildcardsFromPrefix(dashboards.ScopeFoldersPrefix)
|
||||
|
||||
userID := int64(0)
|
||||
namespace, identifier := f.user.GetTypedID()
|
||||
if namespace == identity.TypeUser || namespace == identity.TypeServiceAccount {
|
||||
userID, _ = identity.IntIdentifier(namespace, identifier)
|
||||
var userID int64
|
||||
if id, err := identity.UserIdentifier(f.user.GetID()); err == nil {
|
||||
userID = id
|
||||
}
|
||||
|
||||
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 {
|
||||
namespace, identifier := c.SignedInUser.GetTypedID()
|
||||
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)
|
||||
userID, err := identity.UserIdentifier(c.SignedInUser.GetID())
|
||||
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{
|
||||
@ -101,17 +96,12 @@ func (api *API) GetStars(c *contextmodel.ReqContext) response.Response {
|
||||
// 403: forbiddenError
|
||||
// 500: internalServerError
|
||||
func (api *API) StarDashboard(c *contextmodel.ReqContext) response.Response {
|
||||
namespace, identifier := c.SignedInUser.GetTypedID()
|
||||
if namespace != identity.TypeUser && namespace != identity.TypeServiceAccount {
|
||||
userID, err := identity.UserIdentifier(c.SignedInUser.GetID())
|
||||
if err != 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)
|
||||
}
|
||||
idString := web.Params(c.Req)[":id"]
|
||||
id, err := strconv.ParseInt(idString, 10, 64)
|
||||
id, err := strconv.ParseInt(web.Params(c.Req)[":id"], 10, 64)
|
||||
if err != 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)
|
||||
}
|
||||
|
||||
namespace, identifier := c.SignedInUser.GetTypedID()
|
||||
if namespace != identity.TypeUser && namespace != identity.TypeServiceAccount {
|
||||
userID, err := identity.UserIdentifier(c.SignedInUser.GetID())
|
||||
if err != 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)
|
||||
|
||||
if rsp != nil {
|
||||
return rsp
|
||||
}
|
||||
@ -193,14 +177,9 @@ func (api *API) UnstarDashboard(c *contextmodel.ReqContext) response.Response {
|
||||
return response.Error(http.StatusBadRequest, "Invalid dashboard ID", nil)
|
||||
}
|
||||
|
||||
namespace, identifier := c.SignedInUser.GetTypedID()
|
||||
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)
|
||||
userID, err := identity.UserIdentifier(c.SignedInUser.GetID())
|
||||
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}
|
||||
@ -233,14 +212,9 @@ func (api *API) UnstarDashboardByUID(c *contextmodel.ReqContext) response.Respon
|
||||
return response.Error(http.StatusBadRequest, "Invalid dashboard UID", nil)
|
||||
}
|
||||
|
||||
namespace, identifier := c.SignedInUser.GetTypedID()
|
||||
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)
|
||||
userID, err := identity.UserIdentifier(c.SignedInUser.GetID())
|
||||
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)
|
||||
|
@ -49,7 +49,7 @@ func (tapi *TeamAPI) createTeam(c *contextmodel.ReqContext) response.Response {
|
||||
// if the request is authenticated using API tokens
|
||||
// the SignedInUser is an empty struct therefore
|
||||
// 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 {
|
||||
case identity.TypeUser:
|
||||
userID, err := strconv.ParseInt(identifier, 10, 64)
|
||||
|
@ -169,7 +169,7 @@ func (u *SignedInUser) GetAllowedKubernetesNamespace() string {
|
||||
// GetCacheKey returns a unique key for the entity.
|
||||
// Add an extra prefix to avoid collisions with other caches
|
||||
func (u *SignedInUser) GetCacheKey() string {
|
||||
namespace, id := u.GetTypedID()
|
||||
typ, id := u.GetID().Type(), u.GetID().ID()
|
||||
if !u.HasUniqueId() {
|
||||
// Hack use the org role as id for identities that do not have a unique id
|
||||
// e.g. anonymous and render key.
|
||||
@ -181,7 +181,7 @@ func (u *SignedInUser) GetCacheKey() string {
|
||||
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
|
||||
@ -245,13 +245,11 @@ func (u *SignedInUser) GetOrgRole() identity.RoleType {
|
||||
|
||||
// GetID returns namespaced id for the entity
|
||||
func (u *SignedInUser) GetID() identity.TypedID {
|
||||
ns, id := u.GetTypedID()
|
||||
ns, id := u.getTypeAndID()
|
||||
return identity.NewTypedIDString(ns, id)
|
||||
}
|
||||
|
||||
// GetTypedID returns the namespace and ID of the active entity
|
||||
// The namespace is one of the constants defined in pkg/apimachinery/identity
|
||||
func (u *SignedInUser) GetTypedID() (identity.IdentityType, string) {
|
||||
func (u *SignedInUser) getTypeAndID() (identity.IdentityType, string) {
|
||||
switch {
|
||||
case u.ApiKeyID != 0:
|
||||
return identity.TypeAPIKey, strconv.FormatInt(u.ApiKeyID, 10)
|
||||
|
@ -114,8 +114,7 @@ func ApplyUserHeader(sendUserHeader bool, req *http.Request, user identity.Reque
|
||||
return
|
||||
}
|
||||
|
||||
namespace, _ := user.GetTypedID()
|
||||
if namespace == identity.TypeUser || namespace == identity.TypeServiceAccount {
|
||||
if identity.IsIdentityType(user.GetID(), identity.TypeUser) {
|
||||
req.Header.Set(UserHeaderName, user.GetLogin())
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user