diff --git a/app/controllers/carto/api/api_keys_controller.rb b/app/controllers/carto/api/api_keys_controller.rb index 6bc090fe79..3b44e9273b 100644 --- a/app/controllers/carto/api/api_keys_controller.rb +++ b/app/controllers/carto/api/api_keys_controller.rb @@ -2,11 +2,11 @@ class Carto::Api::ApiKeysController < ::Api::ApplicationController include Carto::ControllerHelper include Carto::UUIDHelper - ssl_required :create, :destroy + ssl_required :create, :destroy, :regenerate_token before_filter :api_authorization_required before_filter :check_feature_flag - before_filter :load_api_key, only: [:destroy] + before_filter :load_api_key, only: [:destroy, :regenerate_token] rescue_from Carto::LoadError, with: :rescue_from_carto_error rescue_from Carto::UnprocesableEntityError, with: :rescue_from_carto_error @@ -28,6 +28,12 @@ class Carto::Api::ApiKeysController < ::Api::ApplicationController render_jsonp(Carto::Api::ApiKeyPresenter.new(@api_key).to_poro, 200) end + def regenerate_token + @api_key.create_token + @api_key.save! + render_jsonp(Carto::Api::ApiKeyPresenter.new(@api_key).to_poro, 200) + end + private def check_feature_flag diff --git a/app/models/carto/api_key.rb b/app/models/carto/api_key.rb index d7551032e6..6cdbe47790 100644 --- a/app/models/carto/api_key.rb +++ b/app/models/carto/api_key.rb @@ -38,18 +38,18 @@ class Carto::ApiKey < ActiveRecord::Base @api_key_grants ||= ::Carto::ApiKeyGrants.new(grants) end - private - - PASSWORD_LENGTH = 40 - - REDIS_KEY_PREFIX = 'api_keys:'.freeze - def create_token begin self.token = generate_auth_token end while self.class.exists?(token: token) end + private + + PASSWORD_LENGTH = 40 + + REDIS_KEY_PREFIX = 'api_keys:'.freeze + def create_db_config begin self.db_role = Carto::DB::Sanitize.sanitize_identifier("#{user.username}_role_#{SecureRandom.hex}") diff --git a/config/routes.rb b/config/routes.rb index 5bb571d400..5740cf6fb5 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -583,6 +583,9 @@ CartoDB::Application.routes.draw do resource :metrics, only: [:create] resources :api_keys, only: [:create, :destroy], constraints: { id: /[^\/]+/ } + scope 'api_keys/:id/token' do + post 'regenerate' => 'api_keys#regenerate_token', as: :regenerate_api_key_token + end scope '/viz/:visualization_id', constraints: { id: /[^\/]+/ } do resources :analyses, only: [:show, :create, :update, :destroy], constraints: { id: /[^\/]+/ } diff --git a/spec/requests/carto/api/api_keys_controller_spec.rb b/spec/requests/carto/api/api_keys_controller_spec.rb index e011182260..5777299d11 100644 --- a/spec/requests/carto/api/api_keys_controller_spec.rb +++ b/spec/requests/carto/api/api_keys_controller_spec.rb @@ -148,4 +148,26 @@ describe Carto::Api::ApiKeysController do api_key.destroy end end + + describe '#regenerate' do + before(:all) do + @api_key = FactoryGirl.create(:api_key_apis, user_id: @user1.id) + end + + after(:all) do + @api_key.destroy + end + + it 'regenerates the token' do + old_token = @api_key.token + options = { user_domain: @user1.username, api_key: @user1.api_key, id: @api_key.id } + post_json regenerate_api_key_token_url(options) do |response| + response.status.should eq 200 + response.body[:token].should_not be_nil + response.body[:token].should_not eq old_token + @api_key.reload + response.body[:token].should eq @api_key.token + end + end + end end