docbrown/app/controllers/admin/configs_controller.rb
Arit Amana 1912ffdc46
[Team Email Login] Refactor the Email Authentication flow (#11090)
* Hooked "Enable" button to hidden checkbox

* Hooked "Close" button to close email settings and show "Enable/Edit" button

* Additional hookups

* Start building generalized Modal blocks

* Everything hooked up except styling and a few Qs

* last of the hookups; ensure logic flow

* clean up

* specs to cover email auth refactor

* Fix bug surfaced by Vaidehi

* Incorporate PR feedback

* prevent email auth disable if invite-only-mode

* adjust emailAuthModal body text

* Sundry improvements

* Last-mile tweaks

* Trying to get 3rd party auth deselect to work

* delete unnecssary function

* remove superfluous comment

* Move inline styling into CSS file

* Incorporate PR feedback

* Incorporate more PR feedback

* Make Confirm btn intent clearer

* Add TODO comment
2020-10-28 13:37:11 -04:00

237 lines
6.6 KiB
Ruby

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
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_EMPTY_ENUMERABLES =
%i[
authentication_providers
].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
invite_only_mode
allow_both_email_signup_and_login
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
].freeze
layout "admin"
before_action :extra_authorization_and_confirmation, only: [:create]
before_action :validate_inputs, only: [:create]
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 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
toggle_email_password_authentication
redirect_to admin_config_path, notice: "Site configuration was successfully updated."
end
private
def confirmation_text
"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
def extra_authorization_and_confirmation
not_authorized unless current_user.has_role?(:single_resource_admin, Config) # Special additional permission
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
redirect_to admin_config_path, alert: "😭 #{errors.join(',')}" 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 toggle_email_password_authentication
if SiteConfig.allow_both_email_signup_and_login
SiteConfig.allow_email_password_registration = true
SiteConfig.allow_email_password_login = true
else
SiteConfig.allow_email_password_registration = false
SiteConfig.allow_email_password_login = false
SiteConfig.invite_only_mode = false
end
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
end
end