accesscontrol service read replica (#89963)
* accesscontrol service read replica * now using the ReplDB interface * ReadReplica for GetUser
This commit is contained in:
@@ -36,17 +36,17 @@ const (
|
||||
WHERE br.role = ?`
|
||||
)
|
||||
|
||||
func ProvideService(sql db.DB) *AccessControlStore {
|
||||
func ProvideService(sql db.ReplDB) *AccessControlStore {
|
||||
return &AccessControlStore{sql}
|
||||
}
|
||||
|
||||
type AccessControlStore struct {
|
||||
sql db.DB
|
||||
sql db.ReplDB
|
||||
}
|
||||
|
||||
func (s *AccessControlStore) GetUserPermissions(ctx context.Context, query accesscontrol.GetUserPermissionsQuery) ([]accesscontrol.Permission, error) {
|
||||
result := make([]accesscontrol.Permission, 0)
|
||||
err := s.sql.WithDbSession(ctx, func(sess *db.Session) error {
|
||||
err := s.sql.ReadReplica().WithDbSession(ctx, func(sess *db.Session) error {
|
||||
if query.UserID == 0 && len(query.TeamIDs) == 0 && len(query.Roles) == 0 {
|
||||
// no permission to fetch
|
||||
return nil
|
||||
@@ -104,7 +104,7 @@ func (s *AccessControlStore) GetTeamsPermissions(ctx context.Context, query acce
|
||||
orgID := query.OrgID
|
||||
rolePrefixes := query.RolePrefixes
|
||||
result := make([]teamPermission, 0)
|
||||
err := s.sql.WithDbSession(ctx, func(sess *db.Session) error {
|
||||
err := s.sql.ReadReplica().WithDbSession(ctx, func(sess *db.Session) error {
|
||||
if len(teams) == 0 {
|
||||
// no permission to fetch
|
||||
return nil
|
||||
@@ -172,7 +172,7 @@ func (s *AccessControlStore) SearchUsersPermissions(ctx context.Context, orgID i
|
||||
}
|
||||
}
|
||||
|
||||
if err := s.sql.WithDbSession(ctx, func(sess *db.Session) error {
|
||||
if err := s.sql.ReadReplica().WithDbSession(ctx, func(sess *db.Session) error {
|
||||
roleNameFilterJoin := ""
|
||||
if len(options.RolePrefixes) > 0 {
|
||||
roleNameFilterJoin = "INNER JOIN role AS r ON up.role_id = r.id"
|
||||
@@ -198,7 +198,7 @@ func (s *AccessControlStore) SearchUsersPermissions(ctx context.Context, orgID i
|
||||
params = append(params, userID)
|
||||
}
|
||||
|
||||
grafanaAdmin := fmt.Sprintf(grafanaAdminAssignsSQL, s.sql.Quote("user"))
|
||||
grafanaAdmin := fmt.Sprintf(grafanaAdminAssignsSQL, s.sql.ReadReplica().Quote("user"))
|
||||
params = append(params, accesscontrol.RoleGrafanaAdmin)
|
||||
if options.NamespacedID != "" {
|
||||
grafanaAdmin += " AND sa.user_id = ?"
|
||||
@@ -284,11 +284,11 @@ func (s *AccessControlStore) GetUsersBasicRoles(ctx context.Context, userFilter
|
||||
IsAdmin bool `xorm:"is_admin"`
|
||||
}
|
||||
dbRoles := make([]UserOrgRole, 0)
|
||||
if err := s.sql.WithDbSession(ctx, func(sess *db.Session) error {
|
||||
if err := s.sql.ReadReplica().WithDbSession(ctx, func(sess *db.Session) error {
|
||||
// Find roles
|
||||
q := `
|
||||
SELECT u.id, ou.role, u.is_admin
|
||||
FROM ` + s.sql.GetDialect().Quote("user") + ` AS u
|
||||
FROM ` + s.sql.ReadReplica().GetDialect().Quote("user") + ` AS u
|
||||
LEFT JOIN org_user AS ou ON u.id = ou.user_id
|
||||
WHERE (u.is_admin OR ou.org_id = ?)
|
||||
`
|
||||
@@ -318,7 +318,7 @@ func (s *AccessControlStore) GetUsersBasicRoles(ctx context.Context, userFilter
|
||||
}
|
||||
|
||||
func (s *AccessControlStore) DeleteUserPermissions(ctx context.Context, orgID, userID int64) error {
|
||||
err := s.sql.WithDbSession(ctx, func(sess *db.Session) error {
|
||||
err := s.sql.DB().WithDbSession(ctx, func(sess *db.Session) error {
|
||||
roleDeleteQuery := "DELETE FROM user_role WHERE user_id = ?"
|
||||
roleDeleteParams := []any{roleDeleteQuery, userID}
|
||||
if orgID != accesscontrol.GlobalOrgID {
|
||||
@@ -383,7 +383,7 @@ func (s *AccessControlStore) DeleteUserPermissions(ctx context.Context, orgID, u
|
||||
}
|
||||
|
||||
func (s *AccessControlStore) DeleteTeamPermissions(ctx context.Context, orgID, teamID int64) error {
|
||||
err := s.sql.WithDbSession(ctx, func(sess *db.Session) error {
|
||||
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}
|
||||
|
||||
|
||||
@@ -470,8 +470,8 @@ func createUsersAndTeams(t *testing.T, store db.DB, svcs helperServices, orgID i
|
||||
return res
|
||||
}
|
||||
|
||||
func setupTestEnv(t testing.TB) (*database.AccessControlStore, rs.Store, user.Service, team.Service, org.Service, *sqlstore.SQLStore) {
|
||||
sql, cfg := db.InitTestDBWithCfg(t)
|
||||
func setupTestEnv(t testing.TB) (*database.AccessControlStore, rs.Store, user.Service, team.Service, org.Service, *sqlstore.ReplStore) {
|
||||
sql, cfg := db.InitTestReplDBWithCfg(t)
|
||||
cfg.AutoAssignOrg = true
|
||||
cfg.AutoAssignOrgRole = "Viewer"
|
||||
cfg.AutoAssignOrgId = 1
|
||||
|
||||
@@ -18,7 +18,7 @@ func extServiceRoleName(externalServiceID string) string {
|
||||
|
||||
func (s *AccessControlStore) DeleteExternalServiceRole(ctx context.Context, externalServiceID string) error {
|
||||
uid := accesscontrol.PrefixedRoleUID(extServiceRoleName(externalServiceID))
|
||||
return s.sql.WithDbSession(ctx, func(sess *db.Session) error {
|
||||
return s.sql.DB().WithDbSession(ctx, func(sess *db.Session) error {
|
||||
stored, errGet := getRoleByUID(ctx, sess, uid)
|
||||
if errGet != nil {
|
||||
// Role not found, nothing to do
|
||||
@@ -55,7 +55,7 @@ func (s *AccessControlStore) SaveExternalServiceRole(ctx context.Context, cmd ac
|
||||
role := genExternalServiceRole(cmd)
|
||||
assignment := genExternalServiceAssignment(cmd)
|
||||
|
||||
return s.sql.WithDbSession(ctx, func(sess *db.Session) error {
|
||||
return s.sql.DB().WithDbSession(ctx, func(sess *db.Session) error {
|
||||
// Create or update the role
|
||||
existingRole, errSaveRole := s.saveRole(ctx, sess, &role)
|
||||
if errSaveRole != nil {
|
||||
|
||||
@@ -7,9 +7,10 @@ import (
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/db"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestAccessControlStore_SaveExternalServiceRole(t *testing.T) {
|
||||
@@ -114,7 +115,7 @@ func TestAccessControlStore_SaveExternalServiceRole(t *testing.T) {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
s := &AccessControlStore{
|
||||
sql: db.InitTestDB(t),
|
||||
sql: db.InitTestReplDB(t),
|
||||
}
|
||||
|
||||
for i := range tt.runs {
|
||||
@@ -125,7 +126,7 @@ func TestAccessControlStore_SaveExternalServiceRole(t *testing.T) {
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
errDBSession := s.sql.WithDbSession(ctx, func(sess *db.Session) error {
|
||||
errDBSession := s.sql.DB().WithDbSession(ctx, func(sess *db.Session) error {
|
||||
storedRole, err := getRoleByUID(ctx, sess, accesscontrol.PrefixedRoleUID(extServiceRoleName(tt.runs[i].cmd.ExternalServiceID)))
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, storedRole)
|
||||
@@ -187,13 +188,13 @@ func TestAccessControlStore_DeleteExternalServiceRole(t *testing.T) {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
s := &AccessControlStore{
|
||||
sql: db.InitTestDB(t),
|
||||
sql: db.InitTestReplDB(t),
|
||||
}
|
||||
if tt.init != nil {
|
||||
tt.init(t, ctx, s)
|
||||
}
|
||||
roleID := int64(-1)
|
||||
err := s.sql.WithDbSession(ctx, func(sess *db.Session) error {
|
||||
err := s.sql.DB().WithDbSession(ctx, func(sess *db.Session) error {
|
||||
role, err := getRoleByUID(ctx, sess, accesscontrol.PrefixedRoleUID(extServiceRoleName(tt.id)))
|
||||
if err != nil && !errors.Is(err, accesscontrol.ErrRoleNotFound) {
|
||||
return err
|
||||
@@ -217,7 +218,7 @@ func TestAccessControlStore_DeleteExternalServiceRole(t *testing.T) {
|
||||
}
|
||||
|
||||
// Assignments should be deleted
|
||||
_ = s.sql.WithDbSession(ctx, func(sess *db.Session) error {
|
||||
_ = s.sql.DB().WithDbSession(ctx, func(sess *db.Session) error {
|
||||
var assignment accesscontrol.UserRole
|
||||
count, err := sess.Where("role_id = ?", roleID).Count(&assignment)
|
||||
require.NoError(t, err)
|
||||
@@ -226,7 +227,7 @@ func TestAccessControlStore_DeleteExternalServiceRole(t *testing.T) {
|
||||
})
|
||||
|
||||
// Permissions should be deleted
|
||||
_ = s.sql.WithDbSession(ctx, func(sess *db.Session) error {
|
||||
_ = s.sql.DB().WithDbSession(ctx, func(sess *db.Session) error {
|
||||
var permission accesscontrol.Permission
|
||||
count, err := sess.Where("role_id = ?", roleID).Count(&permission)
|
||||
require.NoError(t, err)
|
||||
@@ -235,7 +236,7 @@ func TestAccessControlStore_DeleteExternalServiceRole(t *testing.T) {
|
||||
})
|
||||
|
||||
// Role should be deleted
|
||||
_ = s.sql.WithDbSession(ctx, func(sess *db.Session) error {
|
||||
_ = s.sql.DB().WithDbSession(ctx, func(sess *db.Session) error {
|
||||
storedRole, err := getRoleByUID(ctx, sess, accesscontrol.PrefixedRoleUID(extServiceRoleName(tt.id)))
|
||||
require.ErrorIs(t, err, accesscontrol.ErrRoleNotFound)
|
||||
require.Nil(t, storedRole)
|
||||
|
||||
Reference in New Issue
Block a user