mirror of
https://github.com/akvorado/akvorado.git
synced 2025-12-11 22:14:02 +01:00
common/kafka: add support for OAuth2
The support is still pretty basic. Notably, scopes are not configurable (waiting for someone to request them) and maybe there client ID and secrets should not be provided as username/password. Fix #1714
This commit is contained in:
114
common/kafka/oauth_test.go
Normal file
114
common/kafka/oauth_test.go
Normal file
@@ -0,0 +1,114 @@
|
||||
// SPDX-FileCopyrightText: 2025 Free Mobile
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
package kafka
|
||||
|
||||
import (
|
||||
"akvorado/common/helpers"
|
||||
"akvorado/common/reporter"
|
||||
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/IBM/sarama"
|
||||
"golang.org/x/oauth2"
|
||||
"golang.org/x/oauth2/clientcredentials"
|
||||
)
|
||||
|
||||
func TestOAuth2ServerPassword(t *testing.T) {
|
||||
oauthServer := helpers.CheckExternalService(t, "mock-auth2-server",
|
||||
[]string{"mock-oauth2-server:8080", "127.0.0.1:5556"})
|
||||
|
||||
ctx := context.Background()
|
||||
conf := &oauth2.Config{
|
||||
ClientID: "kafka-client",
|
||||
ClientSecret: "kafka-client-secret",
|
||||
Endpoint: oauth2.Endpoint{
|
||||
TokenURL: fmt.Sprintf("http://%s/default/token", oauthServer),
|
||||
},
|
||||
Scopes: []string{"openid"},
|
||||
}
|
||||
|
||||
token, err := conf.PasswordCredentialsToken(ctx, "akvorado@example.com", "password")
|
||||
if err != nil {
|
||||
t.Fatalf("PasswordCredentialsToken() error:\n%+v", err)
|
||||
}
|
||||
|
||||
t.Logf("Access token: %s", token.AccessToken)
|
||||
t.Logf("Token type: %s", token.TokenType)
|
||||
t.Logf("Expiry: %s", token.Expiry.Format(time.RFC3339))
|
||||
}
|
||||
|
||||
func TestOAuth2ServerClientCredentials(t *testing.T) {
|
||||
oauthServer := helpers.CheckExternalService(t, "mock-oauth2-server",
|
||||
[]string{"mock-oauth2-server:8080", "127.0.0.1:5556"})
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
// Use clientcredentials.Config instead of oauth2.Config
|
||||
config := clientcredentials.Config{
|
||||
ClientID: "kafka-client",
|
||||
ClientSecret: "kafka-client-secret",
|
||||
TokenURL: fmt.Sprintf("http://%s/default/token", oauthServer),
|
||||
Scopes: []string{"openid"},
|
||||
}
|
||||
|
||||
// Get token directly from the client credentials config
|
||||
token, err := config.Token(ctx)
|
||||
if err != nil {
|
||||
t.Fatalf("ClientCredentials Token() error:\n%+v", err)
|
||||
}
|
||||
|
||||
t.Logf("Access token: %s", token.AccessToken)
|
||||
t.Logf("Token type: %s", token.TokenType)
|
||||
t.Logf("Expiry: %s", token.Expiry.Format(time.RFC3339))
|
||||
}
|
||||
|
||||
// Example with kcat:
|
||||
// kcat -b 127.0.0.1:9093 \
|
||||
// -X security.protocol=SASL_PLAINTEXT \
|
||||
// -X sasl.mechanisms=OAUTHBEARER \
|
||||
// -X sasl.oauthbearer.method=OIDC \ // -X sasl.oauthbearer.client.id=kafka-client \
|
||||
// -X sasl.oauthbearer.client.secret=kafka-client-secret \
|
||||
// -X sasl.oauthbearer.token.endpoint.url=http://127.0.0.1:5556/default/token \
|
||||
// -t my-topic -C -d all
|
||||
|
||||
func TestOAuth2Broker(t *testing.T) {
|
||||
r := reporter.NewMock(t)
|
||||
GlobalKafkaLogger.Register(r)
|
||||
defer GlobalKafkaLogger.Unregister()
|
||||
|
||||
// Ensure broker is ready.
|
||||
SetupKafkaBroker(t)
|
||||
|
||||
// Then try again with OAuth2.
|
||||
oauthServer := helpers.CheckExternalService(t, "mock-auth2-server",
|
||||
[]string{"mock-oauth2-server:8080", "127.0.0.1:5556"})
|
||||
broker := helpers.CheckExternalService(t, "Kafka",
|
||||
[]string{"kafka:9093", "127.0.0.1:9093"})
|
||||
|
||||
config := DefaultConfiguration()
|
||||
config.SASL = SASLConfiguration{
|
||||
Username: "kafka-client",
|
||||
Password: "kafka-client-secret",
|
||||
Mechanism: SASLOauth,
|
||||
OAuthTokenURL: fmt.Sprintf("http://%s/default/token", oauthServer),
|
||||
}
|
||||
kafkaConfig, err := NewConfig(config)
|
||||
if err != nil {
|
||||
t.Fatalf("NewConfig() error:\n%+v", err)
|
||||
}
|
||||
if err := kafkaConfig.Validate(); err != nil {
|
||||
t.Fatalf("Validate() error:\n%+v", err)
|
||||
}
|
||||
|
||||
client, err := sarama.NewClient([]string{broker}, kafkaConfig)
|
||||
if err != nil {
|
||||
t.Fatalf("sarama.NewClient() error:\n%+v", err)
|
||||
}
|
||||
if err := client.RefreshMetadata(); err != nil {
|
||||
t.Fatalf("client.RefreshMetadata() error:\n%+v", err)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user