Skip to content

Commit

Permalink
implement secret manager authentication dao
Browse files Browse the repository at this point in the history
  • Loading branch information
lindgrenj6 committed Nov 8, 2022
1 parent a8faa8a commit 30ea7d6
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 10 deletions.
6 changes: 5 additions & 1 deletion config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,11 @@ func Get() *SourcesApiConfig {
case SecretsManagerStore:
options.SetDefault("SecretsManagerAccessKey", os.Getenv("SECRETS_MANAGER_ACCESS_KEY"))
options.SetDefault("SecretsManagerSecretKey", os.Getenv("SECRETS_MANAGER_SECRET_KEY"))
options.SetDefault("SecretsManagerPrefix", os.Getenv("SECRETS_MANAGER_PREFIX"))
prefix := os.Getenv("SECRETS_MANAGER_PREFIX")
if prefix == "" {
prefix = "sources-development"
}
options.SetDefault("SecretsManagerPrefix", prefix)
options.SetDefault("LocalStackURL", os.Getenv("LOCALSTACK_URL"))
}

Expand Down
153 changes: 145 additions & 8 deletions dao/authentication_secrets_manager_dao.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package dao

import (
"fmt"

"github.com/RedHatInsights/sources-api-go/dao/amazon"
m "github.com/RedHatInsights/sources-api-go/model"
)

Expand All @@ -18,23 +21,157 @@ type authenticationSecretsManagerDaoImpl struct {
authenticationDaoDbImpl
}

func (a *authenticationSecretsManagerDaoImpl) Create(src *m.Authentication) error {
panic("not implemented") // TODO: Implement
func (a *authenticationSecretsManagerDaoImpl) Create(auth *m.Authentication) error {
// only reach out to amazon if there is a password present, otherwise pass
// straight through to the db dao.
if auth.Password != nil {
sm, err := amazon.NewSecretsManagerClient()
if err != nil {
return err
}

auth.TenantID = *a.TenantID
arn, err := sm.CreateSecret(auth, *auth.Password)
if err != nil {
return err
}

err = auth.SetPassword(arn)
if err != nil {
return err
}
}

return a.authenticationDaoDbImpl.Create(auth)
}

func (a *authenticationSecretsManagerDaoImpl) BulkCreate(src *m.Authentication) error {
panic("not implemented") // TODO: Implement
func (a *authenticationSecretsManagerDaoImpl) BulkCreate(auth *m.Authentication) error {
// only reach out to amazon if there is a password present, otherwise pass
// straight through to the db dao.
if auth.Password != nil {
sm, err := amazon.NewSecretsManagerClient()
if err != nil {
return err
}

auth.TenantID = *a.TenantID
arn, err := sm.CreateSecret(auth, *auth.Password)
if err != nil {
return err
}

err = auth.SetPassword(arn)
if err != nil {
return err
}
}

return a.authenticationDaoDbImpl.BulkCreate(auth)
}

func (a *authenticationSecretsManagerDaoImpl) Update(src *m.Authentication) error {
panic("not implemented") // TODO: Implement
func (a *authenticationSecretsManagerDaoImpl) Update(auth *m.Authentication) error {
// only reach out to amazon if there is a password present, otherwise pass
// straight through to the db dao.
if auth.Password != nil {
// fetch the ARN of the current password (since we overwrote it in memory)
arns := make([]*string, 1)
err := a.getDbWithModel().
Where("id = ?", auth.GetID()).
Limit(1).
Pluck("password_hash", &arns).Error
if err != nil {
return err
}
if *arns[0] == "" {
return fmt.Errorf("failed to fetch ARN for authentication %v", auth.GetID())
}

sm, err := amazon.NewSecretsManagerClient()
if err != nil {
return err
}

err = sm.UpdateSecret(*arns[0], *auth.Password)
if err != nil {
return err
}

// set the password back to the ARN so that we don't overwrite it.
auth.Password = arns[0]
}

return a.authenticationDaoDbImpl.Update(auth)
}

func (a *authenticationSecretsManagerDaoImpl) Delete(id string) (*m.Authentication, error) {
panic("not implemented") // TODO: Implement
auth, err := a.authenticationDaoDbImpl.Delete(id)
if err != nil {
return nil, err
}

// only reach out to amazon to nuke the secret if the password exists
if auth.Password != nil {
sm, err := amazon.NewSecretsManagerClient()
if err != nil {
return nil, err
}

err = sm.DeleteSecret(*auth.Password)
if err != nil {
return nil, err
}
}

return auth, nil
}

// BulkDelete deletes all the authentications given as a list, and returns the ones that were deleted.
func (a *authenticationSecretsManagerDaoImpl) BulkDelete(authentications []m.Authentication) ([]m.Authentication, error) {
panic("not implemented") // TODO: Implement
auths, err := a.authenticationDaoDbImpl.BulkDelete(authentications)
if err != nil {
return nil, err
}

sm, err := amazon.NewSecretsManagerClient()
if err != nil {
return nil, err
}

// go through and clean up the aws resoures, logging if there is a failure.
for i := range authentications {
if authentications[i].Password != nil {
err := sm.DeleteSecret(*authentications[i].Password)
if err != nil {
DB.Logger.Warn(a.ctx, "Failed to delete secret %v: %v", authentications[i].Password, err)
}
}
}

return auths, nil
}

// overriding the GetById function to fetch from secrets manager if the password
// is present - this is mostly for internal responses.
func (a *authenticationSecretsManagerDaoImpl) GetById(id string) (*m.Authentication, error) {
auth, err := a.authenticationDaoDbImpl.GetById(id)
if err != nil {
return nil, err
}

if auth.Password != nil {
sm, err := amazon.NewSecretsManagerClient()
if err != nil {
return nil, err
}

pass, err := sm.GetSecret(*auth.Password)
if err != nil {
return nil, err
}

// set the password in-memory to the secrets-manager password
auth.Password = pass
}

return auth, nil
}
2 changes: 1 addition & 1 deletion model/secret_store_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func (auth *Authentication) GetPassword() (*string, error) {
return auth.Password, nil

case config.SecretsManagerStore:
return nil, ErrBadSecretStore
return auth.Password, nil

default:
return nil, ErrBadSecretStore
Expand Down

0 comments on commit 30ea7d6

Please sign in to comment.