Commit 8154cc0f authored by Jan Provaznik's avatar Jan Provaznik

Merge branch 'rc/generate_oauth_on_subscription_create' into 'master'

Generate oauth token on subscription create

See merge request gitlab-org/gitlab!63259
parents 6bf6a221 fc940cc1
......@@ -2,8 +2,12 @@
module Subscriptions
class CreateService
include Gitlab::Utils::StrongMemoize
attr_reader :current_user, :customer_params, :subscription_params
CUSTOMERS_OAUTH_APP_ID_CACHE_KEY = 'customers_oauth_app_id'
def initialize(current_user, group:, customer_params:, subscription_params:)
@current_user = current_user
@group = group
......@@ -16,6 +20,8 @@ module Subscriptions
return response unless response[:success]
oauth_token&.save
# We can't use an email from GL.com because it may differ from the billing email.
# Instead we use the email received from the CustomersDot as a billing email.
customer_data = response.with_indifferent_access[:data][:customer]
......@@ -41,10 +47,10 @@ module Subscriptions
}
end
# Return an empty hash for now, because the Customers API requires the credentials attribute to be present,
# although it does not require the actual values. Remove this once the Customers API has been updated.
def credentials_attrs
{}
{
token: oauth_token&.token
}
end
def customer_attrs
......@@ -89,5 +95,31 @@ module Subscriptions
def client
Gitlab::SubscriptionPortal::Client
end
def customers_oauth_app_id
Rails.cache.fetch(CUSTOMERS_OAUTH_APP_ID_CACHE_KEY, expires_in: 1.hour) do
response = client.customers_oauth_app_id
response.dig(:data, 'oauth_app_id')
end
end
def oauth_token
strong_memoize(:oauth_token) do
next unless customers_oauth_app_id
application = Doorkeeper::Application.find_by_uid(customers_oauth_app_id)
existing_token = Doorkeeper::AccessToken.matching_token_for(application, current_user.id, application.scopes)
next existing_token if existing_token
Doorkeeper::AccessToken.new(
application_id: customers_oauth_app_id,
resource_owner_id: current_user.id,
token: Doorkeeper::OAuth::Helpers::UniqueToken.generate,
scopes: application.scopes.to_s
)
end
end
end
end
......@@ -33,6 +33,10 @@ module Gitlab
http_get("api/payment_methods/#{id}", admin_headers)
end
def customers_oauth_app_id
http_get("api/v1/oauth_app_id", admin_headers)
end
private
def error_message
......
......@@ -2,7 +2,9 @@
"customer": {
"provider": "gitlab",
"uid": 111,
"credentials": {},
"credentials": {
"token": "foo_token"
},
"customer": {
"country": "NLD",
"address_1": "Address line 1",
......
......@@ -124,4 +124,17 @@ RSpec.describe Gitlab::SubscriptionPortal::Clients::Rest do
it_behaves_like 'when response code is 500'
it_behaves_like 'when http call raises an exception'
end
describe '#customers_oauth_app_id' do
subject do
client.customers_oauth_app_id
end
let(:http_method) { :get }
it_behaves_like 'when response is successful'
it_behaves_like 'when response code is 422'
it_behaves_like 'when response code is 500'
it_behaves_like 'when http call raises an exception'
end
end
......@@ -7,6 +7,7 @@ RSpec.describe Subscriptions::CreateService do
let_it_be(:user) { create(:user, id: 111, first_name: 'First name', last_name: 'Last name', email: 'first.last@gitlab.com') }
let_it_be(:group) { create(:group, id: 222, name: 'Group name') }
let_it_be(:oauth_app) { create(:oauth_application) }
let_it_be(:customer_params) do
{
......@@ -33,6 +34,11 @@ RSpec.describe Subscriptions::CreateService do
let_it_be(:create_service_params) { Gitlab::Json.parse(fixture_file('create_service_params.json', dir: 'ee')).deep_symbolize_keys }
describe '#execute' do
before do
allow(client).to receive(:customers_oauth_app_id).and_return( { data: { 'oauth_app_id' => oauth_app.uid } } )
allow(Doorkeeper::OAuth::Helpers::UniqueToken).to receive(:generate).and_return('foo_token')
end
context 'when failing to create a customer' do
before do
allow(client).to receive(:create_customer).and_return(success: false, data: { errors: 'failed to create customer' })
......@@ -41,20 +47,30 @@ RSpec.describe Subscriptions::CreateService do
it 'returns the response hash' do
expect(execute).to eq(success: false, data: { errors: 'failed to create customer' })
end
it 'does not save oauth token' do
expect { execute }.not_to change { Doorkeeper::AccessToken.count }
end
end
context 'when successfully creating a customer' do
before do
allow(client).to receive(:create_customer).and_return(success: true, data: { success: true, 'customer' => { 'authentication_token' => 'token', 'email' => customer_email } })
end
it 'creates a subscription with the returned authentication token' do
expect(client)
allow(client)
.to receive(:create_subscription)
.with(anything, customer_email, 'token')
.and_return(success: true, data: { success: true, subscription_id: 'xxx' })
end
it 'creates a subscription with the returned authentication token' do
execute
expect(client).to have_received(:create_subscription).with(anything, customer_email, 'token')
end
it 'saves oauth token' do
expect { execute }.to change { Doorkeeper::AccessToken.count }.by(1)
end
context 'when failing to create a subscription' do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment