diff --git a/hscontrol/db/node.go b/hscontrol/db/node.go index f1bf1e73..52030bfb 100644 --- a/hscontrol/db/node.go +++ b/hscontrol/db/node.go @@ -371,7 +371,7 @@ func (hsdb *HSDatabase) RegisterNodeFromAuthCallback( node.User = *user node.RegisterMethod = registrationMethod - if !node.IsApproved() && manualApprovedNode == false { + if !node.IsApproved() && !manualApprovedNode { node.Approved = true } diff --git a/hscontrol/db/node_test.go b/hscontrol/db/node_test.go index 4446726a..0aaadf3f 100644 --- a/hscontrol/db/node_test.go +++ b/hscontrol/db/node_test.go @@ -202,7 +202,7 @@ func (s *Suite) TestListPeersWithoutNonAuthorized(c *check.C) { } node := types.Node{ - ID: types.NodeID(int64(index)), + ID: types.NodeID(uint64(index)), MachineKey: machineKey.Public(), NodeKey: nodeKey.Public(), Hostname: "testnode" + strconv.Itoa(index), diff --git a/hscontrol/types/common.go b/hscontrol/types/common.go index 05a0b709..b6e162e4 100644 --- a/hscontrol/types/common.go +++ b/hscontrol/types/common.go @@ -16,8 +16,8 @@ const ( ) const ( - SchemaHttp = "http" - SchemaHttps = "https" + SchemaHTTP = "http" + SchemaHTTPS = "https" ) var ErrCannotParsePrefix = errors.New("cannot parse prefix") diff --git a/integration/auth_approval_test.go b/integration/auth_approval_test.go index c9fd98a9..d4b86505 100644 --- a/integration/auth_approval_test.go +++ b/integration/auth_approval_test.go @@ -4,18 +4,20 @@ import ( "context" "crypto/tls" "fmt" - "github.com/juanfont/headscale/gen/go/headscale/v1" - "github.com/juanfont/headscale/hscontrol/types" - "github.com/juanfont/headscale/integration/hsic" - "github.com/samber/lo" - "github.com/stretchr/testify/assert" "io" "log" "net/http" "net/netip" "net/url" + "strconv" "strings" "testing" + + "github.com/juanfont/headscale/gen/go/headscale/v1" + "github.com/juanfont/headscale/hscontrol/types" + "github.com/juanfont/headscale/integration/hsic" + "github.com/samber/lo" + "github.com/stretchr/testify/assert" ) type AuthApprovalScenario struct { @@ -75,11 +77,11 @@ func TestAuthNodeApproval(t *testing.T) { }, &allNodes, ) - assert.NoError(t, err) + assertNoErr(t, err) for _, node := range allNodes { _, err = headscale.Execute([]string{ - "headscale", "nodes", "approve", "--identifier", fmt.Sprintf("%d", node.GetId()), + "headscale", "nodes", "approve", "--identifier", strconv.FormatUint(node.GetId(), 10), }) assertNoErr(t, err) } @@ -238,10 +240,10 @@ func (s *AuthApprovalScenario) runHeadscaleRegister(userStr string, loginURL *ur log.Printf("loginURL: %s", loginURL) loginURL.Host = fmt.Sprintf("%s:%d", headscale.GetIP(), 8080) - loginURL.Scheme = types.SchemaHttp + loginURL.Scheme = types.SchemaHTTP if len(headscale.GetCert()) > 0 { - loginURL.Scheme = types.SchemaHttps + loginURL.Scheme = types.SchemaHTTPS } insecureTransport := &http.Transport{ diff --git a/integration/cli_test.go b/integration/cli_test.go index 5926d426..8bccc6a1 100644 --- a/integration/cli_test.go +++ b/integration/cli_test.go @@ -1196,6 +1196,138 @@ func TestNodeCommand(t *testing.T) { assert.Len(t, listOnlyMachineUserAfterDelete, 4) } +func TestNodeApproveCommand(t *testing.T) { + IntegrationSkip(t) + t.Parallel() + + scenario, err := NewScenario(dockertestMaxWait()) + assertNoErr(t, err) + defer scenario.ShutdownAssertNoPanics(t) + + spec := map[string]int{ + "node-approve-user": 0, + } + + err = scenario.CreateHeadscaleEnv( + spec, + []tsic.Option{}, + hsic.WithTestName("clins"), + hsic.WithManualApproveNewNode(), + ) + assertNoErr(t, err) + + headscale, err := scenario.Headscale() + assertNoErr(t, err) + + // Pregenerated machine keys + machineKeys := []string{ + "mkey:9b2ffa7e08cc421a3d2cca9012280f6a236fd0de0b4ce005b30a98ad930306fe", + "mkey:6abd00bb5fdda622db51387088c68e97e71ce58e7056aa54f592b6a8219d524c", + "mkey:f08305b4ee4250b95a70f3b7504d048d75d899993c624a26d422c67af0422507", + "mkey:8bc13285cee598acf76b1824a6f4490f7f2e3751b201e28aeb3b07fe81d5b4a1", + "mkey:cf7b0fd05da556fdc3bab365787b506fd82d64a70745db70e00e86c1b1c03084", + } + nodes := make([]*v1.Node, len(machineKeys)) + + for index, machineKey := range machineKeys { + _, err := headscale.Execute( + []string{ + "headscale", + "debug", + "create-node", + "--name", + fmt.Sprintf("node-%d", index+1), + "--user", + "node-approve-user", + "--key", + machineKey, + "--output", + "json", + }, + ) + assert.NoError(t, err) + + var node v1.Node + err = executeAndUnmarshal( + headscale, + []string{ + "headscale", + "nodes", + "--user", + "node-approve-user", + "register", + "--key", + machineKey, + "--output", + "json", + }, + &node, + ) + assert.NoError(t, err) + + nodes[index] = &node + } + + assert.Len(t, nodes, len(machineKeys)) + + var listAll []v1.Node + err = executeAndUnmarshal( + headscale, + []string{ + "headscale", + "nodes", + "list", + "--output", + "json", + }, + &listAll, + ) + assert.NoError(t, err) + + assert.Len(t, listAll, 5) + + assert.False(t, listAll[0].GetApproved()) + assert.False(t, listAll[1].GetApproved()) + assert.False(t, listAll[2].GetApproved()) + assert.False(t, listAll[3].GetApproved()) + assert.False(t, listAll[4].GetApproved()) + + for idx := 0; idx < 3; idx++ { + _, err := headscale.Execute( + []string{ + "headscale", + "nodes", + "approve", + "--identifier", + fmt.Sprintf("%d", listAll[idx].GetId()), + }, + ) + assert.NoError(t, err) + } + + var listAllAfterApprove []v1.Node + err = executeAndUnmarshal( + headscale, + []string{ + "headscale", + "nodes", + "list", + "--output", + "json", + }, + &listAllAfterApprove, + ) + assert.NoError(t, err) + + assert.Len(t, listAllAfterApprove, 5) + + assert.True(t, listAllAfterApprove[0].GetApproved()) + assert.True(t, listAllAfterApprove[1].GetApproved()) + assert.True(t, listAllAfterApprove[2].GetApproved()) + assert.False(t, listAllAfterApprove[3].GetApproved()) + assert.False(t, listAllAfterApprove[4].GetApproved()) +} + func TestNodeExpireCommand(t *testing.T) { IntegrationSkip(t) t.Parallel()