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

[Citi OFN Voucher] Add VINE connected app #12886

Merged
merged 12 commits into from
Oct 14, 2024

Conversation

rioug
Copy link
Collaborator

@rioug rioug commented Oct 2, 2024

⚠️ When working on this use the Clockify code: Citi Food Vouchers: #1A. #11922 Citi OFN Voucher - VINE Integration ⚠️

What? Why?

Add VINE connected app, it allows an enterprise to provide a VINE API key and secret to be able to use VINE voucher for their enterprise.

A user is part of a team, so a successful call to /my-team endpoint mean the API key and secret are valid. It means the the API key needs at a minimum the "My Team Read" ability in VINE.

What should we test?

Turn on "connected_apps" feature toggle.
Make sure you have a valid API key and secret for vine staging server : https://vine-staging.openfoodnetwork.org.au/login

In the back office, logged as a super admin, enable Voucher Integration Engine (VINE) :

  • Go to "Configuration" tab, and click on connected app settings in the left hand side menu
  • Select "Voucher Integration Engine (Vine)"
  • Click "Update" to save the change

Still logged as a super admin:

  • Go to enterprise settings, for an enterprise you are not managing
  • Select "Connected Apps" on the left hand side menu
  • In the Voucher Integration Engine check :
    • the VINE API Key, VINE secret inputs and Connect button are disabled
    • It should say : "Only managers can connect apps"

As an enterprise manager:

  • Go to enterprise settings, for an enterprise you are managing
  • Select "Connected Apps" on the left hand side menu
  • Enter your API Key and secret and click "Connect" :
    --> The API Key should get added to the enterprise, and you should see a "Disconnect" button
  • Click on "Disconnect" :
    --> The API Key will be removed from the enterprise, and you should see an API Key and secret input and a "Connect" button
  • Enter a wrong API Key or secret and click "Connect" :
    --> You should get an error message asking you to check if you entered your API Key and secret correctly
  • Enter only an API Key or a secret and click "Connect" :
    --> You should get an error message saying API Key and secret can't be blank

Release notes

Changelog Category (reviewers may add a label for the release notes):

  • User facing changes
  • API changes (V0, V1, DFC or Webhook)
  • Technical changes only
  • Feature toggled

⚠️ We need to provision production servers to add new configuration before the release, see dependencies below ⚠️

The title of the pull request will be included in the release notes.

Dependencies

This PR requires an encryption key set to work :

Documentation updates

The connection/disconnection logic is yet to be implemented
@rioug rioug added the user facing changes Thes pull requests affect the user experience label Oct 2, 2024
Generate a JWT token to be used to connect to the VINE api
@rioug rioug added feature toggled These pull requests' changes are invisible by default and are grouped in release notes and removed user facing changes Thes pull requests affect the user experience labels Oct 2, 2024
Copy link
Member

@dacook dacook left a comment

Choose a reason for hiding this comment

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

Great work! This looks like a good fit for our "connected apps". I think there might be one line to clean up, other comments are pretty minor and don't need changes.

config/locales/en.yml Outdated Show resolved Hide resolved
config/locales/en.yml Outdated Show resolved Hide resolved
spec/services/vine_api_service_spec.rb Show resolved Hide resolved
app/models/connected_apps/vine.rb Show resolved Hide resolved
app/models/connected_apps/vine.rb Outdated Show resolved Hide resolved
Copy link
Member

@mkllnk mkllnk left a comment

Choose a reason for hiding this comment

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

Really nice work, well done. Just a few little tweaks... ✨

config/locales/en.yml Outdated Show resolved Hide resolved
config/locales/en.yml Outdated Show resolved Hide resolved
spec/support/vcr_setup.rb Show resolved Hide resolved
app/services/vine_api_service.rb Show resolved Hide resolved
spec/services/vine_api_service_spec.rb Outdated Show resolved Hide resolved
spec/models/connected_apps/vine_spec.rb Outdated Show resolved Hide resolved
channel: SessionChannel.for_request(request))
end

def connect_vine
Copy link
Member

Choose a reason for hiding this comment

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

I think that we can leave it for now but it would be better to move app-specific logic into the apps and have the controller be agnostic of the app's needs.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

To be honest I would prefer to have the connect logic to be separated from the model and having a service handle the connection bit before storing the result in the model.
But yeah, this should live in a service.

Copy link
Member

Choose a reason for hiding this comment

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

Good point, too. If we take the logic out of the models then we don't really need a polymorphic model. The beauty of the polymorphic model is that it loads the right code automatically. But reducing models to data storage is really handy as well. Then we just need service objects that are coupled to app types. I'm not sure which is better. Maybe it's just that the VINE app has some additional logic that should go into a service.

Copy link
Member

Choose a reason for hiding this comment

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

I notice that we're validating the presence of two values now, which we want to store in the model. ActiveRecord validations are made for that kind of thing (I guess it would have to be a custom validation to handle the values inside the data blob, but it still seems appropriate).
I'm not sure it's worth moving the logic right now though.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I feel like we might need other connected apps to see if a pattern emerges before we can refine the design. Maybe VINE is the odd one who knows. If I get a bit of time, I'll look at moving the VINE logic to a service.

def connected_app_params
params.permit(:type)
params.permit(:type, :vine_api_key)
Copy link
Member

Choose a reason for hiding this comment

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

We could ask the app to give us a list of allowed parameters.

spec/requests/admin/connected_apps_controller_spec.rb Outdated Show resolved Hide resolved
The VINE Api require a secret and an API key to be used. The secret is
used to sign the request. The secret is linked to the API key so we need
to store it along side the key.
Added layer of security, we encrypt the API key and related secret.
It requires setting up some encryption keys that can be generated wiht
`bin/rails db:encryption:init`
Copy link
Member

@mkllnk mkllnk left a comment

Choose a reason for hiding this comment

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

Nice!

I queried Paul about the different handling of the secret but let's go ahead with this for now. We can use this interface either way.

channel: SessionChannel.for_request(request))
end

def connect_vine
Copy link
Member

Choose a reason for hiding this comment

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

Good point, too. If we take the logic out of the models then we don't really need a polymorphic model. The beauty of the polymorphic model is that it loads the right code automatically. But reducing models to data storage is really handy as well. Then we just need service objects that are coupled to app types. I'm not sure which is better. Maybe it's just that the VINE app has some additional logic that should go into a service.

.env Outdated
Comment on lines 65 to 67
# VINE API settings
# VINE_API_URL="https://vine-staging.openfoodnetwork.org.au/api/v1"
# VINE_API_SECRET="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I was a bit too quick here, we stil need the VINE_API_URL 😅 , I'll fix that this afternoon

Copy link
Member

@dacook dacook left a comment

Choose a reason for hiding this comment

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

Nice, looking good, but as mentioned awaiting VINE_API_URL..

channel: SessionChannel.for_request(request))
end

def connect_vine
Copy link
Member

Choose a reason for hiding this comment

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

I notice that we're validating the presence of two values now, which we want to store in the model. ActiveRecord validations are made for that kind of thing (I guess it would have to be a custom validation to handle the values inside the data blob, but it still seems appropriate).
I'm not sure it's worth moving the logic right now though.

And add error handling if the variable is not set
@rioug rioug requested review from dacook and mkllnk October 8, 2024 04:06
The condition for checking the error now match a real scenario
@RachL RachL self-assigned this Oct 14, 2024
@RachL RachL added the pr-staged-au staging.openfoodnetwork.org.au label Oct 14, 2024
@RachL
Copy link
Contributor

RachL commented Oct 14, 2024

@rioug all scenario are passing 🎉

I'm noticing that it is enough to be manager to have permission in the connected apps area. I wonder if we want to restrict to enterprise owners. Will ask in product circle.

In the meantime, merging :)

@RachL RachL merged commit f54552f into openfoodfoundation:master Oct 14, 2024
53 checks passed
@RachL RachL removed the pr-staged-au staging.openfoodnetwork.org.au label Oct 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature toggled These pull requests' changes are invisible by default and are grouped in release notes
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

[Citi Vouchers] Add VINE connected app
4 participants