Skip to content
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

Merged
merged 17 commits into from
Jun 21, 2024

Conversation

AsabuHere
Copy link
Contributor

@AsabuHere AsabuHere commented May 29, 2024

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

  • I acknowledge that all my contributions will be made under the project's license
  • I have made a material change to the repo (functionality, testing, spelling, grammar)
  • I have read the Contribution Guidelines and my PR follows them
  • I have titled the PR appropriately
  • I have updated my branch with the main branch
  • I have added tests that prove my fix is effective or that my feature works
  • I have added the necessary documentation about the functionality in the appropriate .md file
  • I have added inline documentation to the code I modified

If you have questions, please file a support ticket, or create a GitHub Issue in this repository.

@AsabuHere AsabuHere requested review from kridai and sbansla May 29, 2024 03:36
@sbansla
Copy link
Contributor

sbansla commented May 29, 2024

@AsabuHere
Going forward all APIs will be moving towards Bearer Token Authentication, So we don't want to change pagination just for one API.
[Important] Make sure whatever pagination you are using for Orgs API is compatible with other APIs as well.
Add summary to PR.

Rest Proxy supports 2 types of pagination.
I will message you what are those pagination and we don't want to support any 3rd pagination technique.

@AsabuHere
Copy link
Contributor Author

@AsabuHere Going forward all APIs will be moving towards Bearer Token Authentication, So we don't want to change pagination just for one API. [Important] Make sure whatever pagination you are using for Orgs API is compatible with other APIs as well. Add summary to PR.

Rest Proxy supports 2 types of pagination. I will message you what are those pagination and we don't want to support any 3rd pagination technique.

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

@sbansla @kridai Can you please approve?

@AsabuHere AsabuHere changed the title Fix: Handling Null pointers when meta information is null in a rest response fix: Handling Null pointers when meta information is null in a rest response Jun 3, 2024
import com.twilio.Twilio;

import com.twilio.TwilioNoAuth;
import com.twilio.base.Resource;
Copy link
Contributor

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

@kridai
Copy link
Contributor

kridai commented Jun 13, 2024

@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) {
Copy link
Contributor

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

@AsabuHere
Copy link
Contributor Author

@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

Added

@AsabuHere
Copy link
Contributor Author

@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

added

@Setter
private final String grantType;
private final String clientId;
private final String clientSecret;
Copy link
Contributor

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();
Copy link
Contributor

@sbansla sbansla Jun 14, 2024

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);
Copy link
Contributor

@sbansla sbansla Jun 14, 2024

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);
Copy link
Contributor

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

  1. clientId, clientSecret, grantType
  2. clientId, clientSecret, grantType and other variables which are not mandatory.

@@ -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();
Copy link
Contributor

@sbansla sbansla Jun 14, 2024

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.

@@ -119,9 +128,15 @@ public Response request(BearerTokenRequest request) {
}
logRequest(request);
Response response = httpClient.reliableRequest(request);
int statusCode = response.getStatusCode();
Copy link
Contributor

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);
Copy link
Contributor

@sbansla sbansla Jun 14, 2024

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.

Copy link
Contributor

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;
Copy link
Contributor

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;
Copy link
Contributor

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.


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

builder.region(TwilioBearerTokenAuth.region);
builder.edge(TwilioBearerTokenAuth.edge);
builder.tokenManager(TwilioBearerTokenAuth.tokenManager);
builder.tokenManager(TwilioBearerTokenAuth.tokenManager);
Copy link
Contributor

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();
Copy link
Contributor

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();
Copy link
Contributor

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);
Copy link
Contributor

@sbansla sbansla Jun 20, 2024

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:

  1. CallOrgs API
    If orgs api is called without init, then it will throw null pointer exception. This exception need to be handled.

Case2:

  1. TwilioBearerTokenAuth.init() // Initialize
  2. TwilioBearerTokenAuth.invalidate() // invalidate
  3. CallOrgs API
    In case2, previous invalidated token manager will be used, so during invalidate, tokenManager needs to be invalidated.

Once done, test above scenarios.

@AsabuHere AsabuHere changed the title fix: Handling Null pointers when meta information is null in a rest response feat: Support for token based authentication and addition of helpers for organisation apis Jun 21, 2024
@AsabuHere AsabuHere merged commit b5d7622 into auth-rest-client Jun 21, 2024
7 of 8 checks passed
@AsabuHere AsabuHere deleted the auth_nullpointer_fix branch June 21, 2024 14:33
AsabuHere added a commit that referenced this pull request Jun 25, 2024
…nd PUT method in REST calls (#803)

* feat: Support for token based authentication and addition of helpers for organisation apis (#797)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants