Skip to content

Commit 549d4a9

Browse files
authored
chore: upgrade golangci-lint to v2 and modernize codebase (#68)
1 parent 53b77a5 commit 549d4a9

65 files changed

Lines changed: 335 additions & 176 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/lint.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ jobs:
2424
go mod verify
2525
go mod download
2626
27-
LINT_VERSION=1.64.8
27+
LINT_VERSION=2.7.2
2828
curl -fsSL https://github.com/golangci/golangci-lint/releases/download/v${LINT_VERSION}/golangci-lint-${LINT_VERSION}-linux-amd64.tar.gz | \
2929
tar xz --strip-components 1 --wildcards \*/golangci-lint
3030
mkdir -p bin && mv golangci-lint bin/
@@ -45,6 +45,6 @@ jobs:
4545
assert-nothing-changed go fmt ./...
4646
assert-nothing-changed go mod tidy
4747
48-
bin/golangci-lint run --out-format=colored-line-number --timeout=3m || STATUS=$?
48+
bin/golangci-lint run --timeout=3m || STATUS=$?
4949
5050
exit $STATUS

.golangci.yml

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
version: "2"
2+
13
run:
24
timeout: 5m
35
tests: true
@@ -8,21 +10,24 @@ linters:
810
- govet
911
- errcheck
1012
- staticcheck
11-
- gofmt
12-
- goimports
1313
- revive
1414
- ineffassign
15-
- typecheck
1615
- unused
17-
- gosimple
1816
- misspell
1917
- nakedret
2018
- bodyclose
2119
- gocritic
2220
- makezero
2321
- gosec
2422

23+
formatters:
24+
enable:
25+
- gofmt
26+
- goimports
27+
2528
output:
26-
formats: colored-line-number
27-
print-issued-lines: true
28-
print-linter-name: true
29+
formats:
30+
text:
31+
path: stdout
32+
print-issued-lines: true
33+
print-linter-name: true

cmd/streamnative-mcp-server/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
// Package main is the entry point for the StreamNative MCP server.
1516
package main
1617

1718
import (

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ go 1.24.4
55
require (
66
github.com/99designs/keyring v1.2.2
77
github.com/apache/pulsar-client-go v0.13.1
8-
github.com/dgrijalva/jwt-go v3.2.0+incompatible
8+
github.com/golang-jwt/jwt v3.2.1+incompatible
99
github.com/google/go-cmp v0.7.0
1010
github.com/hamba/avro/v2 v2.28.0
1111
github.com/mark3labs/mcp-go v0.43.2

go.sum

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,6 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
4848
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
4949
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
5050
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
51-
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
52-
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
5351
github.com/dimfeld/httptreemux v5.0.1+incompatible h1:Qj3gVcDNoOthBAqftuD596rm4wg/adLLz5xh5CmpiCA=
5452
github.com/dimfeld/httptreemux v5.0.1+incompatible/go.mod h1:rbUlSV+CCpv/SuqUTP/8Bk2O3LyUV436/yaRGkhP6Z0=
5553
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
@@ -85,6 +83,7 @@ github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+
8583
github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
8684
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
8785
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
86+
github.com/golang-jwt/jwt v3.2.1+incompatible h1:73Z+4BJcrTC+KczS6WvTPvRGOp1WmfEP4Q1lOd9Z/+c=
8887
github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
8988
github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI=
9089
github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=

pkg/auth/auth.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
// Package auth provides authentication and authorization functionality for StreamNative MCP Server.
16+
// It implements OAuth 2.0 flows including client credentials and device authorization grants.
1517
package auth
1618

1719
import (
@@ -20,12 +22,13 @@ import (
2022
"io"
2123
"time"
2224

23-
"github.com/dgrijalva/jwt-go"
25+
"github.com/golang-jwt/jwt"
2426
"golang.org/x/oauth2"
2527
"k8s.io/utils/clock"
2628
)
2729

2830
const (
31+
// ClaimNameUserName is the JWT claim name for the username.
2932
ClaimNameUserName = "https://streamnative.io/username"
3033
)
3134

@@ -42,6 +45,7 @@ type AuthorizationGrantRefresher interface {
4245
Refresh(grant *AuthorizationGrant) (*AuthorizationGrant, error)
4346
}
4447

48+
// AuthorizationGrantType defines the supported OAuth2 grant types.
4549
type AuthorizationGrantType string
4650

4751
const (
@@ -139,17 +143,18 @@ func ExtractUserName(token oauth2.Token) (string, error) {
139143
return "", fmt.Errorf("access token doesn't contain a recognizable user claim")
140144
}
141145

146+
// DumpToken outputs token information to the provided writer for debugging.
142147
func DumpToken(out io.Writer, token oauth2.Token) {
143148
p := jwt.Parser{}
144149
claims := jwt.MapClaims{}
145150
if _, _, err := p.ParseUnverified(token.AccessToken, claims); err != nil {
146-
fmt.Fprintf(out, "Unable to parse token. Err: %v\n", err)
151+
_, _ = fmt.Fprintf(out, "Unable to parse token. Err: %v\n", err)
147152
return
148153
}
149154

150155
text, err := json.MarshalIndent(claims, "", " ")
151156
if err != nil {
152-
fmt.Fprintf(out, "Unable to print token. Err: %v\n", err)
157+
_, _ = fmt.Fprintf(out, "Unable to print token. Err: %v\n", err)
153158
}
154159
_, _ = out.Write(text)
155160
_, _ = fmt.Fprintln(out, "")

pkg/auth/authorization_tokenretriever.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ type TokenErrorResponse struct {
8282
ErrorDescription string `json:"error_description"`
8383
}
8484

85+
// TokenError represents an error response from the token endpoint.
8586
type TokenError struct {
8687
ErrorCode string
8788
ErrorDescription string
@@ -222,6 +223,7 @@ func (ce *TokenRetriever) ExchangeCode(req AuthorizationCodeExchangeRequest) (*T
222223
if err != nil {
223224
return nil, err
224225
}
226+
defer func() { _ = response.Body.Close() }()
225227

226228
return ce.handleAuthTokensResponse(response)
227229
}
@@ -230,7 +232,7 @@ func (ce *TokenRetriever) ExchangeCode(req AuthorizationCodeExchangeRequest) (*T
230232
// auth tokens for errors and parsing the raw body to a TokenResult struct
231233
func (ce *TokenRetriever) handleAuthTokensResponse(resp *http.Response) (*TokenResult, error) {
232234
if resp.Body != nil {
233-
defer resp.Body.Close()
235+
defer func() { _ = resp.Body.Close() }()
234236
}
235237

236238
if resp.StatusCode < 200 || resp.StatusCode > 299 {
@@ -272,6 +274,7 @@ func (ce *TokenRetriever) ExchangeDeviceCode(ctx context.Context, req DeviceCode
272274
if err != nil {
273275
return nil, err
274276
}
277+
defer func() { _ = response.Body.Close() }()
275278
token, err := ce.handleAuthTokensResponse(response)
276279
if err == nil {
277280
return token, nil
@@ -314,6 +317,7 @@ func (ce *TokenRetriever) ExchangeRefreshToken(req RefreshTokenExchangeRequest)
314317
if err != nil {
315318
return nil, err
316319
}
320+
defer func() { _ = response.Body.Close() }()
317321

318322
return ce.handleAuthTokensResponse(response)
319323
}
@@ -330,6 +334,7 @@ func (ce *TokenRetriever) ExchangeClientCredentials(req ClientCredentialsExchang
330334
if err != nil {
331335
return nil, err
332336
}
337+
defer func() { _ = response.Body.Close() }()
333338

334339
return ce.handleAuthTokensResponse(response)
335340
}

pkg/auth/cache/cache.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
// Package cache provides cached token sources for authentication flows.
1516
package cache
1617

1718
import (
@@ -51,6 +52,7 @@ type tokenCache struct {
5152
token *oauth2.Token
5253
}
5354

55+
// NewDefaultTokenCache creates a default token cache with the given store and refresher.
5456
func NewDefaultTokenCache(store store.Store, audience string,
5557
refresher auth.AuthorizationGrantRefresher) (CachingTokenSource, error) {
5658
cache := &tokenCache{

pkg/auth/client_credentials_flow.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ type ClientCredentialsExchanger interface {
4141
ExchangeClientCredentials(req ClientCredentialsExchangeRequest) (*TokenResult, error)
4242
}
4343

44+
// NewClientCredentialsFlow creates a new client credentials flow with the given components.
4445
func NewClientCredentialsFlow(
4546
issuerData Issuer,
4647
provider ClientCredentialsProvider,
@@ -98,6 +99,7 @@ func NewDefaultClientCredentialsFlowWithKeyFileStruct(issuerData Issuer, keyFile
9899

99100
var _ Flow = &ClientCredentialsFlow{}
100101

102+
// Authorize requests an authorization grant using the client credentials flow.
101103
func (c *ClientCredentialsFlow) Authorize() (*AuthorizationGrant, error) {
102104
keyFile, err := c.provider.GetClientCredentials()
103105
if err != nil {
@@ -121,12 +123,14 @@ func (c *ClientCredentialsFlow) Authorize() (*AuthorizationGrant, error) {
121123
return grant, nil
122124
}
123125

126+
// ClientCredentialsGrantRefresher refreshes client-credentials grants using the token endpoint.
124127
type ClientCredentialsGrantRefresher struct {
125128
issuerData Issuer
126129
exchanger ClientCredentialsExchanger
127130
clock clock.Clock
128131
}
129132

133+
// NewDefaultClientCredentialsGrantRefresher creates a default client credentials grant refresher.
130134
func NewDefaultClientCredentialsGrantRefresher(issuerData Issuer,
131135
clock clock.Clock) (*ClientCredentialsGrantRefresher, error) {
132136
wellKnownEndpoints, err := GetOIDCWellKnownEndpointsFromIssuerURL(issuerData.IssuerEndpoint)
@@ -147,6 +151,7 @@ func NewDefaultClientCredentialsGrantRefresher(issuerData Issuer,
147151

148152
var _ AuthorizationGrantRefresher = &ClientCredentialsGrantRefresher{}
149153

154+
// Refresh exchanges the client credentials for a fresh authorization grant.
150155
func (g *ClientCredentialsGrantRefresher) Refresh(grant *AuthorizationGrant) (*AuthorizationGrant, error) {
151156
if grant.Type != GrantTypeClientCredentials {
152157
return nil, errors.New("unsupported grant type")

pkg/auth/client_credentials_provider.go

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,26 +18,33 @@ import (
1818
"encoding/json"
1919
"fmt"
2020
"os"
21+
"path/filepath"
2122
"strings"
2223
)
2324

2425
const (
26+
// KeyFileTypeServiceAccount identifies service account key files.
2527
KeyFileTypeServiceAccount = "sn_service_account"
26-
FILE = "file://"
27-
DATA = "data://"
28+
// FILE indicates a file:// key file reference.
29+
FILE = "file://"
30+
// DATA indicates a data:// inline key file reference.
31+
DATA = "data://"
2832
)
2933

34+
// KeyFileProvider provides client credentials from a key file path.
3035
type KeyFileProvider struct {
3136
KeyFile string
3237
}
3338

39+
// KeyFile holds service account credentials from a JSON key file.
3440
type KeyFile struct {
3541
Type string `json:"type"`
3642
ClientID string `json:"client_id"`
3743
ClientSecret string `json:"client_secret"`
3844
ClientEmail string `json:"client_email"`
3945
}
4046

47+
// NewClientCredentialsProviderFromKeyFile creates a provider from a key file path.
4148
func NewClientCredentialsProviderFromKeyFile(keyFile string) *KeyFileProvider {
4249
return &KeyFileProvider{
4350
KeyFile: keyFile,
@@ -46,13 +53,14 @@ func NewClientCredentialsProviderFromKeyFile(keyFile string) *KeyFileProvider {
4653

4754
var _ ClientCredentialsProvider = &KeyFileProvider{}
4855

56+
// GetClientCredentials loads client credentials from the configured key file source.
4957
func (k *KeyFileProvider) GetClientCredentials() (*KeyFile, error) {
5058
var keyFile []byte
5159
var err error
5260
switch {
5361
case strings.HasPrefix(k.KeyFile, FILE):
5462
filename := strings.TrimPrefix(k.KeyFile, FILE)
55-
keyFile, err = os.ReadFile(filename)
63+
keyFile, err = os.ReadFile(filepath.Clean(filename))
5664
case strings.HasPrefix(k.KeyFile, DATA):
5765
keyFile = []byte(strings.TrimPrefix(k.KeyFile, DATA))
5866
case strings.HasPrefix(k.KeyFile, "data:"):
@@ -80,17 +88,20 @@ func (k *KeyFileProvider) GetClientCredentials() (*KeyFile, error) {
8088
return &v, nil
8189
}
8290

91+
// KeyFileStructProvider provides client credentials from an in-memory KeyFile struct.
8392
type KeyFileStructProvider struct {
8493
KeyFile *KeyFile
8594
}
8695

96+
// GetClientCredentials returns the client credentials from the in-memory KeyFile.
8797
func (k *KeyFileStructProvider) GetClientCredentials() (*KeyFile, error) {
8898
if k.KeyFile == nil {
8999
return nil, fmt.Errorf("key file is nil")
90100
}
91101
return k.KeyFile, nil
92102
}
93103

104+
// NewClientCredentialsProviderFromKeyFileStruct creates a provider from an in-memory KeyFile.
94105
func NewClientCredentialsProviderFromKeyFileStruct(keyFile *KeyFile) *KeyFileStructProvider {
95106
return &KeyFileStructProvider{
96107
KeyFile: keyFile,

0 commit comments

Comments
 (0)