grafana/pkg/api/admin_test.go
Eric Leijonmarck 59bdff0280
Auth: Add anonymous users view and stats (#78685)
* Add anonymous stats and user table

- anonymous users users page
- add feature toggle `anonymousAccess`
- remove check for enterprise for `Device-Id` header in request
- add anonusers/device count to stats

* promise all, review comments

* make use of promise all settled

* refactoring: devices instead of users

* review comments, moved countdevices to httpserver

* fakeAnonService for tests and generate openapi spec

* do not commit openapi3 and api-merged

* add openapi

* Apply suggestions from code review

Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com>

* formatin

* precise anon devices to avoid confusion

---------

Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com>
Co-authored-by: jguer <me@jguer.space>
2023-11-29 17:58:41 +01:00

174 lines
5.0 KiB
Go

package api
import (
"io"
"net/http"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/infra/db/dbtest"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/anonymous/anontest"
"github.com/grafana/grafana/pkg/services/stats"
"github.com/grafana/grafana/pkg/services/stats/statstest"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/web/webtest"
)
func TestAPI_AdminGetSettings(t *testing.T) {
type testCase struct {
desc string
expectedCode int
expectedBody string
permissions []accesscontrol.Permission
}
tests := []testCase{
{
desc: "should return all settings",
expectedCode: http.StatusOK,
expectedBody: `{"auth.proxy":{"enable_login_token":"false","enabled":"false"},"auth.saml":{"allow_idp_initiated":"false","enabled":"true"}}`,
permissions: []accesscontrol.Permission{
{
Action: accesscontrol.ActionSettingsRead,
Scope: accesscontrol.ScopeSettingsAll,
},
},
},
{
desc: "should only return auth.saml settings",
expectedCode: http.StatusOK,
expectedBody: `{"auth.saml":{"allow_idp_initiated":"false","enabled":"true"}}`,
permissions: []accesscontrol.Permission{
{
Action: accesscontrol.ActionSettingsRead,
Scope: "settings:auth.saml:*",
},
},
},
{
desc: "should only partial properties from auth.saml and auth.proxy settings",
expectedCode: http.StatusOK,
expectedBody: `{"auth.proxy":{"enable_login_token":"false"},"auth.saml":{"enabled":"true"}}`,
permissions: []accesscontrol.Permission{
{
Action: accesscontrol.ActionSettingsRead,
Scope: "settings:auth.saml:enabled",
},
{
Action: accesscontrol.ActionSettingsRead,
Scope: "settings:auth.proxy:enable_login_token",
},
},
},
}
cfg := setting.NewCfg()
//seed sections and keys
cfg.Raw.DeleteSection("DEFAULT")
saml, err := cfg.Raw.NewSection("auth.saml")
assert.NoError(t, err)
_, err = saml.NewKey("enabled", "true")
assert.NoError(t, err)
_, err = saml.NewKey("allow_idp_initiated", "false")
assert.NoError(t, err)
proxy, err := cfg.Raw.NewSection("auth.proxy")
assert.NoError(t, err)
_, err = proxy.NewKey("enabled", "false")
assert.NoError(t, err)
_, err = proxy.NewKey("enable_login_token", "false")
assert.NoError(t, err)
for _, tt := range tests {
t.Run(tt.desc, func(t *testing.T) {
server := SetupAPITestServer(t, func(hs *HTTPServer) {
hs.Cfg = cfg
hs.SettingsProvider = setting.ProvideProvider(hs.Cfg)
})
res, err := server.Send(webtest.RequestWithSignedInUser(server.NewGetRequest("/api/admin/settings"), userWithPermissions(1, tt.permissions)))
require.NoError(t, err)
assert.Equal(t, tt.expectedCode, res.StatusCode)
body, err := io.ReadAll(res.Body)
require.NoError(t, err)
assert.Equal(t, tt.expectedBody, string(body))
require.NoError(t, res.Body.Close())
})
}
}
func TestAdmin_AccessControl(t *testing.T) {
type testCase struct {
desc string
url string
permissions []accesscontrol.Permission
expectedCode int
}
tests := []testCase{
{
expectedCode: http.StatusOK,
desc: "AdminGetStats should return 200 for user with correct permissions",
url: "/api/admin/stats",
permissions: []accesscontrol.Permission{
{
Action: accesscontrol.ActionServerStatsRead,
},
},
},
{
expectedCode: http.StatusForbidden,
desc: "AdminGetStats should return 403 for user without required permissions",
url: "/api/admin/stats",
permissions: []accesscontrol.Permission{
{
Action: "wrong",
},
},
},
{
expectedCode: http.StatusOK,
desc: "AdminGetSettings should return 200 for user with correct permissions",
url: "/api/admin/settings",
permissions: []accesscontrol.Permission{
{
Action: accesscontrol.ActionSettingsRead,
},
},
},
{
expectedCode: http.StatusForbidden,
desc: "AdminGetSettings should return 403 for user without required permissions",
url: "/api/admin/settings",
permissions: []accesscontrol.Permission{
{
Action: "wrong",
},
},
},
}
for _, tt := range tests {
t.Run(tt.desc, func(t *testing.T) {
fakeStatsService := statstest.NewFakeService()
fakeStatsService.ExpectedAdminStats = &stats.AdminStats{}
fakeAnonService := anontest.NewFakeService()
fakeAnonService.ExpectedCountDevices = 0
server := SetupAPITestServer(t, func(hs *HTTPServer) {
hs.Cfg = setting.NewCfg()
hs.SQLStore = dbtest.NewFakeDB()
hs.SettingsProvider = &setting.OSSImpl{Cfg: hs.Cfg}
hs.statsService = fakeStatsService
hs.anonService = fakeAnonService
})
res, err := server.Send(webtest.RequestWithSignedInUser(server.NewGetRequest(tt.url), userWithPermissions(1, tt.permissions)))
require.NoError(t, err)
assert.Equal(t, tt.expectedCode, res.StatusCode)
require.NoError(t, res.Body.Close())
})
}
}