diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index f02c9c97595..98cafcd2f24 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -25,7 +25,7 @@ class ApplicationController < ActionController::Base # and then raising a CSRF exception def handle_unverified_request # NOTE: API key is secret, having it invalidates the need for a CSRF token - unless is_api? + unless is_api? || is_user_api? super clear_current_user render text: "['BAD CSRF']", status: 403 @@ -501,7 +501,7 @@ class ApplicationController < ActionController::Base def check_xhr # bypass xhr check on PUT / POST / DELETE provided api key is there, otherwise calling api is annoying - return if !request.get? && is_api? + return if !request.get? && (is_api? || is_user_api?) raise RenderEmpty.new unless ((request.format && request.format.json?) || request.xhr?) end diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 7f68a648eff..52618c5cafd 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -467,7 +467,7 @@ class PostsController < ApplicationController json_obj = json_obj[:post] end - if !success && GlobalSetting.try(:verbose_api_logging) && is_api? + if !success && GlobalSetting.try(:verbose_api_logging) && (is_api? || is_user_api?) Rails.logger.error "Error creating post via API:\n\n#{json_obj.inspect}" end diff --git a/lib/auth/current_user_provider.rb b/lib/auth/current_user_provider.rb index 4de839d7d7c..cdd4d495fcc 100644 --- a/lib/auth/current_user_provider.rb +++ b/lib/auth/current_user_provider.rb @@ -25,6 +25,10 @@ class Auth::CurrentUserProvider raise NotImplementedError end + def is_user_api? + raise NotImplementedError + end + # we may need to know very early on in the middleware if an auth token # exists, to optimise caching def has_auth_cookie? diff --git a/lib/auth/default_current_user_provider.rb b/lib/auth/default_current_user_provider.rb index 3326cbc51c7..3bd91684f2f 100644 --- a/lib/auth/default_current_user_provider.rb +++ b/lib/auth/default_current_user_provider.rb @@ -8,6 +8,7 @@ class Auth::DefaultCurrentUserProvider USER_API_KEY ||= "HTTP_USER_API_KEY".freeze USER_API_CLIENT_ID ||= "HTTP_USER_API_CLIENT_ID".freeze API_KEY_ENV ||= "_DISCOURSE_API".freeze + USER_API_KEY_ENV ||= "_DISCOURSE_USER_API".freeze TOKEN_COOKIE ||= "_t".freeze PATH_INFO ||= "PATH_INFO".freeze COOKIE_ATTEMPTS_PER_MIN ||= 10 @@ -97,7 +98,7 @@ class Auth::DefaultCurrentUserProvider limiter_min.performed! limiter_day.performed! - @env[API_KEY_ENV] = true + @env[USER_API_KEY_ENV] = true end @env[CURRENT_USER_KEY] = current_user @@ -172,7 +173,12 @@ class Auth::DefaultCurrentUserProvider # api has special rights return true if api was detected def is_api? current_user - @env[API_KEY_ENV] + !!(@env[API_KEY_ENV]) + end + + def is_user_api? + current_user + !!(@env[USER_API_KEY_ENV]) end def has_auth_cookie? diff --git a/lib/current_user.rb b/lib/current_user.rb index 5c5ec6b2509..79a04e4a71f 100644 --- a/lib/current_user.rb +++ b/lib/current_user.rb @@ -26,6 +26,10 @@ module CurrentUser current_user_provider.is_api? end + def is_user_api? + current_user_provider.is_user_api? + end + def current_user current_user_provider.current_user end diff --git a/spec/components/auth/default_current_user_provider_spec.rb b/spec/components/auth/default_current_user_provider_spec.rb index 54559c15869..e9a680dd22e 100644 --- a/spec/components/auth/default_current_user_provider_spec.rb +++ b/spec/components/auth/default_current_user_provider_spec.rb @@ -175,7 +175,11 @@ describe Auth::DefaultCurrentUserProvider do "HTTP_USER_API_KEY" => api_key.key, } - expect(provider("/", params).current_user.id).to eq(user.id) + good_provider = provider("/", params) + + expect(good_provider.current_user.id).to eq(user.id) + expect(good_provider.is_api?).to eq(false) + expect(good_provider.is_user_api?).to eq(true) expect { provider("/", params.merge({"REQUEST_METHOD" => "POST"})).current_user