Skip to content

Commit f375b6d

Browse files
authored
Reduce verbosity of use.authentications(...) DSL for OAuth2/OIDC (#1513)
* Reduce verbosity of use.authentications(...) DSL for OAuth2/OIDC Signed-off-by: Matheus Cruz <matheuscruz.dev@gmail.com> * Delegate UseAuthenticationsBuilder oidc/oauth2 shorthands to DSL helpers Signed-off-by: Matheus Cruz <matheuscruz.dev@gmail.com> --------- Signed-off-by: Matheus Cruz <matheuscruz.dev@gmail.com>
1 parent b0d9e6a commit f375b6d

2 files changed

Lines changed: 374 additions & 0 deletions

File tree

fluent/spec/src/main/java/io/serverlessworkflow/fluent/spec/UseAuthenticationsBuilder.java

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@
1515
*/
1616
package io.serverlessworkflow.fluent.spec;
1717

18+
import io.serverlessworkflow.api.types.OAuth2AuthenticationData;
1819
import io.serverlessworkflow.api.types.UseAuthentications;
20+
import io.serverlessworkflow.fluent.spec.OAuth2AuthenticationPolicyBuilder.OAuth2AuthenticationPropertiesEndpointsBuilder;
21+
import io.serverlessworkflow.fluent.spec.dsl.DSL;
1922
import java.util.function.Consumer;
2023

2124
public class UseAuthenticationsBuilder {
@@ -35,6 +38,56 @@ public UseAuthenticationsBuilder authentication(
3538
return this;
3639
}
3740

41+
public UseAuthenticationsBuilder basic(String name, String username, String password) {
42+
return authentication(name, DSL.basic(username, password));
43+
}
44+
45+
public UseAuthenticationsBuilder bearer(String name, String token) {
46+
return authentication(name, DSL.bearer(token));
47+
}
48+
49+
public UseAuthenticationsBuilder digest(String name, String username, String password) {
50+
return authentication(name, DSL.digest(username, password));
51+
}
52+
53+
public UseAuthenticationsBuilder oidc(
54+
String name, String authority, OAuth2AuthenticationData.OAuth2AuthenticationDataGrant grant) {
55+
return authentication(name, DSL.oidc(authority, grant));
56+
}
57+
58+
public UseAuthenticationsBuilder oidc(
59+
String name,
60+
String authority,
61+
OAuth2AuthenticationData.OAuth2AuthenticationDataGrant grant,
62+
String clientId,
63+
String clientSecret) {
64+
return authentication(name, DSL.oidc(authority, grant, clientId, clientSecret));
65+
}
66+
67+
public UseAuthenticationsBuilder oauth2(
68+
String name,
69+
String authority,
70+
OAuth2AuthenticationData.OAuth2AuthenticationDataGrant grant,
71+
String clientId,
72+
String clientSecret) {
73+
return oidc(name, authority, grant, clientId, clientSecret);
74+
}
75+
76+
public UseAuthenticationsBuilder oauth2(
77+
String name,
78+
String authority,
79+
OAuth2AuthenticationData.OAuth2AuthenticationDataGrant grant,
80+
String clientId,
81+
String clientSecret,
82+
Consumer<OAuth2AuthenticationPropertiesEndpointsBuilder> endpoints) {
83+
return authentication(name, DSL.oauth2(authority, grant, clientId, clientSecret, endpoints));
84+
}
85+
86+
public UseAuthenticationsBuilder oauth2(
87+
String name, Consumer<OAuth2AuthenticationPolicyBuilder> configurer) {
88+
return authentication(name, a -> a.oauth2(configurer));
89+
}
90+
3891
public UseAuthentications build() {
3992
return authentication;
4093
}
Lines changed: 321 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,321 @@
1+
/*
2+
* Copyright 2020-Present The Serverless Workflow Specification Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.serverlessworkflow.fluent.spec;
17+
18+
import static org.assertj.core.api.Assertions.assertThat;
19+
20+
import io.serverlessworkflow.api.types.AuthenticationPolicyUnion;
21+
import io.serverlessworkflow.api.types.OAuth2AuthenticationData.OAuth2AuthenticationDataGrant;
22+
import io.serverlessworkflow.api.types.UseAuthentications;
23+
import io.serverlessworkflow.api.types.Workflow;
24+
import java.net.URI;
25+
import org.junit.jupiter.api.Test;
26+
27+
public class UseAuthenticationsBuilderTest {
28+
29+
@Test
30+
void basic_shorthand_creates_basic_policy() {
31+
Workflow wf =
32+
WorkflowBuilder.workflow("f")
33+
.use(u -> u.authentications(a -> a.basic("myBasic", "admin", "secret")))
34+
.build();
35+
36+
UseAuthentications auths = wf.getUse().getAuthentications();
37+
AuthenticationPolicyUnion union = auths.getAdditionalProperties().get("myBasic");
38+
assertThat(union).isNotNull();
39+
assertThat(union.getBasicAuthenticationPolicy()).isNotNull();
40+
41+
var props = union.getBasicAuthenticationPolicy().getBasic().getBasicAuthenticationProperties();
42+
assertThat(props.getUsername()).isEqualTo("admin");
43+
assertThat(props.getPassword()).isEqualTo("secret");
44+
}
45+
46+
@Test
47+
void bearer_shorthand_creates_bearer_policy() {
48+
Workflow wf =
49+
WorkflowBuilder.workflow("f")
50+
.use(u -> u.authentications(a -> a.bearer("myBearer", "token-xyz")))
51+
.build();
52+
53+
AuthenticationPolicyUnion union =
54+
wf.getUse().getAuthentications().getAdditionalProperties().get("myBearer");
55+
assertThat(union).isNotNull();
56+
assertThat(union.getBearerAuthenticationPolicy()).isNotNull();
57+
assertThat(
58+
union
59+
.getBearerAuthenticationPolicy()
60+
.getBearer()
61+
.getBearerAuthenticationProperties()
62+
.getToken())
63+
.isEqualTo("token-xyz");
64+
}
65+
66+
@Test
67+
void digest_shorthand_creates_digest_policy() {
68+
Workflow wf =
69+
WorkflowBuilder.workflow("f")
70+
.use(u -> u.authentications(a -> a.digest("myDigest", "user", "p@ss")))
71+
.build();
72+
73+
AuthenticationPolicyUnion union =
74+
wf.getUse().getAuthentications().getAdditionalProperties().get("myDigest");
75+
assertThat(union).isNotNull();
76+
assertThat(union.getDigestAuthenticationPolicy()).isNotNull();
77+
78+
var props =
79+
union.getDigestAuthenticationPolicy().getDigest().getDigestAuthenticationProperties();
80+
assertThat(props.getUsername()).isEqualTo("user");
81+
assertThat(props.getPassword()).isEqualTo("p@ss");
82+
}
83+
84+
@Test
85+
void oidc_shorthand_without_client_creates_oidc_policy() {
86+
Workflow wf =
87+
WorkflowBuilder.workflow("f")
88+
.use(
89+
u ->
90+
u.authentications(
91+
a ->
92+
a.oidc(
93+
"myOidc",
94+
"https://auth.example.com/",
95+
OAuth2AuthenticationDataGrant.CLIENT_CREDENTIALS)))
96+
.build();
97+
98+
AuthenticationPolicyUnion union =
99+
wf.getUse().getAuthentications().getAdditionalProperties().get("myOidc");
100+
assertThat(union).isNotNull();
101+
assertThat(union.getOpenIdConnectAuthenticationPolicy()).isNotNull();
102+
103+
var props =
104+
union
105+
.getOpenIdConnectAuthenticationPolicy()
106+
.getOidc()
107+
.getOpenIdConnectAuthenticationProperties();
108+
assertThat(props.getAuthority().getLiteralUri())
109+
.isEqualTo(URI.create("https://auth.example.com/"));
110+
assertThat(props.getGrant()).isEqualTo(OAuth2AuthenticationDataGrant.CLIENT_CREDENTIALS);
111+
assertThat(props.getClient()).isNull();
112+
}
113+
114+
@Test
115+
void oidc_shorthand_with_client_creates_oidc_policy() {
116+
Workflow wf =
117+
WorkflowBuilder.workflow("f")
118+
.use(
119+
u ->
120+
u.authentications(
121+
a ->
122+
a.oidc(
123+
"myOidc",
124+
"https://auth.example.com/",
125+
OAuth2AuthenticationDataGrant.CLIENT_CREDENTIALS,
126+
"client-id",
127+
"client-secret")))
128+
.build();
129+
130+
AuthenticationPolicyUnion union =
131+
wf.getUse().getAuthentications().getAdditionalProperties().get("myOidc");
132+
assertThat(union).isNotNull();
133+
assertThat(union.getOpenIdConnectAuthenticationPolicy()).isNotNull();
134+
135+
var props =
136+
union
137+
.getOpenIdConnectAuthenticationPolicy()
138+
.getOidc()
139+
.getOpenIdConnectAuthenticationProperties();
140+
assertThat(props.getAuthority().getLiteralUri())
141+
.isEqualTo(URI.create("https://auth.example.com/"));
142+
assertThat(props.getGrant()).isEqualTo(OAuth2AuthenticationDataGrant.CLIENT_CREDENTIALS);
143+
assertThat(props.getClient().getId()).isEqualTo("client-id");
144+
assertThat(props.getClient().getSecret()).isEqualTo("client-secret");
145+
}
146+
147+
@Test
148+
void oauth2_shorthand_with_client_creates_oidc_policy() {
149+
Workflow wf =
150+
WorkflowBuilder.workflow("f")
151+
.use(
152+
u ->
153+
u.authentications(
154+
a ->
155+
a.oauth2(
156+
"myAuth",
157+
"https://auth.example.com/",
158+
OAuth2AuthenticationDataGrant.CLIENT_CREDENTIALS,
159+
"cid",
160+
"csecret")))
161+
.build();
162+
163+
AuthenticationPolicyUnion union =
164+
wf.getUse().getAuthentications().getAdditionalProperties().get("myAuth");
165+
assertThat(union).isNotNull();
166+
assertThat(union.getOpenIdConnectAuthenticationPolicy()).isNotNull();
167+
168+
var props =
169+
union
170+
.getOpenIdConnectAuthenticationPolicy()
171+
.getOidc()
172+
.getOpenIdConnectAuthenticationProperties();
173+
assertThat(props.getAuthority().getLiteralUri())
174+
.isEqualTo(URI.create("https://auth.example.com/"));
175+
assertThat(props.getGrant()).isEqualTo(OAuth2AuthenticationDataGrant.CLIENT_CREDENTIALS);
176+
assertThat(props.getClient().getId()).isEqualTo("cid");
177+
assertThat(props.getClient().getSecret()).isEqualTo("csecret");
178+
}
179+
180+
@Test
181+
void oauth2_shorthand_with_custom_endpoints() {
182+
Workflow wf =
183+
WorkflowBuilder.workflow("f")
184+
.use(
185+
u ->
186+
u.authentications(
187+
a ->
188+
a.oauth2(
189+
"myAuth",
190+
"https://auth.example.com/",
191+
OAuth2AuthenticationDataGrant.CLIENT_CREDENTIALS,
192+
"cid",
193+
"csecret",
194+
e -> e.token("/custom/token"))))
195+
.build();
196+
197+
AuthenticationPolicyUnion union =
198+
wf.getUse().getAuthentications().getAdditionalProperties().get("myAuth");
199+
assertThat(union).isNotNull();
200+
assertThat(union.getOAuth2AuthenticationPolicy()).isNotNull();
201+
202+
var props =
203+
union
204+
.getOAuth2AuthenticationPolicy()
205+
.getOauth2()
206+
.getOAuth2ConnectAuthenticationProperties();
207+
assertThat(props.getAuthority().getLiteralUri())
208+
.isEqualTo(URI.create("https://auth.example.com/"));
209+
assertThat(props.getGrant()).isEqualTo(OAuth2AuthenticationDataGrant.CLIENT_CREDENTIALS);
210+
assertThat(props.getClient().getId()).isEqualTo("cid");
211+
assertThat(props.getClient().getSecret()).isEqualTo("csecret");
212+
assertThat(props.getEndpoints().getToken()).isEqualTo("/custom/token");
213+
}
214+
215+
@Test
216+
void oauth2_full_builder_shorthand() {
217+
Workflow wf =
218+
WorkflowBuilder.workflow("f")
219+
.use(
220+
u ->
221+
u.authentications(
222+
a ->
223+
a.oauth2(
224+
"myAuth",
225+
o ->
226+
o.endpoints(e -> e.token("/t").revocation("/r"))
227+
.authority("https://auth.example.com/")
228+
.grant(OAuth2AuthenticationDataGrant.CLIENT_CREDENTIALS)
229+
.scopes("read", "write")
230+
.client(c -> c.id("cid").secret("csecret")))))
231+
.build();
232+
233+
AuthenticationPolicyUnion union =
234+
wf.getUse().getAuthentications().getAdditionalProperties().get("myAuth");
235+
assertThat(union).isNotNull();
236+
assertThat(union.getOAuth2AuthenticationPolicy()).isNotNull();
237+
238+
var props =
239+
union
240+
.getOAuth2AuthenticationPolicy()
241+
.getOauth2()
242+
.getOAuth2ConnectAuthenticationProperties();
243+
assertThat(props.getAuthority().getLiteralUri())
244+
.isEqualTo(URI.create("https://auth.example.com/"));
245+
assertThat(props.getEndpoints().getToken()).isEqualTo("/t");
246+
assertThat(props.getEndpoints().getRevocation()).isEqualTo("/r");
247+
assertThat(props.getScopes()).containsExactly("read", "write");
248+
}
249+
250+
@Test
251+
void multiple_named_authentications_via_chaining() {
252+
Workflow wf =
253+
WorkflowBuilder.workflow("f")
254+
.use(
255+
u ->
256+
u.authentications(
257+
a ->
258+
a.oauth2(
259+
"joogle",
260+
"https://joogle.example.com/",
261+
OAuth2AuthenticationDataGrant.CLIENT_CREDENTIALS,
262+
"joogle-id",
263+
"joogle-secret")
264+
.oauth2(
265+
"jahoo",
266+
"https://jahoo.example.com/",
267+
OAuth2AuthenticationDataGrant.CLIENT_CREDENTIALS,
268+
"jahoo-id",
269+
"jahoo-secret")))
270+
.build();
271+
272+
UseAuthentications auths = wf.getUse().getAuthentications();
273+
assertThat(auths.getAdditionalProperties()).hasSize(2);
274+
assertThat(auths.getAdditionalProperties()).containsKeys("joogle", "jahoo");
275+
276+
var joogleProps =
277+
auths
278+
.getAdditionalProperties()
279+
.get("joogle")
280+
.getOpenIdConnectAuthenticationPolicy()
281+
.getOidc()
282+
.getOpenIdConnectAuthenticationProperties();
283+
assertThat(joogleProps.getClient().getId()).isEqualTo("joogle-id");
284+
285+
var jahooProps =
286+
auths
287+
.getAdditionalProperties()
288+
.get("jahoo")
289+
.getOpenIdConnectAuthenticationPolicy()
290+
.getOidc()
291+
.getOpenIdConnectAuthenticationProperties();
292+
assertThat(jahooProps.getClient().getId()).isEqualTo("jahoo-id");
293+
}
294+
295+
@Test
296+
void mixed_auth_types_via_chaining() {
297+
Workflow wf =
298+
WorkflowBuilder.workflow("f")
299+
.use(
300+
u ->
301+
u.authentications(
302+
a ->
303+
a.basic("b", "user", "pass")
304+
.bearer("t", "token-123")
305+
.oauth2(
306+
"o",
307+
"https://auth.example.com/",
308+
OAuth2AuthenticationDataGrant.CLIENT_CREDENTIALS,
309+
"cid",
310+
"csecret")))
311+
.build();
312+
313+
UseAuthentications auths = wf.getUse().getAuthentications();
314+
assertThat(auths.getAdditionalProperties()).hasSize(3);
315+
assertThat(auths.getAdditionalProperties().get("b").getBasicAuthenticationPolicy()).isNotNull();
316+
assertThat(auths.getAdditionalProperties().get("t").getBearerAuthenticationPolicy())
317+
.isNotNull();
318+
assertThat(auths.getAdditionalProperties().get("o").getOpenIdConnectAuthenticationPolicy())
319+
.isNotNull();
320+
}
321+
}

0 commit comments

Comments
 (0)