Skip to content

Commit

Permalink
Refactor authn-k8s-client to be authentication flow generic
Browse files Browse the repository at this point in the history
  • Loading branch information
tzheleznyak committed Dec 21, 2021
1 parent b28a639 commit c5ec2e1
Show file tree
Hide file tree
Showing 22 changed files with 578 additions and 554 deletions.
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ follow the instructions in this section.
### Update the version, changelog, and notices
1. Create a new branch for the version bump.
1. Based on the unreleased content, determine the new version number and update
the [version.go](pkg/authenticator/version.go) file.
the [version.go](pkg/authenticator/common/version.go) file.
1. Determine the new version number and update the Helm `Chart.yaml` files in the `helm/conjur-*/` directories.
1. Review the git log and ensure the [changelog](CHANGELOG.md) contains all
relevant recent changes with references to GitHub issues or PRs, if possible.
Expand Down
2 changes: 1 addition & 1 deletion bin/build_utils
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ set -euo pipefail
# Functions to generate version numbers for this project
####

readonly VERSION_GO_FILE="pkg/authenticator/version.go"
readonly VERSION_GO_FILE="pkg/authenticator/common/version.go"

function short_version_tag() {
grep -v '^//' "${VERSION_GO_FILE}" | grep 'var Version =' | awk -F'= ' '{print $2}' | tr -d '"'
Expand Down
16 changes: 8 additions & 8 deletions cmd/authenticator/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,28 @@ package main

import (
"fmt"
"github.com/cyberark/conjur-authn-k8s-client/pkg/authenticator"
"os"
"time"

"github.com/cenkalti/backoff"

"github.com/cyberark/conjur-authn-k8s-client/pkg/authenticator"
authnConfig "github.com/cyberark/conjur-authn-k8s-client/pkg/authenticator/config"
"github.com/cyberark/conjur-authn-k8s-client/pkg/authenticator/common"
"github.com/cyberark/conjur-authn-k8s-client/pkg/log"
)

func main() {
log.Info(log.CAKC048, authenticator.FullVersionName)
log.Info(log.CAKC048, common.FullVersionName)

var err error

config, err := authnConfig.NewFromEnv()
config, err := authenticator.NewConfigFromEnv()
if err != nil {
printErrorAndExit(log.CAKC018)
}

// Create new Authenticator
authn, err := authenticator.New(*config)
authn, err := authenticator.NewAuthenticator(config)
if err != nil {
printErrorAndExit(log.CAKC019)
}
Expand All @@ -43,14 +43,14 @@ func main() {
return log.RecordedError(log.CAKC016)
}

if authn.Config.ContainerMode == "init" {
if config.GetContainerMode() == "init" {
os.Exit(0)
}

log.Info(log.CAKC047, authn.Config.TokenRefreshTimeout)
log.Info(log.CAKC047, config.GetTokenTimeout())

fmt.Println()
time.Sleep(authn.Config.TokenRefreshTimeout)
time.Sleep(config.GetTokenTimeout())

// Reset exponential backoff
expBackoff.Reset()
Expand Down
34 changes: 34 additions & 0 deletions pkg/authenticator/authenticator_factory.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package authenticator

import (
"fmt"
"github.com/cyberark/conjur-authn-k8s-client/pkg/access_token"
"github.com/cyberark/conjur-authn-k8s-client/pkg/authenticator/common"
k8sAuthenitcator "github.com/cyberark/conjur-authn-k8s-client/pkg/authenticator/k8s"
"github.com/cyberark/conjur-authn-k8s-client/pkg/log"
)

func NewAuthenticator(conf common.ConfigurationInterface) (common.AuthenticatorInterface, error) {
authn, error := getAuthenticator(conf)
if error != nil {
return nil, error
}
return authn.Init(&conf)
}

func NewAuthenticatorWithAccessToken(conf common.ConfigurationInterface, token access_token.AccessToken) (common.AuthenticatorInterface, error) {
var error error
var authn common.AuthenticatorInterface
authn, error = getAuthenticator(conf)
if error != nil {
return nil, error
}
return authn.InitWithAccessToken(&conf, token)
}

func getAuthenticator(conf common.ConfigurationInterface) (common.AuthenticatorInterface, error) {
if conf.GetAuthenticationType() == k8sAuthenitcator.AuthnType {
return &k8sAuthenitcator.Authenticator{}, nil
}
return nil, fmt.Errorf(log.CAKC064)
}
12 changes: 12 additions & 0 deletions pkg/authenticator/common/authenticator_interface.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package common

import (
"github.com/cyberark/conjur-authn-k8s-client/pkg/access_token"
)

type AuthenticatorInterface interface {
Init(config *ConfigurationInterface) (AuthenticatorInterface, error)
InitWithAccessToken(config *ConfigurationInterface, token access_token.AccessToken) (AuthenticatorInterface, error)
Authenticate() error
GetAccessToken() access_token.AccessToken
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package authenticator
package common

import (
"crypto/tls"
Expand All @@ -9,7 +9,7 @@ import (
"github.com/cyberark/conjur-authn-k8s-client/pkg/log"
)

func newHTTPSClient(CACert []byte, certPEMBlock, keyPEMBlock []byte) (*http.Client, error) {
func NewHTTPSClient(CACert []byte, certPEMBlock, keyPEMBlock []byte) (*http.Client, error) {
caCertPool := x509.NewCertPool()
ok := caCertPool.AppendCertsFromPEM(CACert)
if !ok {
Expand Down
58 changes: 58 additions & 0 deletions pkg/authenticator/common/common_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package common

import (
"fmt"
"github.com/cyberark/conjur-authn-k8s-client/pkg/log"
"strconv"
"time"
)

// Config defines the configuration parameters
// for the authentication requests
type Config struct {
Account string
ClientCertPath string
ClientCertRetryCountLimit int
ContainerMode string
SSLCertificate []byte
TokenFilePath string
TokenRefreshTimeout time.Duration
URL string
Username *Username
}

func (config *Config) LoadConfig(settings map[string]string) {
for key, value := range settings {
switch key {
case "CONJUR_ACCOUNT":
config.Account = value
case "CONJUR_AUTHN_LOGIN":
username, _ := NewUsername(value)
config.Username = username
case "CONJUR_AUTHN_URL":
config.URL = value
case "CONJUR_SSL_CERTIFICATE":
config.SSLCertificate = []byte(value)
case "CONTAINER_MODE":
config.ContainerMode = value
case "CONJUR_AUTHN_TOKEN_FILE":
config.TokenFilePath = value
case "CONJUR_CLIENT_CERT_PATH":
config.ClientCertPath = value
case "CONJUR_CLIENT_CERT_RETRY_COUNT_LIMIT":
limit, _ := strconv.Atoi(value)
config.ClientCertRetryCountLimit = limit
case "CONJUR_TOKEN_TIMEOUT":
timeout, _ := durationFromString(key, value)
config.TokenRefreshTimeout = timeout
}
}
}

func durationFromString(key, value string) (time.Duration, error) {
duration, err := time.ParseDuration(value)
if err != nil {
return 0, fmt.Errorf(log.CAKC060, key, value)
}
return duration, nil
}
16 changes: 16 additions & 0 deletions pkg/authenticator/common/configuration_interface.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package common

import (
"time"
)

type ConfigurationInterface interface {
LoadConfig(settings map[string]string)
GetAuthenticationType() string
GetEnvVariables() []string
GetRequiredVariables() []string
GetDefaultValues() map[string]string
GetContainerMode() string
GetTokenFilePath() string
GetTokenTimeout() time.Duration
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package config
package common

import (
"strings"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package config
package common

import (
"fmt"
Expand All @@ -19,7 +19,7 @@ func TestNewUsername(t *testing.T) {

// ASSERT
assert.Equal(t, "host.path.to.policy", usernameStruct.Prefix)
assert.Equal(t, "namespace.resource_type.resource_id", usernameStruct.Suffix)
assert.Equal(t, "namespace.resource_type.resource_id", usernameStruct.Suffix)
})

t.Run("shorter than 4 parts", func(t *testing.T) {
Expand All @@ -31,10 +31,9 @@ func TestNewUsername(t *testing.T) {

// ASSERT
assert.Equal(t, "host.policy", usernameStruct.Prefix)
assert.Equal(t, "host_id", usernameStruct.Suffix)
assert.Equal(t, "host_id", usernameStruct.Suffix)
})


t.Run("missing host/ prefix", func(t *testing.T) {
// SETUP & EXERCISE
_, err := NewUsername("namespace/resource_type/resource_id")
Expand Down
72 changes: 72 additions & 0 deletions pkg/authenticator/common/validations.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package common

import (
"errors"
"fmt"
"strconv"

"github.com/cyberark/conjur-authn-k8s-client/pkg/log"
)

// ReadFileFunc defines the interface for reading an SSL Certificate from the env
type ReadFileFunc func(filename string) ([]byte, error)

func validTimeout(key, timeoutStr string) error {
_, err := durationFromString(key, timeoutStr)
return err
}

func validInt(key, value string) error {
_, err := strconv.Atoi(value)
if err != nil {
return fmt.Errorf(log.CAKC060, key, value)
}
return nil
}

func validUsername(key, value string) error {
_, err := NewUsername(value)
return err
}

func validConjurVersion(key, version string) error {
// Only versions '4' & '5' are allowed, with '5' being used as the default
switch version {
case "4":
break
case "5":
break
default:
return fmt.Errorf(log.CAKC060, key, version)
}

return nil
}

func ValidateSetting(key string, value string) error {
switch key {
case "CONJUR_AUTHN_LOGIN":
return validUsername(key, value)
case "CONJUR_CLIENT_CERT_RETRY_COUNT_LIMIT":
return validInt(key, value)
case "CONJUR_TOKEN_TIMEOUT":
return validTimeout(key, value)
case "CONJUR_VERSION":
return validConjurVersion(key, value)
default:
return nil
}
}

func ReadSSLCert(settings map[string]string, readFile ReadFileFunc) ([]byte, error) {
SSLCert := settings["CONJUR_SSL_CERTIFICATE"]
SSLCertPath := settings["CONJUR_CERT_FILE"]
if SSLCert == "" && SSLCertPath == "" {
return nil, errors.New(log.CAKC007)
}

if SSLCert != "" {
return []byte(SSLCert), nil
}
return readFile(SSLCertPath)
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package authenticator
package common

import "fmt"

Expand Down
Loading

0 comments on commit c5ec2e1

Please sign in to comment.