@@ -5,11 +5,13 @@ public sealed class ConnectEndpointTests(IntegrationEnvironmentFixture factory)
55{
66 private readonly Fixture _fixture = new ( ) ;
77
8- [ Fact ( DisplayName = "[e2e] - when POST /openid/connect/token with valid realm credentials should return access token" ) ]
9- public async Task WhenPostTokenWithValidRealmCredentials_ShouldReturnAccessToken ( )
8+ [ Fact ( DisplayName = "[e2e] - when POST /openid/connect/token with valid client credentials should return access token" ) ]
9+ public async Task WhenPostTokenWithValidClientCredentials_ShouldReturnAccessToken ( )
1010 {
1111 /* arrange: authenticate user and get access token */
12+ var clientCollection = factory . Services . GetRequiredService < IClientCollection > ( ) ;
1213 var httpClient = factory . HttpClient . WithRealmHeader ( "master" ) ;
14+
1315 var userCredentials = new AuthenticationCredentials
1416 {
1517 Username = "federation.testing.user" ,
@@ -24,35 +26,46 @@ public async Task WhenPostTokenWithValidRealmCredentials_ShouldReturnAccessToken
2426
2527 httpClient . WithAuthorization ( authentication . AccessToken ) ;
2628
27- /* arrange: create a realm to use as client */
28- var payload = _fixture . Build < RealmCreationScheme > ( )
29- . With ( realm => realm . Name , $ "test-realm-{ Guid . NewGuid ( ) } ")
30- . With ( realm => realm . Description , $ "test-description-{ Guid . NewGuid ( ) } ")
29+ /* arrange: create a client */
30+ var payload = _fixture . Build < ClientCreationScheme > ( )
31+ . With ( client => client . Name , "root" )
32+ . With ( client => client . Flows , [ Grant . ClientCredentials ] )
33+ . With ( client => client . RedirectUris , [ ] )
3134 . Create ( ) ;
3235
33- var realmResponse = await httpClient . PostAsJsonAsync ( "api/v1/realms" , payload ) ;
34- var realm = await realmResponse . Content . ReadFromJsonAsync < RealmDetailsScheme > ( ) ;
36+ var response = await httpClient . PostAsJsonAsync ( "api/v1/clients" , payload ) ;
3537
36- Assert . NotNull ( realm ) ;
37- Assert . Equal ( HttpStatusCode . Created , realmResponse . StatusCode ) ;
38+ Assert . NotNull ( response ) ;
39+ Assert . Equal ( HttpStatusCode . Created , response . StatusCode ) ;
40+
41+ var filters = ClientFilters . WithSpecifications ( )
42+ . WithName ( payload . Name )
43+ . Build ( ) ;
44+
45+ var clients = await clientCollection . GetClientsAsync ( filters ) ;
46+ var client = clients . FirstOrDefault ( ) ;
3847
39- /* arrange: prepare client credentials using realm data */
48+ Assert . NotEmpty ( clients ) ;
49+ Assert . NotNull ( client ) ;
50+
51+ /* arrange: prepare client credentials */
4052 var credentials = new Dictionary < string , string >
4153 {
4254 { "grant_type" , "client_credentials" } ,
43- { "client_id" , realm . ClientId } ,
44- { "client_secret" , realm . ClientSecret }
55+ { "client_id" , client . ClientId } ,
56+ { "client_secret" , client . Secret }
4557 } ;
4658
4759 var content = new FormUrlEncodedContent ( credentials ) ;
4860 var connectClient = factory . HttpClient ;
4961
5062 /* act: send POST request to token endpoint */
51- var response = await connectClient . PostAsync ( "api/v1/protocol/open-id/connect/token" , content ) ;
52- var grantedToken = await response . Content . ReadFromJsonAsync < ClientAuthenticationResult > ( ) ;
63+ var httpResponse = await connectClient . PostAsync ( "api/v1/protocol/open-id/connect/token" , content ) ;
64+ var grantedToken = await httpResponse . Content . ReadFromJsonAsync < ClientAuthenticationResult > ( ) ;
5365
5466 /* assert: response should be 200 OK */
55- Assert . Equal ( HttpStatusCode . OK , response . StatusCode ) ;
67+ Assert . Equal ( HttpStatusCode . OK , httpResponse . StatusCode ) ;
68+
5669 Assert . NotNull ( grantedToken ) ;
5770 Assert . False ( string . IsNullOrWhiteSpace ( grantedToken . AccessToken ) ) ;
5871 }
@@ -86,7 +99,9 @@ public async Task WhenPostTokenWithNonExistentClient_ShouldReturnUnauthorized()
8699 public async Task WhenPostTokenWithInvalidClientSecret_ShouldReturnUnauthorized ( )
87100 {
88101 /* arrange: authenticate user and get access token */
102+ var clientCollection = factory . Services . GetRequiredService < IClientCollection > ( ) ;
89103 var httpClient = factory . HttpClient . WithRealmHeader ( "master" ) ;
104+
90105 var userCredentials = new AuthenticationCredentials
91106 {
92107 Username = "federation.testing.user" ,
@@ -100,37 +115,47 @@ public async Task WhenPostTokenWithInvalidClientSecret_ShouldReturnUnauthorized(
100115
101116 httpClient . WithAuthorization ( authentication . AccessToken ) ;
102117
103- /* arrange: create a realm */
104- var payload = _fixture . Build < RealmCreationScheme > ( )
105- . With ( realm => realm . Name , $ "test-realm-{ Guid . NewGuid ( ) } ")
106- . With ( realm => realm . Description , $ "test-description-{ Guid . NewGuid ( ) } ")
118+ /* arrange: create a client */
119+ var payload = _fixture . Build < ClientCreationScheme > ( )
120+ . With ( client => client . Name , "admin" )
121+ . With ( client => client . Flows , [ Grant . ClientCredentials ] )
122+ . With ( client => client . RedirectUris , [ ] )
107123 . Create ( ) ;
108124
109- var httpResponse = await httpClient . PostAsJsonAsync ( "api/v1/realms" , payload ) ;
110- var realm = await httpResponse . Content . ReadFromJsonAsync < RealmDetailsScheme > ( ) ;
125+ var response = await httpClient . PostAsJsonAsync ( "api/v1/clients" , payload ) ;
111126
112- Assert . NotNull ( realm ) ;
127+ Assert . NotNull ( response ) ;
128+ Assert . Equal ( HttpStatusCode . Created , response . StatusCode ) ;
129+
130+ var filters = ClientFilters . WithSpecifications ( )
131+ . WithName ( payload . Name )
132+ . Build ( ) ;
133+
134+ var clients = await clientCollection . GetClientsAsync ( filters ) ;
135+ var client = clients . FirstOrDefault ( ) ;
136+
137+ Assert . NotEmpty ( clients ) ;
138+ Assert . NotNull ( client ) ;
113139
114140 /* arrange: prepare credentials with wrong secret */
115141 var credentials = new Dictionary < string , string >
116142 {
117143 { "grant_type" , "client_credentials" } ,
118- { "client_id" , realm . ClientId } ,
144+ { "client_id" , client . ClientId } ,
119145 { "client_secret" , "wrong-secret" }
120146 } ;
121147
122148 /* act: send POST request with invalid secret */
123-
124149 var content = new FormUrlEncodedContent ( credentials ) ;
125150 var connectClient = factory . HttpClient ;
126151
127- var response = await connectClient . PostAsync ( "api/v1/protocol/open-id/connect/token" , content ) ;
128- var error = await response . Content . ReadFromJsonAsync < Error > ( ) ;
152+ var httpResponse = await connectClient . PostAsync ( "api/v1/protocol/open-id/connect/token" , content ) ;
153+ var error = await httpResponse . Content . ReadFromJsonAsync < Error > ( ) ;
129154
130155 /* assert: response should be 401 Unauthorized */
131156 Assert . NotNull ( error ) ;
132157
133- Assert . Equal ( HttpStatusCode . Unauthorized , response . StatusCode ) ;
158+ Assert . Equal ( HttpStatusCode . Unauthorized , httpResponse . StatusCode ) ;
134159 Assert . Equal ( AuthenticationErrors . InvalidClientCredentials , error ) ;
135160 }
136161
@@ -200,14 +225,16 @@ public async Task WhenPostTokenWithValidAuthorizationCode_ShouldReturnAccessToke
200225 // arrange: resolve required dependencies
201226 var tokenCollection = factory . Services . GetRequiredService < ITokenCollection > ( ) ;
202227 var userCollection = factory . Services . GetRequiredService < IUserCollection > ( ) ;
228+ var clientCollection = factory . Services . GetRequiredService < IClientCollection > ( ) ;
203229
204- // arrange: authenticate as master to create realm
230+ // arrange: authenticate as master to create client and realm
205231 var masterClient = factory . HttpClient . WithRealmHeader ( "master" ) ;
206232 var masterCredentials = new AuthenticationCredentials
207233 {
208234 Username = "federation.testing.user" ,
209235 Password = "federation.testing.password"
210236 } ;
237+
211238 var authentication = await masterClient . PostAsJsonAsync ( "api/v1/identity/authenticate" , masterCredentials ) ;
212239 var grantedToken = await authentication . Content . ReadFromJsonAsync < AuthenticationResult > ( ) ;
213240
@@ -217,17 +244,46 @@ public async Task WhenPostTokenWithValidAuthorizationCode_ShouldReturnAccessToke
217244 masterClient . WithAuthorization ( grantedToken . AccessToken ) ;
218245
219246 // arrange: create realm
220- var payload = _fixture . Build < RealmCreationScheme > ( )
247+ var realmPayload = _fixture . Build < RealmCreationScheme > ( )
221248 . With ( realm => realm . Name , $ "test-realm-{ Guid . NewGuid ( ) } ")
222249 . With ( realm => realm . Description , $ "test-description-{ Guid . NewGuid ( ) } ")
223250 . Create ( ) ;
224251
225- var realmResponse = await masterClient . PostAsJsonAsync ( "api/v1/realms" , payload ) ;
252+ var realmResponse = await masterClient . PostAsJsonAsync ( "api/v1/realms" , realmPayload ) ;
226253 var realm = await realmResponse . Content . ReadFromJsonAsync < RealmDetailsScheme > ( ) ;
227254
228255 Assert . NotNull ( realm ) ;
229256 Assert . Equal ( HttpStatusCode . Created , realmResponse . StatusCode ) ;
230257
258+ // arrange: create client for authorization_code grant
259+ var realmMasterClient = factory . HttpClient . WithRealmHeader ( realm . Name ) ;
260+ var realmAuth = await realmMasterClient . PostAsJsonAsync ( "api/v1/identity/authenticate" , masterCredentials ) ;
261+
262+ var realmAdminClient = factory . HttpClient
263+ . WithRealmHeader ( realm . Name )
264+ . WithAuthorization ( grantedToken . AccessToken ) ;
265+
266+ var payload = _fixture . Build < ClientCreationScheme > ( )
267+ . With ( client => client . Name , "root" )
268+ . With ( client => client . Flows , [ Grant . ClientCredentials ] )
269+ . With ( client => client . RedirectUris , [ ] )
270+ . Create ( ) ;
271+
272+ var httpResponse = await realmAdminClient . PostAsJsonAsync ( "api/v1/clients" , payload ) ;
273+
274+ Assert . NotNull ( httpResponse ) ;
275+ Assert . Equal ( HttpStatusCode . Created , httpResponse . StatusCode ) ;
276+
277+ var clientFilters = ClientFilters . WithSpecifications ( )
278+ . WithName ( payload . Name )
279+ . Build ( ) ;
280+
281+ var clients = await clientCollection . GetClientsAsync ( clientFilters ) ;
282+ var client = clients . FirstOrDefault ( ) ;
283+
284+ Assert . NotEmpty ( clients ) ;
285+ Assert . NotNull ( client ) ;
286+
231287 // arrange: create user for realm
232288 var credentials = new IdentityEnrollmentCredentials
233289 {
@@ -297,7 +353,7 @@ public async Task WhenPostTokenWithValidAuthorizationCode_ShouldReturnAccessToke
297353 {
298354 { "grant_type" , "authorization_code" } ,
299355 { "code" , authorizationCode } ,
300- { "client_id" , realm . ClientId } ,
356+ { "client_id" , client . ClientId } ,
301357 { "code_verifier" , codeVerifier }
302358 } ;
303359
0 commit comments