2022-05-20 22:55:07 +08:00
package accesscontrol
import (
"fmt"
"time"
2025-05-02 23:13:01 +08:00
"github.com/grafana/grafana/pkg/util/xorm"
2022-05-20 22:55:07 +08:00
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/sqlstore/migrator"
)
func AddAlertingPermissionsMigrator ( mg * migrator . Migrator ) {
mg . AddMigration ( "alerting notification permissions" , & alertingMigrator { } )
}
type alertingMigrator struct {
sess * xorm . Session
migrator * migrator . Migrator
migrator . MigrationBase
}
var _ migrator . CodeMigration = new ( alertingMigrator )
func ( m * alertingMigrator ) SQL ( migrator . Dialect ) string {
return "code migration"
}
func ( m * alertingMigrator ) Exec ( sess * xorm . Session , migrator * migrator . Migrator ) error {
m . sess = sess
m . migrator = migrator
return m . migrateNotificationActions ( )
}
func ( m * alertingMigrator ) migrateNotificationActions ( ) error {
var results [ ] accesscontrol . Permission
err := m . sess . Table ( & accesscontrol . Permission { } ) . In ( "action" , "alert.notifications:update" , "alert.notifications:create" , "alert.notifications:delete" , accesscontrol . ActionAlertingNotificationsWrite ) . Find ( & results )
if err != nil {
return fmt . Errorf ( "failed to query permission table: %w" , err )
}
groupByRoleID := make ( map [ int64 ] bool )
toDelete := make ( [ ] interface { } , 0 , len ( results ) )
for _ , result := range results {
if result . Action == accesscontrol . ActionAlertingNotificationsWrite {
groupByRoleID [ result . RoleID ] = false
continue // do not delete this permission
}
if _ , ok := groupByRoleID [ result . RoleID ] ; ! ok {
groupByRoleID [ result . RoleID ] = true
}
toDelete = append ( toDelete , result . ID )
}
toAdd := make ( [ ] accesscontrol . Permission , 0 , len ( groupByRoleID ) )
now := time . Now ( )
for roleID , add := range groupByRoleID {
if ! add {
m . migrator . Logger . Info ( fmt . Sprintf ( "skip adding action %s to role ID %d because it is already there" , accesscontrol . ActionAlertingNotificationsWrite , roleID ) )
continue
}
toAdd = append ( toAdd , accesscontrol . Permission {
RoleID : roleID ,
Action : accesscontrol . ActionAlertingNotificationsWrite ,
Scope : "" ,
Created : now ,
Updated : now ,
} )
}
if len ( toAdd ) > 0 {
added , err := m . sess . Table ( & accesscontrol . Permission { } ) . InsertMulti ( toAdd )
if err != nil {
return fmt . Errorf ( "failed to insert new permissions:%w" , err )
}
m . migrator . Logger . Debug ( fmt . Sprintf ( "updated %d of %d roles with new permission %s" , added , len ( toAdd ) , accesscontrol . ActionAlertingNotificationsWrite ) )
}
if len ( toDelete ) > 0 {
_ , err = m . sess . Table ( & accesscontrol . Permission { } ) . In ( "id" , toDelete ... ) . Delete ( accesscontrol . Permission { } )
if err != nil {
return fmt . Errorf ( "failed to delete deprecated permissions [alert.notifications:update, alert.notifications:create, alert.notifications:delete]:%w" , err )
}
}
return nil
}
2024-11-07 00:31:40 +08:00
type receiverCreateScopeMigration struct {
migrator . MigrationBase
}
var _ migrator . CodeMigration = new ( alertingMigrator )
func ( m * receiverCreateScopeMigration ) SQL ( migrator . Dialect ) string {
return "code migration"
}
func ( m * receiverCreateScopeMigration ) Exec ( sess * xorm . Session , mg * migrator . Migrator ) error {
result , err := sess . Exec ( ` UPDATE permission
SET scope = ' ' ,
kind = ' ' ,
attribute = ' ' ,
identifier = ' '
WHERE action = ' alert . notifications . receivers : create '
AND ( scope < > ' ' OR kind < > ' ' OR attribute < > ' ' OR identifier < > ' ' ) ; ` )
if result != nil {
aff , _ := result . RowsAffected ( )
if aff > 0 {
mg . Logger . Info ( "Removed scope from permission 'alert.notifications.receivers:create'" , "affectedRows" , aff )
}
}
return err
}
func AddReceiverCreateScopeMigration ( mg * migrator . Migrator ) {
mg . AddMigration ( "remove scope from alert.notifications.receivers:create" , & receiverCreateScopeMigration { } )
}