Access control: Basic structure and functionality behind feature toggle (#31893)

Co-authored-by: Alexander Zobnin <alexander.zobnin@grafana.com>
Co-authored-by: Emil Tullstedt <emil.tullstedt@grafana.com>
Co-authored-by: Arve Knudsen <arve.knudsen@grafana.com>
Co-authored-by: Marcus Efraimsson <marcus.efraimsson@grafana.com>
This commit is contained in:
Alexander Zobnin
2021-03-22 13:22:48 +01:00
committed by GitHub
co-authored by Alexander Zobnin Emil Tullstedt Arve Knudsen Marcus Efraimsson
parent fd9dee87e4
commit 20bd591bea
18 changed files with 2556 additions and 10 deletions
@@ -0,0 +1,121 @@
package testing
import (
"context"
"testing"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/sqlstore"
)
type RoleTestCase struct {
Name string
UID string
Permissions []PermissionTestCase
}
type PermissionTestCase struct {
Permission string
Scope string
}
func CreateRole(t *testing.T, ac accesscontrol.Store, p RoleTestCase) *accesscontrol.RoleDTO {
createRoleCmd := accesscontrol.CreateRoleWithPermissionsCommand{
OrgID: 1,
UID: p.UID,
Name: p.Name,
Permissions: []accesscontrol.Permission{},
}
for _, perm := range p.Permissions {
createRoleCmd.Permissions = append(createRoleCmd.Permissions, accesscontrol.Permission{
Permission: perm.Permission,
Scope: perm.Scope,
})
}
res, err := ac.CreateRoleWithPermissions(context.Background(), createRoleCmd)
require.NoError(t, err)
return res
}
func CreateUserWithRole(t *testing.T, db *sqlstore.SQLStore, ac accesscontrol.Store, user string, roles []RoleTestCase) {
createUserCmd := models.CreateUserCommand{
Email: user + "@test.com",
Name: user,
Login: user,
OrgId: 1,
}
u, err := db.CreateUser(context.Background(), createUserCmd)
require.NoError(t, err)
userId := u.Id
for _, p := range roles {
createRoleCmd := accesscontrol.CreateRoleCommand{
OrgID: 1,
Name: p.Name,
}
res, err := ac.CreateRole(context.Background(), createRoleCmd)
require.NoError(t, err)
roleId := res.ID
for _, perm := range p.Permissions {
permCmd := accesscontrol.CreatePermissionCommand{
RoleID: roleId,
Permission: perm.Permission,
Scope: perm.Scope,
}
_, err := ac.CreatePermission(context.Background(), permCmd)
require.NoError(t, err)
}
addUserRoleCmd := accesscontrol.AddUserRoleCommand{
OrgID: 1,
RoleID: roleId,
UserID: userId,
}
err = ac.AddUserRole(&addUserRoleCmd)
require.NoError(t, err)
}
}
func CreateTeamWithRole(t *testing.T, db *sqlstore.SQLStore, ac accesscontrol.Store, teamname string, roles []RoleTestCase) {
email, orgID := teamname+"@test.com", int64(1)
team, err := db.CreateTeam(teamname, email, orgID)
require.NoError(t, err)
teamId := team.Id
for _, p := range roles {
createRoleCmd := accesscontrol.CreateRoleCommand{
OrgID: orgID,
Name: p.Name,
}
res, err := ac.CreateRole(context.Background(), createRoleCmd)
require.NoError(t, err)
roleId := res.ID
for _, perm := range p.Permissions {
permCmd := accesscontrol.CreatePermissionCommand{
RoleID: roleId,
Permission: perm.Permission,
Scope: perm.Scope,
}
_, err := ac.CreatePermission(context.Background(), permCmd)
require.NoError(t, err)
}
addTeamRoleCmd := accesscontrol.AddTeamRoleCommand{
OrgID: 1,
RoleID: roleId,
TeamID: teamId,
}
err = ac.AddTeamRole(&addTeamRoleCmd)
require.NoError(t, err)
}
}
@@ -0,0 +1,109 @@
package testing
import (
"context"
"fmt"
"math"
"testing"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/sqlstore"
)
const (
usernamePrefix = "user"
teamPrefix = "team"
PermissionsPerRole = 10
UsersPerTeam = 10
)
func GenerateRoles(b *testing.B, db *sqlstore.SQLStore, ac accesscontrol.Store, rolesPerUser, users int) {
numberOfTeams := int(math.Ceil(float64(users) / UsersPerTeam))
globalUserId := 0
for i := 0; i < numberOfTeams; i++ {
// Create team
teamName := fmt.Sprintf("%s%v", teamPrefix, i)
teamEmail := fmt.Sprintf("%s@test.com", teamName)
team, err := db.CreateTeam(teamName, teamEmail, 1)
require.NoError(b, err)
teamId := team.Id
// Create team roles
for j := 0; j < rolesPerUser; j++ {
roleName := fmt.Sprintf("role_%s_%v", teamName, j)
createRoleCmd := accesscontrol.CreateRoleCommand{OrgID: 1, Name: roleName}
res, err := ac.CreateRole(context.Background(), createRoleCmd)
require.NoError(b, err)
roleId := res.ID
for k := 0; k < PermissionsPerRole; k++ {
permission := fmt.Sprintf("permission_%v", k)
scope := fmt.Sprintf("scope_%v", k)
permCmd := accesscontrol.CreatePermissionCommand{
RoleID: roleId,
Permission: permission,
Scope: scope,
}
_, err := ac.CreatePermission(context.Background(), permCmd)
require.NoError(b, err)
}
addTeamRoleCmd := accesscontrol.AddTeamRoleCommand{
OrgID: 1,
RoleID: roleId,
TeamID: teamId,
}
err = ac.AddTeamRole(&addTeamRoleCmd)
require.NoError(b, err)
}
// Create team users
for u := 0; u < UsersPerTeam; u++ {
userName := fmt.Sprintf("%s%v", usernamePrefix, globalUserId)
userEmail := fmt.Sprintf("%s@test.com", userName)
createUserCmd := models.CreateUserCommand{Email: userEmail, Name: userName, Login: userName, OrgId: 1}
user, err := db.CreateUser(context.Background(), createUserCmd)
require.NoError(b, err)
userId := user.Id
globalUserId++
// Create user roles
for j := 0; j < rolesPerUser; j++ {
roleName := fmt.Sprintf("role_%s_%v", userName, j)
createRoleCmd := accesscontrol.CreateRoleCommand{OrgID: 1, Name: roleName}
res, err := ac.CreateRole(context.Background(), createRoleCmd)
require.NoError(b, err)
roleId := res.ID
for k := 0; k < PermissionsPerRole; k++ {
permission := fmt.Sprintf("permission_%v", k)
scope := fmt.Sprintf("scope_%v", k)
permCmd := accesscontrol.CreatePermissionCommand{
RoleID: roleId,
Permission: permission,
Scope: scope,
}
_, err := ac.CreatePermission(context.Background(), permCmd)
require.NoError(b, err)
}
addUserRoleCmd := accesscontrol.AddUserRoleCommand{
OrgID: 1,
RoleID: roleId,
UserID: userId,
}
err = ac.AddUserRole(&addUserRoleCmd)
require.NoError(b, err)
}
err = db.AddTeamMember(userId, 1, teamId, false, 1)
require.NoError(b, err)
}
}
}