Skip to content

Commit

Permalink
feat: use a struct to group validate input function parameters (#116)
Browse files Browse the repository at this point in the history
* feat: use a struct to group validate input function parameters

* feat: use a struct to group validate input function parameters
  • Loading branch information
btfhernandez authored Jul 3, 2024
1 parent 695c216 commit 50d55d2
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 34 deletions.
17 changes: 16 additions & 1 deletion TestClient.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,23 @@ func main() {
//certificate = os.Getenv("CERTIFICATE")
//certificateKey = os.Getenv("CERTIFICATE_KEY")

// Create an instance of ValidationParams
params := utils.ValidationParams{
ClientID: clientId,
ClientSecret: clientSecret,
ApiUrl: &apiUrl,
ClientTimeOutInSeconds: clientTimeOutInSeconds,
Separator: &separator,
VerifyCa: verifyCa,
Logger: zapLogger,
Certificate: certificate,
CertificateKey: certificateKey,
RetryMaxElapsedTimeMinutes: &retryMaxElapsedTimeMinutes,
MaxFileSecretSizeBytes: &maxFileSecretSizeBytes,
}

// validate inputs
errorsInInputs := utils.ValidateInputs(clientId, clientSecret, &apiUrl, clientTimeOutInSeconds, &separator, verifyCa, zapLogger, certificate, certificateKey, &retryMaxElapsedTimeMinutes, &maxFileSecretSizeBytes)
errorsInInputs := utils.ValidateInputs(params)

if errorsInInputs != nil {
return
Expand Down
78 changes: 46 additions & 32 deletions api/utils/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,20 @@ import (
validator "github.com/go-playground/validator/v10"
)

type ValidationParams struct {
ClientID string
ClientSecret string
ApiUrl *string
ClientTimeOutInSeconds int
Separator *string
VerifyCa bool
Logger logging.Logger
Certificate string
CertificateKey string
RetryMaxElapsedTimeMinutes *int
MaxFileSecretSizeBytes *int
}

// UserInputValidaton responsible for input paramerter validation.
type UserInputValidaton struct {
ClientId string `validate:"required,min=36,max=36"`
Expand All @@ -27,89 +41,89 @@ type UserInputValidaton struct {
var validate *validator.Validate

// ValidateInputs is responsible for validating end-user inputs.
func ValidateInputs(clientId string, clientSecret string, apiUrl *string, clientTimeOutinSeconds int, separator *string, verifyCa bool, logger logging.Logger, certificate string, certificate_key string, retryMaxElapsedTimeMinutes *int, maxFileSecretSizeBytes *int) error {
func ValidateInputs(params ValidationParams) error {

if clientTimeOutinSeconds == 0 {
clientTimeOutinSeconds = 30
if params.ClientTimeOutInSeconds == 0 {
params.ClientTimeOutInSeconds = 30
}

if *retryMaxElapsedTimeMinutes == 0 {
*retryMaxElapsedTimeMinutes = 2
if *params.RetryMaxElapsedTimeMinutes == 0 {
*params.RetryMaxElapsedTimeMinutes = 2
}

if *maxFileSecretSizeBytes == 0 {
*maxFileSecretSizeBytes = 4000000
if *params.MaxFileSecretSizeBytes == 0 {
*params.MaxFileSecretSizeBytes = 4000000
}

if strings.TrimSpace(*separator) == "" {
*separator = "/"
if strings.TrimSpace(*params.Separator) == "" {
*params.Separator = "/"
}

*apiUrl = strings.TrimSpace(*apiUrl)
*params.ApiUrl = strings.TrimSpace(*params.ApiUrl)

err := ValidateURL(*apiUrl)
err := ValidateURL(*params.ApiUrl)
if err != nil {
logger.Error(err.Error())
params.Logger.Error(err.Error())
return err
}

validate = validator.New(validator.WithRequiredStructEnabled())

userInput := &UserInputValidaton{
ClientId: clientId,
ClientSecret: clientSecret,
ApiUrl: *apiUrl,
ClientTimeOutinSeconds: clientTimeOutinSeconds,
Separator: *separator,
MaxFileSecretSizeBytes: *maxFileSecretSizeBytes,
ClientId: params.ClientID,
ClientSecret: params.ClientSecret,
ApiUrl: *params.ApiUrl,
ClientTimeOutinSeconds: params.ClientTimeOutInSeconds,
Separator: *params.Separator,
MaxFileSecretSizeBytes: *params.MaxFileSecretSizeBytes,
}

if !verifyCa {
logger.Warn("verifyCa=false is insecure, instructs not to verify the certificate authority.")
if !params.VerifyCa {
params.Logger.Warn("verifyCa=false is insecure, instructs not to verify the certificate authority.")
}

err = validate.Struct(userInput)
if err != nil {
logger.Error(err.Error())
params.Logger.Error(err.Error())
return err
}

message := ""

if certificate != "" && certificate_key != "" {
if params.Certificate != "" && params.CertificateKey != "" {

certificateLengthInBits := utf8.RuneCountInString(certificate) * 8
certificateLengthInBits := utf8.RuneCountInString(params.Certificate) * 8

if certificateLengthInBits > 32768 {
message = "invalid length for certificate, the maximum size is 32768 bits"
logger.Error(message)
params.Logger.Error(message)
return errors.New(message)
}

certificateKeyLengthInBits := utf8.RuneCountInString(certificate_key) * 8
certificateKeyLengthInBits := utf8.RuneCountInString(params.CertificateKey) * 8

if certificateKeyLengthInBits > 32768 {
message = "invalid length for certificate key, the maximum size is 32768 bits"
logger.Error(message)
params.Logger.Error(message)
return errors.New(message)
}

if !strings.HasPrefix(certificate, "-----BEGIN CERTIFICATE-----") || !strings.HasSuffix(certificate, "-----END CERTIFICATE-----") {
if !strings.HasPrefix(params.Certificate, "-----BEGIN CERTIFICATE-----") || !strings.HasSuffix(params.Certificate, "-----END CERTIFICATE-----") {
message = "invalid certificate content, must contain BEGIN and END CERTIFICATE"
logger.Error(message)
params.Logger.Error(message)
return errors.New(message)
}

if !strings.HasPrefix(certificate_key, "-----BEGIN PRIVATE KEY-----") || !strings.HasSuffix(certificate_key, "-----END PRIVATE KEY-----") {
if !strings.HasPrefix(params.CertificateKey, "-----BEGIN PRIVATE KEY-----") || !strings.HasSuffix(params.CertificateKey, "-----END PRIVATE KEY-----") {
message = "invalid certificate key content, must contain BEGIN and END PRIVATE KEY"
logger.Error(message)
params.Logger.Error(message)
return errors.New(message)
}

}

message = fmt.Sprintf("Library settings: ClientId=%v, ApiUrl=%v, ClientTimeOutinSeconds=%v, Separator=%v, VerifyCa=%v, MaxFileSecretSizeBytes=%v, UsingCertificate=%v", userInput.ClientId, userInput.ApiUrl, userInput.ClientTimeOutinSeconds, userInput.Separator, verifyCa, userInput.MaxFileSecretSizeBytes, certificate != "")
logger.Debug(message)
message = fmt.Sprintf("Library settings: ClientId=%v, ApiUrl=%v, ClientTimeOutinSeconds=%v, Separator=%v, VerifyCa=%v, MaxFileSecretSizeBytes=%v, UsingCertificate=%v", userInput.ClientId, userInput.ApiUrl, userInput.ClientTimeOutinSeconds, userInput.Separator, params.VerifyCa, userInput.MaxFileSecretSizeBytes, params.Certificate != "")
params.Logger.Debug(message)
return nil
}

Expand Down
17 changes: 16 additions & 1 deletion performancetest/PerformanceTest.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,23 @@ func callPasswordSafeAPI() {
retryMaxElapsedTimeMinutes := 15
maxFileSecretSizeBytes := 5000000

// Create an instance of ValidationParams
params := utils.ValidationParams{
ClientID: clientId,
ClientSecret: clientSecret,
ApiUrl: &apiUrl,
ClientTimeOutInSeconds: clientTimeOutInSeconds,
Separator: &separator,
VerifyCa: verifyCa,
Logger: zapLogger,
Certificate: certificate,
CertificateKey: certificateKey,
RetryMaxElapsedTimeMinutes: &retryMaxElapsedTimeMinutes,
MaxFileSecretSizeBytes: &maxFileSecretSizeBytes,
}

// validate inputs
errorsInInputs := utils.ValidateInputs(clientId, clientSecret, &apiUrl, clientTimeOutInSeconds, &separator, verifyCa, zapLogger, certificate, certificateKey, &retryMaxElapsedTimeMinutes, &maxFileSecretSizeBytes)
errorsInInputs := utils.ValidateInputs(params)
if errorsInInputs != nil {
return
}
Expand Down

0 comments on commit 50d55d2

Please sign in to comment.