mirror of
https://github.com/netbirdio/netbird.git
synced 2026-10-20 12:29:09 +02:00
* use libopenapi OpenAPI generator Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * added a handler for v1alpha1/peers Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * wire up request validator Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * wired up spec-based validation Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * use sync validation; set base url to v1alpha1 Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * moved stuff around, extracted runtime libopenapu deps into runtime_tooling Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * testing /peers path params Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * fixed tests Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * added user schemas and paths Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * use api validation in tests Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * post-merge fixes Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * deleted tmp command used to test validator integration Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * require request body in post/put requests in order to force validation Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * making linter happy Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * switch to api/v1alpha1 Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * go mod tidy Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * keep the original order of middleware: metrics, cors, then auth Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * return 422 on validation errors Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * cleanups Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * more cleanups Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * v1alpha1 spec cleanups Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * no need for a double-pointer Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * more linter fixes Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * removed more double pointers Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * use di to inject api_v0 and api_v1 http routers Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * do not re-add middleware on repeated call to ApiHandler Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * support for pagination and filtering in /peers call Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * calling ApiRouter() now also calls ApiV1Router() Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * adding peer filters Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * introduced paginated GetAllPeers call Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * wire up pagination Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * convert pagination state to query scope Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * peer filter wip Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * implemented peer filter Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * test for filtering by os Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * support for sorting of peers Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * support for ordering + tests Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * more tests Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * wire up total number of records in paginated GetAllPeers call Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * cleaned up GetAllPeers response Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * pacify linter Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * cleanups and fixes Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * moar cleanups Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * pacify linter Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * remove duplicated test Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * make linter happy Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * moving GetAllPeersPaginated to peer manager, p. 1 Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * moving GetAllPeersPaginated to peer manager, p. 2 Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * added peer manager tests for GetPeersPaginated Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * order peers in GetAccountPeersPaginated by their ids by default Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * always order by peer_id, filter out proxies Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * fixed broken tests Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * support for filtering of peers by peer_id in GetAllPeers() Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * filtering by peer_ids Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * use lowercase in 'like' queries, drop ordering by ip Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * drop sort_by ip key Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * drop forced_approve filter Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * replace mac with darwin in peer os filter Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * fix peers query parameter: use peer_ids Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * fixed broken peer_test Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> * responded to feedback Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> --------- Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io>
198 lines
9.4 KiB
Go
198 lines
9.4 KiB
Go
package peers
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"testing"
|
|
|
|
"github.com/netbirdio/netbird/management/server/peer"
|
|
"github.com/netbirdio/netbird/management/server/permissions"
|
|
"github.com/netbirdio/netbird/management/server/permissions/modules"
|
|
"github.com/netbirdio/netbird/management/server/permissions/operations"
|
|
"github.com/netbirdio/netbird/management/server/store"
|
|
"github.com/netbirdio/netbird/management/server/types"
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"go.uber.org/mock/gomock"
|
|
)
|
|
|
|
func TestManager_GetPeersPaginated_HappyPath(t *testing.T) {
|
|
ctrl := gomock.NewController(t)
|
|
// GetUserByUserID
|
|
// GetAccountPeersPaginated
|
|
// GetAccountSettings
|
|
// GetUserPeers
|
|
mockStore := store.NewMockStore(ctrl)
|
|
// ValidateUserPermissions
|
|
permissionsManager := permissions.NewMockManager(ctrl)
|
|
|
|
m := NewManager(mockStore, permissionsManager)
|
|
|
|
mockStore.EXPECT().GetUserByUserID(gomock.Any(), gomock.Eq(store.LockingStrengthNone), gomock.Eq("test-user")).Times(1).
|
|
Return(&types.User{
|
|
Id: "test-user",
|
|
}, nil)
|
|
permissionsManager.EXPECT().ValidateUserPermissions(gomock.Any(), gomock.Eq("test-account"), gomock.Eq("test-user"), gomock.Eq(modules.Peers), gomock.Eq(operations.Read)).Times(1).
|
|
Return(true, context.Background(), nil)
|
|
mockStore.EXPECT().GetAccountPeersPaginated(gomock.Any(), gomock.Eq(store.LockingStrengthNone), gomock.Eq("test-account"),
|
|
gomock.Eq(store.PaginationState{Page: 11, PageSize: 111}), gomock.Eq(store.PeerFilters{UserId: "test-user"}),
|
|
gomock.Eq(store.PeerSorting{Fields: []store.PeerSortingKey{{Field: store.PeerSortByName, Order: store.DescOrderBy}}})).Times(1).
|
|
Return([]*peer.Peer{{ID: "test-peer"}}, 10, nil)
|
|
|
|
peers, total, err := m.GetPeersPaginated(context.Background(), "test-account", "test-user",
|
|
store.PaginationState{Page: 11, PageSize: 111}, store.PeerFilters{UserId: "test-user"},
|
|
store.PeerSorting{Fields: []store.PeerSortingKey{{Field: store.PeerSortByName, Order: store.DescOrderBy}}})
|
|
|
|
assert.Equal(t, []*peer.Peer{{ID: "test-peer"}}, peers)
|
|
assert.Equal(t, 10, total)
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
func TestManager_GetPeersPaginated_GetUserWithError(t *testing.T) {
|
|
ctrl := gomock.NewController(t)
|
|
mockStore := store.NewMockStore(ctrl)
|
|
permissionsManager := permissions.NewMockManager(ctrl)
|
|
|
|
m := NewManager(mockStore, permissionsManager)
|
|
|
|
mockStore.EXPECT().GetUserByUserID(gomock.Any(), gomock.Eq(store.LockingStrengthNone), gomock.Eq("test-user")).Times(1).
|
|
Return(nil, fmt.Errorf("boom!"))
|
|
|
|
_, total, err := m.GetPeersPaginated(context.Background(), "test-account", "test-user",
|
|
store.PaginationState{Page: 11, PageSize: 111}, store.PeerFilters{UserId: "test-user"},
|
|
store.PeerSorting{Fields: []store.PeerSortingKey{{Field: store.PeerSortByName, Order: store.DescOrderBy}}})
|
|
|
|
assert.Equal(t, 0, total)
|
|
assert.ErrorContains(t, err, "boom!")
|
|
}
|
|
|
|
func TestManager_GetPeersPaginated_NoPermission(t *testing.T) {
|
|
ctrl := gomock.NewController(t)
|
|
mockStore := store.NewMockStore(ctrl)
|
|
permissionsManager := permissions.NewMockManager(ctrl)
|
|
|
|
m := NewManager(mockStore, permissionsManager)
|
|
|
|
mockStore.EXPECT().GetUserByUserID(gomock.Any(), gomock.Eq(store.LockingStrengthNone), gomock.Eq("test-user")).Times(1).
|
|
Return(&types.User{
|
|
Id: "test-user",
|
|
}, nil)
|
|
permissionsManager.EXPECT().ValidateUserPermissions(gomock.Any(), gomock.Eq("test-account"), gomock.Eq("test-user"), gomock.Eq(modules.Peers), gomock.Eq(operations.Read)).Times(1).
|
|
Return(false, context.Background(), nil)
|
|
mockStore.EXPECT().GetAccountSettings(gomock.Any(), gomock.Eq(store.LockingStrengthNone), gomock.Eq("test-account")).Times(1).
|
|
Return(&types.Settings{RegularUsersViewBlocked: false}, nil)
|
|
mockStore.EXPECT().GetUserPeers(gomock.Any(), gomock.Eq(store.LockingStrengthNone), gomock.Eq("test-account"), gomock.Eq("test-user")).Times(1).
|
|
Return([]*peer.Peer{{ID: "test-peer"}}, nil)
|
|
|
|
peers, total, err := m.GetPeersPaginated(context.Background(), "test-account", "test-user",
|
|
store.PaginationState{Page: 11, PageSize: 111}, store.PeerFilters{UserId: "test-user"},
|
|
store.PeerSorting{Fields: []store.PeerSortingKey{{Field: store.PeerSortByName, Order: store.DescOrderBy}}})
|
|
|
|
assert.Equal(t, []*peer.Peer{{ID: "test-peer"}}, peers)
|
|
assert.Equal(t, 1, total)
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
func TestManager_GetPeersPaginated_NoPermission_GetUserPeers_WithError(t *testing.T) {
|
|
ctrl := gomock.NewController(t)
|
|
mockStore := store.NewMockStore(ctrl)
|
|
permissionsManager := permissions.NewMockManager(ctrl)
|
|
|
|
m := NewManager(mockStore, permissionsManager)
|
|
|
|
mockStore.EXPECT().GetUserByUserID(gomock.Any(), gomock.Eq(store.LockingStrengthNone), gomock.Eq("test-user")).Times(1).
|
|
Return(&types.User{
|
|
Id: "test-user",
|
|
}, nil)
|
|
permissionsManager.EXPECT().ValidateUserPermissions(gomock.Any(), gomock.Eq("test-account"), gomock.Eq("test-user"), gomock.Eq(modules.Peers), gomock.Eq(operations.Read)).Times(1).
|
|
Return(false, context.Background(), nil)
|
|
mockStore.EXPECT().GetAccountSettings(gomock.Any(), gomock.Eq(store.LockingStrengthNone), gomock.Eq("test-account")).Times(1).
|
|
Return(&types.Settings{RegularUsersViewBlocked: false}, nil)
|
|
mockStore.EXPECT().GetUserPeers(gomock.Any(), gomock.Eq(store.LockingStrengthNone), gomock.Eq("test-account"), gomock.Eq("test-user")).Times(1).
|
|
Return(nil, fmt.Errorf("boom!"))
|
|
|
|
_, total, err := m.GetPeersPaginated(context.Background(), "test-account", "test-user",
|
|
store.PaginationState{Page: 11, PageSize: 111}, store.PeerFilters{UserId: "test-user"},
|
|
store.PeerSorting{Fields: []store.PeerSortingKey{{Field: store.PeerSortByName, Order: store.DescOrderBy}}})
|
|
|
|
assert.Equal(t, 0, total)
|
|
assert.ErrorContains(t, err, "boom!")
|
|
}
|
|
|
|
func TestManager_GetPeersPaginated_GetAccountSettings_WithError(t *testing.T) {
|
|
ctrl := gomock.NewController(t)
|
|
mockStore := store.NewMockStore(ctrl)
|
|
permissionsManager := permissions.NewMockManager(ctrl)
|
|
|
|
m := NewManager(mockStore, permissionsManager)
|
|
|
|
mockStore.EXPECT().GetUserByUserID(gomock.Any(), gomock.Eq(store.LockingStrengthNone), gomock.Eq("test-user")).Times(1).
|
|
Return(&types.User{
|
|
Id: "test-user",
|
|
}, nil)
|
|
permissionsManager.EXPECT().ValidateUserPermissions(gomock.Any(), gomock.Eq("test-account"), gomock.Eq("test-user"), gomock.Eq(modules.Peers), gomock.Eq(operations.Read)).Times(1).
|
|
Return(false, context.Background(), nil)
|
|
mockStore.EXPECT().GetAccountSettings(gomock.Any(), gomock.Eq(store.LockingStrengthNone), gomock.Eq("test-account")).Times(1).
|
|
Return(nil, fmt.Errorf("boom!"))
|
|
|
|
_, total, err := m.GetPeersPaginated(context.Background(), "test-account", "test-user",
|
|
store.PaginationState{Page: 11, PageSize: 111}, store.PeerFilters{UserId: "test-user"},
|
|
store.PeerSorting{Fields: []store.PeerSortingKey{{Field: store.PeerSortByName, Order: store.DescOrderBy}}})
|
|
|
|
assert.Equal(t, 0, total)
|
|
assert.ErrorContains(t, err, "boom!")
|
|
}
|
|
func TestManager_GetPeersPaginated_NoPermission_User_IsRestrictable_ViewUnblocked(t *testing.T) {
|
|
ctrl := gomock.NewController(t)
|
|
mockStore := store.NewMockStore(ctrl)
|
|
permissionsManager := permissions.NewMockManager(ctrl)
|
|
|
|
m := NewManager(mockStore, permissionsManager)
|
|
|
|
mockStore.EXPECT().GetUserByUserID(gomock.Any(), gomock.Eq(store.LockingStrengthNone), gomock.Eq("test-user")).Times(1).
|
|
Return(&types.User{
|
|
Id: "test-user",
|
|
Role: types.UserRoleUser,
|
|
}, nil)
|
|
permissionsManager.EXPECT().ValidateUserPermissions(gomock.Any(), gomock.Eq("test-account"), gomock.Eq("test-user"), gomock.Eq(modules.Peers), gomock.Eq(operations.Read)).Times(1).
|
|
Return(false, context.Background(), nil)
|
|
mockStore.EXPECT().GetAccountSettings(gomock.Any(), gomock.Eq(store.LockingStrengthNone), gomock.Eq("test-account")).Times(1).
|
|
Return(&types.Settings{RegularUsersViewBlocked: false}, nil)
|
|
mockStore.EXPECT().GetUserPeers(gomock.Any(), gomock.Eq(store.LockingStrengthNone), gomock.Eq("test-account"), gomock.Eq("test-user")).Times(1).
|
|
Return([]*peer.Peer{{ID: "test-peer"}}, nil)
|
|
|
|
peers, total, err := m.GetPeersPaginated(context.Background(), "test-account", "test-user",
|
|
store.PaginationState{Page: 11, PageSize: 111}, store.PeerFilters{UserId: "test-user"},
|
|
store.PeerSorting{Fields: []store.PeerSortingKey{{Field: store.PeerSortByName, Order: store.DescOrderBy}}})
|
|
|
|
assert.Equal(t, []*peer.Peer{{ID: "test-peer"}}, peers)
|
|
assert.Equal(t, 1, total)
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
func TestManager_GetPeersPaginated_NoPermission_User_IsRestrictable_ViewBlocked(t *testing.T) {
|
|
ctrl := gomock.NewController(t)
|
|
mockStore := store.NewMockStore(ctrl)
|
|
permissionsManager := permissions.NewMockManager(ctrl)
|
|
|
|
m := NewManager(mockStore, permissionsManager)
|
|
|
|
mockStore.EXPECT().GetUserByUserID(gomock.Any(), gomock.Eq(store.LockingStrengthNone), gomock.Eq("test-user")).Times(1).
|
|
Return(&types.User{
|
|
Id: "test-user",
|
|
Role: types.UserRoleUser,
|
|
}, nil)
|
|
permissionsManager.EXPECT().ValidateUserPermissions(gomock.Any(), gomock.Eq("test-account"), gomock.Eq("test-user"), gomock.Eq(modules.Peers), gomock.Eq(operations.Read)).Times(1).
|
|
Return(false, context.Background(), nil)
|
|
mockStore.EXPECT().GetAccountSettings(gomock.Any(), gomock.Eq(store.LockingStrengthNone), gomock.Eq("test-account")).Times(1).
|
|
Return(&types.Settings{RegularUsersViewBlocked: true}, nil)
|
|
|
|
peers, total, err := m.GetPeersPaginated(context.Background(), "test-account", "test-user",
|
|
store.PaginationState{Page: 11, PageSize: 111}, store.PeerFilters{UserId: "test-user"},
|
|
store.PeerSorting{Fields: []store.PeerSortingKey{{Field: store.PeerSortByName, Order: store.DescOrderBy}}})
|
|
|
|
assert.Equal(t, make([]*peer.Peer, 0), peers)
|
|
assert.Equal(t, 0, total)
|
|
assert.NoError(t, err)
|
|
}
|