github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/internal/domain/oauth20/resolver.go (about) 1 package oauth20 2 3 import ( 4 "context" 5 "fmt" 6 7 "github.com/kyma-incubator/compass/components/director/internal/model" 8 9 pkgmodel "github.com/kyma-incubator/compass/components/director/pkg/model" 10 11 "github.com/kyma-incubator/compass/components/director/pkg/log" 12 13 "github.com/kyma-incubator/compass/components/director/pkg/apperrors" 14 15 "github.com/hashicorp/go-multierror" 16 17 "github.com/kyma-incubator/compass/components/director/pkg/graphql" 18 "github.com/kyma-incubator/compass/components/director/pkg/persistence" 19 "github.com/pkg/errors" 20 ) 21 22 // SystemAuthService missing godoc 23 //go:generate mockery --name=SystemAuthService --output=automock --outpkg=automock --case=underscore --disable-version-string 24 type SystemAuthService interface { 25 CreateWithCustomID(ctx context.Context, id string, objectType pkgmodel.SystemAuthReferenceObjectType, objectID string, authInput *model.AuthInput) (string, error) 26 GetByIDForObject(ctx context.Context, objectType pkgmodel.SystemAuthReferenceObjectType, authID string) (*pkgmodel.SystemAuth, error) 27 } 28 29 // ApplicationService missing godoc 30 //go:generate mockery --name=ApplicationService --output=automock --outpkg=automock --case=underscore --disable-version-string 31 type ApplicationService interface { 32 Exist(ctx context.Context, id string) (bool, error) 33 } 34 35 // RuntimeService missing godoc 36 //go:generate mockery --name=RuntimeService --output=automock --outpkg=automock --case=underscore --disable-version-string 37 type RuntimeService interface { 38 Exist(ctx context.Context, id string) (bool, error) 39 } 40 41 // IntegrationSystemService missing godoc 42 //go:generate mockery --name=IntegrationSystemService --output=automock --outpkg=automock --case=underscore --disable-version-string 43 type IntegrationSystemService interface { 44 Exists(ctx context.Context, id string) (bool, error) 45 } 46 47 // SystemAuthConverter missing godoc 48 //go:generate mockery --name=SystemAuthConverter --output=automock --outpkg=automock --case=underscore --disable-version-string 49 type SystemAuthConverter interface { 50 ToGraphQL(model *pkgmodel.SystemAuth) (graphql.SystemAuth, error) 51 } 52 53 // Service missing godoc 54 //go:generate mockery --name=Service --output=automock --outpkg=automock --case=underscore --disable-version-string 55 type Service interface { 56 CreateClientCredentials(ctx context.Context, objectType pkgmodel.SystemAuthReferenceObjectType) (*model.OAuthCredentialDataInput, error) 57 DeleteClientCredentials(ctx context.Context, clientID string) error 58 } 59 60 // Resolver missing godoc 61 type Resolver struct { 62 transact persistence.Transactioner 63 svc Service 64 systemAuthSvc SystemAuthService 65 systemAuthConv SystemAuthConverter 66 appSvc ApplicationService 67 rtmSvc RuntimeService 68 isSvc IntegrationSystemService 69 } 70 71 // NewResolver missing godoc 72 func NewResolver(transactioner persistence.Transactioner, svc Service, appSvc ApplicationService, rtmSvc RuntimeService, isSvc IntegrationSystemService, systemAuthSvc SystemAuthService, systemAuthConv SystemAuthConverter) *Resolver { 73 return &Resolver{transact: transactioner, svc: svc, appSvc: appSvc, rtmSvc: rtmSvc, systemAuthSvc: systemAuthSvc, isSvc: isSvc, systemAuthConv: systemAuthConv} 74 } 75 76 // RequestClientCredentialsForRuntime missing godoc 77 func (r *Resolver) RequestClientCredentialsForRuntime(ctx context.Context, id string) (graphql.SystemAuth, error) { 78 return r.generateClientCredentials(ctx, pkgmodel.RuntimeReference, id) 79 } 80 81 // RequestClientCredentialsForApplication missing godoc 82 func (r *Resolver) RequestClientCredentialsForApplication(ctx context.Context, id string) (graphql.SystemAuth, error) { 83 return r.generateClientCredentials(ctx, pkgmodel.ApplicationReference, id) 84 } 85 86 // RequestClientCredentialsForIntegrationSystem missing godoc 87 func (r *Resolver) RequestClientCredentialsForIntegrationSystem(ctx context.Context, id string) (graphql.SystemAuth, error) { 88 return r.generateClientCredentials(ctx, pkgmodel.IntegrationSystemReference, id) 89 } 90 91 func (r *Resolver) generateClientCredentials(ctx context.Context, objType pkgmodel.SystemAuthReferenceObjectType, objID string) (graphql.SystemAuth, error) { 92 tx, err := r.transact.Begin() 93 if err != nil { 94 return nil, err 95 } 96 defer r.transact.RollbackUnlessCommitted(ctx, tx) 97 98 log.C(ctx).Infof("Requesting creation of client credentials for %s with id %s", objType, objID) 99 ctx = persistence.SaveToContext(ctx, tx) 100 101 exists, err := r.checkObjectExist(ctx, objType, objID) 102 if err != nil { 103 return nil, errors.Wrapf(err, "while checking if %s with ID '%s' exists", objType, objID) 104 } 105 if !exists { 106 return nil, fmt.Errorf("%s with ID '%s' not found", objType, objID) 107 } 108 109 log.C(ctx).Debugf("Generating client credentials for %s with id %s by Director", objType, objID) 110 clientCreds, err := r.svc.CreateClientCredentials(ctx, objType) 111 if err != nil { 112 return nil, errors.Wrapf(err, "while creating client credentials for %s with id %s", objType, objID) 113 } 114 if clientCreds == nil { 115 return nil, apperrors.NewInvalidDataError("client credentials cannot be empty") 116 } 117 log.C(ctx).Debugf("Client credentials for %s with id %s are successfully generated by Director", objType, objID) 118 cleanupOnError := func(originalErr error) error { 119 cleanupErr := r.svc.DeleteClientCredentials(ctx, clientCreds.ClientID) 120 if cleanupErr != nil { 121 return multierror.Append(err, cleanupErr) 122 } 123 124 return originalErr 125 } 126 127 id := clientCreds.ClientID 128 log.C(ctx).Debugf("Creating SystemAuth for the client credentials for %s with id %s", objType, objID) 129 _, err = r.systemAuthSvc.CreateWithCustomID(ctx, id, objType, objID, &model.AuthInput{ 130 Credential: &model.CredentialDataInput{ 131 Oauth: clientCreds, 132 }, 133 }) 134 if err != nil { 135 finalErr := cleanupOnError(err) 136 return nil, errors.Wrapf(finalErr, "error occurred while creating SystemAuth for %s with id %s", objType, objID) 137 } 138 log.C(ctx).Debugf("Successfully created SystemAuth for the client credentials for %s with id %s", objType, objID) 139 140 sysAuth, err := r.systemAuthSvc.GetByIDForObject(ctx, objType, id) 141 if err != nil { 142 finalErr := cleanupOnError(err) 143 return nil, finalErr 144 } 145 146 err = tx.Commit() 147 if err != nil { 148 finalErr := cleanupOnError(err) 149 return nil, finalErr 150 } 151 152 log.C(ctx).Infof("Successfully created client credentials with client_id %s for %s with id %s", id, objType, objID) 153 return r.systemAuthConv.ToGraphQL(sysAuth) 154 } 155 156 func (r *Resolver) checkObjectExist(ctx context.Context, objType pkgmodel.SystemAuthReferenceObjectType, objID string) (bool, error) { 157 switch objType { 158 case pkgmodel.RuntimeReference: 159 return r.rtmSvc.Exist(ctx, objID) 160 case pkgmodel.ApplicationReference: 161 return r.appSvc.Exist(ctx, objID) 162 case pkgmodel.IntegrationSystemReference: 163 return r.isSvc.Exists(ctx, objID) 164 } 165 166 return false, fmt.Errorf("invalid object type %s", objType) 167 }