github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/internal/scopes_sync/service_test.go (about) 1 package scopes 2 3 import ( 4 "context" 5 "testing" 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/internal/domain/oauth20" 12 "github.com/ory/hydra-client-go/models" 13 14 "github.com/kyma-incubator/compass/components/director/internal/repo" 15 "github.com/kyma-incubator/compass/components/director/internal/scopes_sync/automock" 16 "github.com/kyma-incubator/compass/components/director/pkg/persistence/txtest" 17 "github.com/kyma-incubator/compass/components/director/pkg/str" 18 "github.com/pkg/errors" 19 "github.com/stretchr/testify/assert" 20 "github.com/stretchr/testify/mock" 21 ) 22 23 func TestSyncService_UpdateClientScopes(t *testing.T) { 24 const clientID = "client-id" 25 selectCondition := repo.Conditions{ 26 repo.NewNotEqualCondition("(value -> 'Credential' -> 'Oauth')", "null"), 27 } 28 29 t.Run("fails when oauth service cannot list clients", func(t *testing.T) { 30 // GIVEN 31 oauthSvc := &automock.OAuthService{} 32 oauthSvc.On("ListClients").Return(nil, errors.New("error")) 33 scopeSyncSvc := NewService(oauthSvc, nil, &automock.SystemAuthRepo{}) 34 // WHEN 35 err := scopeSyncSvc.SynchronizeClientScopes(context.TODO()) 36 // THEN 37 assert.Error(t, err, "while listing clients from hydra") 38 }) 39 40 t.Run("fails when cannot begin transaction", func(t *testing.T) { 41 // GIVEN 42 oauthSvc := &automock.OAuthService{} 43 oauthSvc.On("ListClients").Return([]*models.OAuth2Client{}, nil) 44 mockedTx, transactioner := txtest.NewTransactionContextGenerator(errors.New("error while transaction begin")).ThatFailsOnBegin() 45 defer mockedTx.AssertExpectations(t) 46 defer transactioner.AssertExpectations(t) 47 defer oauthSvc.AssertExpectations(t) 48 scopeSyncSvc := NewService(oauthSvc, transactioner, &automock.SystemAuthRepo{}) 49 // WHEN 50 err := scopeSyncSvc.SynchronizeClientScopes(context.TODO()) 51 // THEN 52 assert.Error(t, err, "while opening database transaction") 53 }) 54 55 t.Run("fails when cannot list systemAuths", func(t *testing.T) { 56 // GIVEN 57 oauthSvc := &automock.OAuthService{} 58 systemAuthRepo := &automock.SystemAuthRepo{} 59 oauthSvc.On("ListClients").Return([]*models.OAuth2Client{}, nil) 60 mockedTx, transactioner := txtest.NewTransactionContextGenerator(errors.New("error while transaction begin")).ThatDoesntExpectCommit() 61 systemAuthRepo.On("ListGlobalWithConditions", mock.Anything, selectCondition).Return(nil, errors.New("error while listing systemAuths")) 62 defer mockedTx.AssertExpectations(t) 63 defer transactioner.AssertExpectations(t) 64 defer oauthSvc.AssertExpectations(t) 65 scopeSyncSvc := NewService(oauthSvc, transactioner, systemAuthRepo) 66 // WHEN 67 err := scopeSyncSvc.SynchronizeClientScopes(context.TODO()) 68 // THEN 69 assert.Error(t, err, "error while listing systemAuths") 70 }) 71 t.Run("fails when cannot commit transaction", func(t *testing.T) { 72 // GIVEN 73 oauthSvc := &automock.OAuthService{} 74 systemAuthRepo := &automock.SystemAuthRepo{} 75 oauthSvc.On("ListClients").Return([]*models.OAuth2Client{}, nil) 76 mockedTx, transactioner := txtest.NewTransactionContextGenerator(errors.New("error during transaction commit")).ThatFailsOnCommit() 77 systemAuthRepo.On("ListGlobalWithConditions", mock.Anything, selectCondition).Return([]pkgmodel.SystemAuth{}, nil) 78 defer mockedTx.AssertExpectations(t) 79 defer transactioner.AssertExpectations(t) 80 defer oauthSvc.AssertExpectations(t) 81 scopeSyncSvc := NewService(oauthSvc, transactioner, systemAuthRepo) 82 // WHEN 83 err := scopeSyncSvc.SynchronizeClientScopes(context.TODO()) 84 // THEN 85 assert.Error(t, err, "while database transaction commit") 86 }) 87 88 t.Run("won't update client when object type is invalid", func(t *testing.T) { 89 // GIVEN 90 oauthSvc := &automock.OAuthService{} 91 systemAuthRepo := &automock.SystemAuthRepo{} 92 oauthSvc.On("ListClients").Return([]*models.OAuth2Client{}, nil) 93 mockedTx, transactioner := txtest.NewTransactionContextGenerator(errors.New("error")).ThatSucceeds() 94 systemAuthRepo.On("ListGlobalWithConditions", mock.Anything, selectCondition).Return([]pkgmodel.SystemAuth{ 95 { 96 Value: &model.Auth{ 97 Credential: model.CredentialData{ 98 Oauth: &model.OAuthCredentialData{ 99 ClientID: clientID, 100 }, 101 }, 102 }, 103 }, 104 }, nil) 105 defer mockedTx.AssertExpectations(t) 106 defer transactioner.AssertExpectations(t) 107 defer oauthSvc.AssertExpectations(t) 108 scopeSyncSvc := NewService(oauthSvc, transactioner, systemAuthRepo) 109 // WHEN 110 err := scopeSyncSvc.SynchronizeClientScopes(context.TODO()) 111 // THEN 112 assert.EqualError(t, err, "Not all clients were updated successfully") 113 }) 114 115 t.Run("won't update client when getting client credentials scopes fails", func(t *testing.T) { 116 // GIVEN 117 oauthSvc := &automock.OAuthService{} 118 systemAuthRepo := &automock.SystemAuthRepo{} 119 oauthSvc.On("ListClients").Return([]*models.OAuth2Client{}, nil) 120 oauthSvc.On("GetClientDetails", pkgmodel.ApplicationReference).Return(nil, errors.New("error while getting scopes")) 121 mockedTx, transactioner := txtest.NewTransactionContextGenerator(errors.New("error")).ThatSucceeds() 122 systemAuthRepo.On("ListGlobalWithConditions", mock.Anything, selectCondition).Return([]pkgmodel.SystemAuth{ 123 { 124 AppID: str.Ptr("app-id"), 125 Value: &model.Auth{ 126 Credential: model.CredentialData{ 127 Oauth: &model.OAuthCredentialData{ 128 ClientID: clientID, 129 }, 130 }, 131 }, 132 }, 133 }, nil) 134 defer mockedTx.AssertExpectations(t) 135 defer transactioner.AssertExpectations(t) 136 defer oauthSvc.AssertExpectations(t) 137 scopeSyncSvc := NewService(oauthSvc, transactioner, systemAuthRepo) 138 // WHEN 139 err := scopeSyncSvc.SynchronizeClientScopes(context.TODO()) 140 // THEN 141 assert.EqualError(t, err, "Not all clients were updated successfully") 142 }) 143 144 t.Run("won't try to update the client when client is not present in hydra", func(t *testing.T) { 145 // GIVEN 146 oauthSvc := &automock.OAuthService{} 147 systemAuthRepo := &automock.SystemAuthRepo{} 148 oauthSvc.On("ListClients").Return([]*models.OAuth2Client{}, nil) 149 oauthSvc.On("GetClientDetails", pkgmodel.ApplicationReference).Return(&oauth20.ClientDetails{ 150 Scopes: []string{}, 151 GrantTypes: []string{}, 152 }, nil) 153 mockedTx, transactioner := txtest.NewTransactionContextGenerator(errors.New("error")).ThatSucceeds() 154 systemAuthRepo.On("ListGlobalWithConditions", mock.Anything, selectCondition).Return([]pkgmodel.SystemAuth{ 155 { 156 AppID: str.Ptr("app-id"), 157 Value: &model.Auth{ 158 Credential: model.CredentialData{ 159 Oauth: &model.OAuthCredentialData{ 160 ClientID: clientID, 161 }, 162 }, 163 }, 164 }, 165 }, nil) 166 defer mockedTx.AssertExpectations(t) 167 defer transactioner.AssertExpectations(t) 168 defer oauthSvc.AssertExpectations(t) 169 scopeSyncSvc := NewService(oauthSvc, transactioner, systemAuthRepo) 170 // WHEN 171 err := scopeSyncSvc.SynchronizeClientScopes(context.TODO()) 172 // THEN 173 assert.NoError(t, err) 174 }) 175 176 t.Run("won't update scopes if not needed", func(t *testing.T) { 177 // GIVEN 178 oauthSvc := &automock.OAuthService{} 179 systemAuthRepo := &automock.SystemAuthRepo{} 180 oauthSvc.On("ListClients").Return([]*models.OAuth2Client{ 181 { 182 ClientID: clientID, 183 Scope: "scope", 184 }, 185 }, nil) 186 oauthSvc.On("GetClientDetails", pkgmodel.ApplicationReference).Return(&oauth20.ClientDetails{ 187 Scopes: []string{"scope"}, 188 GrantTypes: []string{}, 189 }, nil) 190 mockedTx, transactioner := txtest.NewTransactionContextGenerator(errors.New("error")).ThatSucceeds() 191 systemAuthRepo.On("ListGlobalWithConditions", mock.Anything, selectCondition).Return([]pkgmodel.SystemAuth{ 192 { 193 AppID: str.Ptr("app-id"), 194 Value: &model.Auth{ 195 Credential: model.CredentialData{ 196 Oauth: &model.OAuthCredentialData{ 197 ClientID: clientID, 198 }, 199 }, 200 }, 201 }, 202 }, nil) 203 defer mockedTx.AssertExpectations(t) 204 defer transactioner.AssertExpectations(t) 205 defer oauthSvc.AssertExpectations(t) 206 scopeSyncSvc := NewService(oauthSvc, transactioner, systemAuthRepo) 207 // WHEN 208 err := scopeSyncSvc.SynchronizeClientScopes(context.TODO()) 209 // THEN 210 assert.Nil(t, err) 211 }) 212 213 t.Run("won't update scopes when returned client is not for update", func(t *testing.T) { 214 // GIVEN 215 oauthSvc := &automock.OAuthService{} 216 systemAuthRepo := &automock.SystemAuthRepo{} 217 oauthSvc.On("ListClients").Return([]*models.OAuth2Client{ 218 { 219 ClientID: clientID, 220 Scope: "scope", 221 }, 222 }, nil) 223 mockedTx, transactioner := txtest.NewTransactionContextGenerator(nil).ThatSucceeds() 224 systemAuthRepo.On("ListGlobalWithConditions", mock.Anything, selectCondition).Return([]pkgmodel.SystemAuth{ 225 { 226 AppID: str.Ptr("app-id"), 227 Value: &model.Auth{ 228 Credential: model.CredentialData{}, 229 }, 230 }, 231 }, nil) 232 defer mockedTx.AssertExpectations(t) 233 defer transactioner.AssertExpectations(t) 234 defer oauthSvc.AssertExpectations(t) 235 scopeSyncSvc := NewService(oauthSvc, transactioner, systemAuthRepo) 236 // WHEN 237 err := scopeSyncSvc.SynchronizeClientScopes(context.TODO()) 238 // THEN 239 assert.Nil(t, err) 240 }) 241 242 t.Run("fails when client update in Hydra fails", func(t *testing.T) { 243 // GIVEN 244 oauthSvc := &automock.OAuthService{} 245 systemAuthRepo := &automock.SystemAuthRepo{} 246 oauthSvc.On("ListClients").Return([]*models.OAuth2Client{ 247 { 248 ClientID: clientID, 249 Scope: "first", 250 }, 251 }, nil) 252 oauthSvc.On("GetClientDetails", pkgmodel.ApplicationReference).Return(&oauth20.ClientDetails{ 253 Scopes: []string{"scope"}, 254 GrantTypes: []string{}, 255 }, nil) 256 oauthSvc.On("UpdateClient", mock.Anything, "client-id", pkgmodel.ApplicationReference).Return(errors.New("fail")) 257 mockedTx, transactioner := txtest.NewTransactionContextGenerator(errors.New("error")).ThatSucceeds() 258 systemAuthRepo.On("ListGlobalWithConditions", mock.Anything, selectCondition).Return([]pkgmodel.SystemAuth{ 259 { 260 AppID: str.Ptr("app-id"), 261 Value: &model.Auth{ 262 Credential: model.CredentialData{ 263 Oauth: &model.OAuthCredentialData{ 264 ClientID: clientID, 265 }, 266 }, 267 }, 268 }, 269 }, nil) 270 defer mockedTx.AssertExpectations(t) 271 defer transactioner.AssertExpectations(t) 272 defer oauthSvc.AssertExpectations(t) 273 scopeSyncSvc := NewService(oauthSvc, transactioner, systemAuthRepo) 274 // WHEN 275 err := scopeSyncSvc.SynchronizeClientScopes(context.TODO()) 276 // THEN 277 assert.EqualError(t, err, "Not all clients were updated successfully") 278 }) 279 280 t.Run("will update scopes successfully", func(t *testing.T) { 281 // GIVEN 282 oauthSvc := &automock.OAuthService{} 283 systemAuthRepo := &automock.SystemAuthRepo{} 284 oauthSvc.On("ListClients").Return([]*models.OAuth2Client{ 285 { 286 ClientID: clientID, 287 Scope: "first", 288 }, 289 }, nil) 290 oauthSvc.On("GetClientDetails", pkgmodel.ApplicationReference).Return(&oauth20.ClientDetails{ 291 Scopes: []string{"scope"}, 292 GrantTypes: []string{}, 293 }, nil) 294 oauthSvc.On("UpdateClient", mock.Anything, "client-id", pkgmodel.ApplicationReference).Return(nil) 295 mockedTx, transactioner := txtest.NewTransactionContextGenerator(errors.New("error")).ThatSucceeds() 296 systemAuthRepo.On("ListGlobalWithConditions", mock.Anything, selectCondition).Return([]pkgmodel.SystemAuth{ 297 { 298 AppID: str.Ptr("app-id"), 299 Value: &model.Auth{ 300 Credential: model.CredentialData{ 301 Oauth: &model.OAuthCredentialData{ 302 ClientID: clientID, 303 }, 304 }, 305 }, 306 }, 307 }, nil) 308 defer mockedTx.AssertExpectations(t) 309 defer transactioner.AssertExpectations(t) 310 defer oauthSvc.AssertExpectations(t) 311 scopeSyncSvc := NewService(oauthSvc, transactioner, systemAuthRepo) 312 // WHEN 313 err := scopeSyncSvc.SynchronizeClientScopes(context.TODO()) 314 // THEN 315 assert.Nil(t, err) 316 }) 317 }