diff --git a/ably/auth.go b/ably/auth.go index 1b0dc1b0..56d1a309 100644 --- a/ably/auth.go +++ b/ably/auth.go @@ -545,7 +545,7 @@ func detectAuthMethod(opts *clientOptions) (int, error) { if !isKeyValid { return 0, newError(ErrInvalidCredential, errInvalidKey) } - if opts.NoTLS { + if opts.NoTLS && !opts.InsecureAllowBasicAuthWithoutTLS { return 0, newError(ErrInvalidUseOfBasicAuthOverNonTLSTransport, errInsecureBasicAuth) } return authBasic, nil diff --git a/ably/options.go b/ably/options.go index 1bf26783..6c7c8362 100644 --- a/ably/options.go +++ b/ably/options.go @@ -408,6 +408,10 @@ type clientOptions struct { // LogHandler controls the log output of the library. This is a function to handle each line of log output. // platform specific (TO3c) LogHandler Logger + + // InsecureAllowBasicAuthWithoutTLS permits an API key to be used even if the connection + // will not use TLS, something which would otherwise not be permitted for security reasons. + InsecureAllowBasicAuthWithoutTLS bool } func (opts *clientOptions) validate() error { @@ -1316,6 +1320,14 @@ func WithDial(dial func(protocol string, u *url.URL, timeout time.Duration) (con } } +// WithInsecureAllowBasicAuthWithoutTLS permits an API key to be used even if the connection +// will not use TLS, something which would otherwise not be permitted for security reasons. +func WithInsecureAllowBasicAuthWithoutTLS() ClientOption { + return func(opts *clientOptions) { + opts.InsecureAllowBasicAuthWithoutTLS = true + } +} + func applyOptionsWithDefaults(opts ...ClientOption) *clientOptions { to := defaultOptions // No need to set hosts by default diff --git a/ably/options_test.go b/ably/options_test.go index 855076bd..cc86e794 100644 --- a/ably/options_test.go +++ b/ably/options_test.go @@ -236,6 +236,28 @@ func TestScopeParams(t *testing.T) { }) } +func TestOption_NoTLS(t *testing.T) { + t.Run("does not allow basic auth with no TLS", func(t *testing.T) { + _, err := ably.NewREST( + ably.WithKey("xxxxxx.yyyyyy:zzzzzz"), + ably.WithTLS(false), + ) + assert.Error(t, err) + errInfo, ok := err.(*ably.ErrorInfo) + assert.True(t, ok) + assert.Equal(t, errInfo.Code, ably.ErrInvalidUseOfBasicAuthOverNonTLSTransport) + }) + + t.Run("allows basic auth with no TLS when InsecureAllowBasicAuthWithoutTLS is set", func(t *testing.T) { + _, err := ably.NewREST( + ably.WithKey("xxxxxx.yyyyyy:zzzzzz"), + ably.WithTLS(false), + ably.WithInsecureAllowBasicAuthWithoutTLS(), + ) + assert.NoError(t, err) + }) +} + func TestPaginateParams(t *testing.T) { t.Run("returns nil with no values", func(t *testing.T) {