Files
grafana/pkg/services/accesscontrol/resourceservices/resource_services.go
T
Grot (@grafanabot) 358db0d130 Access control: FGAC for team sync endpoints (#44673) (#44856)
* add actions for team group sync

* extend the hook to allow specifying whether the user is external

* move user struct to type package

* interface for permission service to allow mocking it

* reuse existing permissions

* test fix

* refactor

* linting

(cherry picked from commit 602d62ebcc)

Co-authored-by: Ieva <ieva.vasiljeva@grafana.com>
2022-02-03 15:48:13 +00:00

104 lines
3.0 KiB
Go

package resourceservices
import (
"context"
"fmt"
"strconv"
"github.com/grafana/grafana/pkg/api/routing"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/accesscontrol/resourcepermissions"
"github.com/grafana/grafana/pkg/services/sqlstore"
)
func ProvideResourceServices(router routing.RouteRegister, sql *sqlstore.SQLStore, ac accesscontrol.AccessControl, store resourcepermissions.Store) (*ResourceServices, error) {
teamPermissions, err := ProvideTeamPermissions(router, sql, ac, store)
if err != nil {
return nil, err
}
return &ResourceServices{services: map[string]*resourcepermissions.Service{
"teams": teamPermissions,
}}, nil
}
type ResourceServices struct {
services map[string]*resourcepermissions.Service
}
func (s *ResourceServices) GetTeamService() *resourcepermissions.Service {
return s.services["teams"]
}
var (
TeamMemberActions = []string{
accesscontrol.ActionTeamsRead,
}
TeamAdminActions = []string{
accesscontrol.ActionTeamsRead,
accesscontrol.ActionTeamsDelete,
accesscontrol.ActionTeamsWrite,
accesscontrol.ActionTeamsPermissionsRead,
accesscontrol.ActionTeamsPermissionsWrite,
}
)
func ProvideTeamPermissions(router routing.RouteRegister, sql *sqlstore.SQLStore, ac accesscontrol.AccessControl, store resourcepermissions.Store) (*resourcepermissions.Service, error) {
options := resourcepermissions.Options{
Resource: "teams",
OnlyManaged: true,
ResourceValidator: func(ctx context.Context, orgID int64, resourceID string) error {
id, err := strconv.ParseInt(resourceID, 10, 64)
if err != nil {
return err
}
err = sql.GetTeamById(context.Background(), &models.GetTeamByIdQuery{
OrgId: orgID,
Id: id,
})
if err != nil {
return err
}
return nil
},
Assignments: resourcepermissions.Assignments{
Users: true,
Teams: false,
BuiltInRoles: false,
},
PermissionsToActions: map[string][]string{
"Member": TeamMemberActions,
"Admin": TeamAdminActions,
},
ReaderRoleName: "Team permission reader",
WriterRoleName: "Team permission writer",
RoleGroup: "Teams",
OnSetUser: func(session *sqlstore.DBSession, orgID int64, user accesscontrol.User, resourceID, permission string) error {
teamId, err := strconv.ParseInt(resourceID, 10, 64)
if err != nil {
return err
}
switch permission {
case "Member":
return sqlstore.AddOrUpdateTeamMemberHook(session, user.ID, orgID, teamId, user.IsExternal, 0)
case "Admin":
return sqlstore.AddOrUpdateTeamMemberHook(session, user.ID, orgID, teamId, user.IsExternal, models.PERMISSION_ADMIN)
case "":
return sqlstore.RemoveTeamMemberHook(session, &models.RemoveTeamMemberCommand{
OrgId: orgID,
UserId: user.ID,
TeamId: teamId,
})
default:
return fmt.Errorf("invalid team permission type %s", permission)
}
},
}
return resourcepermissions.New(options, router, ac, store, sql)
}