From 54937fa5a769767b01f831510d19e21bb9bcb75a Mon Sep 17 00:00:00 2001 From: Ben Halpern Date: Tue, 1 Dec 2020 12:22:07 -0500 Subject: [PATCH] Add configs/show api for admins (#11358) * Add configs/show api for admins * Add initial test * Add test * Update docs/api_v0.yml Co-authored-by: rhymes * Change to single resource * Change authentication approach * Change to status code spec * Fix spec path * Final touches * Update spec/requests/api/v0/admin/configs_spec.rb Co-authored-by: Michael Kohl * Proper stubbing Co-authored-by: rhymes Co-authored-by: Michael Kohl --- .../api/v0/admin/configs_controller.rb | 14 ++++++ app/controllers/api/v0/api_controller.rb | 4 ++ .../api/v0/admin/configs/show.json.jbuilder | 3 ++ config/routes.rb | 4 ++ docs/api_v0.yml | 26 +++++++++- spec/requests/api/v0/admin/configs_spec.rb | 50 +++++++++++++++++++ 6 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 app/controllers/api/v0/admin/configs_controller.rb create mode 100644 app/views/api/v0/admin/configs/show.json.jbuilder create mode 100644 spec/requests/api/v0/admin/configs_spec.rb diff --git a/app/controllers/api/v0/admin/configs_controller.rb b/app/controllers/api/v0/admin/configs_controller.rb new file mode 100644 index 000000000..913739aff --- /dev/null +++ b/app/controllers/api/v0/admin/configs_controller.rb @@ -0,0 +1,14 @@ +module Api + module V0 + module Admin + class ConfigsController < ApiController + before_action :authenticate_with_api_key_or_current_user! + before_action :authorize_super_admin + + def show + @site_configs = SiteConfig.all + end + end + end + end +end diff --git a/app/controllers/api/v0/api_controller.rb b/app/controllers/api/v0/api_controller.rb index fd4b9ebe4..dc165edf3 100644 --- a/app/controllers/api/v0/api_controller.rb +++ b/app/controllers/api/v0/api_controller.rb @@ -47,6 +47,10 @@ module Api end end + def authorize_super_admin + error_unauthorized unless @user.has_role?(:super_admin) + end + # Checks if the user is authenticated, sets @user to nil otherwise def authenticate_with_api_key_or_current_user @user = authenticate_with_api_key || current_user diff --git a/app/views/api/v0/admin/configs/show.json.jbuilder b/app/views/api/v0/admin/configs/show.json.jbuilder new file mode 100644 index 000000000..b6881c70c --- /dev/null +++ b/app/views/api/v0/admin/configs/show.json.jbuilder @@ -0,0 +1,3 @@ +@site_configs.each do |config| + json.set! config.var, config.value +end diff --git a/config/routes.rb b/config/routes.rb index 92cf668c0..a6a0f4d65 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -206,6 +206,10 @@ Rails.application.routes.draw do resources :organizations, only: [:show], param: :username do resources :users, only: [:index], to: "organizations#users" end + + namespace :admin do + resource :config, only: %i[show], defaults: { format: :json } + end end end diff --git a/docs/api_v0.yml b/docs/api_v0.yml index 6d151094e..ecb91682b 100644 --- a/docs/api_v0.yml +++ b/docs/api_v0.yml @@ -151,7 +151,6 @@ components: status: type: integer format: int32 - ArticleIndex: type: object required: @@ -1760,6 +1759,8 @@ components: profile_image: https://res.cloudinary.com/...jpeg tags: + - name: admin-configuration + description: Site-wide configuration set by admins (requires super admin authorization) - name: articles description: Articles are all the posts users create on DEV - name: comments @@ -1788,6 +1789,29 @@ tags: description: User or organization profile images paths: + /admin/config: + get: + operationId: getConfig + summary: Admin config + description: | + This endpoint returns the "site config" as set by admin. + tags: + - admin-configuration + security: + - api_key: [] + - oauth2: [] + x-code-samples: + - lang: Shell + label: curl + source: | + curl -H "api-key: API_KEY" https://dev.to/api/admin/config + responses: + "200": + description: All site-wide config + content: + application/json: + schema: + type: object /articles: get: operationId: getArticles diff --git a/spec/requests/api/v0/admin/configs_spec.rb b/spec/requests/api/v0/admin/configs_spec.rb new file mode 100644 index 000000000..e49a0bc7d --- /dev/null +++ b/spec/requests/api/v0/admin/configs_spec.rb @@ -0,0 +1,50 @@ +require "rails_helper" + +RSpec.describe "Api::V0::Admin::Configs", type: :request do + let(:api_secret) { create(:api_secret) } + let(:user) { api_secret.user } + + describe "GET /api/admin/config" do + before do + allow(SiteConfig).to receive(:community_name).and_return("ANYTHING") + allow(SiteConfig).to receive(:all).and_return([SiteConfig.new(var: "community_name", value: "ANYTHING")]) + end + + context "when user is super admin" do + before do + user.add_role(:super_admin) + end + + it "renders json when passed key" do + headers = { "api-key" => api_secret.secret, "content-type" => "application/json" } + get api_admin_config_path, headers: headers + + expect(response.parsed_body["community_name"]).to eq SiteConfig.community_name + end + + it "renders json when signed in" do + sign_in user + get api_admin_config_path + + expect(response.parsed_body["community_name"]).to eq SiteConfig.community_name + end + end + + context "when user is not super admin" do + it "renders unauthorized json" do + headers = { "api-key" => api_secret.secret, "content-type" => "application/json" } + get api_admin_config_path, headers: headers + + expect(response).to have_http_status(:unauthorized) + expect(response.parsed_body["error"]).to eq "unauthorized" + end + end + + context "when no user" do + it "renders unauthorized json" do + get api_admin_config_path + expect(response).to have_http_status(:unauthorized) + end + end + end +end