RBAC: Make RBAC action names more consistent (#49730) (#50083)

* update action names

* correctly retrieve teams for signed in user

* remove test

* undo swagger changes

* undo swagger changes pt2

* add migration from old action names to the new ones

* rename from list to read

* linting

* also update alertign actions

* fix migration

(cherry picked from commit 5dbea9996b)

Co-authored-by: Ieva <ieva.vasiljeva@grafana.com>
This commit is contained in:
Grot (@grafanabot)
2022-06-02 15:15:40 +02:00
committed by GitHub
co-authored by Ieva
parent b342fe6e30
commit 3e7a2111e6
32 changed files with 279 additions and 222 deletions
@@ -0,0 +1,68 @@
package accesscontrol
import (
"fmt"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/sqlstore/migrator"
"xorm.io/xorm"
)
func AddActionNameMigrator(mg *migrator.Migrator) {
mg.AddMigration("RBAC action name migrator", &actionNameMigrator{})
}
type actionNameMigrator struct {
sess *xorm.Session
migrator *migrator.Migrator
migrator.MigrationBase
}
var _ migrator.CodeMigration = new(actionNameMigrator)
func (m *actionNameMigrator) SQL(migrator.Dialect) string {
return CodeMigrationSQL
}
func (m *actionNameMigrator) Exec(sess *xorm.Session, migrator *migrator.Migrator) error {
m.sess = sess
m.migrator = migrator
return m.migrateActionNames()
}
func (m *actionNameMigrator) migrateActionNames() error {
actionNameMapping := map[string]string{
"licensing:update": "licensing:write",
"reports.admin:create": "reports:create",
"reports.admin:write": "reports:write",
"org.users.role:update": accesscontrol.ActionOrgUsersWrite,
"users.authtoken:update": accesscontrol.ActionUsersAuthTokenUpdate,
"users.password:update": accesscontrol.ActionUsersPasswordUpdate,
"users.permissions:update": accesscontrol.ActionUsersPermissionsUpdate,
"users.quotas:update": accesscontrol.ActionUsersQuotasUpdate,
"teams.roles:list": "teams.roles:read",
"users.roles:list": "users.roles:read",
"users.authtoken:list": accesscontrol.ActionUsersAuthTokenList,
"users.quotas:list": accesscontrol.ActionUsersQuotasList,
"users.permissions:list": "users.permissions:read",
"alert.instances:update": accesscontrol.ActionAlertingInstanceUpdate,
"alert.rules:update": accesscontrol.ActionAlertingRuleUpdate,
}
for oldName, newName := range actionNameMapping {
_, err := m.sess.Table(&accesscontrol.Permission{}).Where("action = ?", oldName).Update(&accesscontrol.Permission{Action: newName})
if err != nil {
return fmt.Errorf("failed to update permission table for action %s: %w", oldName, err)
}
}
actionsToDelete := []string{"users.teams:read", "roles:list"}
for _, action := range actionsToDelete {
_, err := m.sess.Table(&accesscontrol.Permission{}).Where("action = ?", action).Delete(accesscontrol.Permission{})
if err != nil {
return fmt.Errorf("failed to update permission table for action %s: %w", action, err)
}
}
return nil
}
@@ -90,6 +90,7 @@ func (*OSSMigrations) AddMigration(mg *Migrator) {
accesscontrol.AddManagedPermissionsMigration(mg)
accesscontrol.AddManagedFolderAlertActionsMigration(mg)
accesscontrol.AddActionNameMigrator(mg)
}
func addMigrationLogMigrations(mg *Migrator) {
+12 -1
View File
@@ -310,12 +310,23 @@ func (ss *SQLStore) GetTeamsByUser(ctx context.Context, query *models.GetTeamsBy
query.Result = make([]*models.TeamDTO, 0)
var sql bytes.Buffer
var params []interface{}
params = append(params, query.OrgId, query.UserId)
sql.WriteString(getTeamSelectSQLBase([]string{}))
sql.WriteString(` INNER JOIN team_member on team.id = team_member.team_id`)
sql.WriteString(` WHERE team.org_id = ? and team_member.user_id = ?`)
err := sess.SQL(sql.String(), query.OrgId, query.UserId).Find(&query.Result)
if !ac.IsDisabled(ss.Cfg) {
acFilter, err := ac.Filter(query.SignedInUser, "team.id", "teams:id:", ac.ActionTeamsRead)
if err != nil {
return err
}
sql.WriteString(` and` + acFilter.Where)
params = append(params, acFilter.Args...)
}
err := sess.SQL(sql.String(), params...).Find(&query.Result)
return err
})
}
+8 -1
View File
@@ -222,7 +222,14 @@ func TestIntegrationTeamCommandsAndQueries(t *testing.T) {
err := sqlStore.AddTeamMember(userIds[0], testOrgID, groupId, false, 0)
require.NoError(t, err)
query := &models.GetTeamsByUserQuery{OrgId: testOrgID, UserId: userIds[0]}
query := &models.GetTeamsByUserQuery{
OrgId: testOrgID,
UserId: userIds[0],
SignedInUser: &models.SignedInUser{
OrgId: testOrgID,
Permissions: map[int64]map[string][]string{testOrgID: {ac.ActionOrgUsersRead: {ac.ScopeUsersAll}, ac.ActionTeamsRead: {ac.ScopeTeamsAll}}},
},
}
err = sqlStore.GetTeamsByUser(context.Background(), query)
require.NoError(t, err)
require.Equal(t, len(query.Result), 1)
+14 -1
View File
@@ -577,7 +577,20 @@ func (ss *SQLStore) GetSignedInUser(ctx context.Context, query *models.GetSigned
user.ExternalAuthId = ""
}
getTeamsByUserQuery := &models.GetTeamsByUserQuery{OrgId: user.OrgId, UserId: user.UserId}
// tempUser is used to retrieve the teams for the signed in user for internal use.
tempUser := &models.SignedInUser{
OrgId: user.OrgId,
Permissions: map[int64]map[string][]string{
user.OrgId: {
ac.ActionTeamsRead: {ac.ScopeTeamsAll},
},
},
}
getTeamsByUserQuery := &models.GetTeamsByUserQuery{
OrgId: user.OrgId,
UserId: user.UserId,
SignedInUser: tempUser,
}
err = ss.GetTeamsByUser(ctx, getTeamsByUserQuery)
if err != nil {
return err