Fix gRPC auth: inject bearer token via PerRPCCredentials
The gRPC client was not sending the authorization header, causing "missing authorization header" errors even when a token was configured. Also fix config test to isolate from real ~/.config/mcrctl.toml. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -62,10 +62,14 @@ func newClient(serverURL, grpcAddr, token, caCertFile string) (*apiClient, error
|
||||
|
||||
if grpcAddr != "" {
|
||||
creds := credentials.NewTLS(tlsCfg)
|
||||
cc, err := grpc.NewClient(grpcAddr,
|
||||
dialOpts := []grpc.DialOption{
|
||||
grpc.WithTransportCredentials(creds),
|
||||
grpc.WithDefaultCallOptions(grpc.ForceCodecV2(mcrv1.JSONCodec{})),
|
||||
)
|
||||
}
|
||||
if token != "" {
|
||||
dialOpts = append(dialOpts, grpc.WithPerRPCCredentials(bearerToken(token)))
|
||||
}
|
||||
cc, err := grpc.NewClient(grpcAddr, dialOpts...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("grpc dial: %w", err)
|
||||
}
|
||||
@@ -91,6 +95,16 @@ func (c *apiClient) useGRPC() bool {
|
||||
return c.grpcConn != nil
|
||||
}
|
||||
|
||||
// bearerToken implements grpc.PerRPCCredentials, injecting the
|
||||
// Authorization header into every gRPC call.
|
||||
type bearerToken string
|
||||
|
||||
func (t bearerToken) GetRequestMetadata(_ context.Context, _ ...string) (map[string]string, error) {
|
||||
return map[string]string{"authorization": "Bearer " + string(t)}, nil
|
||||
}
|
||||
|
||||
func (t bearerToken) RequireTransportSecurity() bool { return true }
|
||||
|
||||
// apiError is the JSON error envelope returned by the REST API.
|
||||
type apiError struct {
|
||||
Error string `json:"error"`
|
||||
|
||||
@@ -38,7 +38,9 @@ ca_cert = "/path/to/ca.pem"
|
||||
}
|
||||
|
||||
func TestLoadConfigMissingDefaultIsOK(t *testing.T) {
|
||||
// Empty path triggers default search; missing file is not an error.
|
||||
// Point XDG_CONFIG_HOME at an empty dir so we don't find the real config.
|
||||
t.Setenv("XDG_CONFIG_HOME", t.TempDir())
|
||||
|
||||
cfg, err := loadConfig("")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
||||
Reference in New Issue
Block a user