package services import ( "context" "database/sql" "errors" sqlerror "edge-infra.dev/pkg/edge/api/apierror/sql" "edge-infra.dev/pkg/edge/api/graph/model" sqlquery "edge-infra.dev/pkg/edge/api/sql" ) //go:generate mockgen -destination=../mocks/mock_iam_settings_service.go -package=mocks edge-infra.dev/pkg/edge/api/services IAMSettingsService type IAMSettingsService interface { CreateSettings(ctx context.Context, bannerID string, providerSettings model.ProviderInput) (*model.Provider, error) GetSettings(ctx context.Context, bannerID string) (*model.Provider, error) UpdateSettings(ctx context.Context, bannerID string, providerSettings model.ProviderInput) (*model.Provider, error) DeleteSettings(ctx context.Context, bannerID string) (*model.Provider, error) } type iamSettingService struct { SQLDB *sql.DB } func (o *iamSettingService) CreateSettings(ctx context.Context, bannerID string, providerSettings model.ProviderInput) (*model.Provider, error) { var ps model.Provider tx, err := o.SQLDB.BeginTx(ctx, &sql.TxOptions{}) if err != nil { return nil, err } defer func() { if err != nil { err = errors.Join(err, tx.Rollback()) } }() _, errID := o.getProviderSettingsID(ctx, bannerID) if errID == nil { return o.UpdateSettings(ctx, bannerID, providerSettings) } row := tx.QueryRowContext(ctx, sqlquery.InsertProviderSettings, providerSettings.PinAttempts, providerSettings.PinExpire, providerSettings.PinHistory, providerSettings.PinLength, providerSettings.BarcodeExpire, providerSettings.BarcodePrefix, providerSettings.BarcodeLength, providerSettings.BcryptCost, providerSettings.ProfileExpire) err = row.Scan(&ps.ProviderSettingsID) if err != nil { return nil, sqlerror.Wrap(err) } err = o.createProviderOwner(ctx, bannerID, ps.ProviderSettingsID, tx) if err != nil { return nil, sqlerror.Wrap(err) } if err = tx.Commit(); err != nil { return nil, err } settings, err := o.GetSettings(ctx, bannerID) if err != nil { return nil, sqlerror.Wrap(err) } return settings, err } func (o *iamSettingService) GetSettings(ctx context.Context, bannerID string) (*model.Provider, error) { //use provider settings edge id to get configuration var settings model.Provider providerSettingsID, errID := o.getProviderSettingsID(ctx, bannerID) if errID != nil { return nil, sqlerror.Wrap(errID) } row := o.SQLDB.QueryRowContext(ctx, sqlquery.GetProviderSettings, providerSettingsID) err := row.Scan(&settings.ProviderSettingsID, &settings.PinAttempts, &settings.PinHistory, &settings.PinLength, &settings.BarcodePrefix, &settings.BarcodeLength, &settings.BcryptCost, &settings.PinExpire, &settings.BarcodeExpire, &settings.ProfileExpire) //return settings with provided id return &settings, err } //nolint:gocyclo func (o *iamSettingService) UpdateSettings(ctx context.Context, bannerID string, providerSettings model.ProviderInput) (*model.Provider, error) { tx, err := o.SQLDB.BeginTx(ctx, &sql.TxOptions{}) if err != nil { return nil, err } defer func() { if err != nil { err = errors.Join(err, tx.Rollback()) } }() providerSettingsID, errID := o.getProviderSettingsID(ctx, bannerID) if errID != nil { return nil, sqlerror.Wrap(errID) } if providerSettings.PinAttempts != nil { _, err = tx.ExecContext(ctx, sqlquery.UpdatePinAttempts, providerSettings.PinAttempts, providerSettingsID) if err != nil { return nil, sqlerror.Wrap(err) } } if providerSettings.PinExpire != nil { _, err = tx.ExecContext(ctx, sqlquery.UpdatePinExpire, providerSettings.PinExpire, providerSettingsID) if err != nil { return nil, sqlerror.Wrap(err) } } if providerSettings.PinHistory != nil { _, err = tx.ExecContext(ctx, sqlquery.UpdatePinHistory, providerSettings.PinHistory, providerSettingsID) if err != nil { return nil, sqlerror.Wrap(err) } } if providerSettings.PinLength != nil { _, err = tx.ExecContext(ctx, sqlquery.UpdatePinLength, providerSettings.PinLength, providerSettingsID) if err != nil { return nil, sqlerror.Wrap(err) } } if providerSettings.BarcodeExpire != nil { _, err = tx.ExecContext(ctx, sqlquery.UpdateBarcodeExpire, providerSettings.BarcodeExpire, providerSettingsID) if err != nil { return nil, sqlerror.Wrap(err) } } if providerSettings.BarcodePrefix != nil { _, err = tx.ExecContext(ctx, sqlquery.UpdateBarcodePrefix, providerSettings.BarcodePrefix, providerSettingsID) if err != nil { return nil, sqlerror.Wrap(err) } } if providerSettings.BarcodeLength != nil { _, err = tx.ExecContext(ctx, sqlquery.UpdateBarcodeLength, providerSettings.BarcodeLength, providerSettingsID) if err != nil { return nil, sqlerror.Wrap(err) } } if providerSettings.BcryptCost != nil { _, err = tx.ExecContext(ctx, sqlquery.UpdateBcryptCost, providerSettings.BcryptCost, providerSettingsID) if err != nil { return nil, sqlerror.Wrap(err) } } if providerSettings.ProfileExpire != nil { _, err = tx.ExecContext(ctx, sqlquery.UpdateProfileExpire, providerSettings.ProfileExpire, providerSettingsID) if err != nil { return nil, sqlerror.Wrap(err) } } if err = tx.Commit(); err != nil { return nil, err } settings, err := o.GetSettings(ctx, bannerID) return settings, err } func (o *iamSettingService) DeleteSettings(ctx context.Context, bannerID string) (*model.Provider, error) { rowDeleted, err := o.GetSettings(ctx, bannerID) if err != nil { return nil, err } providerSettingsID, errID := o.getProviderSettingsID(ctx, bannerID) if errID != nil { return nil, sqlerror.Wrap(errID) } _, err = o.SQLDB.ExecContext(ctx, sqlquery.DeleteProviderSettings, providerSettingsID) if err != nil { return nil, sqlerror.Wrap(err) } //delete associated owner after row is deleted err = o.deleteProviderOwner(ctx, providerSettingsID) if err != nil { return nil, sqlerror.Wrap(err) } return rowDeleted, nil } func (o *iamSettingService) getProviderSettingsID(ctx context.Context, bannerID string) (string, error) { var settingsID string row := o.SQLDB.QueryRowContext(ctx, sqlquery.GetProviderOwner, bannerID) err := row.Scan(&settingsID) //return settings with provided id return settingsID, err } func (o *iamSettingService) deleteProviderOwner(ctx context.Context, providerSettingsID string) error { _, err := o.SQLDB.ExecContext(ctx, sqlquery.DeleteProviderOwner, providerSettingsID) if err != nil { return sqlerror.Wrap(err) } return nil } func (o *iamSettingService) createProviderOwner(ctx context.Context, bannerID string, providerSettingsID string, tx *sql.Tx) error { if _, err := tx.ExecContext(ctx, sqlquery.InsertProviderOwner, bannerID, providerSettingsID); err != nil { return sqlerror.Wrap(err) } return nil } func NewIAMSettingsService(sqlDB *sql.DB) *iamSettingService { //nolint return &iamSettingService{ SQLDB: sqlDB, } }