Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement default server authenticators #4558

Merged
merged 3 commits into from
Jan 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
in a future release.
- `service.telemetry.metrics.level` and `service.telemetry.metrics.address`
should be used to configure collector self-metrics.
- `configauth`: add helpers to create new server authenticators. (#4558)

## 🧰 Bug fixes 🧰

Expand Down
4 changes: 2 additions & 2 deletions config/configauth/configauth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func TestGetServerAuthenticator(t *testing.T) {
}{
{
desc: "obtain server authenticator",
authenticator: &MockServerAuthenticator{},
authenticator: NewServerAuthenticator(),
expected: nil,
},
{
Expand Down Expand Up @@ -87,7 +87,7 @@ func TestGetClientAuthenticator(t *testing.T) {
},
{
desc: "not a client authenticator",
authenticator: &MockServerAuthenticator{},
authenticator: NewServerAuthenticator(),
expected: errNotClientAuthenticator,
},
}
Expand Down
86 changes: 86 additions & 0 deletions config/configauth/default_serverauthenticator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package configauth // import "go.opentelemetry.io/collector/config/configauth"

import (
"context"

"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/component/componenthelper"
)

var _ ServerAuthenticator = (*defaultServerAuthenticator)(nil)

// Option represents the possible options for NewServerAuthenticator.
type Option func(*defaultServerAuthenticator)

type defaultServerAuthenticator struct {
AuthenticateFunc
componenthelper.StartFunc
componenthelper.ShutdownFunc
}

// WithAuthenticate specifies which function to use to perform the authentication.
func WithAuthenticate(authenticateFunc AuthenticateFunc) Option {
return func(o *defaultServerAuthenticator) {
o.AuthenticateFunc = authenticateFunc
}
}

// WithStart overrides the default `Start` function for a component.Component.
// The default always returns nil.
func WithStart(startFunc componenthelper.StartFunc) Option {
return func(o *defaultServerAuthenticator) {
o.StartFunc = startFunc
}
}

// WithShutdown overrides the default `Shutdown` function for a component.Component.
// The default always returns nil.
func WithShutdown(shutdownFunc componenthelper.ShutdownFunc) Option {
return func(o *defaultServerAuthenticator) {
o.ShutdownFunc = shutdownFunc
}
}

// NewServerAuthenticator returns a ServerAuthenticator configured with the provided options.
func NewServerAuthenticator(options ...Option) ServerAuthenticator {
bc := &defaultServerAuthenticator{
AuthenticateFunc: func(ctx context.Context, headers map[string][]string) (context.Context, error) { return ctx, nil },
StartFunc: func(ctx context.Context, host component.Host) error { return nil },
ShutdownFunc: func(ctx context.Context) error { return nil },
}

for _, op := range options {
op(bc)
}

return bc
}

// Authenticate performs the authentication.
func (a *defaultServerAuthenticator) Authenticate(ctx context.Context, headers map[string][]string) (context.Context, error) {
return a.AuthenticateFunc(ctx, headers)
}

// Start the component.
func (a *defaultServerAuthenticator) Start(ctx context.Context, host component.Host) error {
return a.StartFunc(ctx, host)
}

// Shutdown stops the component.
func (a *defaultServerAuthenticator) Shutdown(ctx context.Context) error {
return a.ShutdownFunc(ctx)
}
95 changes: 95 additions & 0 deletions config/configauth/default_serverauthenticator_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package configauth

import (
"context"
"testing"

"github.com/stretchr/testify/assert"

"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/component/componenttest"
)

func TestDefaultValues(t *testing.T) {
// prepare
e := NewServerAuthenticator()

// test
t.Run("start", func(t *testing.T) {
err := e.Start(context.Background(), componenttest.NewNopHost())
assert.NoError(t, err)
})

t.Run("authenticate", func(t *testing.T) {
ctx, err := e.Authenticate(context.Background(), make(map[string][]string))
assert.NotNil(t, ctx)
assert.NoError(t, err)
})

t.Run("shutdown", func(t *testing.T) {
err := e.Shutdown(context.Background())
assert.NoError(t, err)
})
}

func TestWithAuthenticateFunc(t *testing.T) {
// prepare
authCalled := false
e := NewServerAuthenticator(
WithAuthenticate(func(ctx context.Context, headers map[string][]string) (context.Context, error) {
authCalled = true
return ctx, nil
}),
)

// test
_, err := e.Authenticate(context.Background(), make(map[string][]string))

// verify
assert.True(t, authCalled)
assert.NoError(t, err)
}

func TestWithStart(t *testing.T) {
called := false
e := NewServerAuthenticator(WithStart(func(c context.Context, h component.Host) error {
called = true
return nil
}))

// test
err := e.Start(context.Background(), componenttest.NewNopHost())

// verify
assert.True(t, called)
assert.NoError(t, err)
}

func TestWithShutdown(t *testing.T) {
called := false
e := NewServerAuthenticator(WithShutdown(func(c context.Context) error {
called = true
return nil
}))

// test
err := e.Shutdown(context.Background())

// verify
assert.True(t, called)
assert.NoError(t, err)
}
50 changes: 0 additions & 50 deletions config/configauth/mock_serverauth.go

This file was deleted.

65 changes: 0 additions & 65 deletions config/configauth/mock_serverauth_test.go

This file was deleted.

2 changes: 1 addition & 1 deletion config/configgrpc/configgrpc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ func TestGrpcServerAuthSettings(t *testing.T) {
}
host := &mockHost{
ext: map[config.ComponentID]component.Extension{
config.NewComponentID("mock"): &configauth.MockServerAuthenticator{},
config.NewComponentID("mock"): configauth.NewServerAuthenticator(),
},
}
opts, err := gss.ToServerOption(host, componenttest.NewNopTelemetrySettings())
Expand Down
9 changes: 5 additions & 4 deletions config/confighttp/confighttp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -775,14 +775,15 @@ func TestServerAuth(t *testing.T) {
AuthenticatorID: config.NewComponentID("mock"),
},
}

host := &mockHost{
ext: map[config.ComponentID]component.Extension{
config.NewComponentID("mock"): &configauth.MockServerAuthenticator{
Copy link
Member Author

Choose a reason for hiding this comment

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

This is a good example of how consumers would be able to use this. I like the new approach, especially as it allows consumers to omit specifying the default implementations to use, like demonstrated by the removal of line 785.

AuthenticateFunc: func(ctx context.Context, headers map[string][]string) (context.Context, error) {
config.NewComponentID("mock"): configauth.NewServerAuthenticator(
configauth.WithAuthenticate(func(ctx context.Context, headers map[string][]string) (context.Context, error) {
authCalled = true
return ctx, nil
},
},
}),
),
},
}

Expand Down