@ -9,11 +9,15 @@ import (
"io"
"net/http"
"net/http/httptest"
"net/netip"
"net/url"
"strings"
"testing"
"tailscale.com/client/tailscale/apitype"
"tailscale.com/hostinfo"
"tailscale.com/ipn/ipnlocal"
"tailscale.com/tailcfg"
"tailscale.com/tstest"
)
@ -77,3 +81,68 @@ func TestSetPushDeviceToken(t *testing.T) {
t . Errorf ( "hostinfo.PushDeviceToken=%q, want %q" , got , want )
}
}
type whoIsBackend struct {
whoIs func ( ipp netip . AddrPort ) ( n tailcfg . NodeView , u tailcfg . UserProfile , ok bool )
peerCaps map [ netip . Addr ] tailcfg . PeerCapMap
}
func ( b whoIsBackend ) WhoIs ( ipp netip . AddrPort ) ( n tailcfg . NodeView , u tailcfg . UserProfile , ok bool ) {
return b . whoIs ( ipp )
}
func ( b whoIsBackend ) PeerCaps ( ip netip . Addr ) tailcfg . PeerCapMap {
return b . peerCaps [ ip ]
}
// Tests that the WhoIs handler accepts either IPs or IP:ports.
//
// From https://github.com/tailscale/tailscale/pull/9714 (a PR that is effectively a bug report)
func TestWhoIsJustIP ( t * testing . T ) {
h := & Handler {
PermitRead : true ,
}
for _ , input := range [ ] string { "100.101.102.103" , "127.0.0.1:123" } {
rec := httptest . NewRecorder ( )
t . Run ( input , func ( t * testing . T ) {
b := whoIsBackend {
whoIs : func ( ipp netip . AddrPort ) ( n tailcfg . NodeView , u tailcfg . UserProfile , ok bool ) {
if ! strings . Contains ( input , ":" ) {
want := netip . MustParseAddrPort ( "100.101.102.103:0" )
if ipp != want {
t . Fatalf ( "backend called with %v; want %v" , ipp , want )
}
}
return ( & tailcfg . Node {
ID : 123 ,
Addresses : [ ] netip . Prefix {
netip . MustParsePrefix ( "100.101.102.103/32" ) ,
} ,
} ) . View ( ) ,
tailcfg . UserProfile { ID : 456 , DisplayName : "foo" } ,
true
} ,
peerCaps : map [ netip . Addr ] tailcfg . PeerCapMap {
netip . MustParseAddr ( "100.101.102.103" ) : map [ tailcfg . PeerCapability ] [ ] tailcfg . RawMessage {
"foo" : { ` "bar" ` } ,
} ,
} ,
}
h . serveWhoIsWithBackend ( rec , httptest . NewRequest ( "GET" , "/v0/whois?addr=" + url . QueryEscape ( input ) , nil ) , b )
var res apitype . WhoIsResponse
if err := json . Unmarshal ( rec . Body . Bytes ( ) , & res ) ; err != nil {
t . Fatal ( err )
}
if got , want := res . Node . ID , tailcfg . NodeID ( 123 ) ; got != want {
t . Errorf ( "res.Node.ID=%v, want %v" , got , want )
}
if got , want := res . UserProfile . DisplayName , "foo" ; got != want {
t . Errorf ( "res.UserProfile.DisplayName=%q, want %q" , got , want )
}
if got , want := len ( res . CapMap ) , 1 ; got != want {
t . Errorf ( "capmap size=%v, want %v" , got , want )
}
} )
}
}