Alerting: Export contact points to check access control action instead legacy role (#71990)

* introduce a new action "alert.provisioning.secrets:read" and role "fixed:alerting.provisioning.secrets:reader"
* update alerting API authorization layer to let the user read provisioning with the new action
* let new action use decrypt flag
* add action and role to docs
This commit is contained in:
Yuri Tseretyan
2023-08-08 12:29:34 -04:00
committed by GitHub
parent e1d239a86e
commit 6b4a9d73d7
17 changed files with 347 additions and 104 deletions

View File

@@ -12,14 +12,17 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/infra/db"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/accesscontrol/acimpl"
"github.com/grafana/grafana/pkg/services/accesscontrol/actest"
"github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
"github.com/grafana/grafana/pkg/services/ngalert/models"
"github.com/grafana/grafana/pkg/services/ngalert/notifier"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/secrets"
"github.com/grafana/grafana/pkg/services/secrets/database"
"github.com/grafana/grafana/pkg/services/secrets/manager"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
)
func TestContactPointService(t *testing.T) {
@@ -243,6 +246,7 @@ func TestContactPointService(t *testing.T) {
func TestContactPointServiceDecryptRedact(t *testing.T) {
sqlStore := db.InitTestDB(t)
secretsService := manager.SetupTestService(t, database.ProvideSecretsStore(sqlStore))
ac := acimpl.ProvideAccessControl(setting.NewCfg())
t.Run("GetContactPoints gets redacted contact points by default", func(t *testing.T) {
sut := createContactPointServiceSut(t, secretsService)
@@ -253,20 +257,36 @@ func TestContactPointServiceDecryptRedact(t *testing.T) {
require.Equal(t, "slack receiver", cps[0].Name)
require.Equal(t, definitions.RedactedValue, cps[0].Settings.Get("url").MustString())
})
t.Run("GetContactPoints errors when Decrypt = true and user not Org Admin", func(t *testing.T) {
t.Run("GetContactPoints errors when Decrypt = true and user does not have permissions", func(t *testing.T) {
sut := createContactPointServiceSut(t, secretsService)
sut.ac = ac
q := cpsQuery(1)
q.Decrypt = true
_, err := sut.GetContactPoints(context.Background(), q, &user.SignedInUser{})
require.ErrorIs(t, err, ErrPermissionDenied)
})
t.Run("GetContactPoints errors when Decrypt = true and user is nil", func(t *testing.T) {
sut := createContactPointServiceSut(t, secretsService)
sut.ac = ac
q := cpsQuery(1)
q.Decrypt = true
_, err := sut.GetContactPoints(context.Background(), q, nil)
require.ErrorIs(t, err, ErrPermissionDenied)
})
t.Run("GetContactPoints gets decrypted contact points when Decrypt = true and user is Org Admin", func(t *testing.T) {
t.Run("GetContactPoints gets decrypted contact points when Decrypt = true and user has permissions", func(t *testing.T) {
sut := createContactPointServiceSut(t, secretsService)
sut.ac = ac
q := cpsQuery(1)
q.Decrypt = true
cps, err := sut.GetContactPoints(context.Background(), q, &user.SignedInUser{OrgID: 1, OrgRole: org.RoleAdmin})
cps, err := sut.GetContactPoints(context.Background(), q, &user.SignedInUser{OrgID: 1, Permissions: map[int64]map[string][]string{
1: {
accesscontrol.ActionAlertingProvisioningReadSecrets: nil,
},
}})
require.NoError(t, err)
require.Len(t, cps, 1)
@@ -325,6 +345,7 @@ func createContactPointServiceSut(t *testing.T, secretService secrets.Service) *
xact: newNopTransactionManager(),
encryptionService: secretService,
log: log.NewNopLogger(),
ac: actest.FakeAccessControl{},
}
}