-
Notifications
You must be signed in to change notification settings - Fork 427
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Support for token based authentication and addition of helpers for organisation apis #797
Conversation
@AsabuHere Rest Proxy supports 2 types of pagination. |
This is not addition of a new pagination mechanism. This is just handling of a null pointer issue. When meta is not present, the sdk is breaking, to prevent that added a check to verify if meta is null or not before actually using it |
import com.twilio.Twilio; | ||
|
||
import com.twilio.TwilioNoAuth; | ||
import com.twilio.base.Resource; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Create separate Resource for noauth and create all api files
@AsabuHere We also need an example of how the auth token based authentication apis will be called via the client /customer. Could you please add an example here |
|
||
private static volatile ExecutorService executorService; | ||
|
||
private TwilioBearerTokenAuth() { | ||
} | ||
|
||
public static synchronized void init(final String accessToken) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are we expecting the client to first create a token manager and then pass it here. We should just collect all the info from the client need to initialize and internally create/set the tokenManger if needed
Added |
added |
src/main/java/com/twilio/http/bearertoken/BearerTokenTwilioRestClient.java
Outdated
Show resolved
Hide resolved
src/main/java/com/twilio/http/bearertoken/BearerTokenTwilioRestClient.java
Outdated
Show resolved
Hide resolved
@Setter | ||
private final String grantType; | ||
private final String clientId; | ||
private final String clientSecret; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lets add all fields to this class which /v1/token api has.
|
||
@Override | ||
public String refreshAccessToken(String refreshToken){ | ||
Token token = Token.creator(grantType, clientId).setClientSecret(refreshToken).create(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no concept of refresh token now for client credential. Remove this.
class BearerTokenAuthenticationExamples { | ||
public static void main { | ||
//Getting access token | ||
TokenManager tokenManager = new TokenManagerImpl(GRANT_TYPE, CLIENT_ID, CLIENT_SECRET); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As we discussion on call, Customer don't need to initialise 'TokenManagerImpl', SDK will do it without customer intervention.
@@ -69,6 +69,7 @@ private static BearerTokenTwilioRestClient buildOAuthRestClient() { | |||
|
|||
builder.region(TwilioBearerTokenAuth.region); | |||
builder.edge(TwilioBearerTokenAuth.edge); | |||
builder.tokenManager(TwilioBearerTokenAuth.tokenManager); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should not be taking tokenManager from customer, SDK should be taking following inputs from customer clientId, clientSecret, grantType from customer.
Above are mandatory.
So there would be 2 constructors
- clientId, clientSecret, grantType
- clientId, clientSecret, grantType and other variables which are not mandatory.
src/main/java/com/twilio/http/bearertoken/BearerTokenTwilioRestClient.java
Outdated
Show resolved
Hide resolved
@@ -119,9 +128,15 @@ public Response request(BearerTokenRequest request) { | |||
} | |||
logRequest(request); | |||
Response response = httpClient.reliableRequest(request); | |||
int statusCode = response.getStatusCode(); | |||
if(statusCode == 401){ | |||
this.accessToken = tokenManager.fetchAccessToken(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you test a scenario where fetching of access token is failed.
In my opinion TokenCreator will throw the exception and that will be propagated to orgs api, will that be good, propagating one api exception to another api ?
We should do some handling in TokenManager implementation class.
Logging need to be done otherwise during debugging we won't know which API call failed.
You can think and then we can also discuss on this.
src/main/java/com/twilio/rest/previewiam/organizations/TokenCreator.java
Show resolved
Hide resolved
@@ -119,9 +128,15 @@ public Response request(BearerTokenRequest request) { | |||
} | |||
logRequest(request); | |||
Response response = httpClient.reliableRequest(request); | |||
int statusCode = response.getStatusCode(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there will be scenario where response is null, we have to handle that as well.
@@ -119,9 +128,15 @@ public Response request(BearerTokenRequest request) { | |||
} | |||
logRequest(request); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
During request logging SDK is printing key of authorization which will be equal to "Bearer actual_token_value"
So in short token is getting logged, which shouldn't be logged.
Can you make sure that clientSecret and token is not logged anywhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You might need to override logRequest method in accordance to bearer token request.
@@ -61,6 +64,7 @@ public static class Builder { | |||
private String edge; | |||
private HttpClient httpClient; | |||
private List<String> userAgentExtensions; | |||
private TokenManager tokenManager; | |||
|
|||
public Builder(String accessToken) { | |||
this.accessToken = accessToken; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
access token setting needs to be removed from here.
@@ -47,6 +49,7 @@ private BearerTokenTwilioRestClient(BearerTokenTwilioRestClient.Builder b) { | |||
this.httpClient = b.httpClient; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
access token needs to be removed from here as well.
… on auto generation
… on auto generation
|
||
if (userAgentExtensions != null) { | ||
builder.userAgentExtensions(TwilioBearerTokenAuth.userAgentExtensions); | ||
} | ||
|
||
builder.region(TwilioBearerTokenAuth.region); | ||
builder.edge(TwilioBearerTokenAuth.edge); | ||
builder.tokenManager(TwilioBearerTokenAuth.tokenManager); | ||
builder.tokenManager(TwilioBearerTokenAuth.tokenManager); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line of code is written twice, one line can be removed.
throw new AuthenticationException("Access Token is expired."); | ||
|
||
if (accessToken == null || accessToken.isEmpty() || isTokenExpired(this.accessToken)) { | ||
this.accessToken = tokenManager.fetchAccessToken(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code has to be thread safe.
} catch(Exception e){ | ||
throw new ApiException("Token creation failed"); | ||
} | ||
return token.getAccessToken(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add null check for token.
} | ||
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); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug:
Follow below steps:
Case1:
- CallOrgs API
If orgs api is called without init, then it will throw null pointer exception. This exception need to be handled.
Case2:
- TwilioBearerTokenAuth.init() // Initialize
- TwilioBearerTokenAuth.invalidate() // invalidate
- CallOrgs API
In case2, previous invalidated token manager will be used, so during invalidate, tokenManager needs to be invalidated.
Once done, test above scenarios.
Fixes
A short description of what this PR does.
The Page class in bearertoken section is responsible for handling the pagination. This fetch "meta" information from the root level and use this information for pagination. For /scim/Users endpoint, this information is not present at root level which is causing the sdk to break. To avoid this added a null check after fetching "meta" from root level and proceed only if its not null
Checklist
If you have questions, please file a support ticket, or create a GitHub Issue in this repository.