github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/grpc/test/insecure_creds_test.go (about) 1 /* 2 * 3 * Copyright 2020 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 package test 20 21 import ( 22 "context" 23 "net" 24 "strings" 25 "testing" 26 "time" 27 28 grpc "github.com/hxx258456/ccgo/grpc" 29 "github.com/hxx258456/ccgo/grpc/codes" 30 "github.com/hxx258456/ccgo/grpc/credentials" 31 "github.com/hxx258456/ccgo/grpc/credentials/insecure" 32 "github.com/hxx258456/ccgo/grpc/internal/stubserver" 33 "github.com/hxx258456/ccgo/grpc/peer" 34 "github.com/hxx258456/ccgo/grpc/status" 35 36 testpb "github.com/hxx258456/ccgo/grpc/test/grpc_testing" 37 ) 38 39 const defaultTestTimeout = 5 * time.Second 40 41 // testLegacyPerRPCCredentials is a PerRPCCredentials that has yet incorporated security level. 42 type testLegacyPerRPCCredentials struct{} 43 44 func (cr testLegacyPerRPCCredentials) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) { 45 return nil, nil 46 } 47 48 func (cr testLegacyPerRPCCredentials) RequireTransportSecurity() bool { 49 return true 50 } 51 52 func getSecurityLevel(ai credentials.AuthInfo) credentials.SecurityLevel { 53 if c, ok := ai.(interface { 54 GetCommonAuthInfo() credentials.CommonAuthInfo 55 }); ok { 56 return c.GetCommonAuthInfo().SecurityLevel 57 } 58 return credentials.InvalidSecurityLevel 59 } 60 61 // TestInsecureCreds tests the use of insecure creds on the server and client 62 // side, and verifies that expect security level and auth info are returned. 63 // Also verifies that this credential can interop with existing `WithInsecure` 64 // DialOption. 65 func (s) TestInsecureCreds(t *testing.T) { 66 tests := []struct { 67 desc string 68 clientInsecureCreds bool 69 serverInsecureCreds bool 70 }{ 71 { 72 desc: "client and server insecure creds", 73 clientInsecureCreds: true, 74 serverInsecureCreds: true, 75 }, 76 { 77 desc: "client only insecure creds", 78 clientInsecureCreds: true, 79 }, 80 { 81 desc: "server only insecure creds", 82 serverInsecureCreds: true, 83 }, 84 } 85 86 for _, test := range tests { 87 t.Run(test.desc, func(t *testing.T) { 88 ss := &stubserver.StubServer{ 89 EmptyCallF: func(ctx context.Context, in *testpb.Empty) (*testpb.Empty, error) { 90 if !test.serverInsecureCreds { 91 return &testpb.Empty{}, nil 92 } 93 94 pr, ok := peer.FromContext(ctx) 95 if !ok { 96 return nil, status.Error(codes.DataLoss, "Failed to get peer from ctx") 97 } 98 // Check security level. 99 secLevel := getSecurityLevel(pr.AuthInfo) 100 if secLevel == credentials.InvalidSecurityLevel { 101 return nil, status.Errorf(codes.Unauthenticated, "peer.AuthInfo does not implement GetCommonAuthInfo()") 102 } 103 if secLevel != credentials.NoSecurity { 104 return nil, status.Errorf(codes.Unauthenticated, "Wrong security level: got %q, want %q", secLevel, credentials.NoSecurity) 105 } 106 return &testpb.Empty{}, nil 107 }, 108 } 109 110 sOpts := []grpc.ServerOption{} 111 if test.serverInsecureCreds { 112 sOpts = append(sOpts, grpc.Creds(insecure.NewCredentials())) 113 } 114 s := grpc.NewServer(sOpts...) 115 defer s.Stop() 116 117 testpb.RegisterTestServiceServer(s, ss) 118 119 lis, err := net.Listen("tcp", "localhost:0") 120 if err != nil { 121 t.Fatalf("net.Listen(tcp, localhost:0) failed: %v", err) 122 } 123 124 go s.Serve(lis) 125 126 addr := lis.Addr().String() 127 opts := []grpc.DialOption{grpc.WithInsecure()} 128 if test.clientInsecureCreds { 129 opts = []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())} 130 } 131 cc, err := grpc.Dial(addr, opts...) 132 if err != nil { 133 t.Fatalf("grpc.Dial(%q) failed: %v", addr, err) 134 } 135 defer cc.Close() 136 137 c := testpb.NewTestServiceClient(cc) 138 ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) 139 defer cancel() 140 if _, err = c.EmptyCall(ctx, &testpb.Empty{}); err != nil { 141 t.Fatalf("EmptyCall(_, _) = _, %v; want _, <nil>", err) 142 } 143 }) 144 } 145 } 146 147 func (s) TestInsecureCreds_WithPerRPCCredentials_AsCallOption(t *testing.T) { 148 ss := &stubserver.StubServer{ 149 EmptyCallF: func(ctx context.Context, in *testpb.Empty) (*testpb.Empty, error) { 150 return &testpb.Empty{}, nil 151 }, 152 } 153 154 s := grpc.NewServer(grpc.Creds(insecure.NewCredentials())) 155 defer s.Stop() 156 testpb.RegisterTestServiceServer(s, ss) 157 158 lis, err := net.Listen("tcp", "localhost:0") 159 if err != nil { 160 t.Fatalf("net.Listen(tcp, localhost:0) failed: %v", err) 161 } 162 go s.Serve(lis) 163 164 addr := lis.Addr().String() 165 ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) 166 defer cancel() 167 168 dopts := []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())} 169 copts := []grpc.CallOption{grpc.PerRPCCredentials(testLegacyPerRPCCredentials{})} 170 cc, err := grpc.Dial(addr, dopts...) 171 if err != nil { 172 t.Fatalf("grpc.Dial(%q) failed: %v", addr, err) 173 } 174 defer cc.Close() 175 176 const wantErr = "transport: cannot send secure credentials on an insecure connection" 177 c := testpb.NewTestServiceClient(cc) 178 if _, err = c.EmptyCall(ctx, &testpb.Empty{}, copts...); err == nil || !strings.Contains(err.Error(), wantErr) { 179 t.Fatalf("insecure credentials with per-RPC credentials requiring transport security returned error: %v; want %s", err, wantErr) 180 } 181 } 182 183 func (s) TestInsecureCreds_WithPerRPCCredentials_AsDialOption(t *testing.T) { 184 ss := &stubserver.StubServer{ 185 EmptyCallF: func(_ context.Context, _ *testpb.Empty) (*testpb.Empty, error) { 186 return &testpb.Empty{}, nil 187 }, 188 } 189 190 s := grpc.NewServer(grpc.Creds(insecure.NewCredentials())) 191 defer s.Stop() 192 testpb.RegisterTestServiceServer(s, ss) 193 194 lis, err := net.Listen("tcp", "localhost:0") 195 if err != nil { 196 t.Fatalf("net.Listen(tcp, localhost:0) failed: %v", err) 197 } 198 go s.Serve(lis) 199 200 addr := lis.Addr().String() 201 dopts := []grpc.DialOption{ 202 grpc.WithTransportCredentials(insecure.NewCredentials()), 203 grpc.WithPerRPCCredentials(testLegacyPerRPCCredentials{}), 204 } 205 const wantErr = "the credentials require transport level security" 206 if _, err := grpc.Dial(addr, dopts...); err == nil || !strings.Contains(err.Error(), wantErr) { 207 t.Fatalf("grpc.Dial(%q) returned err %v, want: %v", addr, err, wantErr) 208 } 209 }