Skip to content

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
KalpitTiwari03 authored Aug 15, 2023
2 parents 8d75b17 + 0e15d7c commit 381c7a6
Show file tree
Hide file tree
Showing 21 changed files with 384 additions and 214 deletions.
10 changes: 9 additions & 1 deletion aruba/cucumber.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,15 @@ RUN_COMMAND="docker run -t --rm \
-e CLOUD_APIKEY \
-e CLOUD_ZONE \
-e TPP_IP \
-e TPP_CN"
-e TPP_CN \
-e OKTA_CLIENT_ID \
-e OKTA_CLIENT_ID_PASS \
-e OKTA_AUTH_SERVER \
-e OKTA_CLIENT_SECRET \
-e OKTA_ACCESS_TOKEN \
-e OKTA_CREDS_USR \
-e OKTA_CREDS_PSW \
-e OKTA_SCOPE"

# Use getopts to handle command-line options
while getopts "a:b:" opt; do
Expand Down
45 changes: 45 additions & 0 deletions aruba/features/firefly/credmgmt-firefly.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
@FIREFLY
Feature: Managing credentials tokens from Identity Providers

As a user
I want to get credentials for Firefly with Okta as IdP

Background:
Given the default aruba exit timeout is 180 seconds

Scenario Outline: request access token from IdP
When I get credentials from "<identity-provider>"
And I remember the output
And it should output access token

Examples:
| identity-provider |
| Okta |

Scenario Outline: request access token from IdP in JSON format
When I get credentials from "<identity-provider>" with -format json
And I remember the output
And it should output access token in JSON

Examples:
| identity-provider |
| Okta |

Scenario Outline: request access token from IdP using password flow
When I get credentials from "<identity-provider>" with username and password
And I remember the output
And it should output access token

Examples:
| identity-provider |
| Okta |

@TODO # currently interactive mode is not working for Idp for Firefly
Scenario Outline: request access token from IdP using password flow interactively
When I interactively get credentials from "<identity-provider>" with username and no password
And I remember the output
And it should output access token

Examples:
| identity-provider |
| Okta |
51 changes: 51 additions & 0 deletions aruba/features/firefly/step_definitions/my_steps.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@

When(/^I( interactively)? get credentials from "(.*)"(?: with)?(.+)?$/) do |interactively, identity_provider, flags|

idp_token_url = ""
idp_user = ""
idp_password = ""
idp_client_id = ""
idp_client_secret = ""
idp_scope = ""

case identity_provider
when "Okta"
idp_token_url = "#{ENV['OKTA_AUTH_SERVER']}/v1/token"
idp_user = ENV['OKTA_CREDS_USR']
idp_password = ENV['OKTA_CREDS_PSW']
if flags === " username and no password" || flags === " username and password"
idp_client_id = ENV['OKTA_CLIENT_ID_PASS']
else
idp_client_id = ENV['OKTA_CLIENT_ID']
end
idp_client_secret = ENV['OKTA_CLIENT_SECRET']
idp_scope = ENV['OKTA_SCOPE']
else
fail(ArgumentError.new("Unknown Identity Provider: #{identity_provider}"))
end

if flags === " username and no password"
cmd = "vcert getcred -platform firefly -token-url '#{idp_token_url}' -client-id '#{idp_client_id}'" +
" -username '#{idp_user}' -scope '#{idp_scope}'"
elsif flags === " username and password"
cmd = "vcert getcred -platform firefly -token-url '#{idp_token_url}' -client-id '#{idp_client_id}'" +
" -username '#{idp_user}' -password '#{idp_password}' -scope '#{idp_scope}'"
else
# client id is our default
cmd = "vcert getcred -platform firefly -token-url '#{idp_token_url}'" +
" -client-id '#{idp_client_id}' -client-secret #{idp_client_secret} -scope '#{idp_scope}' #{flags}"
end

if interactively
Kernel.puts cmd
steps %{
Then I run `#{cmd}` interactively
And I type "#{idp_password}"
Then the exit status should be 0
}
else
steps %{
Then I try to run `#{cmd}`
}
end
end
2 changes: 1 addition & 1 deletion cmd/vcert/args.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ type commandFlags struct {
validDays string
validPeriod string
platformString string
platform venafi.PlatformType
platform venafi.Platform
policyName string
policySpecLocation string
policyConfigStarter bool
Expand Down
7 changes: 4 additions & 3 deletions cmd/vcert/playbook.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"net/http"
"os"

"github.com/Venafi/vcert/v5/pkg/venafi"
"github.com/urfave/cli/v2"
"go.uber.org/zap"
"golang.org/x/crypto/pkcs12"
Expand Down Expand Up @@ -129,7 +130,7 @@ func doRunPlaybook(_ *cli.Context) error {
os.Exit(1)
}

if playbook.Config.Connection.Platform == domain.CTypeTPP {
if playbook.Config.Connection.Platform == venafi.TPP {
err = service.ValidateTPPCredentials(&playbook)
if err != nil {
zap.L().Error("invalid tpp credentials", zap.Error(err))
Expand Down Expand Up @@ -158,7 +159,7 @@ func setPlaybookTLSConfig(playbook domain.Playbook) error {
// and to enable certificate authentication

// Set RenegotiateFreelyAsClient in case of we're communicating with MTLS enabled TPP server
if playbook.Config.Connection.Platform == domain.CTypeTPP {
if playbook.Config.Connection.Platform == venafi.TPP {
tlsConfig.Renegotiation = tls.RenegotiateFreelyAsClient
}

Expand All @@ -167,7 +168,7 @@ func setPlaybookTLSConfig(playbook domain.Playbook) error {
}

// Try to set up certificate authentication if enabled
if playbook.Config.Connection.Platform == domain.CTypeTPP && playbook.Config.Connection.Credentials.P12Task != "" {
if playbook.Config.Connection.Platform == venafi.TPP && playbook.Config.Connection.Credentials.P12Task != "" {
zap.L().Info("attempting to enable certificate authentication to TPP")
var p12FileLocation string
var p12Password string
Expand Down
7 changes: 4 additions & 3 deletions cmd/vcert/playbook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"golang.org/x/crypto/pkcs12"

"github.com/Venafi/vcert/v5/pkg/playbook/app/domain"
"github.com/Venafi/vcert/v5/pkg/venafi"
)

type logLine struct {
Expand Down Expand Up @@ -55,7 +56,7 @@ func (s *PlaybookSuite) TestPlaybook_SetTLSConfig() {
},
Config: domain.Config{
Connection: domain.Connection{
Platform: domain.CTypeTPP,
Platform: venafi.TPP,
Credentials: domain.Authentication{P12Task: "p12Auth"},
},
},
Expand Down Expand Up @@ -114,7 +115,7 @@ func (s *PlaybookSuite) TestPlaybook_SetTLSConfig_noP12Certificate() {
},
Config: domain.Config{
Connection: domain.Connection{
Platform: domain.CTypeTPP,
Platform: venafi.TPP,
Credentials: domain.Authentication{P12Task: "p12Auth"},
Insecure: true,
},
Expand Down Expand Up @@ -165,7 +166,7 @@ func (s *PlaybookSuite) TestPlaybook_SetTLSConfig_noCertAuth() {
CertificateTasks: nil,
Config: domain.Config{
Connection: domain.Connection{
Platform: domain.CTypeVaaS,
Platform: venafi.TLSPCloud,
Credentials: domain.Authentication{},
},
},
Expand Down
39 changes: 39 additions & 0 deletions pkg/endpoint/authentication.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright 2023 Venafi, Inc.
*
* 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 endpoint

// Authentication provides a struct for authentication data. Either specify User and Password for Trust Protection Platform
// or Firefly or ClientId and ClientSecret for Firefly or specify an APIKey for TLS Protect Cloud.
type Authentication struct {
User string `yaml:"-"`
Password string `yaml:"-"`
APIKey string `yaml:"apiKey,omitempty"`
RefreshToken string `yaml:"refreshToken,omitempty"`
Scope string `yaml:"scope,omitempty"`
ClientId string `yaml:"clientId,omitempty"`
ClientSecret string `yaml:"clientSecret,omitempty"`
AccessToken string `yaml:"accessToken,omitempty"`
ClientPKCS12 bool `yaml:"-"`
// IdentityProvider specify the OAuth 2.0 which VCert will be working for authorization purposes
IdentityProvider *OAuthProvider `yaml:"idP,omitempty"`
}

// OAuthProvider provides a struct for the OAuth 2.0 providers information
type OAuthProvider struct {
TokenURL string `yaml:"tokenURL,omitempty"`
Audience string `yaml:"audience,omitempty"`
}
24 changes: 0 additions & 24 deletions pkg/endpoint/endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,30 +147,6 @@ type Filter struct {
WithExpired bool
}

// Authentication provides a struct for authentication data. Either specify User and Password for Trust Protection Platform
// or Firefly or ClientId and ClientSecret for Firefly or specify an APIKey for TLS Protect Cloud.
type Authentication struct {
User string
Password string
APIKey string
RefreshToken string
Scope string
ClientId string
ClientSecret string
AccessToken string
ClientPKCS12 bool
// IdentityProvider specify the OAuth 2.0 which VCert will be working for authorization purposes
IdentityProvider *OAuthProvider
}

// OAuthProvider provides a struct for the OAuth 2.0 providers information
type OAuthProvider struct {
//OAuthProviderType string
//AuthURL string
TokenURL string
Audience string
}

// todo: replace with verror
// ErrRetrieveCertificateTimeout provides a common error structure for a timeout while retrieving a certificate
type ErrRetrieveCertificateTimeout struct {
Expand Down
95 changes: 88 additions & 7 deletions pkg/playbook/app/domain/authentication.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,102 @@

package domain

import (
"github.com/Venafi/vcert/v5/pkg/endpoint"
"gopkg.in/yaml.v3"
)

const (
accessToken = "accessToken"
apiKey = "apiKey"
clientID = "clientId"
clientSecret = "clientSecret"
idP = "idP"
refreshToken = "refreshToken"
p12Task = "p12Task"
scope = "scope"
)

// Authentication holds the credentials to connect to Venafi platforms: TPP and TLSPC
type Authentication struct {
AccessToken string `yaml:"accessToken,omitempty"`
Apikey string `yaml:"apiKey,omitempty"`
ClientID string `yaml:"clientId,omitempty"`
RefreshToken string `yaml:"refreshToken,omitempty"`
Scope string `yaml:"scope,omitempty"`
P12Task string `yaml:"p12Task,omitempty"`
endpoint.Authentication `yaml:"-"`
P12Task string `yaml:"p12Task,omitempty"`
}

// IsEmpty returns true if not credentials are set
func (a Authentication) IsEmpty() bool {
// TODO: This is very hacky.. need specifics based on connection type
if a.Apikey == "" && a.AccessToken == "" && a.RefreshToken == "" && a.P12Task == "" {
if a.APIKey == "" && a.AccessToken == "" && a.RefreshToken == "" && a.P12Task == "" {
return true
}
return false
}

// MarshalYAML customizes the behavior of Authentication when being marshaled into a YAML document.
// The returned value is marshaled in place of the original value implementing Marshaller
func (a Authentication) MarshalYAML() (interface{}, error) {
values := make(map[string]interface{})

if a.AccessToken != "" {
values[accessToken] = a.AccessToken
}
if a.APIKey != "" {
values[apiKey] = a.APIKey
}
if a.ClientId != "" {
values[clientID] = a.ClientId
}
if a.ClientSecret != "" {
values[clientSecret] = a.ClientSecret
}
if a.IdentityProvider != nil {
values[idP] = a.IdentityProvider
}
if a.RefreshToken != "" {
values[refreshToken] = a.RefreshToken
}
if a.P12Task != "" {
values[p12Task] = a.P12Task
}
if a.Scope != "" {
values[scope] = a.Scope
}

return values, nil
}

// UnmarshalYAML customizes the behavior when being unmarshalled from a YAML document
func (a *Authentication) UnmarshalYAML(value *yaml.Node) error {
var authMap map[string]interface{}
err := value.Decode(&authMap)
if err != nil {
return err
}

if _, found := authMap[accessToken]; found {
a.AccessToken = authMap[accessToken].(string)
}
if _, found := authMap[apiKey]; found {
a.APIKey = authMap[apiKey].(string)
}
if _, found := authMap[clientID]; found {
a.ClientId = authMap[clientID].(string)
}
if _, found := authMap[clientSecret]; found {
a.ClientSecret = authMap[clientSecret].(string)
}
//if _, found := authMap[idP]; found {
// a.IdentityProvider = authMap[].(string)
//}
if _, found := authMap[refreshToken]; found {
a.RefreshToken = authMap[refreshToken].(string)
}
if _, found := authMap[p12Task]; found {
a.P12Task = authMap[p12Task].(string)
}
if _, found := authMap[scope]; found {
a.Scope = authMap[scope].(string)
}

return nil
}
Loading

0 comments on commit 381c7a6

Please sign in to comment.