Access Control: Move part of access control database (#40483)
* Add accesscontrol migrations * Add ResourceStore interface and related structs * Add team/user/builtin-role * Add accesscontrol database with functions to handle managed roles and permissions * Add ResourceManager * Add GetUserPermissions * Update pkg/services/accesscontrol/accesscontrol.go Co-authored-by: Emil Tullstedt <emil.tullstedt@grafana.com>
This commit is contained in:
co-authored by
Emil Tullstedt
parent
8c98f24777
commit
3c659f1ea0
@@ -0,0 +1,101 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||
)
|
||||
|
||||
const (
|
||||
globalOrgID = 0
|
||||
)
|
||||
|
||||
func ProvideService(sqlStore *sqlstore.SQLStore) *AccessControlStore {
|
||||
return &AccessControlStore{sqlStore}
|
||||
}
|
||||
|
||||
type AccessControlStore struct {
|
||||
sql *sqlstore.SQLStore
|
||||
}
|
||||
|
||||
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 *sqlstore.DBSession) error {
|
||||
filter, params := userRolesFilter(query.OrgID, query.UserID, query.Roles)
|
||||
|
||||
// TODO: optimize this
|
||||
q := `SELECT
|
||||
permission.id,
|
||||
permission.role_id,
|
||||
permission.action,
|
||||
permission.scope,
|
||||
permission.updated,
|
||||
permission.created
|
||||
FROM permission
|
||||
INNER JOIN role ON role.id = permission.role_id
|
||||
` + filter
|
||||
|
||||
if err := sess.SQL(q, params...).Find(&result); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
return result, err
|
||||
}
|
||||
|
||||
func userRolesFilter(orgID, userID int64, roles []string) (string, []interface{}) {
|
||||
q := `
|
||||
WHERE role.id IN (
|
||||
SELECT ur.role_id
|
||||
FROM user_role AS ur
|
||||
WHERE ur.user_id = ?
|
||||
AND (ur.org_id = ? OR ur.org_id = ?)
|
||||
UNION
|
||||
SELECT tr.role_id FROM team_role as tr
|
||||
INNER JOIN team_member as tm ON tm.team_id = tr.team_id
|
||||
WHERE tm.user_id = ? AND tr.org_id = ?
|
||||
`
|
||||
params := []interface{}{userID, orgID, globalOrgID, userID, orgID}
|
||||
|
||||
if len(roles) != 0 {
|
||||
q += `
|
||||
UNION
|
||||
SELECT br.role_id FROM builtin_role AS br
|
||||
WHERE role IN (? ` + strings.Repeat(", ?", len(roles)-1) + `)
|
||||
`
|
||||
for _, role := range roles {
|
||||
params = append(params, role)
|
||||
}
|
||||
|
||||
q += `AND (br.org_id = ? OR br.org_id = ?)`
|
||||
params = append(params, orgID, globalOrgID)
|
||||
}
|
||||
|
||||
q += `)`
|
||||
|
||||
return q, params
|
||||
}
|
||||
|
||||
func deletePermissions(sess *sqlstore.DBSession, ids []int64) error {
|
||||
if len(ids) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
rawSQL := "DELETE FROM permission WHERE id IN(?" + strings.Repeat(",?", len(ids)-1) + ")"
|
||||
args := make([]interface{}, 0, len(ids)+1)
|
||||
args = append(args, rawSQL)
|
||||
for _, id := range ids {
|
||||
args = append(args, id)
|
||||
}
|
||||
|
||||
_, err := sess.Exec(args...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user