Commit 67541cb9 authored by Bob Van Landuyt's avatar Bob Van Landuyt

Merge branch '301032-activation' into 'master'

Cloud License: Activation to receive license instead of authentication token

See merge request gitlab-org/gitlab!55822
parents b05bd815 21b2cb01
...@@ -17,10 +17,12 @@ module GitlabSubscriptions ...@@ -17,10 +17,12 @@ module GitlabSubscriptions
return response unless response[:success] return response unless response[:success]
if application_settings.update(cloud_license_auth_token: response[:authentication_token]) license = License.new(data: response[:license_key])
response
if license.save
{ success: true }
else else
error(application_settings.errors.full_messages) error(license.errors.full_messages)
end end
rescue => e rescue => e
error(e.message) error(e.message)
......
...@@ -10,19 +10,37 @@ module Gitlab ...@@ -10,19 +10,37 @@ module Gitlab
def activate(activation_code) def activate(activation_code)
uuid = Gitlab::CurrentSettings.uuid uuid = Gitlab::CurrentSettings.uuid
variables = {
activationCode: activation_code,
instanceIdentifier: uuid
}
query = <<~GQL query = <<~GQL
mutation { mutation($activationCode: String!, $instanceIdentifier: String!) {
cloudActivationActivate(input: { activationCode: "#{activation_code}", instanceIdentifier: "#{uuid}" }) { cloudActivationActivate(
authenticationToken input: {
activationCode: $activationCode,
instanceIdentifier: $instanceIdentifier
}
) {
licenseKey
errors errors
} }
} }
GQL GQL
response = execute_graphql_query(query).dig(:data, 'data', 'cloudActivationActivate') response = execute_graphql_query(
{ query: query, variables: variables }
)
if !response[:success] || response.dig(:data, 'errors').present?
return { success: false, errors: response.dig(:data, 'errors') }
end
response = response.dig(:data, 'data', 'cloudActivationActivate')
if response['errors'].blank? if response['errors'].blank?
{ success: true, authentication_token: response['authenticationToken'] } { success: true, license_key: response['licenseKey'] }
else else
{ success: false, errors: response['errors'] } { success: false, errors: response['errors'] }
end end
...@@ -39,7 +57,7 @@ module Gitlab ...@@ -39,7 +57,7 @@ module Gitlab
} }
GQL GQL
response = execute_graphql_query(query).dig(:data) response = execute_graphql_query({ query: query }).dig(:data)
if response['errors'].blank? if response['errors'].blank?
eligible = response.dig('data', 'subscription', 'eoaStarterBronzeEligible') eligible = response.dig('data', 'subscription', 'eoaStarterBronzeEligible')
...@@ -59,13 +77,11 @@ module Gitlab ...@@ -59,13 +77,11 @@ module Gitlab
private private
def execute_graphql_query(query) def execute_graphql_query(params)
response = ::Gitlab::HTTP.post( response = ::Gitlab::HTTP.post(
graphql_endpoint, graphql_endpoint,
headers: admin_headers, headers: admin_headers,
body: { body: params.to_json
query: query
}.to_json
) )
parse_response(response) parse_response(response)
......
...@@ -6,7 +6,7 @@ RSpec.describe Gitlab::SubscriptionPortal::Clients::Graphql do ...@@ -6,7 +6,7 @@ RSpec.describe Gitlab::SubscriptionPortal::Clients::Graphql do
let(:client) { Gitlab::SubscriptionPortal::Client } let(:client) { Gitlab::SubscriptionPortal::Client }
describe '#activate' do describe '#activate' do
let(:authentication_token) { 'authentication_token' } let(:license_key) { 'license_key' }
it 'returns success' do it 'returns success' do
expect(client).to receive(:execute_graphql_query).and_return( expect(client).to receive(:execute_graphql_query).and_return(
...@@ -15,7 +15,7 @@ RSpec.describe Gitlab::SubscriptionPortal::Clients::Graphql do ...@@ -15,7 +15,7 @@ RSpec.describe Gitlab::SubscriptionPortal::Clients::Graphql do
data: { data: {
"data" => { "data" => {
"cloudActivationActivate" => { "cloudActivationActivate" => {
"authenticationToken" => authentication_token, "licenseKey" => license_key,
"errors" => [] "errors" => []
} }
} }
...@@ -25,7 +25,7 @@ RSpec.describe Gitlab::SubscriptionPortal::Clients::Graphql do ...@@ -25,7 +25,7 @@ RSpec.describe Gitlab::SubscriptionPortal::Clients::Graphql do
result = client.activate('activation_code_abc') result = client.activate('activation_code_abc')
expect(result).to eq({ authentication_token: authentication_token, success: true }) expect(result).to eq({ license_key: license_key, success: true })
end end
it 'returns failure' do it 'returns failure' do
...@@ -35,7 +35,7 @@ RSpec.describe Gitlab::SubscriptionPortal::Clients::Graphql do ...@@ -35,7 +35,7 @@ RSpec.describe Gitlab::SubscriptionPortal::Clients::Graphql do
data: { data: {
"data" => { "data" => {
"cloudActivationActivate" => { "cloudActivationActivate" => {
"authenticationToken" => nil, "licenseKey" => nil,
"errors" => ["invalid activation code"] "errors" => ["invalid activation code"]
} }
} }
......
...@@ -6,24 +6,24 @@ RSpec.describe 'Activate a subscription' do ...@@ -6,24 +6,24 @@ RSpec.describe 'Activate a subscription' do
include GraphqlHelpers include GraphqlHelpers
let_it_be(:current_user) { create(:admin) } let_it_be(:current_user) { create(:admin) }
let_it_be(:license_key) { build(:gitlab_license).export }
let(:activation_code) { 'activation_code' }
let(:mutation) do
graphql_mutation(:gitlab_subscription_activate, { activation_code: activation_code })
end
let!(:application_setting) do let!(:application_setting) do
stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false') stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false')
create(:application_setting, cloud_license_enabled: true) create(:application_setting, cloud_license_enabled: true)
end end
let(:authentication_token) { 'authentication_token' }
let(:mutation) do
graphql_mutation(:gitlab_subscription_activate, { activation_code: 'abc' })
end
let(:remote_response) do let(:remote_response) do
{ {
success: true, success: true,
data: { data: {
"data" => { "data" => {
"cloudActivationActivate" => { "cloudActivationActivate" => {
"authenticationToken" => authentication_token, "licenseKey" => license_key,
"errors" => [] "errors" => []
} }
} }
...@@ -31,15 +31,22 @@ RSpec.describe 'Activate a subscription' do ...@@ -31,15 +31,22 @@ RSpec.describe 'Activate a subscription' do
} }
end end
before do it 'persists license key' do
allow(Gitlab::SubscriptionPortal::Client).to receive(:execute_graphql_query).and_return(remote_response) expect(Gitlab::SubscriptionPortal::Client)
end .to receive(:execute_graphql_query)
.with({
query: an_instance_of(String),
variables: {
activationCode: activation_code,
instanceIdentifier: application_setting.uuid
}
})
.and_return(remote_response)
it 'persists authentication token' do
post_graphql_mutation(mutation, current_user: current_user) post_graphql_mutation(mutation, current_user: current_user)
expect(response).to have_gitlab_http_status(:success) expect(response).to have_gitlab_http_status(:success)
expect(graphql_mutation_response(:gitlab_subscription_activate)['errors']).to be_empty expect(graphql_mutation_response(:gitlab_subscription_activate)['errors']).to be_empty
expect(application_setting.reload.cloud_license_auth_token).to eq(authentication_token) expect(License.last.data).to eq(license_key)
end end
end end
...@@ -8,14 +8,14 @@ RSpec.describe GitlabSubscriptions::ActivateService do ...@@ -8,14 +8,14 @@ RSpec.describe GitlabSubscriptions::ActivateService do
create(:application_setting, cloud_license_enabled: cloud_license_enabled) create(:application_setting, cloud_license_enabled: cloud_license_enabled)
end end
let_it_be(:license_key) { build(:gitlab_license).export }
let(:cloud_license_enabled) { true } let(:cloud_license_enabled) { true }
let(:authentication_token) { 'authentication_token' }
let(:activation_code) { 'activation_code' } let(:activation_code) { 'activation_code' }
def stub_client_activate def stub_client_activate
expect(Gitlab::SubscriptionPortal::Client).to receive(:activate) expect(Gitlab::SubscriptionPortal::Client).to receive(:activate)
.with(activation_code) .with(activation_code)
.and_return(response) .and_return(customer_dot_response)
end end
before do before do
...@@ -23,61 +23,58 @@ RSpec.describe GitlabSubscriptions::ActivateService do ...@@ -23,61 +23,58 @@ RSpec.describe GitlabSubscriptions::ActivateService do
end end
context 'when CustomerDot returns success' do context 'when CustomerDot returns success' do
let(:response) { { success: true, authentication_token: authentication_token } } let(:customer_dot_response) { { success: true, license_key: license_key } }
before do before do
stub_client_activate stub_client_activate
end end
it 'persists authentication_token' do it 'persists license' do
expect(subject.execute(activation_code)).to eq(response) expect(subject.execute(activation_code)).to eq({ success: true })
expect(application_settings.reload.cloud_license_auth_token).to eq(authentication_token) expect(License.last.data).to eq(license_key)
end end
context 'when persisting fails' do context 'when persisting fails' do
let(:response) { { success: true, authentication_token: authentication_token } } let(:license_key) { 'invalid key' }
it 'returns error' do it 'returns error' do
application_settings.errors.add(:base, :invalid) expect(subject.execute(activation_code)).to match({ errors: [be_a_kind_of(String)], success: false })
allow(application_settings).to receive(:update).and_return(false)
expect(subject.execute(activation_code)).to eq({ errors: ["is invalid"], success: false })
end end
end end
end end
context 'when CustomerDot returns failure' do context 'when CustomerDot returns failure' do
let(:response) { { success: false, errors: ['foo'] } } let(:customer_dot_response) { { success: false, errors: ['foo'] } }
it 'returns error' do it 'returns error' do
stub_client_activate stub_client_activate
expect(subject.execute(activation_code)).to eq(response) expect(subject.execute(activation_code)).to eq(customer_dot_response)
expect(application_settings.reload.cloud_license_auth_token).to be_nil expect(License.last&.data).not_to eq(license_key)
end end
end end
context 'when not self managed instance' do context 'when not self managed instance' do
let(:response) { { success: false, errors: [described_class::ERROR_MESSAGES[:not_self_managed]] }} let(:customer_dot_response) { { success: false, errors: [described_class::ERROR_MESSAGES[:not_self_managed]] }}
it 'returns error' do it 'returns error' do
allow(Gitlab).to receive(:com?).and_return(true) allow(Gitlab).to receive(:com?).and_return(true)
expect(Gitlab::SubscriptionPortal::Client).not_to receive(:activate) expect(Gitlab::SubscriptionPortal::Client).not_to receive(:activate)
expect(subject.execute(activation_code)).to eq(response) expect(subject.execute(activation_code)).to eq(customer_dot_response)
end end
end end
context 'when cloud licensing disabled' do context 'when cloud licensing disabled' do
let(:response) { { success: false, errors: [described_class::ERROR_MESSAGES[:disabled]] }} let(:customer_dot_response) { { success: false, errors: [described_class::ERROR_MESSAGES[:disabled]] }}
let(:cloud_license_enabled) { false } let(:cloud_license_enabled) { false }
it 'returns error' do it 'returns error' do
expect(Gitlab::SubscriptionPortal::Client).not_to receive(:activate) expect(Gitlab::SubscriptionPortal::Client).not_to receive(:activate)
expect(subject.execute(activation_code)).to eq(response) expect(subject.execute(activation_code)).to eq(customer_dot_response)
end end
end end
......
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