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(integrations): add TwoStep as a new auth_mode for Perimeter 81 #2868

Merged
merged 15 commits into from
Oct 29, 2024

Conversation

hassan254-prog
Copy link
Contributor

Describe your changes

  • Add support for perimeter81

Issue ticket number and link

EXT-195

The flow is somewhat custom, where we send a single api_key and receive an access_token, which can later be used for authentication by passing the token in the headers like this: Authorization: Bearer <ACCESS_TOKEN>. I anticipate the list will continue to grow as we add support for more of these. I’m open to suggestions on how we can better handle these scenarios.

curl -X 'POST' -H 'Content-Type: application/json' \
-d '{
  "grantType": "api_key",
  "apiKey": "<API_KEY>"
}' 'https://api.perimeter81.com/api/v1/auth/authorize'


{
   "data":{
      "tokenType":"bearer",
      "accessToken":"<ACCESS_TOKEN>",
      "accessTokenExpire":<TOKEN_EXPIRE_TIME>
   }
}

@hassan254-prog hassan254-prog self-assigned this Oct 22, 2024
Copy link
Collaborator

@bodinsamuel bodinsamuel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like we could go with some if in the code instead of entirely dedicated auth strategy, but at the same time it keeps them well isolated. I don't know

@hassan254-prog
Copy link
Contributor Author

I have run tests locally using a mock API server based on the provider's API documentation, and tests were successful.

Copy link
Collaborator

@TBonnin TBonnin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is yet another flavor of a 2-steps token based authentication. I am a little bit worried about adding a new credentials type every single time. I wonder if we could define a more generic authMode. We already have token_url, we would need a additional token_url_headers but do we need anything else in the providers.yaml

};

return { params: perimeterCredentials } as unknown as ConnectionConfig;
}
Copy link
Collaborator

@TBonnin TBonnin Oct 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this works only because no other credentials has a attribute called api_key in snake case. It is very fragile and might be a source of bugs if more credentials with an api_key attribute are added. This PR is probably not the place to refactor but a good refactoring of this function would be welcome. For instance credentials could bevalidated with the help of zod schemas

@hassan254-prog
Copy link
Contributor Author

it is yet another flavor of a 2-steps token based authentication. I am a little bit worried about adding a new credentials type every single time. I wonder if we could define a more generic authMode. We already have token_url, we would need a additional token_url_headers but do we need anything else in the providers.yaml

We can also define the various fields i.e api_key for perimeter81, in the providers.

@hassan254-prog
Copy link
Contributor Author

@TBonnin, @bodinsamuel,

I don't know if I have done too much here, but after working on this, I believe we can comfortably merge BILL, TABLEAU, and other future integrations with this kind of flavor. I will open another PR to refactor the above convertCredentialsToConfig. I will need help with renaming the auth_mode. What do you think about the implementation?

This will now enable us to have such:

foo:
    display_name: Foo
    categories:
        - productivity
    auth_mode: TWOSTEP
    proxy:
        base_url: https://api.perimeter81.com/api/rest
    token_url: https://api.${connectionConfig.domain}.com/api/v1/auth/authorize
    token_params: 
        credentials:
            apiKey: ${credential.apiKey}
            grantType: api_key
            site:
                content_url: ${credential.contentUrl}
    token_headers:
        Content-Type: application/json
    token_response:
        token: data.accessToken #Dynamically access the token 
        token_expiration: data.accessTokenExpire #Dynamically access the token expiration date 
        token_expiration_formula: expireAt | expireIn # Same for this we can dynamically pick the formula to calculate the expire at value
    token_expires_in_ms: 36000   # Help us define this if provider has only mentioned in docs but not included in raw cred data
   

Future works for this:

  • Dynamically add authentication in proxy headers for this, i.e:
proxy:
    base_url: https://api.perimeter81.com/api/rest
    authentication_header: X-tableau-Auth ${token}
  • Come up with a way of how we can dynamically add zod validation.

Copy link
Collaborator

@TBonnin TBonnin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

love it. Regarding the naming I feel it should be called TBA for token based authentication and the existing TBA should be renamed NetsuiteTBA because it is very much specific to Netsuite. What do you think?

packages/shared/providers.yaml Outdated Show resolved Hide resolved
@hassan254-prog
Copy link
Contributor Author

love it. Regarding the naming I feel it should be called TBA for token based authentication and the existing TBA should be renamed NetsuiteTBA because it is very much specific to Netsuite. What do you think?

Yes I agree, that would be a better naming strategy. My worry is after renaming would it be a breaking change to the existing TBA connections? Maybe we can start by checking if there are any connections in prod environment.

Copy link
Collaborator

@bodinsamuel bodinsamuel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the grit on this, I haven't tested but looks correct. Last batch of comments 👌🏻

docs-v2/reference/api-configuration.mdx Outdated Show resolved Hide resolved
docs-v2/spec.yaml Outdated Show resolved Hide resolved
packages/shared/lib/services/connection.service.ts Outdated Show resolved Hide resolved
packages/shared/lib/services/connection.service.ts Outdated Show resolved Hide resolved
packages/server/lib/controllers/auth/postTwoStep.ts Outdated Show resolved Hide resolved
@khaliqgant
Copy link
Member

love it. Regarding the naming I feel it should be called TBA for token based authentication and the existing TBA should be renamed NetsuiteTBA because it is very much specific to Netsuite. What do you think?

Yes I agree, that would be a better naming strategy. My worry is after renaming would it be a breaking change to the existing TBA connections? Maybe we can start by checking if there are any connections in prod environment.

There are TBA integrations on prod, so let's hold off on renaming TBA for now.

packages/server/lib/controllers/auth/postTwoStep.ts Outdated Show resolved Hide resolved
packages/shared/providers.yaml Outdated Show resolved Hide resolved
docs-v2/reference/api-configuration.mdx Outdated Show resolved Hide resolved
@hassan254-prog hassan254-prog force-pushed the wari/support-perimeter81 branch from 72d7b38 to b9fbebe Compare October 29, 2024 07:39
@hassan254-prog hassan254-prog changed the title feat(integrations): add support for perimeter81 feat(integrations): add TwoStep as a new auth_mode for Perimeter 81 Oct 29, 2024
@hassan254-prog hassan254-prog merged commit b59443b into master Oct 29, 2024
22 checks passed
@hassan254-prog hassan254-prog deleted the wari/support-perimeter81 branch October 29, 2024 11:28
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.

4 participants