Skip to content

Commit

Permalink
feat: Support for token based authentication and addition of helpers …
Browse files Browse the repository at this point in the history
…for organisation apis (#797)

* Handling null pointers when meta info is null in a response

* Add fetcher class under noauth package

* Making token fetch thread safe

* Token re fetch logic implementation

* adding token class files
  • Loading branch information
AsabuHere committed Jun 21, 2024
1 parent 6a77d8c commit b5d7622
Show file tree
Hide file tree
Showing 18 changed files with 627 additions and 147 deletions.
19 changes: 19 additions & 0 deletions examples/BearerTokenAuthentication.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
class BearerTokenAuthenticationExamples {
public static void main {
//Getting access token - Method #1
TwilioOrgsTokenAuth.init(GRANT_TYPE, CLIENT_ID, CLIENT_SECRET);

//Getting access token - Method #2
//To provide custom token manager implementation
//Need not call init method if customer token manager is passed
//TwilioOrgsTokenAuth.setTokenManager(new OrgsTokenManager(grantType, clientId, clientSecret));

fetchAccountDetails();
}

private static void fetchAccountDetails() {
ResourceSet<Account> accountSet = Account.reader(ORGANISATION_ID).read();
String accountSid = accountSet.iterator().next().getAccountSid();
System.out.println(accountSid);
}
}
84 changes: 0 additions & 84 deletions src/main/java/com/twilio/TwilioBearerTokenAuth.java

This file was deleted.

106 changes: 106 additions & 0 deletions src/main/java/com/twilio/TwilioOrgsTokenAuth.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package com.twilio;

import com.twilio.annotations.Preview;
import com.twilio.exception.AuthenticationException;
import com.twilio.http.bearertoken.BearerTokenTwilioRestClient;
import lombok.Getter;
import lombok.Setter;

import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import com.twilio.http.bearertoken.TokenManager;
import com.twilio.http.bearertoken.OrgsTokenManager;

@Preview
public class TwilioOrgsTokenAuth {
private static String accessToken;
@Getter
private static List<String> userAgentExtensions;
private static String region = System.getenv("TWILIO_REGION");
private static String edge = System.getenv("TWILIO_EDGE");
private static volatile BearerTokenTwilioRestClient restClient;
@Getter @Setter
private static TokenManager tokenManager;

private static volatile ExecutorService executorService;

private TwilioOrgsTokenAuth() {
}

public static synchronized void init(String grantType, String clientId, String clientSecret) {
validateAuthCredentials(grantType, clientId, clientSecret);
tokenManager = new OrgsTokenManager(grantType, clientId, clientSecret);
}
public static synchronized void init(String grantType, String clientId, String clientSecret, String code, String redirectUri, String audience, String refreshToken, String scope) {
validateAuthCredentials(grantType, clientId, clientSecret);
tokenManager = new OrgsTokenManager(grantType, clientId, clientSecret, code, redirectUri, audience, refreshToken, scope);
}

private static void validateAuthCredentials(String grantType, String clientId, String clientSecret){
if (grantType == null) {
throw new AuthenticationException("Grant Type cannot be null");
}
if (clientId == null) {
throw new AuthenticationException("Client Id cannot be null");
}
if (clientSecret == null) {
throw new AuthenticationException("Client Secret cannot be null");
}
return;
}

public static BearerTokenTwilioRestClient getRestClient() {
if (TwilioOrgsTokenAuth.restClient == null) {
synchronized (TwilioOrgsTokenAuth.class) {
if (TwilioOrgsTokenAuth.restClient == null) {
TwilioOrgsTokenAuth.restClient = buildOAuthRestClient();
}
}
}
return TwilioOrgsTokenAuth.restClient;
}
/**
* Returns the Twilio executor service.
*
* @return the Twilio executor service
*/
public static ExecutorService getExecutorService() {
if (TwilioOrgsTokenAuth.executorService == null) {
synchronized (TwilioOrgsTokenAuth.class) {
if (TwilioOrgsTokenAuth.executorService == null) {
TwilioOrgsTokenAuth.executorService = Executors.newCachedThreadPool();
}
}
}
return TwilioOrgsTokenAuth.executorService;
}

private static BearerTokenTwilioRestClient buildOAuthRestClient() {

BearerTokenTwilioRestClient.Builder builder = new BearerTokenTwilioRestClient.Builder();

if (userAgentExtensions != null) {
builder.userAgentExtensions(TwilioOrgsTokenAuth.userAgentExtensions);
}

builder.region(TwilioOrgsTokenAuth.region);
builder.edge(TwilioOrgsTokenAuth.edge);
if(TwilioOrgsTokenAuth.tokenManager == null){
throw new AuthenticationException("Either initialize the authentications class or pass a custom token manager");
}
builder.tokenManager(TwilioOrgsTokenAuth.tokenManager);

return builder.build();
}

/**
* Invalidates the volatile state held in the Twilio singleton.
*/
private static void invalidate() {
TwilioOrgsTokenAuth.restClient = null;
TwilioOrgsTokenAuth.tokenManager = null;
}


}
8 changes: 4 additions & 4 deletions src/main/java/com/twilio/base/bearertoken/Creator.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.twilio.base.bearertoken;

import com.twilio.TwilioBearerTokenAuth;
import com.twilio.TwilioOrgsTokenAuth;
import com.twilio.http.bearertoken.BearerTokenTwilioRestClient;

import java.util.concurrent.CompletableFuture;
Expand All @@ -18,7 +18,7 @@ public abstract class Creator<T extends Resource> {
* @return future that resolves to requested object
*/
public CompletableFuture<T> createAsync() {
return createAsync(TwilioBearerTokenAuth.getRestClient());
return createAsync(TwilioOrgsTokenAuth.getRestClient());
}

/**
Expand All @@ -28,7 +28,7 @@ public CompletableFuture<T> createAsync() {
* @return future that resolves to requested object
*/
public CompletableFuture<T> createAsync(final BearerTokenTwilioRestClient client) {
return CompletableFuture.supplyAsync(() -> create(client), TwilioBearerTokenAuth.getExecutorService());
return CompletableFuture.supplyAsync(() -> create(client), TwilioOrgsTokenAuth.getExecutorService());
}

/**
Expand All @@ -37,7 +37,7 @@ public CompletableFuture<T> createAsync(final BearerTokenTwilioRestClient client
* @return Requested object
*/
public T create() {
return create(TwilioBearerTokenAuth.getRestClient());
return create(TwilioOrgsTokenAuth.getRestClient());
}

/**
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/com/twilio/base/bearertoken/Deleter.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.twilio.base.bearertoken;

import com.twilio.Twilio;
import com.twilio.TwilioBearerTokenAuth;
import com.twilio.TwilioOrgsTokenAuth;
import com.twilio.http.bearertoken.BearerTokenTwilioRestClient;

import java.util.concurrent.CompletableFuture;
Expand All @@ -19,7 +19,7 @@ public abstract class Deleter<T extends Resource> {
* @return future that resolves to true if the object was deleted
*/
public CompletableFuture<Boolean> deleteAsync() {
return deleteAsync(TwilioBearerTokenAuth.getRestClient());
return deleteAsync(TwilioOrgsTokenAuth.getRestClient());
}

/**
Expand All @@ -38,7 +38,7 @@ public CompletableFuture<Boolean> deleteAsync(final BearerTokenTwilioRestClient
* @return true if the object was deleted
*/
public boolean delete() {
return delete(TwilioBearerTokenAuth.getRestClient());
return delete(TwilioOrgsTokenAuth.getRestClient());
}

/**
Expand Down
8 changes: 4 additions & 4 deletions src/main/java/com/twilio/base/bearertoken/Fetcher.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.twilio.base.bearertoken;

import com.twilio.TwilioBearerTokenAuth;
import com.twilio.TwilioOrgsTokenAuth;
import com.twilio.http.bearertoken.BearerTokenTwilioRestClient;

import java.util.concurrent.CompletableFuture;
Expand All @@ -18,7 +18,7 @@ public abstract class Fetcher<T extends Resource> {
* @return future that resolves to requested object
*/
public CompletableFuture<T> fetchAsync() {
return fetchAsync(TwilioBearerTokenAuth.getRestClient());
return fetchAsync(TwilioOrgsTokenAuth.getRestClient());
}

/**
Expand All @@ -28,7 +28,7 @@ public CompletableFuture<T> fetchAsync() {
* @return future that resolves to requested object
*/
public CompletableFuture<T> fetchAsync(final BearerTokenTwilioRestClient client) {
return CompletableFuture.supplyAsync(() -> fetch(client), TwilioBearerTokenAuth.getExecutorService());
return CompletableFuture.supplyAsync(() -> fetch(client), TwilioOrgsTokenAuth.getExecutorService());
}

/**
Expand All @@ -37,7 +37,7 @@ public CompletableFuture<T> fetchAsync(final BearerTokenTwilioRestClient client)
* @return Requested object
*/
public T fetch() {
return fetch(TwilioBearerTokenAuth.getRestClient());
return fetch(TwilioOrgsTokenAuth.getRestClient());
}

/**
Expand Down
41 changes: 23 additions & 18 deletions src/main/java/com/twilio/base/bearertoken/Page.java
Original file line number Diff line number Diff line change
Expand Up @@ -169,28 +169,33 @@ private static <T> Page<T> buildPage(JsonNode root, List<T> results) {

private static <T> Page<T> buildNextGenPage(JsonNode root, List<T> results) {
JsonNode meta = root.get("meta");
Builder<T> builder = new Builder<T>().url(meta.get("url").asText());
Builder<T> builder = new Builder<>();
if(meta != null && meta.get("url") != null) {

JsonNode nextPageNode = meta.get("next_page_url");
if (!nextPageNode.isNull()) {
builder.nextPageUrl(nextPageNode.asText());
}
builder = builder.url(meta.get("url").asText());

JsonNode previousPageNode = meta.get("previous_page_url");
if (!previousPageNode.isNull()) {
builder.previousPageUrl(previousPageNode.asText());
}

JsonNode firstPageNode = meta.get("first_page_url");
if (!firstPageNode.isNull()) {
builder.firstPageUrl(firstPageNode.asText());
}
JsonNode nextPageNode = meta.get("next_page_url");
if (!nextPageNode.isNull()) {
builder.nextPageUrl(nextPageNode.asText());
}

JsonNode pageSizeNode = meta.get("page_size");
if (!pageSizeNode.isNull()) {
builder.pageSize(pageSizeNode.asInt());
} else {
builder.pageSize(results.size());
JsonNode previousPageNode = meta.get("previous_page_url");
if (!previousPageNode.isNull()) {
builder.previousPageUrl(previousPageNode.asText());
}

JsonNode firstPageNode = meta.get("first_page_url");
if (!firstPageNode.isNull()) {
builder.firstPageUrl(firstPageNode.asText());
}

JsonNode pageSizeNode = meta.get("page_size");
if (!pageSizeNode.isNull()) {
builder.pageSize(pageSizeNode.asInt());
} else {
builder.pageSize(results.size());
}
}

return builder.records(results).build();
Expand Down
Loading

0 comments on commit b5d7622

Please sign in to comment.