@@ -898,6 +898,106 @@ func TestStreamCommandResponse(t *testing.T) {
898898 assert .Equal (t , 0 , ts .RequestsRemaining (), ts .ExpectedRequests ())
899899}
900900
901+ func TestReauthenticate (t * testing.T ) {
902+ t .Parallel ()
903+
904+ useragent := "testClient"
905+ ts := dnapitest .NewServer (useragent )
906+ t .Cleanup (func () { ts .Close () })
907+
908+ ca , caPrivkey := dnapitest .NebulaCACert ()
909+ caPEM , err := ca .MarshalToPEM ()
910+ require .NoError (t , err )
911+
912+ c := NewClient (useragent , ts .URL )
913+
914+ code := "foobar"
915+ ts .ExpectEnrollment (code , message .NetworkCurve25519 , func (req message.EnrollRequest ) []byte {
916+ cfg , err := yaml .Marshal (m {
917+ // we need to send this or we'll get an error from the api client
918+ "pki" : m {"ca" : string (caPEM )},
919+ // here we reflect values back to the client for test purposes
920+ "test" : m {"code" : req .Code , "dhPubkey" : req .NebulaPubkeyX25519 },
921+ })
922+ if err != nil {
923+ return jsonMarshal (message.EnrollResponse {
924+ Errors : message.APIErrors {{
925+ Code : "ERR_FAILED_TO_MARSHAL_YAML" ,
926+ Message : "failed to marshal test response config" ,
927+ }},
928+ })
929+ }
930+
931+ return jsonMarshal (message.EnrollResponse {
932+ Data : message.EnrollResponseData {
933+ HostID : "foobar" ,
934+ Counter : 1 ,
935+ Config : cfg ,
936+ TrustedKeys : marshalCAPublicKey (ca .Details .Curve , ca .Details .PublicKey ),
937+ Organization : message.HostOrgMetadata {
938+ ID : "foobaz" ,
939+ Name : "foobar's foo org" ,
940+ },
941+ Network : message.HostNetworkMetadata {
942+ ID : "qux" ,
943+ Name : "the best network" ,
944+ Curve : message .NetworkCurve25519 ,
945+ CIDR : "192.168.100.0/24" ,
946+ },
947+ Host : message.HostHostMetadata {
948+ ID : "quux" ,
949+ Name : "foo host" ,
950+ IPAddress : "192.168.100.2" ,
951+ },
952+ },
953+ })
954+ })
955+
956+ ctx , cancel := context .WithTimeout (context .Background (), 1 * time .Second )
957+ defer cancel ()
958+ config , pkey , creds , _ , err := c .Enroll (ctx , testutil .NewTestLogger (), "foobar" )
959+ require .NoError (t , err )
960+
961+ // make sure all credential values were set
962+ assert .NotEmpty (t , creds .HostID )
963+ assert .NotEmpty (t , creds .PrivateKey )
964+ assert .NotEmpty (t , creds .TrustedKeys )
965+ assert .NotEmpty (t , creds .Counter )
966+
967+ // make sure we got a config back
968+ assert .NotEmpty (t , config )
969+ assert .NotEmpty (t , pkey )
970+
971+ // This time sign the response with the correct CA key.
972+ ts .ExpectDNClientRequest (message .Reauthenticate , http .StatusOK , func (r message.RequestWrapper ) []byte {
973+ newConfigResponse := message.ReauthenticateResponse {
974+ LoginURL : "https://auth.example.com/login?authcode=123" ,
975+ }
976+ rawRes := jsonMarshal (newConfigResponse )
977+
978+ return jsonMarshal (message.SignedResponseWrapper {
979+ Data : message.SignedResponse {
980+ Version : 1 ,
981+ Message : rawRes ,
982+ Signature : ed25519 .Sign (caPrivkey , rawRes ),
983+ },
984+ })
985+ })
986+
987+ ctx , cancel = context .WithTimeout (context .Background (), 1 * time .Second )
988+ defer cancel ()
989+ resp , err := c .Reauthenticate (ctx , * creds )
990+ require .NoError (t , err )
991+ assert .Empty (t , ts .Errors ())
992+ assert .Equal (t , 0 , ts .RequestsRemaining ())
993+
994+ // make sure we got a login URL back
995+ assert .NotEmpty (t , resp )
996+ assert .NotEmpty (t , resp .LoginURL )
997+ assert .Equal (t , "https://auth.example.com/login?authcode=123" , resp .LoginURL )
998+
999+ }
1000+
9011001func jsonMarshal (v interface {}) []byte {
9021002 b , err := json .Marshal (v )
9031003 if err != nil {
0 commit comments