mirror of
https://github.com/tailscale/tailscale.git
synced 2025-04-22 08:51:41 +00:00
controlclient: add auth key test
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
This commit is contained in:
parent
f8b72d2b5b
commit
6b2e29867e
@ -31,6 +31,7 @@ import (
|
|||||||
"tailscale.com/tailcfg"
|
"tailscale.com/tailcfg"
|
||||||
"tailscale.com/testy"
|
"tailscale.com/testy"
|
||||||
"tailscale.io/control" // not yet released
|
"tailscale.io/control" // not yet released
|
||||||
|
"tailscale.io/control/cfgdb"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestTest(t *testing.T) {
|
func TestTest(t *testing.T) {
|
||||||
@ -716,6 +717,69 @@ func TestRefresh(t *testing.T) {
|
|||||||
c1.Shutdown()
|
c1.Shutdown()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAuthKey(t *testing.T) {
|
||||||
|
var nowMu sync.Mutex
|
||||||
|
now := time.Now() // Server and Client use this variable as the current time
|
||||||
|
timeNow := func() time.Time {
|
||||||
|
nowMu.Lock()
|
||||||
|
defer nowMu.Unlock()
|
||||||
|
return now
|
||||||
|
}
|
||||||
|
|
||||||
|
s := newServer(t)
|
||||||
|
s.control.TimeNow = timeNow
|
||||||
|
defer s.close()
|
||||||
|
|
||||||
|
const loginName = "testuser1@example.com"
|
||||||
|
user, err := s.control.DB().FindOrCreateUser("google", loginName, "", "")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run("one-off", func(t *testing.T) {
|
||||||
|
oneOffKey, err := s.control.DB().NewAPIKey(user.ID, cfgdb.KeyCapabilities{
|
||||||
|
Bits: cfgdb.KeyCapOneOffNodeAuth,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
c1 := s.newClientWithKey(t, "c1", string(oneOffKey))
|
||||||
|
c1.Login(nil, 0)
|
||||||
|
c1.waitStatus(t, stateAuthenticated)
|
||||||
|
c1.waitStatus(t, stateSynchronized)
|
||||||
|
c1.Shutdown()
|
||||||
|
|
||||||
|
// Key won't work a second time.
|
||||||
|
c2 := s.newClientWithKey(t, "c2", string(oneOffKey))
|
||||||
|
c2.Login(nil, 0)
|
||||||
|
status := c2.readStatus(t)
|
||||||
|
if e, substr := status.New.Err, `revoked`; !strings.Contains(e, substr) {
|
||||||
|
t.Errorf("Err=%q, expect substring %q", e, substr)
|
||||||
|
}
|
||||||
|
c2.Shutdown()
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("followup", func(t *testing.T) {
|
||||||
|
key, err := s.control.DB().NewAPIKey(user.ID, cfgdb.KeyCapabilities{
|
||||||
|
Bits: cfgdb.KeyCapNodeAuth,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
c1 := s.newClient(t, "c1")
|
||||||
|
c1.Login(nil, 0)
|
||||||
|
c1.waitStatus(t, stateURLVisitRequired)
|
||||||
|
|
||||||
|
c1.direct.authKey = string(key)
|
||||||
|
c1.Login(nil, 0)
|
||||||
|
c1.waitStatus(t, stateAuthenticated)
|
||||||
|
c1.waitStatus(t, stateSynchronized)
|
||||||
|
c1.Shutdown()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestExpectedProvider(t *testing.T) {
|
func TestExpectedProvider(t *testing.T) {
|
||||||
s := newServer(t)
|
s := newServer(t)
|
||||||
defer s.close()
|
defer s.close()
|
||||||
@ -1008,6 +1072,10 @@ type statusChange struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *server) newClient(t *testing.T, name string) *client {
|
func (s *server) newClient(t *testing.T, name string) *client {
|
||||||
|
return s.newClientWithKey(t, name, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *server) newClientWithKey(t *testing.T, name, authKey string) *client {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
ch := make(chan statusChange, 1024)
|
ch := make(chan statusChange, 1024)
|
||||||
@ -1033,6 +1101,7 @@ func (s *server) newClient(t *testing.T, name string) *client {
|
|||||||
return zstd.NewReader(nil)
|
return zstd.NewReader(nil)
|
||||||
},
|
},
|
||||||
KeepAlive: true,
|
KeepAlive: true,
|
||||||
|
AuthKey: authKey,
|
||||||
})
|
})
|
||||||
ctlc.SetStatusFunc(func(new Status) {
|
ctlc.SetStatusFunc(func(new Status) {
|
||||||
select {
|
select {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user