The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
grafana/pkg/services/accesscontrol/database/database.go

122 lines
3.5 KiB

package database
import (
"context"
"strconv"
"strings"
"github.com/grafana/grafana/pkg/infra/db"
"github.com/grafana/grafana/pkg/services/accesscontrol"
)
func ProvideService(sql db.DB) *AccessControlStore {
return &AccessControlStore{sql}
}
type AccessControlStore struct {
sql db.DB
}
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 {
if query.UserID == 0 && len(query.TeamIDs) == 0 && len(query.Roles) == 0 {
// no permission to fetch
return nil
}
filter, params := accesscontrol.UserRolesFilter(query.OrgID, query.UserID, query.TeamIDs, query.Roles)
q := `
SELECT
permission.action,
permission.scope
FROM permission
INNER JOIN role ON role.id = permission.role_id
` + filter
if len(query.Actions) > 0 {
q += " WHERE permission.action IN("
if len(query.Actions) > 0 {
q += "?" + strings.Repeat(",?", len(query.Actions)-1)
}
q += ")"
for _, a := range query.Actions {
params = append(params, a)
}
}
if err := sess.SQL(q, params...).Find(&result); err != nil {
return err
}
return nil
})
return result, err
}
func (s *AccessControlStore) DeleteUserPermissions(ctx context.Context, orgID, userID int64) error {
err := s.sql.WithDbSession(ctx, func(sess *db.Session) error {
roleDeleteQuery := "DELETE FROM user_role WHERE user_id = ?"
roleDeleteParams := []interface{}{roleDeleteQuery, userID}
if orgID != accesscontrol.GlobalOrgID {
roleDeleteQuery += " AND org_id = ?"
roleDeleteParams = []interface{}{roleDeleteQuery, userID, orgID}
}
// Delete user role assignments
if _, err := sess.Exec(roleDeleteParams...); err != nil {
return err
}
// only delete scopes to user if all permissions is removed (i.e. user is removed)
if orgID == accesscontrol.GlobalOrgID {
// Delete permissions that are scoped to user
if _, err := sess.Exec("DELETE FROM permission WHERE scope = ?", accesscontrol.Scope("users", "id", strconv.FormatInt(userID, 10))); err != nil {
return err
}
}
roleQuery := "SELECT id FROM role WHERE name = ?"
roleParams := []interface{}{accesscontrol.ManagedUserRoleName(userID)}
if orgID != accesscontrol.GlobalOrgID {
roleQuery += " AND org_id = ?"
roleParams = []interface{}{accesscontrol.ManagedUserRoleName(userID), orgID}
}
var roleIDs []int64
if err := sess.SQL(roleQuery, roleParams...).Find(&roleIDs); err != nil {
return err
}
if len(roleIDs) == 0 {
return nil
}
permissionDeleteQuery := "DELETE FROM permission WHERE role_id IN(? " + strings.Repeat(",?", len(roleIDs)-1) + ")"
permissionDeleteParams := make([]interface{}, 0, len(roleIDs)+1)
permissionDeleteParams = append(permissionDeleteParams, permissionDeleteQuery)
for _, id := range roleIDs {
permissionDeleteParams = append(permissionDeleteParams, id)
}
// Delete managed user permissions
if _, err := sess.Exec(permissionDeleteParams...); err != nil {
return err
}
managedRoleDeleteQuery := "DELETE FROM role WHERE id IN(? " + strings.Repeat(",?", len(roleIDs)-1) + ")"
managedRoleDeleteParams := []interface{}{managedRoleDeleteQuery}
for _, id := range roleIDs {
managedRoleDeleteParams = append(managedRoleDeleteParams, id)
}
// Delete managed user roles
if _, err := sess.Exec(managedRoleDeleteParams...); err != nil {
return err
}
return nil
})
return err
}