Skip to content

Commit

Permalink
feat: add creating safes feature in terraform provider (#175)
Browse files Browse the repository at this point in the history
* feat: add creating safes feature in terraform provider

* feat: fix PR comments
  • Loading branch information
btfhernandez authored Dec 11, 2024
1 parent 6d63ba2 commit 9b5a870
Show file tree
Hide file tree
Showing 6 changed files with 173 additions and 47 deletions.
17 changes: 17 additions & 0 deletions TestClient.go
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,23 @@ func main() {
// WARNING: Do not log secrets in production code, the following log statement logs test secrets for testing purposes:
zapLogger.Debug(fmt.Sprintf("Created Folder: %v", createdFolder.Name))

safeDetails := entities.FolderDetails{
Name: "SAFE_" + uuid.New().String(),
Description: "My new Safe",
FolderType: "SAFE",
}

// creating a safe.
createdSafe, err := secretObj.CreateFolderFlow("", safeDetails)

if err != nil {
zapLogger.Error(err.Error())
return
}

// WARNING: Do not log secrets in production code, the following log statement logs test secrets for testing purposes:
zapLogger.Debug(fmt.Sprintf("Created Safe: %v", createdSafe.Name))

// signing out
_ = authenticate.SignOut()

Expand Down
12 changes: 6 additions & 6 deletions api/authentication/authentication_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,14 +83,14 @@ func TestSignAppin(t *testing.T) {
testConfig := UserTestConfig{
name: "TestSignAppin",
server: httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
_, err := w.Write([]byte(`{"UserId":1, "EmailAddress":"Felipe"}`))
_, err := w.Write([]byte(`{"UserId":1, "EmailAddress":"[email protected]"}`))
if err != nil {
t.Error("Test case Failed")
}
})),
response: &entities.SignApinResponse{
UserId: 1,
EmailAddress: "Felipe",
EmailAddress: "[email protected]",
},
}

Expand Down Expand Up @@ -120,14 +120,14 @@ func TestSignAppinWithApiKey(t *testing.T) {
testConfig := UserTestConfig{
name: "TestSignAppinWithApiKey",
server: httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
_, err := w.Write([]byte(`{"UserId":1, "EmailAddress":"Felipe"}`))
_, err := w.Write([]byte(`{"UserId":1, "EmailAddress":"[email protected]"}`))
if err != nil {
t.Error("Test case Failed")
}
})),
response: &entities.SignApinResponse{
UserId: 1,
EmailAddress: "Felipe",
EmailAddress: "[email protected]",
},
}

Expand Down Expand Up @@ -209,7 +209,7 @@ func TestGetPasswordSafeAuthentication(t *testing.T) {
}

case "/Auth/SignAppIn":
_, err := w.Write([]byte(`{"UserId":1, "EmailAddress":"Felipe"}`))
_, err := w.Write([]byte(`{"UserId":1, "EmailAddress":"[email protected]"}`))

if err != nil {
t.Error("Test case Failed")
Expand All @@ -221,7 +221,7 @@ func TestGetPasswordSafeAuthentication(t *testing.T) {
})),
response: &entities.SignApinResponse{
UserId: 1,
EmailAddress: "Felipe",
EmailAddress: "[email protected]",
},
}
apiUrl, _ := url.Parse(testConfig.server.URL + "/")
Expand Down
3 changes: 2 additions & 1 deletion api/entities/entities.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ type CreateFolderResponse struct {
type FolderDetails struct {
Name string `json:",omitempty" validate:"required"`
Description string `json:",omitempty" validate:"omitempty,max=256"`
ParentId uuid.UUID `json:",omitempty" validate:"required"`
ParentId uuid.UUID `json:",omitempty" validate:"required_if=FolderType FOLDER"`
UserGroupId int `json:",omitempty" validate:"omitempty"`
FolderType string `json:",omitempty" validate:"required"`
}
24 changes: 12 additions & 12 deletions api/managed_account/managed_account_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ func TestManageAccountFlow(t *testing.T) {
switch r.URL.Path {

case "/Auth/SignAppin":
_, err := w.Write([]byte(`{"UserId":1, "EmailAddress":"Felipe"}`))
_, err := w.Write([]byte(`{"UserId":1, "EmailAddress":"[email protected]"}`))
if err != nil {
t.Error("Test case Failed")
}
Expand Down Expand Up @@ -289,7 +289,7 @@ func TestManageAccountFlowNotFound(t *testing.T) {
switch r.URL.Path {

case "/Auth/SignAppin":
_, err := w.Write([]byte(`{"UserId":1, "EmailAddress":"Felipe"}`))
_, err := w.Write([]byte(`{"UserId":1, "EmailAddress":"[email protected]"}`))
if err != nil {
t.Error("Test case Failed")
}
Expand Down Expand Up @@ -366,7 +366,7 @@ func TestSecretGetSecret(t *testing.T) {
switch r.URL.Path {

case "/Auth/SignAppin":
_, err := w.Write([]byte(`{"UserId":1, "EmailAddress":"Felipe"}`))
_, err := w.Write([]byte(`{"UserId":1, "EmailAddress":"[email protected]"}`))
if err != nil {
t.Error("Test case Failed")
}
Expand Down Expand Up @@ -441,7 +441,7 @@ func TestSecretGetSecrets(t *testing.T) {
switch r.URL.Path {

case "/Auth/SignAppin":
_, err := w.Write([]byte(`{"UserId":1, "EmailAddress":"Felipe"}`))
_, err := w.Write([]byte(`{"UserId":1, "EmailAddress":"[email protected]"}`))
if err != nil {
t.Error("Test case Failed")
}
Expand Down Expand Up @@ -517,7 +517,7 @@ func TestManagedAccountFlowTechnicalErrorCreatingRequest(t *testing.T) {
switch r.URL.Path {

case "/Auth/SignAppin":
_, err := w.Write([]byte(`{"UserId":1, "EmailAddress":"Felipe"}`))
_, err := w.Write([]byte(`{"UserId":1, "EmailAddress":"[email protected]"}`))
if err != nil {
t.Error("Test case Failed")
}
Expand Down Expand Up @@ -592,7 +592,7 @@ func TestManagedAccountFlowBusinesslErrorCreatingRequest(t *testing.T) {
switch r.URL.Path {

case "/Auth/SignAppin":
_, err := w.Write([]byte(`{"UserId":1, "EmailAddress":"Felipe"}`))
_, err := w.Write([]byte(`{"UserId":1, "EmailAddress":"[email protected]"}`))
if err != nil {
t.Error("Test case Failed")
}
Expand Down Expand Up @@ -667,7 +667,7 @@ func TestManagedAccountFlowTechnicalErrorCredentialByRequestId(t *testing.T) {
switch r.URL.Path {

case "/Auth/SignAppin":
_, err := w.Write([]byte(`{"UserId":1, "EmailAddress":"Felipe"}`))
_, err := w.Write([]byte(`{"UserId":1, "EmailAddress":"[email protected]"}`))
if err != nil {
t.Error("Test case Failed")
}
Expand Down Expand Up @@ -742,7 +742,7 @@ func TestManagedAccountFlowBusinessErrorCredentialByRequestId(t *testing.T) {
switch r.URL.Path {

case "/Auth/SignAppin":
_, err := w.Write([]byte(`{"UserId":1, "EmailAddress":"Felipe"}`))
_, err := w.Write([]byte(`{"UserId":1, "EmailAddress":"[email protected]"}`))
if err != nil {
t.Error("Test case Failed")
}
Expand Down Expand Up @@ -817,7 +817,7 @@ func TestManagedAccountFlowBusinessErrorAccountRequestCheckIn(t *testing.T) {
switch r.URL.Path {

case "/Auth/SignAppin":
_, err := w.Write([]byte(`{"UserId":1, "EmailAddress":"Felipe"}`))
_, err := w.Write([]byte(`{"UserId":1, "EmailAddress":"[email protected]"}`))
if err != nil {
t.Error("Test case Failed")
}
Expand Down Expand Up @@ -892,7 +892,7 @@ func TestManagedAccountFlowTechnicalErrorAccountRequestCheckIn(t *testing.T) {
switch r.URL.Path {

case "/Auth/SignAppin":
_, err := w.Write([]byte(`{"UserId":1, "EmailAddress":"Felipe"}`))
_, err := w.Write([]byte(`{"UserId":1, "EmailAddress":"[email protected]"}`))
if err != nil {
t.Error("Test case Failed")
}
Expand Down Expand Up @@ -967,7 +967,7 @@ func TestManagedAccountFlowGetAccountTechnicalError(t *testing.T) {
switch r.URL.Path {

case "/Auth/SignAppin":
_, err := w.Write([]byte(`{"UserId":1, "EmailAddress":"Felipe"}`))
_, err := w.Write([]byte(`{"UserId":1, "EmailAddress":"[email protected]"}`))
if err != nil {
t.Error("Test case Failed")
}
Expand Down Expand Up @@ -1023,7 +1023,7 @@ func TestManageAccountFlowGetAccountBadResponse(t *testing.T) {
switch r.URL.Path {

case "/Auth/SignAppin":
_, err := w.Write([]byte(`{"UserId":1, "EmailAddress":"Felipe"}`))
_, err := w.Write([]byte(`{"UserId":1, "EmailAddress":"[email protected]"}`))
if err != nil {
t.Error("Test case Failed")
}
Expand Down
60 changes: 41 additions & 19 deletions api/secrets/secrets.go
Original file line number Diff line number Diff line change
Expand Up @@ -376,31 +376,45 @@ func (secretObj *SecretObj) SecretGetFolders(endpointPath string) ([]entities.Fo

}

// CreateFolderFlow is responsible for creating folder in Password Safe.
// CreateFolderFlow is responsible for creating folders/safes in Password Safe.
func (secretObj *SecretObj) CreateFolderFlow(folderTarget string, folderDetails entities.FolderDetails) (entities.CreateFolderResponse, error) {

var folder *entities.FolderResponse
var createFolderesponse entities.CreateFolderResponse
var err error

folders, err := secretObj.SecretGetFolders("secrets-safe/folders/")

if err != nil {
return createFolderesponse, err
if folderDetails.FolderType == "" {
folderDetails.FolderType = "FOLDER"
}

for _, v := range folders {
if v.Name == strings.TrimSpace(folderTarget) {
folder = &v
break
secretObj.log.Debug(fmt.Sprintf("Folder Type: %v", folderDetails.FolderType))

// if it is folder
if folderDetails.FolderType == "FOLDER" {
if folderTarget == "" {
return createFolderesponse, fmt.Errorf("parent folder name must not be empty")
}
}

if folder == nil {
return createFolderesponse, fmt.Errorf("folder %v was not found in folder list", folderTarget)
}
folders, err := secretObj.SecretGetFolders("secrets-safe/folders/")

folderId, _ := uuid.Parse(folder.Id)
folderDetails.ParentId = folderId
if err != nil {
return createFolderesponse, err
}

for _, v := range folders {
if v.Name == strings.TrimSpace(folderTarget) {
folder = &v
break
}
}

if folder == nil {
return createFolderesponse, fmt.Errorf("folder %v was not found in folder list", folderTarget)
}

folderId, _ := uuid.Parse(folder.Id)
folderDetails.ParentId = folderId
}

folderDetails, err = utils.ValidateCreateFolderInput(folderDetails)

Expand All @@ -421,9 +435,17 @@ func (secretObj *SecretObj) CreateFolderFlow(folderTarget string, folderDetails
return createFolderesponse, nil
}

// SecretCreateFolder calls Secret Safe API Requests enpoint to create folders in Password Safe.
// SecretCreateFolder calls Secret Safe API Requests enpoint to create folders/safes in Password Safe.
func (secretObj *SecretObj) SecretCreateFolder(folderDetails entities.FolderDetails) (entities.CreateFolderResponse, error) {

path := "secrets-safe/folders/"
function := "SecretCreateSecret"

if folderDetails.FolderType == "SAFE" {
path = "secrets-safe/safes/"
function = "SecretCreateSafes"
}

folderCredentialDetailsJson, err := json.Marshal(folderDetails)

if err != nil {
Expand All @@ -435,16 +457,16 @@ func (secretObj *SecretObj) SecretCreateFolder(folderDetails entities.FolderDeta

var createSecretResponse entities.CreateFolderResponse

SecretCreateSecreUrl := secretObj.authenticationObj.ApiUrl.JoinPath("secrets-safe/folders/").String()
messageLog := fmt.Sprintf("%v %v", "POST", SecretCreateSecreUrl)
SecretCreateSecretUrl := secretObj.authenticationObj.ApiUrl.JoinPath(path).String()
messageLog := fmt.Sprintf("%v %v", "POST", SecretCreateSecretUrl)
secretObj.log.Debug(messageLog)

var body io.ReadCloser
var technicalError error
var businessError error

technicalError = backoff.Retry(func() error {
body, _, technicalError, businessError = secretObj.authenticationObj.HttpClient.CallSecretSafeAPI(SecretCreateSecreUrl, "POST", *b, "SecretCreateSecret", "", "", "application/json")
body, _, technicalError, businessError = secretObj.authenticationObj.HttpClient.CallSecretSafeAPI(SecretCreateSecretUrl, "POST", *b, function, "", "", "application/json")
return technicalError
}, secretObj.authenticationObj.ExponentialBackOff)

Expand Down
Loading

0 comments on commit 9b5a870

Please sign in to comment.