Skip to content

Commit 13069a8

Browse files
committed
Revert "Revert "feat: Support for bearer token authentication and no authentication and PUT method in REST calls (#803)""
This reverts commit 97518df.
1 parent 97518df commit 13069a8

35 files changed

+2372
-331
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,12 @@ public class Example {
125125
}
126126
}
127127
```
128+
### Initialize the client when endpoints does not use basic authentication
129+
The above example shows how to initialize the client in case the endpoints use basic authentication. When the endpoint does not require any authentication, use TwilioNoAuth client instead.
130+
There are endpoints like Organization domain which uses bearer token authentication. Custom Clients needs to be used in such cases and initialize them with the values required for access token generation.
131+
132+
To bypass the initialization step you can also use a custom token manager implementation. Token manager class should implement the Token interface and call a token generation endpoint of your choice.
133+
Detailed examples [here](https://github.com/twilio/twilio-java/tree/main/examples)
128134

129135
### Environment Variables
130136

examples/BearerTokenAuthentication.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
class BearerTokenAuthenticationExamples {
2+
public static void main {
3+
4+
private static final String GRANT_TYPE = "grant_type_to_be_used";
5+
private static final String CLIENT_SID =
6+
"client_id_of_the_organization";
7+
private static final String CLIENT_SECRET = "client_secret_of_organization";
8+
private static final String ORGANISATION_ID = "id_of_the_organization";
9+
10+
//Getting access token - Method #1
11+
TwilioOrgsTokenAuth.init(GRANT_TYPE, CLIENT_ID, CLIENT_SECRET);
12+
13+
//Getting access token - Method #2
14+
//To provide custom token manager implementation
15+
//Need not call init method if customer token manager is passed
16+
//TwilioOrgsTokenAuth.setTokenManager(new CustomTokenManagerImpl(GRANT_TYPE, CLIENT_ID, CLIENT_SECRET));
17+
18+
fetchAccountDetails();
19+
}
20+
21+
private static void fetchAccountDetails() {
22+
ResourceSet<Account> accountSet = Account.reader(ORGANISATION_ID).read();
23+
String accountSid = accountSet.iterator().next().getAccountSid();
24+
System.out.println(accountSid);
25+
}
26+
}

pom.xml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,17 @@
315315
<version>1.10.19</version>
316316
<scope>test</scope>
317317
</dependency>
318+
<dependency>
319+
<groupId>com.auth0</groupId>
320+
<artifactId>java-jwt</artifactId>
321+
<version>4.4.0</version>
322+
<exclusions>
323+
<exclusion>
324+
<groupId>com.fasterxml.jackson.core</groupId>
325+
<artifactId>jackson-databind</artifactId>
326+
</exclusion>
327+
</exclusions>
328+
</dependency>
318329
</dependencies>
319330
<build>
320331
<plugins>

src/main/java/com/twilio/Domains.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ public enum Domains {
3232
NUMBERS("numbers"),
3333
OAUTH("oauth"),
3434
PREVIEW("preview"),
35+
PREVIEWIAM("preview-iam"),
3536
PRICING("pricing"),
3637
PROXY("proxy"),
3738
ROUTES("routes"),
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package com.twilio;
2+
3+
import com.twilio.annotations.Preview;
4+
import com.twilio.http.noauth.NoAuthTwilioRestClient;
5+
import lombok.Getter;
6+
7+
import java.util.List;
8+
import com.twilio.exception.AuthenticationException;
9+
10+
@Preview
11+
public class TwilioNoAuth {
12+
@Getter
13+
private static List<String> userAgentExtensions;
14+
private static String region = System.getenv("TWILIO_REGION");
15+
private static String edge = System.getenv("TWILIO_EDGE");
16+
17+
private static volatile NoAuthTwilioRestClient noAuthTwilioRestClient;
18+
19+
private TwilioNoAuth() {
20+
}
21+
22+
public static NoAuthTwilioRestClient getRestClient() {
23+
if (TwilioNoAuth.noAuthTwilioRestClient == null) {
24+
synchronized (TwilioNoAuth.class) {
25+
if (TwilioNoAuth.noAuthTwilioRestClient == null) {
26+
TwilioNoAuth.noAuthTwilioRestClient = buildOAuthRestClient();
27+
}
28+
}
29+
}
30+
return TwilioNoAuth.noAuthTwilioRestClient;
31+
}
32+
33+
private static NoAuthTwilioRestClient buildOAuthRestClient() {
34+
35+
NoAuthTwilioRestClient.Builder builder = new NoAuthTwilioRestClient.Builder();
36+
37+
if (userAgentExtensions != null) {
38+
builder.userAgentExtensions(TwilioNoAuth.userAgentExtensions);
39+
}
40+
41+
builder.region(TwilioNoAuth.region);
42+
builder.edge(TwilioNoAuth.edge);
43+
44+
return builder.build();
45+
}
46+
47+
48+
}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
package com.twilio;
2+
3+
import com.twilio.annotations.Preview;
4+
import com.twilio.exception.AuthenticationException;
5+
import com.twilio.http.bearertoken.BearerTokenTwilioRestClient;
6+
import lombok.Getter;
7+
import lombok.Setter;
8+
9+
import java.util.List;
10+
import java.util.concurrent.ExecutorService;
11+
import java.util.concurrent.Executors;
12+
import com.twilio.http.bearertoken.TokenManager;
13+
import com.twilio.http.bearertoken.OrgsTokenManager;
14+
15+
@Preview
16+
public class TwilioOrgsTokenAuth {
17+
private static String accessToken;
18+
@Getter
19+
private static List<String> userAgentExtensions;
20+
private static String region = System.getenv("TWILIO_REGION");
21+
private static String edge = System.getenv("TWILIO_EDGE");
22+
private static volatile BearerTokenTwilioRestClient restClient;
23+
@Getter @Setter
24+
private static TokenManager tokenManager;
25+
26+
private static volatile ExecutorService executorService;
27+
28+
private TwilioOrgsTokenAuth() {
29+
}
30+
31+
public static synchronized void init(String grantType, String clientId, String clientSecret) {
32+
validateAuthCredentials(grantType, clientId, clientSecret);
33+
tokenManager = new OrgsTokenManager(grantType, clientId, clientSecret);
34+
}
35+
public static synchronized void init(String grantType, String clientId, String clientSecret, String code, String redirectUri, String audience, String refreshToken, String scope) {
36+
validateAuthCredentials(grantType, clientId, clientSecret);
37+
tokenManager = new OrgsTokenManager(grantType, clientId, clientSecret, code, redirectUri, audience, refreshToken, scope);
38+
}
39+
40+
private static void validateAuthCredentials(String grantType, String clientId, String clientSecret){
41+
if (grantType == null) {
42+
throw new AuthenticationException("Grant Type cannot be null");
43+
}
44+
if (clientId == null) {
45+
throw new AuthenticationException("Client Id cannot be null");
46+
}
47+
if (clientSecret == null) {
48+
throw new AuthenticationException("Client Secret cannot be null");
49+
}
50+
return;
51+
}
52+
53+
public static BearerTokenTwilioRestClient getRestClient() {
54+
if (TwilioOrgsTokenAuth.restClient == null) {
55+
synchronized (TwilioOrgsTokenAuth.class) {
56+
if (TwilioOrgsTokenAuth.restClient == null) {
57+
TwilioOrgsTokenAuth.restClient = buildOAuthRestClient();
58+
}
59+
}
60+
}
61+
return TwilioOrgsTokenAuth.restClient;
62+
}
63+
/**
64+
* Returns the Twilio executor service.
65+
*
66+
* @return the Twilio executor service
67+
*/
68+
public static ExecutorService getExecutorService() {
69+
if (TwilioOrgsTokenAuth.executorService == null) {
70+
synchronized (TwilioOrgsTokenAuth.class) {
71+
if (TwilioOrgsTokenAuth.executorService == null) {
72+
TwilioOrgsTokenAuth.executorService = Executors.newCachedThreadPool();
73+
}
74+
}
75+
}
76+
return TwilioOrgsTokenAuth.executorService;
77+
}
78+
79+
private static BearerTokenTwilioRestClient buildOAuthRestClient() {
80+
81+
BearerTokenTwilioRestClient.Builder builder = new BearerTokenTwilioRestClient.Builder();
82+
83+
if (userAgentExtensions != null) {
84+
builder.userAgentExtensions(TwilioOrgsTokenAuth.userAgentExtensions);
85+
}
86+
87+
builder.region(TwilioOrgsTokenAuth.region);
88+
builder.edge(TwilioOrgsTokenAuth.edge);
89+
if(TwilioOrgsTokenAuth.tokenManager == null){
90+
throw new AuthenticationException("Either initialize the authentications class or pass a custom token manager");
91+
}
92+
builder.tokenManager(TwilioOrgsTokenAuth.tokenManager);
93+
94+
return builder.build();
95+
}
96+
97+
/**
98+
* Invalidates the volatile state held in the Twilio singleton.
99+
*/
100+
private static void invalidate() {
101+
TwilioOrgsTokenAuth.restClient = null;
102+
TwilioOrgsTokenAuth.tokenManager = null;
103+
}
104+
105+
106+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.twilio.annotations;
2+
3+
import java.lang.annotation.*;
4+
5+
@Retention(RetentionPolicy.RUNTIME)
6+
@Target({ElementType.TYPE, ElementType.METHOD})
7+
public @interface Beta {
8+
String value() default "This class/method is under beta and is subjected to change. Use with caution.";
9+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.twilio.annotations;
2+
3+
import java.lang.annotation.ElementType;
4+
import java.lang.annotation.Retention;
5+
import java.lang.annotation.RetentionPolicy;
6+
import java.lang.annotation.Target;
7+
8+
@Retention(RetentionPolicy.RUNTIME)
9+
@Target({ElementType.TYPE, ElementType.METHOD})
10+
public @interface Preview {
11+
String value() default "This class/method is under preview and is subjected to change. Use with caution.";
12+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package com.twilio.base.bearertoken;
2+
3+
import com.twilio.TwilioOrgsTokenAuth;
4+
import com.twilio.http.bearertoken.BearerTokenTwilioRestClient;
5+
6+
import java.util.concurrent.CompletableFuture;
7+
8+
/**
9+
* Executor for creation of a resource.
10+
*
11+
* @param <T> type of the resource
12+
*/
13+
public abstract class Creator<T extends Resource> {
14+
15+
/**
16+
* Execute an async request using default client.
17+
*
18+
* @return future that resolves to requested object
19+
*/
20+
public CompletableFuture<T> createAsync() {
21+
return createAsync(TwilioOrgsTokenAuth.getRestClient());
22+
}
23+
24+
/**
25+
* Execute an async request using specified client.
26+
*
27+
* @param client client used to make request
28+
* @return future that resolves to requested object
29+
*/
30+
public CompletableFuture<T> createAsync(final BearerTokenTwilioRestClient client) {
31+
return CompletableFuture.supplyAsync(() -> create(client), TwilioOrgsTokenAuth.getExecutorService());
32+
}
33+
34+
/**
35+
* Execute a request using default client.
36+
*
37+
* @return Requested object
38+
*/
39+
public T create() {
40+
return create(TwilioOrgsTokenAuth.getRestClient());
41+
}
42+
43+
/**
44+
* Execute a request using specified client.
45+
*
46+
* @param client client used to make request
47+
* @return Requested object
48+
*/
49+
public abstract T create(final BearerTokenTwilioRestClient client);
50+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package com.twilio.base.bearertoken;
2+
3+
import com.twilio.Twilio;
4+
import com.twilio.TwilioOrgsTokenAuth;
5+
import com.twilio.http.bearertoken.BearerTokenTwilioRestClient;
6+
7+
import java.util.concurrent.CompletableFuture;
8+
9+
/**
10+
* Executor for deletes of a resource.
11+
*
12+
* @param <T> type of the resource
13+
*/
14+
public abstract class Deleter<T extends Resource> {
15+
16+
/**
17+
* Execute an async request using default client.
18+
*
19+
* @return future that resolves to true if the object was deleted
20+
*/
21+
public CompletableFuture<Boolean> deleteAsync() {
22+
return deleteAsync(TwilioOrgsTokenAuth.getRestClient());
23+
}
24+
25+
/**
26+
* Execute an async request using specified client.
27+
*
28+
* @param client client used to make request
29+
* @return future that resolves to true if the object was deleted
30+
*/
31+
public CompletableFuture<Boolean> deleteAsync(final BearerTokenTwilioRestClient client) {
32+
return CompletableFuture.supplyAsync(() -> delete(client), Twilio.getExecutorService());
33+
}
34+
35+
/**
36+
* Execute a request using default client.
37+
*
38+
* @return true if the object was deleted
39+
*/
40+
public boolean delete() {
41+
return delete(TwilioOrgsTokenAuth.getRestClient());
42+
}
43+
44+
/**
45+
* Execute a request using specified client.
46+
*
47+
* @param client client used to make request
48+
* @return true if the object was deleted
49+
*/
50+
public abstract boolean delete(final BearerTokenTwilioRestClient client);
51+
}

0 commit comments

Comments
 (0)