Add config post route for admin api (#11698)
* Add config post route for admin api * Fix params * Extract config_params to concern * Remove print statement * Some changes * A couple changes * Change controller method name and refactor upsert * Fix tests and method names * Fix routes and class stuff * Fix styles * Fix config params * Fix styles * Move regex to constant * Remove single-use after action callbacks * Expose success? method * Fix syntax error * Fix success? return * Switch to guard clause * Final clean ups?
This commit is contained in:
parent
00247bed99
commit
68867e9384
9 changed files with 299 additions and 266 deletions
|
|
@ -29,16 +29,6 @@ module Admin
|
|||
authorize(authorization_resource, :access?, policy_class: InternalPolicy)
|
||||
end
|
||||
|
||||
def bust_content_change_caches
|
||||
CacheBuster.bust("/tags/onboarding") # Needs to change when suggested_tags is edited.
|
||||
CacheBuster.bust("/shell_top") # Cached at edge, sent to service worker.
|
||||
CacheBuster.bust("/shell_bottom") # Cached at edge, sent to service worker.
|
||||
CacheBuster.bust("/async_info/shell_version") # Checks if current users should be busted.
|
||||
CacheBuster.bust("/onboarding") # Page is cached at edge.
|
||||
CacheBuster.bust("/") # Page is cached at edge.
|
||||
SiteConfig.admin_action_taken_at = Time.current # Used as cache key
|
||||
end
|
||||
|
||||
def assign_help_url
|
||||
@help_url = HELP_URLS[controller_name.to_sym]
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,136 +1,6 @@
|
|||
module Admin
|
||||
class ConfigsController < Admin::ApplicationController
|
||||
CAMPAIGN_PARAMS =
|
||||
%i[
|
||||
campaign_call_to_action
|
||||
campaign_featured_tags
|
||||
campaign_hero_html_variant_name
|
||||
campaign_sidebar_enabled
|
||||
campaign_sidebar_image
|
||||
campaign_url
|
||||
campaign_articles_require_approval
|
||||
].freeze
|
||||
|
||||
COMMUNITY_PARAMS =
|
||||
%i[
|
||||
community_name
|
||||
community_emoji
|
||||
collective_noun
|
||||
collective_noun_disabled
|
||||
community_description
|
||||
community_member_label
|
||||
community_copyright_start_year
|
||||
staff_user_id
|
||||
tagline
|
||||
experience_low
|
||||
experience_high
|
||||
].freeze
|
||||
|
||||
NEWSLETTER_PARAMS =
|
||||
%i[
|
||||
mailchimp_api_key
|
||||
mailchimp_community_moderators_id
|
||||
mailchimp_newsletter_id
|
||||
mailchimp_sustaining_members_id
|
||||
mailchimp_tag_moderators_id
|
||||
].freeze
|
||||
|
||||
RATE_LIMIT_PARAMS =
|
||||
%i[
|
||||
rate_limit_comment_creation
|
||||
rate_limit_email_recipient
|
||||
rate_limit_follow_count_daily
|
||||
rate_limit_image_upload
|
||||
rate_limit_published_article_creation
|
||||
rate_limit_published_article_antispam_creation
|
||||
rate_limit_organization_creation
|
||||
rate_limit_user_subscription_creation
|
||||
rate_limit_article_update
|
||||
rate_limit_user_update
|
||||
rate_limit_feedback_message_creation
|
||||
rate_limit_listing_creation
|
||||
rate_limit_reaction_creation
|
||||
rate_limit_send_email_confirmation
|
||||
].freeze
|
||||
|
||||
MASCOT_PARAMS =
|
||||
%i[
|
||||
mascot_image_description
|
||||
mascot_image_url
|
||||
mascot_footer_image_url
|
||||
mascot_footer_image_width
|
||||
mascot_footer_image_height
|
||||
mascot_user_id
|
||||
].freeze
|
||||
|
||||
IMAGE_PARAMS =
|
||||
%i[
|
||||
favicon_url
|
||||
logo_png
|
||||
logo_svg
|
||||
main_social_image
|
||||
secondary_logo_url
|
||||
left_navbar_svg_icon
|
||||
right_navbar_svg_icon
|
||||
].freeze
|
||||
|
||||
ONBOARDING_PARAMS =
|
||||
%i[
|
||||
onboarding_logo_image
|
||||
onboarding_background_image
|
||||
onboarding_taskcard_image
|
||||
suggested_tags
|
||||
suggested_users
|
||||
prefer_manual_suggested_users
|
||||
].freeze
|
||||
|
||||
JOB_PARAMS =
|
||||
%i[
|
||||
jobs_url
|
||||
display_jobs_banner
|
||||
].freeze
|
||||
|
||||
ALLOWED_PARAMS =
|
||||
%i[
|
||||
ga_tracking_id
|
||||
periodic_email_digest_max
|
||||
periodic_email_digest_min
|
||||
sidebar_tags
|
||||
twitter_hashtag
|
||||
shop_url
|
||||
payment_pointer
|
||||
stripe_api_key
|
||||
stripe_publishable_key
|
||||
health_check_token
|
||||
feed_style
|
||||
feed_strategy
|
||||
default_font
|
||||
sponsor_headline
|
||||
public
|
||||
twitter_key
|
||||
twitter_secret
|
||||
github_key
|
||||
github_secret
|
||||
facebook_key
|
||||
facebook_secret
|
||||
apple_client_id
|
||||
apple_key_id
|
||||
apple_pem
|
||||
apple_team_id
|
||||
auth_providers_to_enable
|
||||
invite_only_mode
|
||||
allow_email_password_registration
|
||||
require_captcha_for_email_password_registration
|
||||
primary_brand_color_hex
|
||||
spam_trigger_terms
|
||||
recaptcha_site_key
|
||||
recaptcha_secret_key
|
||||
video_encoder_key
|
||||
tag_feed_minimum_score
|
||||
home_feed_minimum_score
|
||||
allowed_registration_email_domains
|
||||
display_email_domain_allow_list_publicly
|
||||
].freeze
|
||||
include SiteConfigParams
|
||||
|
||||
EMOJI_ONLY_FIELDS = %w[community_emoji].freeze
|
||||
IMAGE_FIELDS =
|
||||
|
|
@ -151,31 +21,20 @@ module Admin
|
|||
layout "admin"
|
||||
|
||||
before_action :extra_authorization_and_confirmation, only: [:create]
|
||||
before_action :validate_inputs, only: [:create]
|
||||
before_action :validate_emoji, only: [:create], if: -> { params[:site_config].keys & EMOJI_ONLY_FIELDS }
|
||||
before_action :validate_image_urls, only: [:create], if: -> { params[:site_config].keys & IMAGE_FIELDS }
|
||||
after_action :bust_content_change_caches, only: [:create]
|
||||
|
||||
def show
|
||||
@confirmation_text = confirmation_text
|
||||
end
|
||||
|
||||
def create
|
||||
clean_up_params
|
||||
|
||||
config_params.each do |key, value|
|
||||
if key == "auth_providers_to_enable"
|
||||
update_enabled_auth_providers(value) unless value.class.name != "String"
|
||||
elsif value.is_a?(Array)
|
||||
SiteConfig.public_send("#{key}=", value.reject(&:blank?)) unless value.empty?
|
||||
elsif value.respond_to?(:to_h)
|
||||
SiteConfig.public_send("#{key}=", value.to_h) unless value.empty?
|
||||
else
|
||||
SiteConfig.public_send("#{key}=", value.strip) unless value.nil?
|
||||
end
|
||||
result = SiteConfigs::Upsert.call(site_config_params)
|
||||
if result.success?
|
||||
Audit::Logger.log(:internal, current_user, params.dup)
|
||||
bust_content_change_caches
|
||||
redirect_to admin_config_path, notice: "Site configuration was successfully updated."
|
||||
else
|
||||
redirect_to admin_config_path, alert: "😭 #{result.errors.to_sentence}"
|
||||
end
|
||||
|
||||
redirect_to admin_config_path, notice: "Site configuration was successfully updated."
|
||||
end
|
||||
|
||||
private
|
||||
|
|
@ -184,29 +43,6 @@ module Admin
|
|||
"My username is @#{current_user.username} and this action is 100% safe and appropriate."
|
||||
end
|
||||
|
||||
def config_params
|
||||
all_params = ALLOWED_PARAMS |
|
||||
CAMPAIGN_PARAMS |
|
||||
COMMUNITY_PARAMS |
|
||||
NEWSLETTER_PARAMS |
|
||||
RATE_LIMIT_PARAMS |
|
||||
MASCOT_PARAMS |
|
||||
IMAGE_PARAMS |
|
||||
ONBOARDING_PARAMS |
|
||||
JOB_PARAMS
|
||||
|
||||
has_emails = params.dig(:site_config, :email_addresses).present?
|
||||
params[:site_config][:email_addresses][:default] = ApplicationConfig["DEFAULT_EMAIL"] if has_emails
|
||||
params&.require(:site_config)&.permit(
|
||||
all_params,
|
||||
authentication_providers: [],
|
||||
social_media_handles: SiteConfig.social_media_handles.keys,
|
||||
email_addresses: SiteConfig.email_addresses.keys,
|
||||
meta_keywords: SiteConfig.meta_keywords.keys,
|
||||
credit_prices_in_cents: SiteConfig.credit_prices_in_cents.keys,
|
||||
)
|
||||
end
|
||||
|
||||
def raise_confirmation_mismatch_error
|
||||
raise ActionController::BadRequest.new, "The confirmation key does not match"
|
||||
end
|
||||
|
|
@ -215,87 +51,5 @@ module Admin
|
|||
not_authorized unless current_user.has_role?(:super_admin)
|
||||
raise_confirmation_mismatch_error if params.require(:confirmation) != confirmation_text
|
||||
end
|
||||
|
||||
def validate_inputs
|
||||
errors = []
|
||||
errors << "Brand color must be darker for accessibility." if brand_contrast_too_low
|
||||
errors << "Brand color must be be a 6 character hex (starting with #)." if brand_color_not_hex
|
||||
errors << "Allowed emails must be list of domains." if allowed_domains_include_improper_format
|
||||
redirect_to admin_config_path, alert: "😭 #{errors.to_sentence}" if errors.any?
|
||||
end
|
||||
|
||||
def validate_emoji
|
||||
emoji_params = config_params.slice(*EMOJI_ONLY_FIELDS).to_h
|
||||
errors = emoji_params.filter_map do |field, value|
|
||||
non_emoji_characters = value.downcase.gsub(EmojiRegex::RGIEmoji, "")
|
||||
"#{field} contains invalid emoji" if non_emoji_characters.present?
|
||||
end
|
||||
redirect_to admin_config_path, alert: "😭 #{errors.to_sentence}" if errors.any?
|
||||
end
|
||||
|
||||
def validate_image_urls
|
||||
image_params = config_params.slice(*IMAGE_FIELDS).to_h
|
||||
errors = image_params.filter_map do |field, url|
|
||||
"#{field} must be a valid URL" unless url.blank? || valid_image_url(url)
|
||||
end
|
||||
redirect_to admin_config_path, alert: "😭 #{errors.to_sentence}" if errors.any?
|
||||
end
|
||||
|
||||
def clean_up_params
|
||||
config = params[:site_config]
|
||||
return unless config
|
||||
|
||||
%i[sidebar_tags suggested_tags suggested_users].each do |param|
|
||||
config[param] = config[param]&.downcase&.delete(" ") if config[param]
|
||||
end
|
||||
config[:credit_prices_in_cents]&.transform_values!(&:to_i)
|
||||
end
|
||||
|
||||
def provider_keys_missing(entry)
|
||||
SiteConfig.public_send("#{entry}_key").blank? || SiteConfig.public_send("#{entry}_secret").blank?
|
||||
end
|
||||
|
||||
def invalid_provider_entry(entry)
|
||||
entry.blank? || helpers.available_providers_array.exclude?(entry) ||
|
||||
provider_keys_missing(entry)
|
||||
end
|
||||
|
||||
def email_login_disabled_with_one_or_less_auth_providers(enabled_providers)
|
||||
!SiteConfig.allow_email_password_login && enabled_providers.count <= 1
|
||||
end
|
||||
|
||||
def update_enabled_auth_providers(value)
|
||||
enabled_providers = []
|
||||
value.split(",").each do |entry|
|
||||
enabled_providers.push(entry) unless invalid_provider_entry(entry)
|
||||
end
|
||||
SiteConfig.public_send("authentication_providers=", enabled_providers) unless
|
||||
email_login_disabled_with_one_or_less_auth_providers(enabled_providers)
|
||||
end
|
||||
|
||||
# Validations
|
||||
def brand_contrast_too_low
|
||||
hex = params.dig(:site_config, :primary_brand_color_hex)
|
||||
hex.present? && Color::Accessibility.new(hex).low_contrast?
|
||||
end
|
||||
|
||||
def brand_color_not_hex
|
||||
hex = params.dig(:site_config, :primary_brand_color_hex)
|
||||
hex.present? && !hex.match?(/\A#(\h{6}|\h{3})\z/)
|
||||
end
|
||||
|
||||
def allowed_domains_include_improper_format
|
||||
domains = params.dig(:site_config, :allowed_registration_email_domains)
|
||||
return unless domains
|
||||
|
||||
domains_array = domains.delete(" ").split(",")
|
||||
valid_domains = domains_array
|
||||
.select { |d| d.match?(/^[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9](?:\.[a-zA-Z]{2,})+$/) }
|
||||
valid_domains.size != domains_array.size
|
||||
end
|
||||
|
||||
def valid_image_url(url)
|
||||
url.match?(VALID_URL)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,12 +2,27 @@ module Api
|
|||
module V0
|
||||
module Admin
|
||||
class ConfigsController < ApiController
|
||||
include SiteConfigParams
|
||||
|
||||
before_action :authenticate_with_api_key_or_current_user!
|
||||
before_action :authorize_super_admin
|
||||
skip_before_action :verify_authenticity_token, only: %i[update]
|
||||
|
||||
def show
|
||||
@site_configs = SiteConfig.all
|
||||
end
|
||||
|
||||
def update
|
||||
result = SiteConfigs::Upsert.call(site_config_params)
|
||||
if result.success?
|
||||
@site_configs = SiteConfig.all
|
||||
Audit::Logger.log(:internal, @user, params.dup)
|
||||
bust_content_change_caches
|
||||
render "show"
|
||||
else
|
||||
render json: { error: result.errors.to_sentence, status: 422 }, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -177,6 +177,16 @@ class ApplicationController < ActionController::Base
|
|||
redirect_to URL.url(request.fullpath)
|
||||
end
|
||||
|
||||
def bust_content_change_caches
|
||||
CacheBuster.bust("/tags/onboarding") # Needs to change when suggested_tags is edited.
|
||||
CacheBuster.bust("/shell_top") # Cached at edge, sent to service worker.
|
||||
CacheBuster.bust("/shell_bottom") # Cached at edge, sent to service worker.
|
||||
CacheBuster.bust("/async_info/shell_version") # Checks if current users should be busted.
|
||||
CacheBuster.bust("/onboarding") # Page is cached at edge.
|
||||
CacheBuster.bust("/") # Page is cached at edge.
|
||||
SiteConfig.admin_action_taken_at = Time.current # Used as cache key
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def configure_permitted_parameters
|
||||
|
|
|
|||
16
app/controllers/concerns/site_config_params.rb
Normal file
16
app/controllers/concerns/site_config_params.rb
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
module SiteConfigParams
|
||||
SPECIAL_PARAMS_TO_ADD =
|
||||
%w[authentication_providers email_addresses meta_keywords credit_prices_in_cents auth_providers_to_enable].freeze
|
||||
def site_config_params
|
||||
has_emails = params.dig(:site_config, :email_addresses).present?
|
||||
params[:site_config][:email_addresses][:default] = ApplicationConfig["DEFAULT_EMAIL"] if has_emails
|
||||
params.require(:site_config)&.permit(
|
||||
(SiteConfig.keys + SPECIAL_PARAMS_TO_ADD).map(&:to_sym),
|
||||
authentication_providers: [],
|
||||
social_media_handles: SiteConfig.social_media_handles.keys,
|
||||
email_addresses: SiteConfig.email_addresses.keys,
|
||||
meta_keywords: SiteConfig.meta_keywords.keys,
|
||||
credit_prices_in_cents: SiteConfig.credit_prices_in_cents.keys,
|
||||
)
|
||||
end
|
||||
end
|
||||
140
app/services/site_configs/upsert.rb
Normal file
140
app/services/site_configs/upsert.rb
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
module SiteConfigs
|
||||
class Upsert
|
||||
EMOJI_ONLY_FIELDS = %w[community_emoji].freeze
|
||||
IMAGE_FIELDS =
|
||||
%w[
|
||||
main_social_image
|
||||
logo_png
|
||||
secondary_logo_url
|
||||
campaign_sidebar_image
|
||||
mascot_image_url
|
||||
mascot_footer_image_url
|
||||
onboarding_logo_image
|
||||
onboarding_background_image
|
||||
onboarding_taskcard_image
|
||||
].freeze
|
||||
|
||||
VALID_URL = %r{\A(http|https)://([/|.|\w|\s|-])*.[a-z]{2,5}(:[0-9]{1,5})?(/.*)?\z}.freeze
|
||||
|
||||
VALID_DOMAIN = /^[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9](?:\.[a-zA-Z]{2,})+$/.freeze
|
||||
|
||||
PARAMS_TO_BE_CLEANED = %i[sidebar_tags suggested_tags suggested_users].freeze
|
||||
|
||||
attr_reader :errors
|
||||
|
||||
def self.call(configs)
|
||||
new(configs).call
|
||||
end
|
||||
|
||||
def initialize(configs)
|
||||
@configs = configs
|
||||
@success = false
|
||||
end
|
||||
|
||||
def call
|
||||
@errors = []
|
||||
clean_up_params
|
||||
validate_inputs
|
||||
validate_emoji
|
||||
validate_image_urls
|
||||
|
||||
return self if @errors.flatten.any?
|
||||
|
||||
@success = true
|
||||
upsert_configs
|
||||
self
|
||||
end
|
||||
|
||||
def success?
|
||||
@success
|
||||
end
|
||||
|
||||
def upsert_configs
|
||||
@configs.each do |key, value|
|
||||
if key == "auth_providers_to_enable"
|
||||
update_enabled_auth_providers(value) unless value.class.name != "String"
|
||||
elsif value.is_a?(Array)
|
||||
SiteConfig.public_send("#{key}=", value.reject(&:blank?)) unless value.empty?
|
||||
elsif value.respond_to?(:to_h)
|
||||
SiteConfig.public_send("#{key}=", value.to_h) unless value.empty?
|
||||
else
|
||||
SiteConfig.public_send("#{key}=", value.strip) unless value.nil?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def clean_up_params
|
||||
PARAMS_TO_BE_CLEANED.each do |param|
|
||||
@configs[param] = @configs[param]&.downcase&.delete(" ") if @configs[param]
|
||||
end
|
||||
@configs[:credit_prices_in_cents]&.transform_values!(&:to_i)
|
||||
end
|
||||
|
||||
def validate_inputs
|
||||
@errors << "Brand color must be darker for accessibility." if brand_contrast_too_low
|
||||
@errors << "Brand color must be be a 6 character hex (starting with #)." if brand_color_not_hex
|
||||
@errors << "Allowed emails must be list of domains." if allowed_domains_include_improper_format
|
||||
end
|
||||
|
||||
def validate_emoji
|
||||
emoji_params = @configs.slice(*EMOJI_ONLY_FIELDS).to_h
|
||||
@errors << emoji_params.filter_map do |field, value|
|
||||
non_emoji_characters = value.downcase.gsub(EmojiRegex::RGIEmoji, "")
|
||||
"#{field} contains invalid emoji" if non_emoji_characters.present?
|
||||
end
|
||||
end
|
||||
|
||||
def validate_image_urls
|
||||
image_params = @configs.slice(*IMAGE_FIELDS).to_h
|
||||
@errors << image_params.filter_map do |field, url|
|
||||
"#{field} must be a valid URL" unless url.blank? || valid_image_url(url)
|
||||
end
|
||||
end
|
||||
|
||||
def update_enabled_auth_providers(value)
|
||||
enabled_providers = value.split(",").filter_map do |entry|
|
||||
entry unless invalid_provider_entry(entry)
|
||||
end
|
||||
SiteConfig.public_send("authentication_providers=", enabled_providers) unless
|
||||
email_login_disabled_with_one_or_less_auth_providers(enabled_providers)
|
||||
end
|
||||
|
||||
def email_login_disabled_with_one_or_less_auth_providers(enabled_providers)
|
||||
!SiteConfig.allow_email_password_login && enabled_providers.count <= 1
|
||||
end
|
||||
|
||||
def invalid_provider_entry(entry)
|
||||
entry.blank? || Authentication::Providers.available.map(&:to_s).exclude?(entry) ||
|
||||
provider_keys_missing(entry)
|
||||
end
|
||||
|
||||
def provider_keys_missing(entry)
|
||||
SiteConfig.public_send("#{entry}_key").blank? || SiteConfig.public_send("#{entry}_secret").blank?
|
||||
end
|
||||
|
||||
# Validations
|
||||
def brand_contrast_too_low
|
||||
hex = @configs[:primary_brand_color_hex]
|
||||
hex.present? && Color::Accessibility.new(hex).low_contrast?
|
||||
end
|
||||
|
||||
def brand_color_not_hex
|
||||
hex = @configs[:primary_brand_color_hex]
|
||||
hex.present? && !hex.match?(/\A#(\h{6}|\h{3})\z/)
|
||||
end
|
||||
|
||||
def allowed_domains_include_improper_format
|
||||
domains = @configs[:allowed_registration_email_domains]
|
||||
return unless domains
|
||||
|
||||
domains_array = domains.delete(" ").split(",")
|
||||
valid_domains = domains_array
|
||||
.select { |d| d.match?(VALID_DOMAIN) }
|
||||
valid_domains.size != domains_array.size
|
||||
end
|
||||
|
||||
def valid_image_url(url)
|
||||
url.match?(VALID_URL)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -205,7 +205,7 @@ Rails.application.routes.draw do
|
|||
end
|
||||
|
||||
namespace :admin do
|
||||
resource :config, only: %i[show], defaults: { format: :json }
|
||||
resource :config, only: %i[show update], defaults: { format: :json }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -661,7 +661,11 @@ components:
|
|||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/Comment"
|
||||
|
||||
SiteConfig:
|
||||
type: object
|
||||
properties:
|
||||
site_config:
|
||||
type: object
|
||||
FollowedTag:
|
||||
type: object
|
||||
required:
|
||||
|
|
@ -1854,6 +1858,61 @@ paths:
|
|||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
put:
|
||||
operationId: upsertConfig
|
||||
summary: Update Site-wide Config
|
||||
description: |
|
||||
This endpoint allows admins to declare values or update values for "site config".
|
||||
tags:
|
||||
- admin-configuration
|
||||
security:
|
||||
- api_key: []
|
||||
- oauth2: []
|
||||
requestBody:
|
||||
description: Config up upsert
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/SiteConfig"
|
||||
responses:
|
||||
"201":
|
||||
description: Newly updated config
|
||||
"400":
|
||||
description: BadRequest
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/APIError"
|
||||
examples:
|
||||
error-bad-request:
|
||||
$ref: "#/components/examples/ErrorBadRequest"
|
||||
"401":
|
||||
description: Unauthorized
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/APIError"
|
||||
examples:
|
||||
error-unauthorized:
|
||||
$ref: "#/components/examples/ErrorUnauthorized"
|
||||
"403":
|
||||
description: Forbidden
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/APIError"
|
||||
examples:
|
||||
error-forbidden:
|
||||
$ref: "#/components/examples/ErrorForbidden"
|
||||
"422":
|
||||
description: Unprocessable Entity
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/APIError"
|
||||
examples:
|
||||
error-unprocessable-entity:
|
||||
$ref: "#/components/examples/ErrorUnprocessableEntity"
|
||||
/articles:
|
||||
get:
|
||||
operationId: getArticles
|
||||
|
|
|
|||
|
|
@ -47,4 +47,53 @@ RSpec.describe "Api::V0::Admin::Configs", type: :request do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "PUT /api/admin/config" do
|
||||
context "when user is super admin" do
|
||||
let(:headers) { { "api-key" => api_secret.secret, "content-type" => "application/json" } }
|
||||
|
||||
before do
|
||||
user.add_role(:super_admin)
|
||||
end
|
||||
|
||||
it "Modifies SiteConfig data" do
|
||||
put api_admin_config_path, params: { site_config: { community_name: "new" } }.to_json, headers: headers
|
||||
|
||||
expect(SiteConfig.community_name).to eq "new"
|
||||
end
|
||||
|
||||
it "enables proper domains to allow list" do
|
||||
proper_list = "dev.to, forem.com, forem.dev"
|
||||
put api_admin_config_path, params: { site_config: { allowed_registration_email_domains: proper_list } }.to_json,
|
||||
headers: headers
|
||||
expect(SiteConfig.allowed_registration_email_domains).to eq(%w[dev.to forem.com forem.dev])
|
||||
end
|
||||
|
||||
it "does not allow improper domain list" do
|
||||
improper_list = "dev.to, foremcom, forem.dev"
|
||||
put api_admin_config_path, params: { site_config: { allowed_registration_email_domains: improper_list } }.to_json,
|
||||
headers: headers
|
||||
expect(SiteConfig.allowed_registration_email_domains).not_to eq(%w[dev.to foremcom forem.dev])
|
||||
end
|
||||
|
||||
it "removes space suggested_tags" do
|
||||
put api_admin_config_path, params: { site_config: { suggested_tags: "hey, haha,hoho, bobo fofo" } }.to_json,
|
||||
headers: headers
|
||||
expect(SiteConfig.suggested_tags).to eq(%w[hey haha hoho bobofofo])
|
||||
end
|
||||
|
||||
it "downcases suggested_tags" do
|
||||
put api_admin_config_path, params: { site_config: { suggested_tags: "hey, haha,hoHo, Bobo Fofo" } }.to_json,
|
||||
headers: headers
|
||||
expect(SiteConfig.suggested_tags).to eq(%w[hey haha hoho bobofofo])
|
||||
end
|
||||
|
||||
it "Renders siteconfig result" do
|
||||
put api_admin_config_path, params: { site_config: { community_name: "new" } }.to_json,
|
||||
headers: headers
|
||||
|
||||
expect(response.parsed_body["community_name"]).to eq SiteConfig.community_name
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue