mirror of
https://github.com/grafana/grafana.git
synced 2024-11-25 10:20:29 -06:00
cfe8317d45
Adds more spans for timing in accesscontrol and remove permission deduplicating code after benchmarking --------- Signed-off-by: Dave Henderson <dave.henderson@grafana.com> Co-authored-by: Dave Henderson <dave.henderson@grafana.com> Co-authored-by: Ieva <ieva.vasiljeva@grafana.com>
306 lines
9.7 KiB
Go
306 lines
9.7 KiB
Go
package api
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/grafana/grafana/pkg/services/authn"
|
|
"github.com/grafana/grafana/pkg/services/authn/authntest"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
|
"github.com/grafana/grafana/pkg/services/accesscontrol/actest"
|
|
"github.com/grafana/grafana/pkg/services/org"
|
|
"github.com/grafana/grafana/pkg/services/org/orgtest"
|
|
"github.com/grafana/grafana/pkg/services/user"
|
|
"github.com/grafana/grafana/pkg/services/user/usertest"
|
|
"github.com/grafana/grafana/pkg/setting"
|
|
"github.com/grafana/grafana/pkg/web/webtest"
|
|
)
|
|
|
|
func TestAPIEndpoint_GetCurrentOrg(t *testing.T) {
|
|
type testCase struct {
|
|
desc string
|
|
expectedCode int
|
|
permission []accesscontrol.Permission
|
|
}
|
|
|
|
tests := []testCase{
|
|
{
|
|
desc: "should be able to view current org with correct permission",
|
|
expectedCode: http.StatusOK,
|
|
permission: []accesscontrol.Permission{{Action: accesscontrol.ActionOrgsRead}},
|
|
},
|
|
{
|
|
desc: "should not be able to view current org without correct permission",
|
|
expectedCode: http.StatusForbidden,
|
|
permission: []accesscontrol.Permission{},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.desc, func(t *testing.T) {
|
|
server := SetupAPITestServer(t, func(hs *HTTPServer) {
|
|
hs.Cfg = setting.NewCfg()
|
|
hs.orgService = &orgtest.FakeOrgService{ExpectedOrg: &org.Org{}}
|
|
})
|
|
|
|
req := webtest.RequestWithSignedInUser(server.NewGetRequest("/api/org/"), userWithPermissions(1, tt.permission))
|
|
res, err := server.Send(req)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, tt.expectedCode, res.StatusCode)
|
|
require.NoError(t, res.Body.Close())
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestAPIEndpoint_UpdateOrg(t *testing.T) {
|
|
type testCase struct {
|
|
desc string
|
|
path string
|
|
body string
|
|
targetOrgID int64
|
|
permission []accesscontrol.Permission
|
|
expectedCode int
|
|
}
|
|
|
|
tests := []testCase{
|
|
{
|
|
desc: "should be able to update current org with correct permissions",
|
|
path: "/api/org",
|
|
body: `{"name": "test"}`,
|
|
permission: []accesscontrol.Permission{{Action: accesscontrol.ActionOrgsWrite}},
|
|
expectedCode: http.StatusOK,
|
|
},
|
|
{
|
|
desc: "should not be able to update current org without correct permissions",
|
|
path: "/api/org",
|
|
body: `{"name": "test"}`,
|
|
permission: []accesscontrol.Permission{},
|
|
expectedCode: http.StatusForbidden,
|
|
},
|
|
{
|
|
desc: "should be able to update address of current org with correct permissions",
|
|
path: "/api/org/address",
|
|
body: `{}`,
|
|
permission: []accesscontrol.Permission{{Action: accesscontrol.ActionOrgsWrite}},
|
|
expectedCode: http.StatusOK,
|
|
},
|
|
{
|
|
desc: "should not be able to update address of current org without correct permissions",
|
|
path: "/api/org/address",
|
|
body: `{}`,
|
|
permission: []accesscontrol.Permission{},
|
|
expectedCode: http.StatusForbidden,
|
|
},
|
|
{
|
|
desc: "should be able to update target org with correct permissions",
|
|
path: "/api/orgs/1",
|
|
body: `{"name": "test"}`,
|
|
targetOrgID: 1,
|
|
permission: []accesscontrol.Permission{{Action: accesscontrol.ActionOrgsWrite}},
|
|
expectedCode: http.StatusOK,
|
|
},
|
|
{
|
|
desc: "should not be able to update target org without correct permissions",
|
|
path: "/api/orgs/2",
|
|
targetOrgID: 2,
|
|
body: `{"name": "test"}`,
|
|
permission: []accesscontrol.Permission{{Action: accesscontrol.ActionOrgsWrite}},
|
|
expectedCode: http.StatusForbidden,
|
|
},
|
|
{
|
|
desc: "should be able to update address of target org with correct permissions",
|
|
path: "/api/orgs/1/address",
|
|
body: `{}`,
|
|
targetOrgID: 1,
|
|
permission: []accesscontrol.Permission{{Action: accesscontrol.ActionOrgsWrite}},
|
|
expectedCode: http.StatusOK,
|
|
},
|
|
{
|
|
desc: "should not be able to update address of target org without correct permissions",
|
|
path: "/api/orgs/2/address",
|
|
body: `{}`,
|
|
targetOrgID: 2,
|
|
permission: []accesscontrol.Permission{{Action: accesscontrol.ActionOrgsWrite}},
|
|
expectedCode: http.StatusForbidden,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.desc, func(t *testing.T) {
|
|
server := SetupAPITestServer(t, func(hs *HTTPServer) {
|
|
hs.Cfg = setting.NewCfg()
|
|
hs.orgService = &orgtest.FakeOrgService{ExpectedOrg: &org.Org{}}
|
|
hs.userService = &usertest.FakeUserService{
|
|
ExpectedSignedInUser: &user.SignedInUser{OrgID: tt.targetOrgID},
|
|
}
|
|
hs.accesscontrolService = actest.FakeService{}
|
|
hs.authnService = &authntest.FakeService{
|
|
ExpectedIdentity: &authn.Identity{
|
|
OrgID: tt.targetOrgID,
|
|
},
|
|
}
|
|
})
|
|
|
|
req := webtest.RequestWithSignedInUser(server.NewRequest(http.MethodPut, tt.path, strings.NewReader(tt.body)), userWithPermissions(1, tt.permission))
|
|
res, err := server.SendJSON(req)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, tt.expectedCode, res.StatusCode)
|
|
require.NoError(t, res.Body.Close())
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestAPIEndpoint_CreateOrgs(t *testing.T) {
|
|
type testCase struct {
|
|
desc string
|
|
permission []accesscontrol.Permission
|
|
expectedCode int
|
|
}
|
|
|
|
tests := []testCase{
|
|
{
|
|
desc: "should be able to create org with correct permission",
|
|
permission: []accesscontrol.Permission{{Action: accesscontrol.ActionOrgsCreate}},
|
|
expectedCode: http.StatusOK,
|
|
},
|
|
{
|
|
desc: "should not be able to create org without correct permission",
|
|
permission: []accesscontrol.Permission{},
|
|
expectedCode: http.StatusForbidden,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.desc, func(t *testing.T) {
|
|
server := SetupAPITestServer(t, func(hs *HTTPServer) {
|
|
hs.Cfg = setting.NewCfg()
|
|
hs.orgService = &orgtest.FakeOrgService{ExpectedOrg: &org.Org{}}
|
|
hs.accesscontrolService = actest.FakeService{}
|
|
hs.userService = &usertest.FakeUserService{
|
|
ExpectedSignedInUser: &user.SignedInUser{UserID: 1, OrgID: 0},
|
|
}
|
|
})
|
|
|
|
req := webtest.RequestWithSignedInUser(server.NewPostRequest("/api/orgs", strings.NewReader(`{"name": "test"}`)), authedUserWithPermissions(1, 0, tt.permission))
|
|
res, err := server.SendJSON(req)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, tt.expectedCode, res.StatusCode)
|
|
require.NoError(t, res.Body.Close())
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestAPIEndpoint_DeleteOrgs(t *testing.T) {
|
|
type testCase struct {
|
|
desc string
|
|
permission []accesscontrol.Permission
|
|
expectedCode int
|
|
}
|
|
|
|
tests := []testCase{
|
|
{
|
|
desc: "should be able to delete org with correct permission",
|
|
permission: []accesscontrol.Permission{{Action: accesscontrol.ActionOrgsDelete}},
|
|
expectedCode: http.StatusOK,
|
|
},
|
|
{
|
|
desc: "should not be able to delete org without correct permission",
|
|
permission: []accesscontrol.Permission{},
|
|
expectedCode: http.StatusForbidden,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.desc, func(t *testing.T) {
|
|
expectedIdentity := &authn.Identity{
|
|
OrgID: 1,
|
|
Permissions: map[int64]map[string][]string{
|
|
1: accesscontrol.GroupScopesByActionContext(context.Background(), tt.permission),
|
|
},
|
|
}
|
|
|
|
server := SetupAPITestServer(t, func(hs *HTTPServer) {
|
|
hs.Cfg = setting.NewCfg()
|
|
hs.orgService = &orgtest.FakeOrgService{ExpectedOrg: &org.Org{}}
|
|
hs.userService = &usertest.FakeUserService{ExpectedSignedInUser: &user.SignedInUser{OrgID: 1}}
|
|
hs.accesscontrolService = actest.FakeService{ExpectedPermissions: tt.permission}
|
|
hs.authnService = &authntest.FakeService{}
|
|
hs.authnService = &authntest.FakeService{
|
|
ExpectedIdentity: expectedIdentity,
|
|
}
|
|
})
|
|
|
|
req := webtest.RequestWithSignedInUser(server.NewRequest(http.MethodDelete, "/api/orgs/1", nil), userWithPermissions(2, nil))
|
|
res, err := server.Send(req)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, tt.expectedCode, res.StatusCode)
|
|
require.NoError(t, res.Body.Close())
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestAPIEndpoint_GetOrg(t *testing.T) {
|
|
type testCase struct {
|
|
desc string
|
|
permissions []accesscontrol.Permission
|
|
expectedCode int
|
|
}
|
|
|
|
tests := []testCase{
|
|
{
|
|
desc: "should be able to fetch org with correct permissions",
|
|
permissions: []accesscontrol.Permission{{Action: accesscontrol.ActionOrgsRead}},
|
|
expectedCode: http.StatusOK,
|
|
},
|
|
{
|
|
desc: "should not be able to fetch org without correct permissions",
|
|
expectedCode: http.StatusForbidden,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.desc, func(t *testing.T) {
|
|
expectedIdentity := &authn.Identity{
|
|
ID: authn.MustParseNamespaceID("user:1"),
|
|
OrgID: 1,
|
|
Permissions: map[int64]map[string][]string{
|
|
0: accesscontrol.GroupScopesByActionContext(context.Background(), tt.permissions),
|
|
1: accesscontrol.GroupScopesByActionContext(context.Background(), tt.permissions),
|
|
},
|
|
}
|
|
|
|
server := SetupAPITestServer(t, func(hs *HTTPServer) {
|
|
hs.Cfg = setting.NewCfg()
|
|
hs.orgService = &orgtest.FakeOrgService{ExpectedOrg: &org.Org{}}
|
|
hs.userService = &usertest.FakeUserService{ExpectedSignedInUser: &user.SignedInUser{OrgID: 1}}
|
|
hs.accesscontrolService = &actest.FakeService{ExpectedPermissions: tt.permissions}
|
|
hs.authnService = &authntest.FakeService{
|
|
ExpectedIdentity: expectedIdentity,
|
|
}
|
|
})
|
|
verify := func(path string) {
|
|
req := webtest.RequestWithSignedInUser(server.NewGetRequest(path), authedUserWithPermissions(1, 1, tt.permissions))
|
|
res, err := server.Send(req)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, tt.expectedCode, res.StatusCode)
|
|
if tt.expectedCode != res.StatusCode {
|
|
t.Log("Failed on path", path)
|
|
}
|
|
require.NoError(t, res.Body.Close())
|
|
}
|
|
// search orgs
|
|
verify("/api/orgs")
|
|
// fetch by id
|
|
verify("/api/orgs/1")
|
|
// fetch by name
|
|
verify("/api/orgs/name/test")
|
|
})
|
|
}
|
|
}
|