Instrument tracing across accesscontrol (#91864)

Instrument tracing across accesscontrol 

---------

Co-authored-by: Dave Henderson <dave.henderson@grafana.com>
This commit is contained in:
Jeff Levin
2024-08-16 14:08:19 -08:00
committed by GitHub
co-authored by Dave Henderson
parent 68f545210d
commit 028e8ac59e
22 changed files with 301 additions and 51 deletions
@@ -8,8 +8,11 @@ import (
"github.com/grafana/grafana/pkg/infra/db"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"go.opentelemetry.io/otel"
)
var tracer = otel.Tracer("github.com/grafana/grafana/pkg/services/accesscontrol/database")
const (
// userAssignsSQL is a query to select all users assignments.
userAssignsSQL = `SELECT ur.user_id, ur.org_id, ur.role_id
@@ -45,6 +48,9 @@ type AccessControlStore struct {
}
func (s *AccessControlStore) GetUserPermissions(ctx context.Context, query accesscontrol.GetUserPermissionsQuery) ([]accesscontrol.Permission, error) {
ctx, span := tracer.Start(ctx, "accesscontrol.database.GetUserPermissions")
defer span.End()
result := make([]accesscontrol.Permission, 0)
err := s.sql.ReadReplica().WithDbSession(ctx, func(sess *db.Session) error {
if query.UserID == 0 && len(query.TeamIDs) == 0 && len(query.Roles) == 0 {
@@ -100,6 +106,9 @@ func (p teamPermission) Permission() accesscontrol.Permission {
}
func (s *AccessControlStore) GetTeamsPermissions(ctx context.Context, query accesscontrol.GetUserPermissionsQuery) (map[int64][]accesscontrol.Permission, error) {
ctx, span := tracer.Start(ctx, "accesscontrol.database.GetTeamsPermissions")
defer span.End()
teams := query.TeamIDs
orgID := query.OrgID
rolePrefixes := query.RolePrefixes
@@ -156,6 +165,9 @@ func (s *AccessControlStore) GetTeamsPermissions(ctx context.Context, query acce
// SearchUsersPermissions returns the list of user permissions in specific organization indexed by UserID
func (s *AccessControlStore) SearchUsersPermissions(ctx context.Context, orgID int64, options accesscontrol.SearchOptions) (map[int64][]accesscontrol.Permission, error) {
ctx, span := tracer.Start(ctx, "accesscontrol.database.SearchUsersPermissions")
defer span.End()
type UserRBACPermission struct {
UserID int64 `xorm:"user_id"`
Action string `xorm:"action"`
@@ -278,6 +290,9 @@ func (s *AccessControlStore) SearchUsersPermissions(ctx context.Context, orgID i
// GetUsersBasicRoles returns the list of user basic roles (Admin, Editor, Viewer, Grafana Admin) indexed by UserID
func (s *AccessControlStore) GetUsersBasicRoles(ctx context.Context, userFilter []int64, orgID int64) (map[int64][]string, error) {
ctx, span := tracer.Start(ctx, "accesscontrol.database.GetUsersBasicRoles")
defer span.End()
type UserOrgRole struct {
UserID int64 `xorm:"id"`
OrgRole string `xorm:"role"`
@@ -318,6 +333,9 @@ func (s *AccessControlStore) GetUsersBasicRoles(ctx context.Context, userFilter
}
func (s *AccessControlStore) DeleteUserPermissions(ctx context.Context, orgID, userID int64) error {
ctx, span := tracer.Start(ctx, "accesscontrol.database.DeleteUserPermissions")
defer span.End()
err := s.sql.DB().WithDbSession(ctx, func(sess *db.Session) error {
roleDeleteQuery := "DELETE FROM user_role WHERE user_id = ?"
roleDeleteParams := []any{roleDeleteQuery, userID}
@@ -383,6 +401,9 @@ func (s *AccessControlStore) DeleteUserPermissions(ctx context.Context, orgID, u
}
func (s *AccessControlStore) DeleteTeamPermissions(ctx context.Context, orgID, teamID int64) error {
ctx, span := tracer.Start(ctx, "accesscontrol.database.DeleteTeamPermissions")
defer span.End()
err := s.sql.DB().WithDbSession(ctx, func(sess *db.Session) error {
roleDeleteQuery := "DELETE FROM team_role WHERE team_id = ? AND org_id = ?"
roleDeleteParams := []any{roleDeleteQuery, teamID, orgID}
@@ -17,6 +17,9 @@ func extServiceRoleName(externalServiceID string) string {
}
func (s *AccessControlStore) DeleteExternalServiceRole(ctx context.Context, externalServiceID string) error {
ctx, span := tracer.Start(ctx, "accesscontrol.database.DeleteExternalServiceRole")
defer span.End()
uid := accesscontrol.PrefixedRoleUID(extServiceRoleName(externalServiceID))
return s.sql.DB().WithDbSession(ctx, func(sess *db.Session) error {
stored, errGet := getRoleByUID(ctx, sess, uid)
@@ -52,6 +55,9 @@ func (s *AccessControlStore) DeleteExternalServiceRole(ctx context.Context, exte
}
func (s *AccessControlStore) SaveExternalServiceRole(ctx context.Context, cmd accesscontrol.SaveExternalServiceRoleCommand) error {
ctx, span := tracer.Start(ctx, "accesscontrol.database.SaveExternalServiceRole")
defer span.End()
role := genExternalServiceRole(cmd)
assignment := genExternalServiceAssignment(cmd)
@@ -103,6 +109,9 @@ func genExternalServiceAssignment(cmd accesscontrol.SaveExternalServiceRoleComma
}
func getRoleByUID(ctx context.Context, sess *db.Session, uid string) (*accesscontrol.Role, error) {
_, span := tracer.Start(ctx, "accesscontrol.database.getRoleByUID")
defer span.End()
var role accesscontrol.Role
has, err := sess.Where("uid = ?", uid).Get(&role)
if err != nil {
@@ -115,6 +124,9 @@ func getRoleByUID(ctx context.Context, sess *db.Session, uid string) (*accesscon
}
func getRoleAssignments(ctx context.Context, sess *db.Session, roleID int64) ([]accesscontrol.UserRole, error) {
_, span := tracer.Start(ctx, "accesscontrol.database.GgetRoleAssignments")
defer span.End()
var assignements []accesscontrol.UserRole
if err := sess.Where("role_id = ?", roleID).Find(&assignements); err != nil {
return nil, err
@@ -123,6 +135,9 @@ func getRoleAssignments(ctx context.Context, sess *db.Session, roleID int64) ([]
}
func getRolePermissions(ctx context.Context, sess *db.Session, id int64) ([]accesscontrol.Permission, error) {
_, span := tracer.Start(ctx, "accesscontrol.database.getRolePermissions")
defer span.End()
var permissions []accesscontrol.Permission
if err := sess.Where("role_id = ?", id).Find(&permissions); err != nil {
return nil, err
@@ -157,6 +172,9 @@ func permissionDiff(previous, new []accesscontrol.Permission) (added, removed []
}
func (*AccessControlStore) saveRole(ctx context.Context, sess *db.Session, role *accesscontrol.Role) (*accesscontrol.Role, error) {
ctx, span := tracer.Start(ctx, "accesscontrol.database.saveRole")
defer span.End()
existingRole, err := getRoleByUID(ctx, sess, role.UID)
if err != nil && !errors.Is(err, accesscontrol.ErrRoleNotFound) {
return nil, err
@@ -177,6 +195,9 @@ func (*AccessControlStore) saveRole(ctx context.Context, sess *db.Session, role
}
func (*AccessControlStore) savePermissions(ctx context.Context, sess *db.Session, roleID int64, permissions []accesscontrol.Permission) error {
ctx, span := tracer.Start(ctx, "accesscontrol.database.savePermissions")
defer span.End()
now := time.Now()
storedPermissions, err := getRolePermissions(ctx, sess, roleID)
if err != nil {
@@ -210,6 +231,9 @@ func (*AccessControlStore) savePermissions(ctx context.Context, sess *db.Session
}
func (*AccessControlStore) saveUserAssignment(ctx context.Context, sess *db.Session, assignment accesscontrol.UserRole) error {
ctx, span := tracer.Start(ctx, "accesscontrol.database.saveUserAssignment")
defer span.End()
// alreadyAssigned checks if the assignment already exists without accounting for the organization
assignments, errGetAssigns := getRoleAssignments(ctx, sess, assignment.RoleID)
if errGetAssigns != nil {
@@ -13,6 +13,9 @@ import (
)
func GetAccessPolicies(ctx context.Context, orgID int64, sql *session.SessionDB, resolver accesscontrol.ScopeAttributeResolverFunc) ([]accesspolicy.Resource, error) {
ctx, span := tracer.Start(ctx, "accesscontrol.database.GetAccessPolicies")
defer span.End()
type permissionInfo struct {
RoleUID string
RoleName string
@@ -25,14 +28,14 @@ func GetAccessPolicies(ctx context.Context, orgID int64, sql *session.SessionDB,
policies := make([]accesspolicy.Resource, 0)
current := &accesspolicy.Resource{}
prevKey := ""
rows, err := sql.Query(ctx, `SELECT
rows, err := sql.Query(ctx, `SELECT
role.uid as role_uid,
role.name as role_name,
scope,
action,
permission.created,
permission.updated
FROM permission
permission.updated
FROM permission
JOIN role ON permission.role_id = role.id
WHERE org_id=?
ORDER BY role.id ASC, scope ASC, action ASC`, orgID)