Skip to content

Conversation

@Oak10
Copy link

@Oak10 Oak10 commented Sep 30, 2025

Description

Added REDIS_SSL_CERT_REQS option to the Redis connection to allow configuring TLS certificate verification (e.g. CERT_NONE, CERT_REQUIRED).

Fixes #450

Type of Change

  • Bug fix
  • New feature
  • Refactor
  • Performance improvement
  • Other

Essential Checklist

Testing

  • I have tested the changes locally and confirmed they work as expected
  • I have added unit tests where necessary and they pass successfully

Bug Fix (if applicable)

  • I have used GitHub syntax to close the related issue (e.g., Fixes #123 or Closes #123)

Additional Information

Please provide any additional context that would help reviewers understand the changes.

@Yeuoly
Copy link
Contributor

Yeuoly commented Oct 11, 2025

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request adds TLS configuration support for Redis connections, which is a great feature. The implementation is mostly well done.

I've found a couple of issues:

  • There's a significant issue in internal/types/app/config.go where the REDIS_SSL_CERT_REQS configuration is handled in a misleading and unsafe way. CERT_OPTIONAL is treated as CERT_REQUIRED, and invalid values are silently ignored.
  • In internal/utils/cache/redis.go, an unrelated change to ScanMap incorrectly ignores a potential error, which should be propagated.

I've provided specific comments and suggestions to address these points. Please take a look.

Comment on lines +286 to +295
switch strings.ToUpper(strings.TrimSpace(c.RedisSSLCertReqs)) {
case "CERT_NONE":
tlsConf.InsecureSkipVerify = true
case "CERT_OPTIONAL":
tlsConf.InsecureSkipVerify = false
case "CERT_REQUIRED", "":
tlsConf.InsecureSkipVerify = false
default:
tlsConf.InsecureSkipVerify = false
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The handling of REDIS_SSL_CERT_REQS has a couple of issues:

  1. CERT_OPTIONAL is implemented identically to CERT_REQUIRED (InsecureSkipVerify = false). This is misleading, as CERT_OPTIONAL typically implies that certificate verification is attempted but not enforced. Go's crypto/tls package does not have a direct equivalent for this behavior. To avoid confusion, it would be better to explicitly disallow this value.
  2. The default case silently treats any invalid value as CERT_REQUIRED. This can hide misconfigurations. It would be safer to return an error for unknown values.

I suggest refactoring this switch statement to be stricter and clearer.

switch strings.ToUpper(strings.TrimSpace(c.RedisSSLCertReqs)) {
	case "CERT_NONE":
		tlsConf.InsecureSkipVerify = true
	case "CERT_REQUIRED", "":
		tlsConf.InsecureSkipVerify = false
	default:
		return nil, fmt.Errorf("invalid value for REDIS_SSL_CERT_REQS: %q. Supported values are 'CERT_NONE', 'CERT_REQUIRED'", c.RedisSSLCertReqs)
	}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @Oak10, I'd like to follow the suggestions, Let's me know your thoughts

Comment on lines +381 to 388
_ = ScanMapAsync[V](key, match, func(m map[string]V) error {
for k, v := range m {
result[k] = v
}

return nil
})
}, context...)

return result, nil
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This change correctly passes the context... to ScanMapAsync, which was a bug. However, it also explicitly ignores the error returned by ScanMapAsync by assigning it to _.

The ScanMapAsync function can return errors from the underlying Redis HSCAN command. By ignoring this error, ScanMap might return a partially populated map or an empty map without signaling that an error occurred.

The function signature of ScanMap is (map[string]V, error), which implies that errors should be propagated. The error should be handled and returned to the caller.

	if err := ScanMapAsync[V](key, match, func(m map[string]V) error {
		for k, v := range m {
			result[k] = v
		}
		return nil
	}, context...); err != nil {
		return nil, err
	}

	return result, nil

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

redis ssl connect

2 participants