mirror of
https://github.com/netbirdio/netbird.git
synced 2026-03-31 06:34:14 -04:00
606 lines
16 KiB
Go
606 lines
16 KiB
Go
//go:build integration
|
|
|
|
package integration
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/netbirdio/netbird/management/server/http/testing/testing_tools"
|
|
"github.com/netbirdio/netbird/management/server/http/testing/testing_tools/channel"
|
|
"github.com/netbirdio/netbird/shared/management/http/api"
|
|
)
|
|
|
|
const (
|
|
testPeerId2 = "testPeerId2"
|
|
)
|
|
|
|
func Test_Peers_GetAll(t *testing.T) {
|
|
users := []struct {
|
|
name string
|
|
userId string
|
|
expectResponse bool
|
|
}{
|
|
{
|
|
name: "Regular user",
|
|
userId: testing_tools.TestUserId,
|
|
expectResponse: false,
|
|
},
|
|
{
|
|
name: "Admin user",
|
|
userId: testing_tools.TestAdminId,
|
|
expectResponse: true,
|
|
},
|
|
{
|
|
name: "Owner user",
|
|
userId: testing_tools.TestOwnerId,
|
|
expectResponse: true,
|
|
},
|
|
{
|
|
name: "Regular service user",
|
|
userId: testing_tools.TestServiceUserId,
|
|
expectResponse: true,
|
|
},
|
|
{
|
|
name: "Admin service user",
|
|
userId: testing_tools.TestServiceAdminId,
|
|
expectResponse: true,
|
|
},
|
|
{
|
|
name: "Blocked user",
|
|
userId: testing_tools.BlockedUserId,
|
|
expectResponse: false,
|
|
},
|
|
{
|
|
name: "Other user",
|
|
userId: testing_tools.OtherUserId,
|
|
expectResponse: false,
|
|
},
|
|
{
|
|
name: "Invalid token",
|
|
userId: testing_tools.InvalidToken,
|
|
expectResponse: false,
|
|
},
|
|
}
|
|
|
|
for _, user := range users {
|
|
t.Run(user.name+" - Get all peers", func(t *testing.T) {
|
|
apiHandler, _, done := channel.BuildApiBlackBoxWithDBState(t, "../testdata/peers_integration.sql", nil, true)
|
|
|
|
req := testing_tools.BuildRequest(t, []byte{}, http.MethodGet, "/api/peers", user.userId)
|
|
recorder := httptest.NewRecorder()
|
|
|
|
apiHandler.ServeHTTP(recorder, req)
|
|
|
|
content, expectResponse := testing_tools.ReadResponse(t, recorder, http.StatusOK, user.expectResponse)
|
|
if !expectResponse {
|
|
return
|
|
}
|
|
|
|
var got []api.PeerBatch
|
|
if err := json.Unmarshal(content, &got); err != nil {
|
|
t.Fatalf("Sent content is not in correct json format; %v", err)
|
|
}
|
|
|
|
assert.GreaterOrEqual(t, len(got), 2, "Expected at least 2 peers")
|
|
|
|
select {
|
|
case <-done:
|
|
case <-time.After(time.Second):
|
|
t.Error("timeout waiting for peerShouldNotReceiveUpdate")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_Peers_GetById(t *testing.T) {
|
|
users := []struct {
|
|
name string
|
|
userId string
|
|
expectResponse bool
|
|
}{
|
|
{
|
|
name: "Regular user",
|
|
userId: testing_tools.TestUserId,
|
|
expectResponse: false,
|
|
},
|
|
{
|
|
name: "Admin user",
|
|
userId: testing_tools.TestAdminId,
|
|
expectResponse: true,
|
|
},
|
|
{
|
|
name: "Owner user",
|
|
userId: testing_tools.TestOwnerId,
|
|
expectResponse: true,
|
|
},
|
|
{
|
|
name: "Regular service user",
|
|
userId: testing_tools.TestServiceUserId,
|
|
expectResponse: true,
|
|
},
|
|
{
|
|
name: "Admin service user",
|
|
userId: testing_tools.TestServiceAdminId,
|
|
expectResponse: true,
|
|
},
|
|
{
|
|
name: "Blocked user",
|
|
userId: testing_tools.BlockedUserId,
|
|
expectResponse: false,
|
|
},
|
|
{
|
|
name: "Other user",
|
|
userId: testing_tools.OtherUserId,
|
|
expectResponse: false,
|
|
},
|
|
{
|
|
name: "Invalid token",
|
|
userId: testing_tools.InvalidToken,
|
|
expectResponse: false,
|
|
},
|
|
}
|
|
|
|
tt := []struct {
|
|
name string
|
|
expectedStatus int
|
|
requestType string
|
|
requestPath string
|
|
requestId string
|
|
verifyResponse func(t *testing.T, peer *api.Peer)
|
|
}{
|
|
{
|
|
name: "Get existing peer",
|
|
requestType: http.MethodGet,
|
|
requestPath: "/api/peers/{peerId}",
|
|
requestId: testing_tools.TestPeerId,
|
|
expectedStatus: http.StatusOK,
|
|
verifyResponse: func(t *testing.T, peer *api.Peer) {
|
|
t.Helper()
|
|
assert.Equal(t, testing_tools.TestPeerId, peer.Id)
|
|
assert.Equal(t, "test-peer-1", peer.Name)
|
|
assert.Equal(t, "test-host-1", peer.Hostname)
|
|
assert.Equal(t, "Debian GNU/Linux ", peer.Os)
|
|
assert.Equal(t, "0.12.0", peer.Version)
|
|
assert.Equal(t, false, peer.SshEnabled)
|
|
assert.Equal(t, true, peer.LoginExpirationEnabled)
|
|
},
|
|
},
|
|
{
|
|
name: "Get second existing peer",
|
|
requestType: http.MethodGet,
|
|
requestPath: "/api/peers/{peerId}",
|
|
requestId: testPeerId2,
|
|
expectedStatus: http.StatusOK,
|
|
verifyResponse: func(t *testing.T, peer *api.Peer) {
|
|
t.Helper()
|
|
assert.Equal(t, testPeerId2, peer.Id)
|
|
assert.Equal(t, "test-peer-2", peer.Name)
|
|
assert.Equal(t, "test-host-2", peer.Hostname)
|
|
assert.Equal(t, "Ubuntu ", peer.Os)
|
|
assert.Equal(t, true, peer.SshEnabled)
|
|
assert.Equal(t, false, peer.LoginExpirationEnabled)
|
|
assert.Equal(t, true, peer.Connected)
|
|
},
|
|
},
|
|
{
|
|
name: "Get non-existing peer",
|
|
requestType: http.MethodGet,
|
|
requestPath: "/api/peers/{peerId}",
|
|
requestId: "nonExistingPeerId",
|
|
expectedStatus: http.StatusNotFound,
|
|
verifyResponse: nil,
|
|
},
|
|
}
|
|
|
|
for _, tc := range tt {
|
|
for _, user := range users {
|
|
t.Run(user.name+" - "+tc.name, func(t *testing.T) {
|
|
apiHandler, _, done := channel.BuildApiBlackBoxWithDBState(t, "../testdata/peers_integration.sql", nil, true)
|
|
|
|
req := testing_tools.BuildRequest(t, []byte{}, tc.requestType, strings.Replace(tc.requestPath, "{peerId}", tc.requestId, 1), user.userId)
|
|
recorder := httptest.NewRecorder()
|
|
|
|
apiHandler.ServeHTTP(recorder, req)
|
|
|
|
content, expectResponse := testing_tools.ReadResponse(t, recorder, tc.expectedStatus, user.expectResponse)
|
|
if !expectResponse {
|
|
return
|
|
}
|
|
|
|
if tc.verifyResponse != nil {
|
|
got := &api.Peer{}
|
|
if err := json.Unmarshal(content, got); err != nil {
|
|
t.Fatalf("Sent content is not in correct json format; %v", err)
|
|
}
|
|
tc.verifyResponse(t, got)
|
|
}
|
|
|
|
select {
|
|
case <-done:
|
|
case <-time.After(time.Second):
|
|
t.Error("timeout waiting for peerShouldNotReceiveUpdate")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
func Test_Peers_Update(t *testing.T) {
|
|
users := []struct {
|
|
name string
|
|
userId string
|
|
expectResponse bool
|
|
}{
|
|
{
|
|
name: "Regular user",
|
|
userId: testing_tools.TestUserId,
|
|
expectResponse: false,
|
|
},
|
|
{
|
|
name: "Admin user",
|
|
userId: testing_tools.TestAdminId,
|
|
expectResponse: true,
|
|
},
|
|
{
|
|
name: "Owner user",
|
|
userId: testing_tools.TestOwnerId,
|
|
expectResponse: true,
|
|
},
|
|
{
|
|
name: "Regular service user",
|
|
userId: testing_tools.TestServiceUserId,
|
|
expectResponse: false,
|
|
},
|
|
{
|
|
name: "Admin service user",
|
|
userId: testing_tools.TestServiceAdminId,
|
|
expectResponse: true,
|
|
},
|
|
{
|
|
name: "Blocked user",
|
|
userId: testing_tools.BlockedUserId,
|
|
expectResponse: false,
|
|
},
|
|
{
|
|
name: "Other user",
|
|
userId: testing_tools.OtherUserId,
|
|
expectResponse: false,
|
|
},
|
|
{
|
|
name: "Invalid token",
|
|
userId: testing_tools.InvalidToken,
|
|
expectResponse: false,
|
|
},
|
|
}
|
|
|
|
tt := []struct {
|
|
name string
|
|
expectedStatus int
|
|
requestBody *api.PeerRequest
|
|
requestType string
|
|
requestPath string
|
|
requestId string
|
|
verifyResponse func(t *testing.T, peer *api.Peer)
|
|
}{
|
|
{
|
|
name: "Update peer name",
|
|
requestType: http.MethodPut,
|
|
requestPath: "/api/peers/{peerId}",
|
|
requestId: testing_tools.TestPeerId,
|
|
requestBody: &api.PeerRequest{
|
|
Name: "updated-peer-name",
|
|
SshEnabled: false,
|
|
LoginExpirationEnabled: true,
|
|
InactivityExpirationEnabled: false,
|
|
},
|
|
expectedStatus: http.StatusOK,
|
|
verifyResponse: func(t *testing.T, peer *api.Peer) {
|
|
t.Helper()
|
|
assert.Equal(t, testing_tools.TestPeerId, peer.Id)
|
|
assert.Equal(t, "updated-peer-name", peer.Name)
|
|
assert.Equal(t, false, peer.SshEnabled)
|
|
assert.Equal(t, true, peer.LoginExpirationEnabled)
|
|
},
|
|
},
|
|
{
|
|
name: "Enable SSH on peer",
|
|
requestType: http.MethodPut,
|
|
requestPath: "/api/peers/{peerId}",
|
|
requestId: testing_tools.TestPeerId,
|
|
requestBody: &api.PeerRequest{
|
|
Name: "test-peer-1",
|
|
SshEnabled: true,
|
|
LoginExpirationEnabled: true,
|
|
InactivityExpirationEnabled: false,
|
|
},
|
|
expectedStatus: http.StatusOK,
|
|
verifyResponse: func(t *testing.T, peer *api.Peer) {
|
|
t.Helper()
|
|
assert.Equal(t, testing_tools.TestPeerId, peer.Id)
|
|
assert.Equal(t, "test-peer-1", peer.Name)
|
|
assert.Equal(t, true, peer.SshEnabled)
|
|
assert.Equal(t, true, peer.LoginExpirationEnabled)
|
|
},
|
|
},
|
|
{
|
|
name: "Disable login expiration on peer",
|
|
requestType: http.MethodPut,
|
|
requestPath: "/api/peers/{peerId}",
|
|
requestId: testing_tools.TestPeerId,
|
|
requestBody: &api.PeerRequest{
|
|
Name: "test-peer-1",
|
|
SshEnabled: false,
|
|
LoginExpirationEnabled: false,
|
|
InactivityExpirationEnabled: false,
|
|
},
|
|
expectedStatus: http.StatusOK,
|
|
verifyResponse: func(t *testing.T, peer *api.Peer) {
|
|
t.Helper()
|
|
assert.Equal(t, testing_tools.TestPeerId, peer.Id)
|
|
assert.Equal(t, false, peer.LoginExpirationEnabled)
|
|
},
|
|
},
|
|
{
|
|
name: "Update non-existing peer",
|
|
requestType: http.MethodPut,
|
|
requestPath: "/api/peers/{peerId}",
|
|
requestId: "nonExistingPeerId",
|
|
requestBody: &api.PeerRequest{
|
|
Name: "updated-name",
|
|
SshEnabled: false,
|
|
LoginExpirationEnabled: false,
|
|
InactivityExpirationEnabled: false,
|
|
},
|
|
expectedStatus: http.StatusNotFound,
|
|
verifyResponse: nil,
|
|
},
|
|
}
|
|
|
|
for _, tc := range tt {
|
|
for _, user := range users {
|
|
t.Run(user.name+" - "+tc.name, func(t *testing.T) {
|
|
apiHandler, am, _ := channel.BuildApiBlackBoxWithDBState(t, "../testdata/peers_integration.sql", nil, false)
|
|
|
|
body, err := json.Marshal(tc.requestBody)
|
|
if err != nil {
|
|
t.Fatalf("Failed to marshal request body: %v", err)
|
|
}
|
|
|
|
req := testing_tools.BuildRequest(t, body, tc.requestType, strings.Replace(tc.requestPath, "{peerId}", tc.requestId, 1), user.userId)
|
|
recorder := httptest.NewRecorder()
|
|
|
|
apiHandler.ServeHTTP(recorder, req)
|
|
|
|
content, expectResponse := testing_tools.ReadResponse(t, recorder, tc.expectedStatus, user.expectResponse)
|
|
if !expectResponse {
|
|
return
|
|
}
|
|
|
|
if tc.verifyResponse != nil {
|
|
got := &api.Peer{}
|
|
if err := json.Unmarshal(content, got); err != nil {
|
|
t.Fatalf("Sent content is not in correct json format; %v", err)
|
|
}
|
|
tc.verifyResponse(t, got)
|
|
|
|
// Verify updated peer in DB
|
|
db := testing_tools.GetDB(t, am.GetStore())
|
|
dbPeer := testing_tools.VerifyPeerInDB(t, db, tc.requestId)
|
|
assert.Equal(t, tc.requestBody.Name, dbPeer.Name)
|
|
assert.Equal(t, tc.requestBody.SshEnabled, dbPeer.SSHEnabled)
|
|
assert.Equal(t, tc.requestBody.LoginExpirationEnabled, dbPeer.LoginExpirationEnabled)
|
|
assert.Equal(t, tc.requestBody.InactivityExpirationEnabled, dbPeer.InactivityExpirationEnabled)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
func Test_Peers_Delete(t *testing.T) {
|
|
users := []struct {
|
|
name string
|
|
userId string
|
|
expectResponse bool
|
|
}{
|
|
{
|
|
name: "Regular user",
|
|
userId: testing_tools.TestUserId,
|
|
expectResponse: false,
|
|
},
|
|
{
|
|
name: "Admin user",
|
|
userId: testing_tools.TestAdminId,
|
|
expectResponse: true,
|
|
},
|
|
{
|
|
name: "Owner user",
|
|
userId: testing_tools.TestOwnerId,
|
|
expectResponse: true,
|
|
},
|
|
{
|
|
name: "Regular service user",
|
|
userId: testing_tools.TestServiceUserId,
|
|
expectResponse: false,
|
|
},
|
|
{
|
|
name: "Admin service user",
|
|
userId: testing_tools.TestServiceAdminId,
|
|
expectResponse: true,
|
|
},
|
|
{
|
|
name: "Blocked user",
|
|
userId: testing_tools.BlockedUserId,
|
|
expectResponse: false,
|
|
},
|
|
{
|
|
name: "Other user",
|
|
userId: testing_tools.OtherUserId,
|
|
expectResponse: false,
|
|
},
|
|
{
|
|
name: "Invalid token",
|
|
userId: testing_tools.InvalidToken,
|
|
expectResponse: false,
|
|
},
|
|
}
|
|
|
|
tt := []struct {
|
|
name string
|
|
expectedStatus int
|
|
requestType string
|
|
requestPath string
|
|
requestId string
|
|
}{
|
|
{
|
|
name: "Delete existing peer",
|
|
requestType: http.MethodDelete,
|
|
requestPath: "/api/peers/{peerId}",
|
|
requestId: testPeerId2,
|
|
expectedStatus: http.StatusOK,
|
|
},
|
|
{
|
|
name: "Delete non-existing peer",
|
|
requestType: http.MethodDelete,
|
|
requestPath: "/api/peers/{peerId}",
|
|
requestId: "nonExistingPeerId",
|
|
expectedStatus: http.StatusNotFound,
|
|
},
|
|
}
|
|
|
|
for _, tc := range tt {
|
|
for _, user := range users {
|
|
t.Run(user.name+" - "+tc.name, func(t *testing.T) {
|
|
apiHandler, am, _ := channel.BuildApiBlackBoxWithDBState(t, "../testdata/peers_integration.sql", nil, false)
|
|
|
|
req := testing_tools.BuildRequest(t, []byte{}, tc.requestType, strings.Replace(tc.requestPath, "{peerId}", tc.requestId, 1), user.userId)
|
|
recorder := httptest.NewRecorder()
|
|
|
|
apiHandler.ServeHTTP(recorder, req)
|
|
|
|
_, expectResponse := testing_tools.ReadResponse(t, recorder, tc.expectedStatus, user.expectResponse)
|
|
if !expectResponse {
|
|
return
|
|
}
|
|
|
|
// Verify peer is actually deleted in DB
|
|
if tc.expectedStatus == http.StatusOK {
|
|
db := testing_tools.GetDB(t, am.GetStore())
|
|
testing_tools.VerifyPeerNotInDB(t, db, tc.requestId)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
func Test_Peers_GetAccessiblePeers(t *testing.T) {
|
|
users := []struct {
|
|
name string
|
|
userId string
|
|
expectResponse bool
|
|
}{
|
|
{
|
|
name: "Regular user",
|
|
userId: testing_tools.TestUserId,
|
|
expectResponse: false,
|
|
},
|
|
{
|
|
name: "Admin user",
|
|
userId: testing_tools.TestAdminId,
|
|
expectResponse: true,
|
|
},
|
|
{
|
|
name: "Owner user",
|
|
userId: testing_tools.TestOwnerId,
|
|
expectResponse: true,
|
|
},
|
|
{
|
|
name: "Regular service user",
|
|
userId: testing_tools.TestServiceUserId,
|
|
expectResponse: false,
|
|
},
|
|
{
|
|
name: "Admin service user",
|
|
userId: testing_tools.TestServiceAdminId,
|
|
expectResponse: true,
|
|
},
|
|
{
|
|
name: "Blocked user",
|
|
userId: testing_tools.BlockedUserId,
|
|
expectResponse: false,
|
|
},
|
|
{
|
|
name: "Other user",
|
|
userId: testing_tools.OtherUserId,
|
|
expectResponse: false,
|
|
},
|
|
{
|
|
name: "Invalid token",
|
|
userId: testing_tools.InvalidToken,
|
|
expectResponse: false,
|
|
},
|
|
}
|
|
|
|
tt := []struct {
|
|
name string
|
|
expectedStatus int
|
|
requestType string
|
|
requestPath string
|
|
requestId string
|
|
}{
|
|
{
|
|
name: "Get accessible peers for existing peer",
|
|
requestType: http.MethodGet,
|
|
requestPath: "/api/peers/{peerId}/accessible-peers",
|
|
requestId: testing_tools.TestPeerId,
|
|
expectedStatus: http.StatusOK,
|
|
},
|
|
{
|
|
name: "Get accessible peers for non-existing peer",
|
|
requestType: http.MethodGet,
|
|
requestPath: "/api/peers/{peerId}/accessible-peers",
|
|
requestId: "nonExistingPeerId",
|
|
expectedStatus: http.StatusOK,
|
|
},
|
|
}
|
|
|
|
for _, tc := range tt {
|
|
for _, user := range users {
|
|
t.Run(user.name+" - "+tc.name, func(t *testing.T) {
|
|
apiHandler, _, done := channel.BuildApiBlackBoxWithDBState(t, "../testdata/peers_integration.sql", nil, true)
|
|
|
|
req := testing_tools.BuildRequest(t, []byte{}, tc.requestType, strings.Replace(tc.requestPath, "{peerId}", tc.requestId, 1), user.userId)
|
|
recorder := httptest.NewRecorder()
|
|
|
|
apiHandler.ServeHTTP(recorder, req)
|
|
|
|
content, expectResponse := testing_tools.ReadResponse(t, recorder, tc.expectedStatus, user.expectResponse)
|
|
if !expectResponse {
|
|
return
|
|
}
|
|
|
|
if tc.expectedStatus == http.StatusOK {
|
|
var got []api.AccessiblePeer
|
|
if err := json.Unmarshal(content, &got); err != nil {
|
|
t.Fatalf("Sent content is not in correct json format; %v", err)
|
|
}
|
|
// The accessible peers list should be a valid array (may be empty if no policies connect peers)
|
|
assert.NotNil(t, got, "Expected accessible peers to be a valid array")
|
|
}
|
|
|
|
select {
|
|
case <-done:
|
|
case <-time.After(time.Second):
|
|
t.Error("timeout waiting for peerShouldNotReceiveUpdate")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
}
|