Skip to content

Commit a8e2f96

Browse files
cvclaude
andcommitted
chore: Enable cyclop, gochecknoglobals, godot, nestif, nlreturn linters
Auto-fixed godot (comment periods) and nlreturn (newlines before returns) across all packages. 23 issues remain for manual refactoring (mcs-e0yb): - 12 cyclop (cyclomatic complexity) - 9 gochecknoglobals (global variables) - 2 nestif (nested if complexity) Temporarily excluded until refactored. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent f506e91 commit a8e2f96

53 files changed

Lines changed: 668 additions & 509 deletions

Some content is hidden

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

.golangci.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,13 @@ linters:
1717
- gosec # Security issues
1818

1919
# Code quality
20+
- cyclop # Cyclomatic complexity
2021
- dupl # Duplicated code blocks
22+
- gochecknoglobals # Disallow global variables
2123
- gochecknoinits # Disallow init functions
24+
- godot # Check comment ending with period
25+
- nestif # Deeply nested if statements
26+
- nlreturn # Newline before return
2227
- canonicalheader # HTTP header canonicalization
2328
- dupword # Duplicate words (typos)
2429
- exhaustive # Exhaustive switch statements
@@ -69,3 +74,16 @@ linters:
6974
- path: _test\.go
7075
linters:
7176
- goconst
77+
# TODO(mcs-e0yb): Temporarily exclude new linters until refactored
78+
# Cyclomatic complexity - 12 functions need refactoring
79+
- path: \.go
80+
linters:
81+
- cyclop
82+
# Global variables - 9 globals need evaluation
83+
- path: \.go
84+
linters:
85+
- gochecknoglobals
86+
# Nested if complexity - 2 functions need refactoring
87+
- path: \.go
88+
linters:
89+
- nestif

internal/api/auth.go

Lines changed: 35 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -19,84 +19,86 @@ import (
1919
)
2020

2121
const (
22-
// AuthRequestTimeout is the timeout for authentication-related API requests
22+
// AuthRequestTimeout is the timeout for authentication-related API requests.
2323
AuthRequestTimeout = 15 * time.Second
2424

25-
// IV is the initialization vector for AES encryption
25+
// IV is the initialization vector for AES encryption.
2626
IV = "0102030405060708"
2727

28-
// SignatureMD5 is used for key derivation
28+
// SignatureMD5 is used for key derivation.
2929
SignatureMD5 = "C383D8C4D279B78130AD52DC71D95CAA"
3030

31-
// AppPackageID identifies the mobile app package
31+
// AppPackageID identifies the mobile app package.
3232
AppPackageID = "com.interrait.mymazda"
3333

34-
// UserAgentBaseAPI is the User-Agent for base API requests
34+
// UserAgentBaseAPI is the User-Agent for base API requests.
3535
UserAgentBaseAPI = "MyMazda-Android/9.0.5"
3636

37-
// UserAgentUsherAPI is the User-Agent for Usher API requests
37+
// UserAgentUsherAPI is the User-Agent for Usher API requests.
3838
UserAgentUsherAPI = "MyMazda/9.0.5 (Google Pixel 3a; Android 11)"
3939

40-
// AppOS identifies the operating system
40+
// AppOS identifies the operating system.
4141
AppOS = "Android"
4242

43-
// AppVersion is the mobile app version
43+
// AppVersion is the mobile app version.
4444
AppVersion = "9.0.5"
4545

46-
// UsherSDKVersion is the Usher SDK version
46+
// UsherSDKVersion is the Usher SDK version.
4747
UsherSDKVersion = "11.3.0700.001"
4848

49-
// InternalUserID is a placeholder used in API requests
49+
// InternalUserID is a placeholder used in API requests.
5050
InternalUserID = "__INTERNAL_ID__"
5151
)
5252

53-
// Authentication endpoint constants
53+
// Authentication endpoint constants.
5454
const (
5555
EndpointCheckVersion = "service/checkVersion"
5656
EndpointEncryptionKey = "system/encryptionKey"
5757
EndpointLogin = "user/login"
5858
)
5959

60-
// Region represents a valid geographic region
60+
// Region represents a valid geographic region.
6161
type Region string
6262

6363
const (
64-
// RegionMNAO represents Mazda North American Operations
64+
// RegionMNAO represents Mazda North American Operations.
6565
RegionMNAO Region = "MNAO"
66-
// RegionMME represents Mazda Europe
66+
// RegionMME represents Mazda Europe.
6767
RegionMME Region = "MME"
68-
// RegionMJO represents Mazda Japan
68+
// RegionMJO represents Mazda Japan.
6969
RegionMJO Region = "MJO"
7070
)
7171

72-
// String returns the string representation of the region
72+
// String returns the string representation of the region.
7373
func (r Region) String() string {
7474
return string(r)
7575
}
7676

77-
// IsValid checks if the region is valid
77+
// IsValid checks if the region is valid.
7878
func (r Region) IsValid() bool {
7979
_, ok := RegionConfigs[string(r)]
80+
8081
return ok
8182
}
8283

83-
// ParseRegion parses a string into a Region, returning an error if invalid
84+
// ParseRegion parses a string into a Region, returning an error if invalid.
8485
func ParseRegion(s string) (Region, error) {
8586
r := Region(s)
8687
if !r.IsValid() {
8788
return "", fmt.Errorf("invalid region: %s (must be one of: MNAO, MME, MJO)", s)
8889
}
90+
8991
return r, nil
9092
}
9193

92-
// RegionConfig holds configuration for a specific region
94+
// RegionConfig holds configuration for a specific region.
9395
type RegionConfig struct {
9496
AppCode string
9597
BaseURL string
9698
UsherURL string
9799
}
98100

99-
// RegionConfigs maps region codes to their configurations
101+
// RegionConfigs maps region codes to their configurations.
100102
var RegionConfigs = map[string]RegionConfig{
101103
"MNAO": {
102104
AppCode: "202007270941270111799",
@@ -115,7 +117,7 @@ var RegionConfigs = map[string]RegionConfig{
115117
},
116118
}
117119

118-
// Client represents an API client
120+
// Client represents an API client.
119121
type Client struct {
120122
email string
121123
password string
@@ -138,7 +140,7 @@ type Client struct {
138140
sleepFunc func(context.Context, time.Duration) error
139141
}
140142

141-
// NewClient creates a new API client
143+
// NewClient creates a new API client.
142144
func NewClient(email, password string, region Region) (*Client, error) {
143145
if !region.IsValid() {
144146
return nil, fmt.Errorf("invalid region: %s", region)
@@ -162,25 +164,25 @@ func NewClient(email, password string, region Region) (*Client, error) {
162164
}, nil
163165
}
164166

165-
// SetDebug enables or disables debug logging
167+
// SetDebug enables or disables debug logging.
166168
func (c *Client) SetDebug(debug bool) {
167169
c.debug = debug
168170
}
169171

170-
// SetCachedCredentials sets the client's cached authentication credentials
172+
// SetCachedCredentials sets the client's cached authentication credentials.
171173
func (c *Client) SetCachedCredentials(accessToken string, accessTokenExpirationTs int64, encKey, signKey string) {
172174
c.accessToken = accessToken
173175
c.accessTokenExpirationTs = accessTokenExpirationTs
174176
c.Keys.EncKey = encKey
175177
c.Keys.SignKey = signKey
176178
}
177179

178-
// GetCredentials returns the current authentication credentials for caching
180+
// GetCredentials returns the current authentication credentials for caching.
179181
func (c *Client) GetCredentials() (accessToken string, accessTokenExpirationTs int64, encKey, signKey string) {
180182
return c.accessToken, c.accessTokenExpirationTs, c.Keys.EncKey, c.Keys.SignKey
181183
}
182184

183-
// GetEncryptionKeys retrieves the encryption and signing keys from the API
185+
// GetEncryptionKeys retrieves the encryption and signing keys from the API.
184186
func (c *Client) GetEncryptionKeys(ctx context.Context) error {
185187
// Ensure we have a timeout for the request
186188
ctx, cancel := context.WithTimeout(ctx, AuthRequestTimeout)
@@ -245,7 +247,7 @@ func (c *Client) GetEncryptionKeys(ctx context.Context) error {
245247
return nil
246248
}
247249

248-
// GetUsherEncryptionKey retrieves the RSA public key from Usher API
250+
// GetUsherEncryptionKey retrieves the RSA public key from Usher API.
249251
func (c *Client) GetUsherEncryptionKey(ctx context.Context) (string, string, error) {
250252
// Ensure we have a timeout for the request
251253
ctx, cancel := context.WithTimeout(ctx, AuthRequestTimeout)
@@ -287,7 +289,7 @@ func (c *Client) GetUsherEncryptionKey(ctx context.Context) (string, string, err
287289
return response.Data.PublicKey, response.Data.VersionPrefix, nil
288290
}
289291

290-
// Login authenticates with the API and retrieves an access token
292+
// Login authenticates with the API and retrieves an access token.
291293
func (c *Client) Login(ctx context.Context) error {
292294
// Ensure we have a timeout for the request
293295
ctx, cancel := context.WithTimeout(ctx, AuthRequestTimeout)
@@ -364,7 +366,7 @@ func (c *Client) Login(ctx context.Context) error {
364366
return nil
365367
}
366368

367-
// IsTokenValid checks if the access token is present and not expired
369+
// IsTokenValid checks if the access token is present and not expired.
368370
func (c *Client) IsTokenValid() bool {
369371
return cache.IsTokenValid(c.accessToken, c.accessTokenExpirationTs)
370372
}
@@ -382,22 +384,25 @@ func (c *Client) getSignFromTimestamp(timestamp string) string {
382384

383385
timestampExtended := strings.ToUpper(timestamp + timestamp[6:] + timestamp[3:])
384386
temporarySignKey := c.getTemporarySignKeyFromAppCode()
387+
385388
return SignWithSHA256(timestampExtended + temporarySignKey)
386389
}
387390

388391
func (c *Client) getTemporarySignKeyFromAppCode() string {
389392
val1 := SignWithMD5(c.appCode + AppPackageID)
390393
val2 := strings.ToLower(SignWithMD5(val1 + SignatureMD5))
394+
391395
return val2[20:32] + val2[0:10] + val2[4:6]
392396
}
393397

394398
func (c *Client) getDecryptionKeyFromAppCode() string {
395399
val1 := SignWithMD5(c.appCode + AppPackageID)
396400
val2 := strings.ToLower(SignWithMD5(val1 + SignatureMD5))
401+
397402
return val2[4:20]
398403
}
399404

400-
// decryptCheckVersionPayload decrypts and parses the checkVersion response payload
405+
// decryptCheckVersionPayload decrypts and parses the checkVersion response payload.
401406
func (c *Client) decryptCheckVersionPayload(payload string) (*CheckVersionResponse, error) {
402407
key := c.getDecryptionKeyFromAppCode()
403408
decrypted, err := DecryptAES128CBC(payload, key, IV)

internal/api/client.go

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,23 @@ import (
1414
)
1515

1616
const (
17-
// MaxRetries is the maximum number of retries for API requests
17+
// MaxRetries is the maximum number of retries for API requests.
1818
MaxRetries = 4
1919
)
2020

2121
// calculateBackoff returns the backoff duration for a given retry count.
22-
// Uses exponential backoff: 1s, 2s, 4s, 8s
22+
// Uses exponential backoff: 1s, 2s, 4s, 8s.
2323
func calculateBackoff(retryCount int) time.Duration {
2424
if retryCount <= 0 {
2525
return 0
2626
}
2727
// 2^(retryCount-1) seconds, capped at 8 seconds
2828
backoffSeconds := min(1<<(retryCount-1), 8)
29+
2930
return time.Duration(backoffSeconds) * time.Second
3031
}
3132

32-
// sleepWithContext sleeps for the specified duration, but returns early if context is cancelled
33+
// sleepWithContext sleeps for the specified duration, but returns early if context is cancelled.
3334
func sleepWithContext(ctx context.Context, duration time.Duration) error {
3435
if duration <= 0 {
3536
return nil
@@ -45,17 +46,17 @@ func sleepWithContext(ctx context.Context, duration time.Duration) error {
4546
}
4647
}
4748

48-
// APIRequest makes an API request with proper encryption, signing, and error handling
49+
// APIRequest makes an API request with proper encryption, signing, and error handling.
4950
func (c *Client) APIRequest(ctx context.Context, method, uri string, queryParams map[string]string, bodyParams map[string]any, needsKeys, needsAuth bool) (map[string]any, error) {
5051
return c.apiRequestWithRetry(ctx, method, uri, queryParams, bodyParams, needsKeys, needsAuth, 0)
5152
}
5253

53-
// APIRequestJSON makes an API request and returns the raw decrypted JSON bytes
54+
// APIRequestJSON makes an API request and returns the raw decrypted JSON bytes.
5455
func (c *Client) APIRequestJSON(ctx context.Context, method, uri string, queryParams map[string]string, bodyParams map[string]any, needsKeys, needsAuth bool) ([]byte, error) {
5556
return c.apiRequestJSONWithRetry(ctx, method, uri, queryParams, bodyParams, needsKeys, needsAuth, 0)
5657
}
5758

58-
// retryFunc is the type for functions that can be retried
59+
// retryFunc is the type for functions that can be retried.
5960
type retryFunc[T any] func(ctx context.Context, method, uri string, queryParams map[string]string, bodyParams map[string]any, needsKeys, needsAuth bool) (T, error)
6061

6162
// genericRetry implements the retry logic with exponential backoff for API requests.
@@ -108,6 +109,7 @@ func genericRetry[T any](
108109
if err := c.sleepFunc(ctx, backoff); err != nil {
109110
return zero, err
110111
}
112+
111113
return genericRetry(ctx, c, method, uri, queryParams, bodyParams, needsKeys, needsAuth, retryCount+1, executeFunc)
112114
} else if errors.As(err, &tokenErr) {
113115
// Login again and retry
@@ -119,8 +121,10 @@ func genericRetry[T any](
119121
if err := c.sleepFunc(ctx, backoff); err != nil {
120122
return zero, err
121123
}
124+
122125
return genericRetry(ctx, c, method, uri, queryParams, bodyParams, needsKeys, needsAuth, retryCount+1, executeFunc)
123126
}
127+
124128
return zero, err
125129
}
126130

@@ -314,34 +318,37 @@ func (c *Client) sendAPIRequestJSON(ctx context.Context, method, uri string, que
314318
return c.decryptPayloadBytes(encryptedPayload)
315319
}
316320

317-
// ensureKeysPresent ensures encryption keys are available
321+
// ensureKeysPresent ensures encryption keys are available.
318322
func (c *Client) ensureKeysPresent(ctx context.Context) error {
319323
if c.Keys.EncKey == "" || c.Keys.SignKey == "" {
320324
return c.GetEncryptionKeys(ctx)
321325
}
326+
322327
return nil
323328
}
324329

325-
// ensureTokenValid ensures access token is valid
330+
// ensureTokenValid ensures access token is valid.
326331
func (c *Client) ensureTokenValid(ctx context.Context) error {
327332
if !c.IsTokenValid() {
328333
return c.Login(ctx)
329334
}
335+
330336
return nil
331337
}
332338

333-
// encryptPayloadUsingKey encrypts a payload using the client's encryption key
339+
// encryptPayloadUsingKey encrypts a payload using the client's encryption key.
334340
func (c *Client) encryptPayloadUsingKey(payload string) (string, error) {
335341
if c.Keys.EncKey == "" {
336342
return "", NewAPIError("Missing encryption key")
337343
}
338344
if payload == "" {
339345
return "", nil
340346
}
347+
341348
return EncryptAES128CBC([]byte(payload), c.Keys.EncKey, IV)
342349
}
343350

344-
// decryptPayloadUsingKey decrypts a payload using the client's encryption key
351+
// decryptPayloadUsingKey decrypts a payload using the client's encryption key.
345352
func (c *Client) decryptPayloadUsingKey(payload string) (map[string]any, error) {
346353
if c.Keys.EncKey == "" {
347354
return nil, NewAPIError("Missing encryption key")
@@ -360,7 +367,7 @@ func (c *Client) decryptPayloadUsingKey(payload string) (map[string]any, error)
360367
return result, nil
361368
}
362369

363-
// decryptPayloadBytes decrypts a payload and returns raw JSON bytes
370+
// decryptPayloadBytes decrypts a payload and returns raw JSON bytes.
364371
func (c *Client) decryptPayloadBytes(payload string) ([]byte, error) {
365372
if c.Keys.EncKey == "" {
366373
return nil, NewAPIError("Missing encryption key")
@@ -374,7 +381,7 @@ func (c *Client) decryptPayloadBytes(payload string) ([]byte, error) {
374381
return decrypted, nil
375382
}
376383

377-
// getSignFromPayloadAndTimestamp generates a signature from payload and timestamp
384+
// getSignFromPayloadAndTimestamp generates a signature from payload and timestamp.
378385
func (c *Client) getSignFromPayloadAndTimestamp(payload, timestamp string) string {
379386
if timestamp == "" {
380387
return ""
@@ -390,7 +397,7 @@ func (c *Client) getSignFromPayloadAndTimestamp(payload, timestamp string) strin
390397
return SignWithSHA256(dataToSign)
391398
}
392399

393-
// logRequest logs request details when debug mode is enabled
400+
// logRequest logs request details when debug mode is enabled.
394401
func (c *Client) logRequest(method, url string, headers map[string]string, body string) {
395402
if !c.debug {
396403
return
@@ -410,7 +417,7 @@ func (c *Client) logRequest(method, url string, headers map[string]string, body
410417
}
411418
}
412419

413-
// logResponse logs response details when debug mode is enabled
420+
// logResponse logs response details when debug mode is enabled.
414421
func (c *Client) logResponse(statusCode int, body []byte) {
415422
if !c.debug {
416423
return

0 commit comments

Comments
 (0)