ServiceAccounts: Add detail view of service account (#44164)
* ServiceAccounts: Add detail view of service account Co-authored-by: eleijonmarck <eric.leijonmarck@gmail.com> * ServiceAccount: Make detail view scopeID Co-authored-by: eleijonmarck <eric.leijonmarck@gmail.com> * ServiceAccount: fix lint error Co-authored-by: eleijonmarck <eric.leijonmarck@gmail.com> Co-authored-by: eleijonmarck <eric.leijonmarck@gmail.com>
This commit is contained in:
co-authored by
eleijonmarck
parent
8917e66eb4
commit
7dab52869e
@@ -2,6 +2,7 @@ package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
@@ -23,7 +24,7 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
serviceaccountIDPath = "/api/org/serviceaccounts/%s"
|
||||
serviceaccountIDPath = "/api/org/serviceaccounts/%v"
|
||||
)
|
||||
|
||||
// test the accesscontrol endpoints
|
||||
@@ -56,9 +57,9 @@ func TestServiceAccountsAPI_DeleteServiceAccount(t *testing.T) {
|
||||
),
|
||||
expectedCode: http.StatusOK,
|
||||
}
|
||||
serviceAccountDeletionScenario(t, http.MethodDelete, serviceaccountIDPath, &testcase.user, func(httpmethod string, endpoint string, user *tests.TestUser) {
|
||||
serviceAccountRequestScenario(t, http.MethodDelete, serviceaccountIDPath, &testcase.user, func(httpmethod string, endpoint string, user *tests.TestUser) {
|
||||
createduser := tests.SetupUserServiceAccount(t, store, testcase.user)
|
||||
server := setupTestServer(t, &svcmock, routing.NewRouteRegister(), testcase.acmock)
|
||||
server := setupTestServer(t, &svcmock, routing.NewRouteRegister(), testcase.acmock, store)
|
||||
actual := requestResponse(server, httpmethod, fmt.Sprintf(endpoint, fmt.Sprint(createduser.Id))).Code
|
||||
require.Equal(t, testcase.expectedCode, actual)
|
||||
})
|
||||
@@ -80,23 +81,22 @@ func TestServiceAccountsAPI_DeleteServiceAccount(t *testing.T) {
|
||||
),
|
||||
expectedCode: http.StatusForbidden,
|
||||
}
|
||||
serviceAccountDeletionScenario(t, http.MethodDelete, serviceaccountIDPath, &testcase.user, func(httpmethod string, endpoint string, user *tests.TestUser) {
|
||||
serviceAccountRequestScenario(t, http.MethodDelete, serviceaccountIDPath, &testcase.user, func(httpmethod string, endpoint string, user *tests.TestUser) {
|
||||
createduser := tests.SetupUserServiceAccount(t, store, testcase.user)
|
||||
server := setupTestServer(t, &svcmock, routing.NewRouteRegister(), testcase.acmock)
|
||||
actual := requestResponse(server, httpmethod, fmt.Sprintf(endpoint, fmt.Sprint(createduser.Id))).Code
|
||||
server := setupTestServer(t, &svcmock, routing.NewRouteRegister(), testcase.acmock, store)
|
||||
actual := requestResponse(server, httpmethod, fmt.Sprintf(endpoint, createduser.Id)).Code
|
||||
require.Equal(t, testcase.expectedCode, actual)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func serviceAccountDeletionScenario(t *testing.T, httpMethod string, endpoint string, user *tests.TestUser, fn func(httpmethod string, endpoint string, user *tests.TestUser)) {
|
||||
func serviceAccountRequestScenario(t *testing.T, httpMethod string, endpoint string, user *tests.TestUser, fn func(httpmethod string, endpoint string, user *tests.TestUser)) {
|
||||
t.Helper()
|
||||
fn(httpMethod, endpoint, user)
|
||||
}
|
||||
|
||||
func setupTestServer(t *testing.T, svc *tests.ServiceAccountMock, routerRegister routing.RouteRegister, acmock *accesscontrolmock.Mock) *web.Mux {
|
||||
store := sqlstore.InitTestDB(t)
|
||||
a := NewServiceAccountsAPI(svc, acmock, routerRegister, database.NewServiceAccountsStore(store))
|
||||
func setupTestServer(t *testing.T, svc *tests.ServiceAccountMock, routerRegister routing.RouteRegister, acmock *accesscontrolmock.Mock, sqlStore *sqlstore.SQLStore) *web.Mux {
|
||||
a := NewServiceAccountsAPI(svc, acmock, routerRegister, database.NewServiceAccountsStore(sqlStore))
|
||||
a.RegisterAPIEndpoints(&setting.Cfg{FeatureToggles: map[string]bool{"service-accounts": true}})
|
||||
|
||||
m := web.New()
|
||||
@@ -117,3 +117,88 @@ func setupTestServer(t *testing.T, svc *tests.ServiceAccountMock, routerRegister
|
||||
a.RouterRegister.Register(m.Router)
|
||||
return m
|
||||
}
|
||||
|
||||
func TestServiceAccountsAPI_RetrieveServiceAccount(t *testing.T) {
|
||||
store := sqlstore.InitTestDB(t)
|
||||
svcmock := tests.ServiceAccountMock{}
|
||||
type testRetrieveSATestCase struct {
|
||||
desc string
|
||||
user *tests.TestUser
|
||||
expectedCode int
|
||||
acmock *accesscontrolmock.Mock
|
||||
userID int
|
||||
}
|
||||
testCases := []testRetrieveSATestCase{
|
||||
{
|
||||
desc: "should be ok to retrieve serviceaccount with permissions",
|
||||
user: &tests.TestUser{Login: "servicetest1@admin", IsServiceAccount: true},
|
||||
acmock: tests.SetupMockAccesscontrol(
|
||||
t,
|
||||
func(c context.Context, siu *models.SignedInUser) ([]*accesscontrol.Permission, error) {
|
||||
return []*accesscontrol.Permission{{Action: serviceaccounts.ActionRead, Scope: serviceaccounts.ScopeAll}}, nil
|
||||
},
|
||||
false,
|
||||
),
|
||||
expectedCode: http.StatusOK,
|
||||
},
|
||||
{
|
||||
desc: "should be forbidden to retrieve serviceaccount if no permissions",
|
||||
user: &tests.TestUser{Login: "servicetest2@admin", IsServiceAccount: true},
|
||||
acmock: tests.SetupMockAccesscontrol(
|
||||
t,
|
||||
func(c context.Context, siu *models.SignedInUser) ([]*accesscontrol.Permission, error) {
|
||||
return []*accesscontrol.Permission{}, nil
|
||||
},
|
||||
false,
|
||||
),
|
||||
expectedCode: http.StatusForbidden,
|
||||
},
|
||||
{
|
||||
desc: "should be not found when the user doesnt exist",
|
||||
user: nil,
|
||||
userID: 12,
|
||||
acmock: tests.SetupMockAccesscontrol(
|
||||
t,
|
||||
func(c context.Context, siu *models.SignedInUser) ([]*accesscontrol.Permission, error) {
|
||||
return []*accesscontrol.Permission{{Action: serviceaccounts.ActionRead, Scope: serviceaccounts.ScopeAll}}, nil
|
||||
},
|
||||
false,
|
||||
),
|
||||
expectedCode: http.StatusNotFound,
|
||||
},
|
||||
}
|
||||
|
||||
var requestResponse = func(server *web.Mux, httpMethod, requestpath string) *httptest.ResponseRecorder {
|
||||
req, err := http.NewRequest(httpMethod, requestpath, nil)
|
||||
require.NoError(t, err)
|
||||
recorder := httptest.NewRecorder()
|
||||
server.ServeHTTP(recorder, req)
|
||||
return recorder
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
serviceAccountRequestScenario(t, http.MethodGet, serviceaccountIDPath, tc.user, func(httpmethod string, endpoint string, user *tests.TestUser) {
|
||||
scopeID := tc.userID
|
||||
if tc.user != nil {
|
||||
createdUser := tests.SetupUserServiceAccount(t, store, *tc.user)
|
||||
scopeID = int(createdUser.Id)
|
||||
}
|
||||
server := setupTestServer(t, &svcmock, routing.NewRouteRegister(), tc.acmock, store)
|
||||
|
||||
actual := requestResponse(server, httpmethod, fmt.Sprintf(endpoint, scopeID))
|
||||
|
||||
actualCode := actual.Code
|
||||
require.Equal(t, tc.expectedCode, actualCode)
|
||||
|
||||
if actualCode == http.StatusOK {
|
||||
actualBody := map[string]interface{}{}
|
||||
err := json.Unmarshal(actual.Body.Bytes(), &actualBody)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, scopeID, int(actualBody["userId"].(float64)))
|
||||
require.Equal(t, tc.user.Login, actualBody["login"].(string))
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user