Skip to content

Commit

Permalink
feat: reactor http client definition
Browse files Browse the repository at this point in the history
  • Loading branch information
gitahernandez committed Feb 20, 2024
1 parent 464441f commit fc9d511
Show file tree
Hide file tree
Showing 9 changed files with 263 additions and 177 deletions.
41 changes: 34 additions & 7 deletions api/authentication/authentication_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ import (
"go-client-library-passwordsafe/api/entities"
"go-client-library-passwordsafe/api/logging"
"go-client-library-passwordsafe/api/utils"
"log"
"os"
"reflect"

"net/http"
"net/http/httptest"
"testing"

"go.uber.org/zap"
)

type UserTestConfig struct {
Expand All @@ -34,13 +34,16 @@ type GetPasswordSafeAuthenticationConfig struct {
response *entities.SignApinResponse
}

var logger = log.New(os.Stdout, "DEBUG: ", log.Ldate|log.Ltime)
var logLogger = logging.NewLogLogger(logger)
var httpClient, _ = utils.GetHttpClient(5, true, "", "")
var authenticate, _ = Authenticate(httpClient, "https://fake.api.com:443/BeyondTrust/api/public/v3/", "fakeone_a654+9sdf7+8we4f", "fakeone_aasd156465sfdef", logLogger, 300)

func TestSignOut(t *testing.T) {
logger, _ := zap.NewDevelopment()
defer logger.Sync()

// create a zap logger wrapper
zapLogger := logging.NewZapLogger(logger)

httpClientObj, _ := utils.GetHttpClient(5, false, "", "", zapLogger)

var authenticate, _ = Authenticate(*httpClientObj, "https://fake.api.com:443/BeyondTrust/api/public/v3/", "fakeone_a654+9sdf7+8we4f", "fakeone_aasd156465sfdef", zapLogger, 300)
testConfig := UserTestConfig{
name: "TestSignOut",
server: httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
Expand All @@ -56,7 +59,15 @@ func TestSignOut(t *testing.T) {
}

func TestSignAppin(t *testing.T) {
logger, _ := zap.NewDevelopment()
defer logger.Sync()

// create a zap logger wrapper
zapLogger := logging.NewZapLogger(logger)

httpClientObj, _ := utils.GetHttpClient(5, false, "", "", zapLogger)

var authenticate, _ = Authenticate(*httpClientObj, "https://fake.api.com:443/BeyondTrust/api/public/v3/", "fakeone_a654+9sdf7+8we4f", "fakeone_aasd156465sfdef", zapLogger, 300)
testConfig := UserTestConfig{
name: "TestSignAppin",
server: httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
Expand All @@ -80,7 +91,15 @@ func TestSignAppin(t *testing.T) {
}

func TestGetToken(t *testing.T) {
logger, _ := zap.NewDevelopment()
defer logger.Sync()

// create a zap logger wrapper
zapLogger := logging.NewZapLogger(logger)

httpClientObj, _ := utils.GetHttpClient(5, false, "", "", zapLogger)

var authenticate, _ = Authenticate(*httpClientObj, "https://fake.api.com:443/BeyondTrust/api/public/v3/", "fakeone_a654+9sdf7+8we4f", "fakeone_aasd156465sfdef", zapLogger, 300)
testConfig := GetTokenConfig{
name: "TestGetToken",
server: httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
Expand Down Expand Up @@ -109,7 +128,15 @@ func TestGetToken(t *testing.T) {
}

func TestGetPasswordSafeAuthentication(t *testing.T) {
logger, _ := zap.NewDevelopment()
defer logger.Sync()

// create a zap logger wrapper
zapLogger := logging.NewZapLogger(logger)

httpClientObj, _ := utils.GetHttpClient(5, false, "", "", zapLogger)

var authenticate, _ = Authenticate(*httpClientObj, "https://fake.api.com:443/BeyondTrust/api/public/v3/", "fakeone_a654+9sdf7+8we4f", "fakeone_aasd156465sfdef", zapLogger, 300)
testConfig := GetPasswordSafeAuthenticationConfig{
name: "TestGetPasswordSafeAuthentication",
server: httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
Expand Down
97 changes: 20 additions & 77 deletions api/authentication/authetication.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import (
"fmt"
"go-client-library-passwordsafe/api/entities"
"go-client-library-passwordsafe/api/logging"
"go-client-library-passwordsafe/api/utils"
"io"

"net/http"
"net/url"
"time"

Expand All @@ -21,13 +21,13 @@ type AuthenticationObj struct {
ApiUrl string
clientId string
clientSecret string
httpClient *http.Client
HttpClient utils.HttpClientObj
ExponentialBackOff *backoff.ExponentialBackOff
log logging.Logger
}

// Authenticate in PS API
func Authenticate(httpClient *http.Client, endpointUrl string, clientId string, clientSecret string, logger logging.Logger, retryMaxElapsedTimeSeconds int) (*AuthenticationObj, error) {
func Authenticate(httpClient utils.HttpClientObj, endpointUrl string, clientId string, clientSecret string, logger logging.Logger, retryMaxElapsedTimeSeconds int) (*AuthenticationObj, error) {

backoffDefinition := backoff.NewExponentialBackOff()
backoffDefinition.InitialInterval = 1 * time.Second
Expand All @@ -39,7 +39,7 @@ func Authenticate(httpClient *http.Client, endpointUrl string, clientId string,

authenticationObj := &AuthenticationObj{
ApiUrl: endpointUrl,
httpClient: client,
HttpClient: client,
clientId: clientId,
clientSecret: clientSecret,
ExponentialBackOff: backoffDefinition,
Expand All @@ -50,20 +50,20 @@ func Authenticate(httpClient *http.Client, endpointUrl string, clientId string,
}

// GetPasswordSafeAuthentication call get token and sign app endpoint
func (c *AuthenticationObj) GetPasswordSafeAuthentication() (entities.SignApinResponse, error) {
accessToken, err := c.GetToken(fmt.Sprintf("%v%v", c.ApiUrl, "Auth/connect/token"), c.clientId, c.clientSecret)
func (authenticationObj *AuthenticationObj) GetPasswordSafeAuthentication() (entities.SignApinResponse, error) {
accessToken, err := authenticationObj.GetToken(fmt.Sprintf("%v%v", authenticationObj.ApiUrl, "Auth/connect/token"), authenticationObj.clientId, authenticationObj.clientSecret)
if err != nil {
return entities.SignApinResponse{}, err
}
signApinResponse, err := c.SignAppin(fmt.Sprintf("%v%v", c.ApiUrl, "Auth/SignAppIn"), accessToken)
signApinResponse, err := authenticationObj.SignAppin(fmt.Sprintf("%v%v", authenticationObj.ApiUrl, "Auth/SignAppIn"), accessToken)
if err != nil {
return entities.SignApinResponse{}, err
}
return signApinResponse, nil
}

// GetToken get token from PS API
func (c *AuthenticationObj) GetToken(endpointUrl string, clientId string, clientSecret string) (string, error) {
func (authenticationObj *AuthenticationObj) GetToken(endpointUrl string, clientId string, clientSecret string) (string, error) {

params := url.Values{}
params.Add("client_id", clientId)
Expand All @@ -78,9 +78,9 @@ func (c *AuthenticationObj) GetToken(endpointUrl string, clientId string, client
buffer.WriteString(params.Encode())

technicalError = backoff.Retry(func() error {
body, technicalError, businessError, _ = c.CallSecretSafeAPI(endpointUrl, "POST", buffer, "GetToken", "")
body, technicalError, businessError, _ = authenticationObj.HttpClient.CallSecretSafeAPI(endpointUrl, "POST", buffer, "GetToken", "")
return technicalError
}, c.ExponentialBackOff)
}, authenticationObj.ExponentialBackOff)

if technicalError != nil {
return "", technicalError
Expand All @@ -102,7 +102,7 @@ func (c *AuthenticationObj) GetToken(endpointUrl string, clientId string, client

err = json.Unmarshal([]byte(responseString), &data)
if err != nil {
c.log.Error(err.Error())
authenticationObj.log.Error(err.Error())
return "", err
}

Expand All @@ -111,7 +111,7 @@ func (c *AuthenticationObj) GetToken(endpointUrl string, clientId string, client
}

// SignAppin Signs app in PS API
func (c *AuthenticationObj) SignAppin(endpointUrl string, accessToken string) (entities.SignApinResponse, error) {
func (authenticationObj *AuthenticationObj) SignAppin(endpointUrl string, accessToken string) (entities.SignApinResponse, error) {

var userObject entities.SignApinResponse
var body io.ReadCloser
Expand All @@ -120,12 +120,12 @@ func (c *AuthenticationObj) SignAppin(endpointUrl string, accessToken string) (e
var scode int

err := backoff.Retry(func() error {
body, technicalError, businessError, scode = c.CallSecretSafeAPI(endpointUrl, "POST", bytes.Buffer{}, "SignAppin", accessToken)
body, technicalError, businessError, scode = authenticationObj.HttpClient.CallSecretSafeAPI(endpointUrl, "POST", bytes.Buffer{}, "SignAppin", accessToken)
if scode == 0 {
return nil
}
return technicalError
}, c.ExponentialBackOff)
}, authenticationObj.ExponentialBackOff)

if err != nil {
return entities.SignApinResponse{}, err
Expand All @@ -148,7 +148,7 @@ func (c *AuthenticationObj) SignAppin(endpointUrl string, accessToken string) (e
err = json.Unmarshal(bodyBytes, &userObject)

if err != nil {
c.log.Error(err.Error())
authenticationObj.log.Error(err.Error())
return entities.SignApinResponse{}, err
}

Expand All @@ -157,78 +157,21 @@ func (c *AuthenticationObj) SignAppin(endpointUrl string, accessToken string) (e

// SignOut signs out Secret Safe API.
// Warn: should only be called one time for all data sources.
func (c *AuthenticationObj) SignOut(url string) error {
c.log.Debug(url)
func (authenticationObj *AuthenticationObj) SignOut(url string) error {
authenticationObj.log.Debug(url)

var technicalError error
var businessError error

technicalError = backoff.Retry(func() error {
_, technicalError, businessError, _ = c.CallSecretSafeAPI(url, "POST", bytes.Buffer{}, "SignOut", "")
_, technicalError, businessError, _ = authenticationObj.HttpClient.CallSecretSafeAPI(url, "POST", bytes.Buffer{}, "SignOut", "")
return technicalError
}, c.ExponentialBackOff)
}, authenticationObj.ExponentialBackOff)

if businessError != nil {
c.log.Error(businessError.Error())
authenticationObj.log.Error(businessError.Error())
return businessError
}

return nil
}

// CallSecretSafeAPI prepares http call
func (c *AuthenticationObj) CallSecretSafeAPI(url string, httpMethod string, body bytes.Buffer, method string, accesToken string) (io.ReadCloser, error, error, int) {
response, technicalError, businessError, scode := c.HttpRequest(url, httpMethod, body, accesToken)
if technicalError != nil {
messageLog := fmt.Sprintf("Error in %v %v \n", method, technicalError)
c.log.Error(messageLog)
}

if businessError != nil {
messageLog := fmt.Sprintf("Error in %v: %v \n", method, businessError)
c.log.Error(messageLog)
}
return response, technicalError, businessError, scode
}

// HttpRequest makes http request to he server
func (c *AuthenticationObj) HttpRequest(url string, method string, body bytes.Buffer, accesToken string) (closer io.ReadCloser, technicalError error, businessError error, scode int) {

req, err := http.NewRequest(method, url, &body)
if err != nil {
return nil, err, nil, 0
}
req.Header = http.Header{
"Content-Type": {"application/json"},
}

if accesToken != "" {
req.Header.Set("Authorization", "Bearer "+accesToken)
}

resp, err := c.httpClient.Do(req)
if err != nil {
c.log.Error(err.Error())
return nil, err, nil, 0
}

if resp.StatusCode >= http.StatusInternalServerError || resp.StatusCode == http.StatusRequestTimeout {
err = fmt.Errorf("error %v: StatusCode: %v, %v, %v", method, scode, err, body)
c.log.Error(err.Error())
return nil, err, nil, resp.StatusCode
}

if resp.StatusCode != http.StatusCreated && resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusNoContent {
respBody := new(bytes.Buffer)
_, err = respBody.ReadFrom(resp.Body)
if err != nil {
c.log.Error(err.Error())
return nil, err, nil, 0
}

err = fmt.Errorf("got a non 200 status code: %v - %v", resp.StatusCode, respBody)
return nil, nil, err, resp.StatusCode
}

return resp.Body, nil, nil, resp.StatusCode
}
12 changes: 6 additions & 6 deletions api/managed_account/managed_account.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ func (managedAccounObj *ManagedAccountstObj) ManagedAccountGet(systemName string
var businessError error

technicalError = backoff.Retry(func() error {
body, technicalError, businessError, _ = managedAccounObj.authenticationObj.CallSecretSafeAPI(url, "GET", bytes.Buffer{}, "ManagedAccountGet", "")
body, technicalError, businessError, _ = managedAccounObj.authenticationObj.HttpClient.CallSecretSafeAPI(url, "GET", bytes.Buffer{}, "ManagedAccountGet", "")
if technicalError != nil {
return technicalError
}
Expand Down Expand Up @@ -175,7 +175,7 @@ func (managedAccounObj *ManagedAccountstObj) ManagedAccountCreateRequest(systemN
var businessError error

technicalError = backoff.Retry(func() error {
body, technicalError, businessError, _ = managedAccounObj.authenticationObj.CallSecretSafeAPI(url, "POST", *b, "ManagedAccountCreateRequest", "")
body, technicalError, businessError, _ = managedAccounObj.authenticationObj.HttpClient.CallSecretSafeAPI(url, "POST", *b, "ManagedAccountCreateRequest", "")
return technicalError
}, managedAccounObj.authenticationObj.ExponentialBackOff)

Expand Down Expand Up @@ -203,14 +203,14 @@ func (managedAccounObj *ManagedAccountstObj) ManagedAccountCreateRequest(systemN
// enpoint and returns secret value by request Id.
func (managedAccounObj *ManagedAccountstObj) CredentialByRequestId(requestId string, url string) (string, error) {
messageLog := fmt.Sprintf("%v %v", "GET", url)
managedAccounObj.log.Debug(messageLog)
managedAccounObj.log.Debug(strings.Replace(messageLog, requestId, "****", -1))

var body io.ReadCloser
var technicalError error
var businessError error

technicalError = backoff.Retry(func() error {
body, technicalError, businessError, _ = managedAccounObj.authenticationObj.CallSecretSafeAPI(url, "GET", bytes.Buffer{}, "CredentialByRequestId", "")
body, technicalError, businessError, _ = managedAccounObj.authenticationObj.HttpClient.CallSecretSafeAPI(url, "GET", bytes.Buffer{}, "CredentialByRequestId", "")
return technicalError
}, managedAccounObj.authenticationObj.ExponentialBackOff)

Expand Down Expand Up @@ -241,7 +241,7 @@ func (managedAccounObj *ManagedAccountstObj) CredentialByRequestId(requestId str
// ManagedAccountRequestCheckIn calls Secret Safe API "Requests/<request_id>/checkin enpoint.
func (managedAccounObj *ManagedAccountstObj) ManagedAccountRequestCheckIn(requestId string, url string) (string, error) {
messageLog := fmt.Sprintf("%v %v", "PUT", url)
managedAccounObj.log.Debug(messageLog)
managedAccounObj.log.Debug(strings.Replace(messageLog, requestId, "****", -1))

data := "{}"
b := bytes.NewBufferString(data)
Expand All @@ -250,7 +250,7 @@ func (managedAccounObj *ManagedAccountstObj) ManagedAccountRequestCheckIn(reques
var businessError error

technicalError = backoff.Retry(func() error {
_, technicalError, businessError, _ = managedAccounObj.authenticationObj.CallSecretSafeAPI(url, "PUT", *b, "ManagedAccountRequestCheckIn", "")
_, technicalError, businessError, _ = managedAccounObj.authenticationObj.HttpClient.CallSecretSafeAPI(url, "PUT", *b, "ManagedAccountRequestCheckIn", "")
return technicalError
}, managedAccounObj.authenticationObj.ExponentialBackOff)

Expand Down
Loading

0 comments on commit fc9d511

Please sign in to comment.