github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/internal/domain/systemauth/service.go (about)

     1  package systemauth
     2  
     3  import (
     4  	"context"
     5  	"time"
     6  
     7  	intModel "github.com/kyma-incubator/compass/components/director/internal/model"
     8  
     9  	"github.com/kyma-incubator/compass/components/director/pkg/model"
    10  
    11  	"github.com/kyma-incubator/compass/components/director/internal/domain/tenant"
    12  	"github.com/kyma-incubator/compass/components/director/pkg/apperrors"
    13  	"github.com/kyma-incubator/compass/components/director/pkg/log"
    14  	"github.com/pkg/errors"
    15  )
    16  
    17  // Repository missing godoc
    18  //go:generate mockery --name=Repository --output=automock --outpkg=automock --case=underscore --disable-version-string
    19  type Repository interface {
    20  	Create(ctx context.Context, item model.SystemAuth) error
    21  	GetByIDForObject(ctx context.Context, tenant, id string, objType model.SystemAuthReferenceObjectType) (*model.SystemAuth, error)
    22  	GetByIDForObjectGlobal(ctx context.Context, id string, objType model.SystemAuthReferenceObjectType) (*model.SystemAuth, error)
    23  	GetByIDGlobal(ctx context.Context, id string) (*model.SystemAuth, error)
    24  	ListForObject(ctx context.Context, tenant string, objectType model.SystemAuthReferenceObjectType, objectID string) ([]model.SystemAuth, error)
    25  	ListForObjectGlobal(ctx context.Context, objectType model.SystemAuthReferenceObjectType, objectID string) ([]model.SystemAuth, error)
    26  	DeleteByIDForObject(ctx context.Context, tenant, id string, objType model.SystemAuthReferenceObjectType) error
    27  	DeleteByIDForObjectGlobal(ctx context.Context, id string, objType model.SystemAuthReferenceObjectType) error
    28  	GetByJSONValue(ctx context.Context, value map[string]interface{}) (*model.SystemAuth, error)
    29  	Update(ctx context.Context, item *model.SystemAuth) error
    30  }
    31  
    32  // UIDService missing godoc
    33  //go:generate mockery --name=UIDService --output=automock --outpkg=automock --case=underscore --disable-version-string
    34  type UIDService interface {
    35  	Generate() string
    36  }
    37  
    38  type service struct {
    39  	repo       Repository
    40  	uidService UIDService
    41  }
    42  
    43  // NewService missing godoc
    44  func NewService(repo Repository, uidService UIDService) *service {
    45  	return &service{
    46  		repo:       repo,
    47  		uidService: uidService,
    48  	}
    49  }
    50  
    51  // Create missing godoc
    52  func (s *service) Create(ctx context.Context, objectType model.SystemAuthReferenceObjectType, objectID string, authInput *intModel.AuthInput) (string, error) {
    53  	return s.create(ctx, s.uidService.Generate(), objectType, objectID, authInput)
    54  }
    55  
    56  // CreateWithCustomID missing godoc
    57  func (s *service) CreateWithCustomID(ctx context.Context, id string, objectType model.SystemAuthReferenceObjectType, objectID string, authInput *intModel.AuthInput) (string, error) {
    58  	return s.create(ctx, id, objectType, objectID, authInput)
    59  }
    60  
    61  func (s *service) create(ctx context.Context, id string, objectType model.SystemAuthReferenceObjectType, objectID string, authInput *intModel.AuthInput) (string, error) {
    62  	tnt, err := tenant.LoadFromContext(ctx)
    63  	if err != nil {
    64  		if !model.IsIntegrationSystemNoTenantFlow(err, objectType) {
    65  			return "", err
    66  		}
    67  	}
    68  
    69  	log.C(ctx).Debugf("Tenant %s loaded while creating SystemAuth for %s with id %s", tnt, objectType, objectID)
    70  
    71  	systemAuth := model.SystemAuth{
    72  		ID:    id,
    73  		Value: authInput.ToAuth(),
    74  	}
    75  
    76  	switch objectType {
    77  	case model.ApplicationReference:
    78  		systemAuth.AppID = &objectID
    79  		systemAuth.TenantID = &tnt
    80  	case model.RuntimeReference:
    81  		systemAuth.RuntimeID = &objectID
    82  		systemAuth.TenantID = &tnt
    83  	case model.IntegrationSystemReference:
    84  		systemAuth.IntegrationSystemID = &objectID
    85  		systemAuth.TenantID = nil
    86  	default:
    87  		return "", apperrors.NewInternalError("unknown reference object type")
    88  	}
    89  
    90  	err = s.repo.Create(ctx, systemAuth)
    91  	if err != nil {
    92  		return "", err
    93  	}
    94  
    95  	return systemAuth.ID, nil
    96  }
    97  
    98  // GetByIDForObject missing godoc
    99  func (s *service) GetByIDForObject(ctx context.Context, objectType model.SystemAuthReferenceObjectType, authID string) (*model.SystemAuth, error) {
   100  	tnt, err := tenant.LoadFromContext(ctx)
   101  	if err != nil {
   102  		if !model.IsIntegrationSystemNoTenantFlow(err, objectType) {
   103  			return nil, errors.Wrapf(err, "while loading tenant from context")
   104  		}
   105  	}
   106  
   107  	var item *model.SystemAuth
   108  
   109  	if objectType == model.IntegrationSystemReference {
   110  		item, err = s.repo.GetByIDForObjectGlobal(ctx, authID, objectType)
   111  	} else {
   112  		item, err = s.repo.GetByIDForObject(ctx, tnt, authID, objectType)
   113  	}
   114  	if err != nil {
   115  		return nil, errors.Wrapf(err, "while getting SystemAuth with ID %s", authID)
   116  	}
   117  
   118  	return item, nil
   119  }
   120  
   121  // GetGlobal missing godoc
   122  func (s *service) GetGlobal(ctx context.Context, id string) (*model.SystemAuth, error) {
   123  	item, err := s.repo.GetByIDGlobal(ctx, id)
   124  	if err != nil {
   125  		return nil, errors.Wrapf(err, "while getting SystemAuth with ID %s", id)
   126  	}
   127  
   128  	return item, nil
   129  }
   130  
   131  // GetByToken get a SystemAuth by a one time token value
   132  func (s *service) GetByToken(ctx context.Context, token string) (*model.SystemAuth, error) {
   133  	return s.repo.GetByJSONValue(ctx, map[string]interface{}{
   134  		"OneTimeToken": map[string]interface{}{
   135  			"Token": token,
   136  			"Used":  false,
   137  		},
   138  	})
   139  }
   140  
   141  // InvalidateToken gets a SystemAuth by ID, sets the Used properties for the OTT and updates the model
   142  func (s *service) InvalidateToken(ctx context.Context, id string) (*model.SystemAuth, error) {
   143  	systemAuth, err := s.GetGlobal(ctx, id)
   144  	if err != nil {
   145  		return nil, err
   146  	}
   147  
   148  	systemAuth.Value.OneTimeToken.Used = true
   149  	systemAuth.Value.OneTimeToken.UsedAt = time.Now()
   150  
   151  	if err := s.repo.Update(ctx, systemAuth); err != nil {
   152  		return nil, err
   153  	}
   154  
   155  	return systemAuth, nil
   156  }
   157  
   158  // Update missing godoc
   159  func (s *service) Update(ctx context.Context, item *model.SystemAuth) error {
   160  	return s.repo.Update(ctx, item)
   161  }
   162  
   163  // UpdateValue get SystemAuth by provided id and update it with the given input
   164  func (s *service) UpdateValue(ctx context.Context, id string, item *intModel.Auth) (*model.SystemAuth, error) {
   165  	systemAuth, err := s.repo.GetByIDGlobal(ctx, id)
   166  	if err != nil {
   167  		return nil, errors.Wrapf(err, "while getting System Auth with id '%s'", id)
   168  	}
   169  
   170  	systemAuth.Value = item
   171  
   172  	if err := s.repo.Update(ctx, systemAuth); err != nil {
   173  		return nil, errors.Wrapf(err, "while updating System Auth with id '%s'", id)
   174  	}
   175  
   176  	return systemAuth, nil
   177  }
   178  
   179  // ListForObject missing godoc
   180  func (s *service) ListForObject(ctx context.Context, objectType model.SystemAuthReferenceObjectType, objectID string) ([]model.SystemAuth, error) {
   181  	tnt, err := tenant.LoadFromContext(ctx)
   182  	if err != nil {
   183  		if !model.IsIntegrationSystemNoTenantFlow(err, objectType) {
   184  			return nil, err
   185  		}
   186  	}
   187  
   188  	var systemAuths []model.SystemAuth
   189  
   190  	if objectType == model.IntegrationSystemReference {
   191  		systemAuths, err = s.repo.ListForObjectGlobal(ctx, objectType, objectID)
   192  	} else {
   193  		systemAuths, err = s.repo.ListForObject(ctx, tnt, objectType, objectID)
   194  	}
   195  	if err != nil {
   196  		return nil, errors.Wrapf(err, "while listing System Auths for %s with reference ID '%s'", objectType, objectID)
   197  	}
   198  
   199  	return systemAuths, nil
   200  }
   201  
   202  // DeleteByIDForObject missing godoc
   203  func (s *service) DeleteByIDForObject(ctx context.Context, objectType model.SystemAuthReferenceObjectType, authID string) error {
   204  	tnt, err := tenant.LoadFromContext(ctx)
   205  	if err != nil {
   206  		if !model.IsIntegrationSystemNoTenantFlow(err, objectType) {
   207  			return err
   208  		}
   209  	}
   210  
   211  	if objectType == model.IntegrationSystemReference {
   212  		err = s.repo.DeleteByIDForObjectGlobal(ctx, authID, objectType)
   213  	} else {
   214  		err = s.repo.DeleteByIDForObject(ctx, tnt, authID, objectType)
   215  	}
   216  	if err != nil {
   217  		return errors.Wrapf(err, "while deleting System Auth with ID '%s' for %s", authID, objectType)
   218  	}
   219  
   220  	return nil
   221  }
   222  
   223  // DeleteMultipleByIDForObject Deletes multiple system auths at a time
   224  func (s *service) DeleteMultipleByIDForObject(ctx context.Context, systemAuths []model.SystemAuth) error {
   225  	for _, auth := range systemAuths {
   226  		referenceType, err := auth.GetReferenceObjectType()
   227  		if err != nil {
   228  			return errors.Wrapf(err, "while fetching System Auth reference object type for id '%s'", auth.ID)
   229  		}
   230  		if err := s.DeleteByIDForObject(ctx, referenceType, auth.ID); err != nil {
   231  			return errors.Wrapf(err, "while deleting System Auth with reference object type '%s' and id '%s'", referenceType, auth.ID)
   232  		}
   233  	}
   234  
   235  	return nil
   236  }