Split Settings::Authentication from SiteConfig (#13095)
* Split Settings::Authentication from SiteConfig * Move specs * Sort fields * Update settings usages * Update recaptcha usages * Add data update script * Update spec * Rename SiteConfigParams concern * Fixes, new route, new controller * Controller and service refactoring * More controller and service updates * Spec updates * More spec fixes * Move file * Fix FeedbackMessagesController * Update admin/configs_spec * Fix remaining specs in admin/configs_spec * Fix configs API * Formatting * Clean up old service object * Various fixes * Update DUS * Add model argument to admin_config_label * Fix key name * Fix specs * Add distinct request caches for settings classes * Fix e2e tests * Fix remaining system spec * Make DUS idempotent * Move routes block * Cleanup * Switch to ActiveSupport::CurrentAttributes * Pinned rails-settings-cached * Update e2e test * Update lib/data_update_scripts/20210316091354_move_authentication_settings.rb Co-authored-by: rhymes <rhymes@hey.com> * Add guard to DUS * Temporarily re-add two SiteConfig fields * Fix config show view Co-authored-by: rhymes <rhymes@hey.com>
This commit is contained in:
parent
1f52ebf302
commit
5406b0576e
88 changed files with 1345 additions and 1125 deletions
3
Gemfile
3
Gemfile
|
|
@ -75,7 +75,8 @@ gem "rack-attack", "~> 6.5.0" # Used to throttle requests to prevent brute force
|
|||
gem "rack-cors", "~> 1.1" # Middleware that will make Rack-based apps CORS compatible
|
||||
gem "rack-timeout", "~> 0.6" # Rack middleware which aborts requests that have been running for longer than a specified timeout
|
||||
gem "rails", "~> 6.1" # Ruby on Rails
|
||||
gem "rails-settings-cached", ">= 2.1.1" # Settings plugin for Rails that makes managing a table of global key, value pairs easy.
|
||||
# Pinned since we have a monkey-patch against this version
|
||||
gem "rails-settings-cached", "= 2.5.2" # Settings plugin for Rails that makes managing a table of global key, value pairs easy.
|
||||
gem "ransack", "~> 2.4" # Searching and sorting
|
||||
gem "recaptcha", "~> 5.7", require: "recaptcha/rails" # Helpers for the reCAPTCHA API
|
||||
gem "redcarpet", "~> 3.5" # A fast, safe and extensible Markdown to (X)HTML parser
|
||||
|
|
|
|||
20
Gemfile.lock
20
Gemfile.lock
|
|
@ -86,7 +86,7 @@ GEM
|
|||
activerecord (>= 5.0, < 6.2)
|
||||
addressable (2.7.0)
|
||||
public_suffix (>= 2.0.2, < 5.0)
|
||||
ahoy_email (2.0.2)
|
||||
ahoy_email (2.0.3)
|
||||
actionmailer (>= 5)
|
||||
addressable (>= 2.3.2)
|
||||
nokogiri
|
||||
|
|
@ -168,7 +168,7 @@ GEM
|
|||
activesupport (>= 3.2.0)
|
||||
carrierwave
|
||||
fastimage
|
||||
chartkick (3.4.2)
|
||||
chartkick (4.0.2)
|
||||
childprocess (3.0.0)
|
||||
cloudinary (1.20.0)
|
||||
aws_cf_signer
|
||||
|
|
@ -424,13 +424,13 @@ GEM
|
|||
listen (3.5.1)
|
||||
rb-fsevent (~> 0.10, >= 0.10.3)
|
||||
rb-inotify (~> 0.9, >= 0.9.10)
|
||||
loofah (2.9.0)
|
||||
loofah (2.9.1)
|
||||
crass (~> 1.0.2)
|
||||
nokogiri (>= 1.5.9)
|
||||
lumberjack (1.2.8)
|
||||
mail (2.7.1)
|
||||
mini_mime (>= 0.1.1)
|
||||
marcel (1.0.0)
|
||||
marcel (1.0.1)
|
||||
memoizable (0.4.2)
|
||||
thread_safe (~> 0.3, >= 0.3.1)
|
||||
memory_profiler (1.0.0)
|
||||
|
|
@ -462,16 +462,12 @@ GEM
|
|||
http-2 (~> 0.11)
|
||||
netrc (0.11.0)
|
||||
nio4r (2.5.7)
|
||||
nokogiri (1.11.3-arm64-darwin)
|
||||
racc (~> 1.4)
|
||||
nokogiri (1.11.3-x86_64-darwin)
|
||||
racc (~> 1.4)
|
||||
nokogiri (1.11.3-x86_64-linux)
|
||||
racc (~> 1.4)
|
||||
notiffany (0.1.3)
|
||||
nenv (~> 0.1)
|
||||
shellany (~> 0.0)
|
||||
oauth (0.5.5)
|
||||
oauth (0.5.6)
|
||||
oauth2 (1.4.7)
|
||||
faraday (>= 0.8, < 2.0)
|
||||
jwt (>= 1.0, < 3.0)
|
||||
|
|
@ -508,7 +504,7 @@ GEM
|
|||
rack
|
||||
orm_adapter (0.5.0)
|
||||
parallel (1.20.1)
|
||||
parser (3.0.0.0)
|
||||
parser (3.0.1.0)
|
||||
ast (~> 2.4.1)
|
||||
patron (0.13.3)
|
||||
pg (1.2.3)
|
||||
|
|
@ -843,8 +839,6 @@ GEM
|
|||
zonebie (0.6.1)
|
||||
|
||||
PLATFORMS
|
||||
arm64-darwin
|
||||
x86_64-darwin
|
||||
x86_64-linux
|
||||
|
||||
DEPENDENCIES
|
||||
|
|
@ -940,7 +934,7 @@ DEPENDENCIES
|
|||
rack-host-redirect (~> 1.3)
|
||||
rack-timeout (~> 0.6)
|
||||
rails (~> 6.1)
|
||||
rails-settings-cached (>= 2.1.1)
|
||||
rails-settings-cached (= 2.5.2)
|
||||
ransack (~> 2.4)
|
||||
recaptcha (~> 5.7)
|
||||
redcarpet (~> 3.5)
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ class Runtime {
|
|||
} else if (/Android/i.test(window.navigator.userAgent)) {
|
||||
return 'Android';
|
||||
} else if (/Linux/i.test(window.navigator.platform)) {
|
||||
return 'Linux';
|
||||
return 'Linux';
|
||||
}
|
||||
|
||||
return 'Unsupported';
|
||||
|
|
|
|||
|
|
@ -1,31 +1,9 @@
|
|||
module Admin
|
||||
class ConfigsController < Admin::ApplicationController
|
||||
include SiteConfigParams
|
||||
|
||||
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_background_image
|
||||
].freeze
|
||||
|
||||
VALID_URL = %r{\A(http|https)://([/|.\w\s-])*.[a-z]{2,5}(:[0-9]{1,5})?(/.*)?\z}.freeze
|
||||
|
||||
layout "admin"
|
||||
|
||||
before_action :extra_authorization_and_confirmation, only: [:create]
|
||||
|
||||
def show
|
||||
@confirmation_text = confirmation_text
|
||||
end
|
||||
class ConfigsController < Admin::SettingsController
|
||||
include SettingsParams
|
||||
|
||||
def create
|
||||
result = SiteConfigs::Upsert.call(site_config_params)
|
||||
result = ::Settings::Upsert.call(settings_params)
|
||||
if result.success?
|
||||
Audit::Logger.log(:internal, current_user, params.dup)
|
||||
bust_content_change_caches
|
||||
|
|
@ -34,20 +12,5 @@ module Admin
|
|||
redirect_to admin_config_path, alert: "😭 #{result.errors.to_sentence}"
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def confirmation_text
|
||||
"My username is @#{current_user.username} and this action is 100% safe and appropriate."
|
||||
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?(:super_admin)
|
||||
raise_confirmation_mismatch_error if params.require(:confirmation) != confirmation_text
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
22
app/controllers/admin/settings/authentications_controller.rb
Normal file
22
app/controllers/admin/settings/authentications_controller.rb
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
module Admin
|
||||
module Settings
|
||||
class AuthenticationsController < Admin::ApplicationController
|
||||
def create
|
||||
result = ::Authentication::SettingsUpsert.call(settings_params)
|
||||
|
||||
if result.success?
|
||||
Audit::Logger.log(:internal, current_user, params.dup)
|
||||
redirect_to admin_config_path, notice: "Site configuration was successfully updated."
|
||||
else
|
||||
redirect_to admin_config_path, alert: "😭 #{result.errors.to_sentence}"
|
||||
end
|
||||
end
|
||||
|
||||
def settings_params
|
||||
params
|
||||
.require(:settings_authentication)
|
||||
.permit(*::Settings::Authentication.keys, :auth_providers_to_enable)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
30
app/controllers/admin/settings_controller.rb
Normal file
30
app/controllers/admin/settings_controller.rb
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
module Admin
|
||||
class SettingsController < Admin::ApplicationController
|
||||
MISMATCH_ERROR = "The confirmation key does not match".freeze
|
||||
|
||||
before_action :extra_authorization_and_confirmation, only: [:create]
|
||||
|
||||
layout "admin"
|
||||
|
||||
def create; end
|
||||
|
||||
def show
|
||||
@confirmation_text = confirmation_text
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def extra_authorization_and_confirmation
|
||||
not_authorized unless current_user.has_role?(:super_admin)
|
||||
raise_confirmation_mismatch_error if params.require(:confirmation) != confirmation_text
|
||||
end
|
||||
|
||||
def confirmation_text
|
||||
"My username is @#{current_user.username} and this action is 100% safe and appropriate."
|
||||
end
|
||||
|
||||
def raise_confirmation_mismatch_error
|
||||
raise ActionController::BadRequest.new, MISMATCH_ERROR
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -2,7 +2,7 @@ module Api
|
|||
module V0
|
||||
module Admin
|
||||
class ConfigsController < ApiController
|
||||
include SiteConfigParams
|
||||
include SettingsParams
|
||||
|
||||
before_action :authenticate_with_api_key_or_current_user!
|
||||
before_action :authorize_super_admin
|
||||
|
|
@ -13,16 +13,30 @@ module Api
|
|||
end
|
||||
|
||||
def update
|
||||
result = SiteConfigs::Upsert.call(site_config_params)
|
||||
if result.success?
|
||||
@site_configs = SiteConfig.all
|
||||
# NOTE: citizen428 - this is not going to scale but I want to wait
|
||||
# until we extract at least one more settings model before deciding
|
||||
# how to change this.
|
||||
settings_result = ::Settings::Upsert.call(settings_params)
|
||||
auth_settings_result = ::Authentication::SettingsUpsert.call(auth_settings_params)
|
||||
|
||||
if settings_result.success? && auth_settings_result.success?
|
||||
@site_configs = SiteConfig.all + Settings::Authentication.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
|
||||
errors = settings_result.errors + auth_settings_result.errors
|
||||
render json: { error: errors.to_sentence, status: 422 }, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def auth_settings_params
|
||||
params
|
||||
.require(:site_config)
|
||||
.permit(*::Settings::Authentication.keys, :providers_to_enable)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,16 +1,26 @@
|
|||
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
|
||||
module SettingsParams
|
||||
SPECIAL_PARAMS_TO_ADD = %w[
|
||||
credit_prices_in_cents
|
||||
email_addresses
|
||||
meta_keywords
|
||||
].freeze
|
||||
|
||||
def settings_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: [],
|
||||
settings_keys.map(&:to_sym),
|
||||
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
|
||||
|
||||
private
|
||||
|
||||
def settings_keys
|
||||
SiteConfig.keys + SPECIAL_PARAMS_TO_ADD
|
||||
end
|
||||
end
|
||||
|
|
@ -51,7 +51,7 @@ class FeedbackMessagesController < ApplicationController
|
|||
private
|
||||
|
||||
def recaptcha_verified?
|
||||
recaptcha_params = { secret_key: SiteConfig.recaptcha_secret_key }
|
||||
recaptcha_params = { secret_key: Settings::Authentication.recaptcha_secret_key }
|
||||
params["g-recaptcha-response"] && verify_recaptcha(recaptcha_params)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@ class RegistrationsController < Devise::RegistrationsController
|
|||
end
|
||||
|
||||
def create
|
||||
not_authorized unless SiteConfig.allow_email_password_registration || SiteConfig.waiting_on_first_user
|
||||
not_authorized unless Settings::Authentication.allow_email_password_registration ||
|
||||
SiteConfig.waiting_on_first_user
|
||||
not_authorized if SiteConfig.waiting_on_first_user && ENV["FOREM_OWNER_SECRET"].present? &&
|
||||
ENV["FOREM_OWNER_SECRET"] != params[:user][:forem_owner_secret]
|
||||
|
||||
|
|
@ -51,13 +52,13 @@ class RegistrationsController < Devise::RegistrationsController
|
|||
end
|
||||
|
||||
def recaptcha_verified?
|
||||
recaptcha_params = { secret_key: SiteConfig.recaptcha_secret_key }
|
||||
recaptcha_params = { secret_key: Settings::Authentication.recaptcha_secret_key }
|
||||
params["g-recaptcha-response"] && verify_recaptcha(recaptcha_params)
|
||||
end
|
||||
|
||||
def check_allowed_email(resource)
|
||||
domain = resource.email.split("@").last
|
||||
allow_list = SiteConfig.allowed_registration_email_domains
|
||||
allow_list = Settings::Authentication.allowed_registration_email_domains
|
||||
return if allow_list.empty? || allow_list.include?(domain)
|
||||
|
||||
resource.email = nil
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ module ApplicationHelper
|
|||
end
|
||||
|
||||
def invite_only_mode?
|
||||
SiteConfig.invite_only_mode?
|
||||
Settings::Authentication.invite_only_mode?
|
||||
end
|
||||
|
||||
def any_enabled_auth_providers?
|
||||
|
|
@ -274,7 +274,7 @@ module ApplicationHelper
|
|||
estimated_user_count > LARGE_USERBASE_THRESHOLD
|
||||
end
|
||||
|
||||
def admin_config_label(method, content = nil)
|
||||
def admin_config_label(method, content = nil, model: SiteConfig)
|
||||
content ||= tag.span(method.to_s.humanize)
|
||||
|
||||
if method.to_sym.in?(VerifySetupCompleted::MANDATORY_CONFIGS)
|
||||
|
|
@ -282,7 +282,8 @@ module ApplicationHelper
|
|||
content = safe_join([content, required])
|
||||
end
|
||||
|
||||
tag.label(content, class: "site-config__label crayons-field__label", for: "site_config_#{method}")
|
||||
label_prefix = model.name.split("::").map(&:underscore).join("_")
|
||||
tag.label(content, class: "site-config__label crayons-field__label", for: "#{label_prefix}_#{method}")
|
||||
end
|
||||
|
||||
def admin_config_description(content)
|
||||
|
|
|
|||
|
|
@ -46,8 +46,9 @@ module AuthenticationHelper
|
|||
end
|
||||
|
||||
def invite_only_mode_or_no_enabled_auth_options
|
||||
SiteConfig.invite_only_mode ||
|
||||
(authentication_enabled_providers.none? && !SiteConfig.allow_email_password_registration)
|
||||
Settings::Authentication.invite_only_mode ||
|
||||
(authentication_enabled_providers.none? &&
|
||||
!Settings::Authentication.allow_email_password_registration)
|
||||
end
|
||||
|
||||
def tooltip_class_on_auth_provider_enablebtn
|
||||
|
|
|
|||
|
|
@ -293,8 +293,12 @@ export default class ConfigController extends Controller {
|
|||
.forEach((provider) => {
|
||||
const { providerName } = provider.dataset;
|
||||
if (
|
||||
!document.getElementById(`site_config_${providerName}_key`).value ||
|
||||
!document.getElementById(`site_config_${providerName}_secret`).value
|
||||
!document.getElementById(
|
||||
`settings_authentication_${providerName}_key`,
|
||||
).value ||
|
||||
!document.getElementById(
|
||||
`settings_authentication_${providerName}_secret`,
|
||||
).value
|
||||
) {
|
||||
providersWithMissingKeys.push(providerName);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
import { callHistoricalAPI, callReferrersAPI } from './client';
|
||||
|
||||
function resetActive(activeButton) {
|
||||
const buttons = document.querySelectorAll('.crayons-tabs--analytics .crayons-tabs__item');
|
||||
const buttons = document.querySelectorAll(
|
||||
'.crayons-tabs--analytics .crayons-tabs__item',
|
||||
);
|
||||
for (let i = 0; i < buttons.length; i += 1) {
|
||||
const button = buttons[i];
|
||||
button.classList.remove('crayons-tabs__item--current');
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ function isFormField(element) {
|
|||
|
||||
/**
|
||||
* Function to handle converting key presses to callback functions
|
||||
*
|
||||
*
|
||||
* @param {KeyboardEvent} e Keyboard event
|
||||
* @param {String} keys special keys formatted in a string
|
||||
* @param {Array} chain array of past keys
|
||||
|
|
@ -96,7 +96,7 @@ export function useKeyboardShortcuts(
|
|||
const [keyChain, setKeyChain] = useState([]);
|
||||
const [mergedOptions, setMergedOptions] = useState({
|
||||
...defaultOptions,
|
||||
...options
|
||||
...options,
|
||||
});
|
||||
|
||||
// update mergedOptions if options prop changes
|
||||
|
|
|
|||
82
app/lib/constants/settings/authentication.rb
Normal file
82
app/lib/constants/settings/authentication.rb
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
module Constants
|
||||
module Settings
|
||||
module Authentication
|
||||
DETAILS = {
|
||||
allowed_registration_email_domains: {
|
||||
description: "Restrict registration to only certain emails? (comma-separated list)",
|
||||
placeholder: "dev.to, forem.com, codenewbie.org"
|
||||
},
|
||||
apple_client_id: {
|
||||
description:
|
||||
"The \"App Bundle\" code for the Authentication Service configured in the Apple Developer Portal",
|
||||
placeholder: "com.example.app"
|
||||
},
|
||||
apple_team_id: {
|
||||
description:
|
||||
"The \"Team ID\" of your Apple Developer Account",
|
||||
placeholder: ""
|
||||
},
|
||||
apple_key_id: {
|
||||
description:
|
||||
"The \"Key ID\" from the Authentication Service configured in the Apple Developer Portal",
|
||||
placeholder: ""
|
||||
},
|
||||
apple_pem: {
|
||||
description:
|
||||
"The \"PEM\" key from the Authentication Service configured in the Apple Developer Portal",
|
||||
placeholder: "-----BEGIN PRIVATE KEY-----\nMIGTAQrux...QPe8Yb\n-----END PRIVATE KEY-----\\n"
|
||||
},
|
||||
display_email_domain_allow_list_publicly: {
|
||||
description: "Do you want to display the list of allowed domains, or keep it private?"
|
||||
},
|
||||
facebook_key: {
|
||||
description:
|
||||
"The \"App ID\" portion of the Basic Settings section of the App page on the Facebook Developer Portal",
|
||||
placeholder: ""
|
||||
},
|
||||
facebook_secret: {
|
||||
description:
|
||||
"The \"App Secret\" portion of the Basic Settings section of the App page on the Facebook Developer Portal",
|
||||
placeholder: ""
|
||||
},
|
||||
github_key: {
|
||||
description: "The \"Client ID\" portion of the GitHub Oauth Apps portal",
|
||||
placeholder: ""
|
||||
},
|
||||
github_secret: {
|
||||
description: "The \"Client Secret\" portion of the GitHub Oauth Apps portal",
|
||||
placeholder: ""
|
||||
},
|
||||
invite_only_mode: {
|
||||
description: "Only users invited by email can join this community.",
|
||||
placeholder: ""
|
||||
},
|
||||
recaptcha_site_key: {
|
||||
description: "Add the site key for Google reCAPTCHA, which is used for reporting abuse",
|
||||
placeholder: "What is the Google reCAPTCHA site key?"
|
||||
},
|
||||
recaptcha_secret_key: {
|
||||
description: "Add the secret key for Google reCAPTCHA, which is used for reporting abuse",
|
||||
placeholder: "What is the Google reCAPTCHA secret key?"
|
||||
},
|
||||
require_captcha_for_email_password_registration: {
|
||||
description: "People will be required to fill out a captcha when
|
||||
they're creating a new account in your community",
|
||||
placeholder: ""
|
||||
},
|
||||
twitter_key: {
|
||||
description: "The \"API key\" portion of consumer keys in the Twitter developer portal.",
|
||||
placeholder: ""
|
||||
},
|
||||
twitter_secret: {
|
||||
description: "The \"API secret key\" portion of consumer keys in the Twitter developer portal.",
|
||||
placeholder: ""
|
||||
},
|
||||
providers: {
|
||||
description: "How can users sign in?",
|
||||
placeholder: ""
|
||||
}
|
||||
}.freeze
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -4,19 +4,6 @@ module Constants
|
|||
SVG_PLACEHOLDER = "<svg ...></svg>".freeze
|
||||
|
||||
DETAILS = {
|
||||
require_captcha_for_email_password_registration: {
|
||||
description: "People will be required to fill out a captcha when
|
||||
they're creating a new account in your community",
|
||||
placeholder: ""
|
||||
},
|
||||
allowed_registration_email_domains: {
|
||||
description: "Restrict registration to only certain emails? (comma-separated list)",
|
||||
placeholder: "dev.to, forem.com, codenewbie.org"
|
||||
},
|
||||
authentication_providers: {
|
||||
description: "How can users sign in?",
|
||||
placeholder: ""
|
||||
},
|
||||
campaign_articles_require_approval: {
|
||||
description: "",
|
||||
placeholder: "Campaign stories show up on sidebar with approval?"
|
||||
|
|
@ -90,9 +77,6 @@ module Constants
|
|||
default_font: {
|
||||
description: "Determines the default Base Reading Font (registered users can change this in their UX settings)"
|
||||
},
|
||||
display_email_domain_allow_list_publicly: {
|
||||
description: "Do you want to display the list of allowed domains, or keep it private?"
|
||||
},
|
||||
display_jobs_banner: {
|
||||
description: "Display a jobs banner that points users to the jobs page when they type 'job'" \
|
||||
"or 'jobs' in the search box",
|
||||
|
|
@ -110,36 +94,6 @@ module Constants
|
|||
description: "The label for the top of the experience level range of a post",
|
||||
placeholder: "Senior Devs"
|
||||
},
|
||||
facebook_key: {
|
||||
description:
|
||||
"The \"App ID\" portion of the Basic Settings section of the App page on the Facebook Developer Portal",
|
||||
placeholder: ""
|
||||
},
|
||||
facebook_secret: {
|
||||
description:
|
||||
"The \"App Secret\" portion of the Basic Settings section of the App page on the Facebook Developer Portal",
|
||||
placeholder: ""
|
||||
},
|
||||
apple_client_id: {
|
||||
description:
|
||||
"The \"App Bundle\" code for the Authentication Service configured in the Apple Developer Portal",
|
||||
placeholder: "com.example.app"
|
||||
},
|
||||
apple_team_id: {
|
||||
description:
|
||||
"The \"Team ID\" of your Apple Developer Account",
|
||||
placeholder: ""
|
||||
},
|
||||
apple_key_id: {
|
||||
description:
|
||||
"The \"Key ID\" from the Authentication Service configured in the Apple Developer Portal",
|
||||
placeholder: ""
|
||||
},
|
||||
apple_pem: {
|
||||
description:
|
||||
"The \"PEM\" key from the Authentication Service configured in the Apple Developer Portal",
|
||||
placeholder: "-----BEGIN PRIVATE KEY-----\nMIGTAQrux...QPe8Yb\n-----END PRIVATE KEY-----\\n"
|
||||
},
|
||||
favicon_url: {
|
||||
description: "Used as the site favicon",
|
||||
placeholder: IMAGE_PLACEHOLDER
|
||||
|
|
@ -157,14 +111,6 @@ module Constants
|
|||
description: "Determines background/border of buttons etc. Must be dark enough to contrast with white text.",
|
||||
placeholder: "#0a0a0a"
|
||||
},
|
||||
github_key: {
|
||||
description: "The \"Client ID\" portion of the GitHub Oauth Apps portal",
|
||||
placeholder: ""
|
||||
},
|
||||
github_secret: {
|
||||
description: "The \"Client Secret\" portion of the GitHub Oauth Apps portal",
|
||||
placeholder: ""
|
||||
},
|
||||
ga_tracking_id: {
|
||||
description: "Google Analytics Tracking ID, e.g. UA-71991000-1",
|
||||
placeholder: ""
|
||||
|
|
@ -177,10 +123,6 @@ module Constants
|
|||
description: "Minimum score needed for a post to show up on the unauthenticated home page.",
|
||||
placeholder: "0"
|
||||
},
|
||||
invite_only_mode: {
|
||||
description: "Only users invited by email can join this community.",
|
||||
placeholder: ""
|
||||
},
|
||||
jobs_url: {
|
||||
description: "URL of the website where open positions are posted",
|
||||
placeholder: "Jobs URL"
|
||||
|
|
@ -258,14 +200,6 @@ module Constants
|
|||
description: "Determines how often periodic email digests are sent",
|
||||
placeholder: 2
|
||||
},
|
||||
recaptcha_site_key: {
|
||||
description: "Add the site key for Google reCAPTCHA, which is used for reporting abuse",
|
||||
placeholder: "What is the Google reCAPTCHA site key?"
|
||||
},
|
||||
recaptcha_secret_key: {
|
||||
description: "Add the secret key for Google reCAPTCHA, which is used for reporting abuse",
|
||||
placeholder: "What is the Google reCAPTCHA secret key?"
|
||||
},
|
||||
secondary_logo_url: {
|
||||
description: "A place for an alternate logo, if you have one. Used throughout member onboarding and in some sign in forms.",
|
||||
placeholder: IMAGE_PLACEHOLDER
|
||||
|
|
@ -327,14 +261,6 @@ module Constants
|
|||
description: "Used as the twitter hashtag of the community",
|
||||
placeholder: "#DEVCommunity"
|
||||
},
|
||||
twitter_key: {
|
||||
description: "The \"API key\" portion of consumer keys in the Twitter developer portal.",
|
||||
placeholder: ""
|
||||
},
|
||||
twitter_secret: {
|
||||
description: "The \"API secret key\" portion of consumer keys in the Twitter developer portal.",
|
||||
placeholder: ""
|
||||
},
|
||||
user_considered_new_days: {
|
||||
description: "The number of days a user is considered new. The default is 3 days, but you can disable this entirely by inputting 0.",
|
||||
placeholder: ::SiteConfig.user_considered_new_days
|
||||
|
|
|
|||
44
app/models/settings/authentication.rb
Normal file
44
app/models/settings/authentication.rb
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
module Settings
|
||||
class Authentication < RailsSettings::Base
|
||||
self.table_name = :settings_authentications
|
||||
|
||||
# The configuration is cached, change this if you want to force update
|
||||
# the cache, or call Settings::Authentication.clear_cache
|
||||
cache_prefix { "v1" }
|
||||
|
||||
field :allow_email_password_login, type: :boolean, default: true
|
||||
field :allow_email_password_registration, type: :boolean, default: false
|
||||
field :allowed_registration_email_domains, type: :array, default: %w[], validates: {
|
||||
valid_domain_csv: true
|
||||
}
|
||||
field :apple_client_id, type: :string
|
||||
field :apple_key_id, type: :string
|
||||
field :apple_pem, type: :string
|
||||
field :apple_team_id, type: :string
|
||||
field :display_email_domain_allow_list_publicly, type: :boolean, default: false
|
||||
field :facebook_key, type: :string
|
||||
field :facebook_secret, type: :string
|
||||
field :github_key, type: :string, default: ApplicationConfig["GITHUB_KEY"]
|
||||
field :github_secret, type: :string, default: ApplicationConfig["GITHUB_SECRET"]
|
||||
field :invite_only_mode, type: :boolean, default: false
|
||||
field :providers, type: :array, default: %w[]
|
||||
field :require_captcha_for_email_password_registration, type: :boolean, default: false
|
||||
field :twitter_key, type: :string, default: ApplicationConfig["TWITTER_KEY"]
|
||||
field :twitter_secret, type: :string, default: ApplicationConfig["TWITTER_SECRET"]
|
||||
|
||||
# Google ReCATPCHA keys
|
||||
field :recaptcha_site_key, type: :string, default: ApplicationConfig["RECAPTCHA_SITE"]
|
||||
field :recaptcha_secret_key, type: :string, default: ApplicationConfig["RECAPTCHA_SECRET"]
|
||||
|
||||
# Apple uses different keys than the usual `PROVIDER_NAME_key` or
|
||||
# `PROVIDER_NAME_secret` so these will help the generalized authentication
|
||||
# code to work, i.e. https://github.com/forem/forem/blob/master/app/helpers/authentication_helper.rb#L26-L29
|
||||
def self.apple_key
|
||||
return unless apple_client_id.present? && apple_key_id.present? &&
|
||||
apple_pem.present? && apple_team_id.present?
|
||||
|
||||
"present"
|
||||
end
|
||||
singleton_class.alias_method(:apple_secret, :apple_key)
|
||||
end
|
||||
end
|
||||
|
|
@ -29,26 +29,12 @@ class SiteConfig < RailsSettings::Base
|
|||
field :health_check_token, type: :string
|
||||
field :video_encoder_key, type: :string
|
||||
|
||||
# Authentication
|
||||
field :allow_email_password_registration, type: :boolean, default: false
|
||||
field :allow_email_password_login, type: :boolean, default: true
|
||||
# NOTE: @citizen428 These two values will be removed once we fully migrated
|
||||
# to Settings::Authentication. Until then we need them for the data update script.
|
||||
field :allowed_registration_email_domains, type: :array, default: %w[], validates: {
|
||||
valid_domain_csv: true
|
||||
}
|
||||
field :display_email_domain_allow_list_publicly, type: :boolean, default: false
|
||||
field :require_captcha_for_email_password_registration, type: :boolean, default: false
|
||||
field :authentication_providers, type: :array, default: %w[]
|
||||
field :invite_only_mode, type: :boolean, default: false
|
||||
field :twitter_key, type: :string, default: ApplicationConfig["TWITTER_KEY"]
|
||||
field :twitter_secret, type: :string, default: ApplicationConfig["TWITTER_SECRET"]
|
||||
field :github_key, type: :string, default: ApplicationConfig["GITHUB_KEY"]
|
||||
field :github_secret, type: :string, default: ApplicationConfig["GITHUB_SECRET"]
|
||||
field :facebook_key, type: :string
|
||||
field :facebook_secret, type: :string
|
||||
field :apple_client_id, type: :string
|
||||
field :apple_key_id, type: :string
|
||||
field :apple_pem, type: :string
|
||||
field :apple_team_id, type: :string
|
||||
|
||||
# Campaign
|
||||
field :campaign_call_to_action, type: :string, default: "Share your project"
|
||||
|
|
@ -98,10 +84,6 @@ class SiteConfig < RailsSettings::Base
|
|||
# Google Analytics Tracking ID, e.g. UA-71991000-1
|
||||
field :ga_tracking_id, type: :string, default: ApplicationConfig["GA_TRACKING_ID"]
|
||||
|
||||
# Google ReCATPCHA keys
|
||||
field :recaptcha_site_key, type: :string, default: ApplicationConfig["RECAPTCHA_SITE"]
|
||||
field :recaptcha_secret_key, type: :string, default: ApplicationConfig["RECAPTCHA_SECRET"]
|
||||
|
||||
# Images
|
||||
field :main_social_image,
|
||||
type: :string,
|
||||
|
|
@ -248,17 +230,6 @@ class SiteConfig < RailsSettings::Base
|
|||
app_domain == "dev.to"
|
||||
end
|
||||
|
||||
# Apple uses different keys than the usual `PROVIDER_NAME_key` or
|
||||
# `PROVIDER_NAME_secret` so these will help the generalized authentication
|
||||
# code to work, i.e. https://github.com/forem/forem/blob/master/app/helpers/authentication_helper.rb#L26-L29
|
||||
def self.apple_key
|
||||
return unless apple_client_id.present? && apple_key_id.present? &&
|
||||
apple_pem.present? && apple_team_id.present?
|
||||
|
||||
"present"
|
||||
end
|
||||
singleton_class.__send__(:alias_method, :apple_secret, :apple_key)
|
||||
|
||||
# To get default values
|
||||
def self.get_default(field)
|
||||
get_field(field)[:default]
|
||||
|
|
|
|||
|
|
@ -44,9 +44,9 @@ module Authentication
|
|||
# TODO: [@forem/oss] ideally this should be "available - disabled"
|
||||
# we can get there once we have feature flags
|
||||
def self.enabled
|
||||
return [] if SiteConfig.invite_only_mode
|
||||
return [] if Settings::Authentication.invite_only_mode
|
||||
|
||||
SiteConfig.authentication_providers.map(&:to_sym).sort
|
||||
Settings::Authentication.providers.map(&:to_sym).sort
|
||||
end
|
||||
|
||||
def self.enabled_for_user(user)
|
||||
|
|
|
|||
68
app/services/authentication/settings_upsert.rb
Normal file
68
app/services/authentication/settings_upsert.rb
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
module Authentication
|
||||
class SettingsUpsert
|
||||
attr_reader :errors
|
||||
|
||||
def self.call(configs)
|
||||
new(configs).call
|
||||
end
|
||||
|
||||
def initialize(configs)
|
||||
@configs = configs
|
||||
@errors = []
|
||||
end
|
||||
|
||||
def call
|
||||
upsert_configs
|
||||
self
|
||||
end
|
||||
|
||||
def success?
|
||||
@errors.none?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# NOTE: @citizen428 - This was adapted from Settings::Upsert. I'll see if
|
||||
# a pattern for refactoring emerges in the future, but for now I'll leave
|
||||
# this as-is.
|
||||
def upsert_configs
|
||||
@configs.each do |key, value|
|
||||
if key == "auth_providers_to_enable"
|
||||
update_enabled_providers(value) unless value.class.name != "String"
|
||||
elsif value.is_a?(Array) && value.any?
|
||||
Settings::Authentication.public_send("#{key}=", value.reject(&:blank?))
|
||||
elsif value.present?
|
||||
Settings::Authentication.public_send("#{key}=", value.strip)
|
||||
end
|
||||
rescue ActiveRecord::RecordInvalid => e
|
||||
@errors << e.message
|
||||
next
|
||||
end
|
||||
end
|
||||
|
||||
def update_enabled_providers(value)
|
||||
enabled_providers = value.split(",").filter_map do |entry|
|
||||
entry unless invalid_provider_entry(entry)
|
||||
end
|
||||
return if email_login_disabled_with_one_or_less_auth_providers(enabled_providers)
|
||||
|
||||
Settings::Authentication.providers = enabled_providers
|
||||
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)
|
||||
Settings::Authentication.public_send("#{entry}_key").blank? ||
|
||||
Settings::Authentication.public_send("#{entry}_secret").blank?
|
||||
end
|
||||
|
||||
def email_login_disabled_with_one_or_less_auth_providers(enabled_providers)
|
||||
!Settings::Authentication.allow_email_password_login &&
|
||||
enabled_providers.count <= 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -7,8 +7,8 @@ module Github
|
|||
# @param credentials [Hash] the OAuth credentials, {client_id:, client_secret:} or {access_token:}
|
||||
def initialize(credentials = nil)
|
||||
credentials ||= {
|
||||
client_id: SiteConfig.github_key,
|
||||
client_secret: SiteConfig.github_secret
|
||||
client_id: Settings::Authentication.github_key,
|
||||
client_secret: Settings::Authentication.github_secret
|
||||
}
|
||||
@credentials = check_credentials!(credentials)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -31,7 +31,8 @@ module ReCaptcha
|
|||
private
|
||||
|
||||
def keys_configured?
|
||||
SiteConfig.recaptcha_site_key.present? && SiteConfig.recaptcha_secret_key.present?
|
||||
Settings::Authentication.recaptcha_site_key.present? &&
|
||||
Settings::Authentication.recaptcha_secret_key.present?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,13 +1,10 @@
|
|||
module ReCaptcha
|
||||
class CheckRegistrationEnabled
|
||||
def self.call
|
||||
new.call
|
||||
end
|
||||
|
||||
def call
|
||||
# ReCaptcha::CheckEnabled.call without a user parameter will return `true`
|
||||
# if the ReCaptcha SiteConfig keys are configured, and `false` otherwise
|
||||
ReCaptcha::CheckEnabled.call && SiteConfig.require_captcha_for_email_password_registration
|
||||
ReCaptcha::CheckEnabled.call &&
|
||||
Settings::Authentication.require_captcha_for_email_password_registration
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
module SiteConfigs
|
||||
module Settings
|
||||
class Upsert
|
||||
EMOJI_ONLY_FIELDS = %w[community_emoji].freeze
|
||||
VALID_DOMAIN = /^[a-zA-Z0-9]{1,61}[a-zA-Z0-9](?:\.[a-zA-Z]{2,})+$/.freeze
|
||||
|
|
@ -34,9 +34,7 @@ module SiteConfigs
|
|||
|
||||
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)
|
||||
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?
|
||||
|
|
@ -60,27 +58,6 @@ module SiteConfigs
|
|||
@configs[:credit_prices_in_cents]&.transform_values!(&:to_i)
|
||||
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
|
||||
|
||||
def create_tags_if_not_created
|
||||
# Bulk create tags if they should exist.
|
||||
# This is an acts-as-taggable-on as used on saving of an Article, etc.
|
||||
|
|
@ -57,8 +57,8 @@ module TwitterClient
|
|||
|
||||
def target
|
||||
Twitter::REST::Client.new(
|
||||
consumer_key: SiteConfig.twitter_key.presence || ApplicationConfig["TWITTER_KEY"],
|
||||
consumer_secret: SiteConfig.twitter_secret.presence || ApplicationConfig["TWITTER_SECRET"],
|
||||
consumer_key: Settings::Authentication.twitter_key.presence || ApplicationConfig["TWITTER_KEY"],
|
||||
consumer_secret: Settings::Authentication.twitter_secret.presence || ApplicationConfig["TWITTER_SECRET"],
|
||||
user_agent: "TwitterRubyGem/#{Twitter::Version} (#{URL.url})",
|
||||
timeouts: {
|
||||
connect: 5,
|
||||
|
|
|
|||
|
|
@ -11,42 +11,42 @@ requires a custom partial
|
|||
<div class="crayons-field">
|
||||
<%= admin_config_label :apple_client_id %>
|
||||
<p class="crayons-field__description">
|
||||
<%= Constants::SiteConfig::DETAILS[:apple_client_id][:description] %>
|
||||
<%= Constants::Settings::Authentication::DETAILS[:apple_client_id][:description] %>
|
||||
</p>
|
||||
<%= f.text_field :apple_client_id,
|
||||
class: "crayons-textfield",
|
||||
value: SiteConfig.apple_client_id,
|
||||
placeholder: Constants::SiteConfig::DETAILS[:apple_client_id][:placeholder] %>
|
||||
value: Settings::Authentication.apple_client_id,
|
||||
placeholder: Constants::Settings::Authentication::DETAILS[:apple_client_id][:placeholder] %>
|
||||
</div>
|
||||
<div class="crayons-field">
|
||||
<%= admin_config_label :apple_key_id %>
|
||||
<p class="crayons-field__description">
|
||||
<%= Constants::SiteConfig::DETAILS[:apple_key_id][:description] %>
|
||||
<%= Constants::Settings::Authentication::DETAILS[:apple_key_id][:description] %>
|
||||
<p>
|
||||
<%= f.text_field :apple_key_id,
|
||||
class: "crayons-textfield",
|
||||
value: SiteConfig.apple_key_id,
|
||||
placeholder: Constants::SiteConfig::DETAILS[:apple_key_id][:placeholder] %>
|
||||
value: Settings::Authentication.apple_key_id,
|
||||
placeholder: Constants::Settings::Authentication::DETAILS[:apple_key_id][:placeholder] %>
|
||||
</div>
|
||||
<div class="crayons-field">
|
||||
<%= admin_config_label :apple_pem %>
|
||||
<p class="crayons-field__description">
|
||||
<%= Constants::SiteConfig::DETAILS[:apple_pem][:description] %>
|
||||
<%= Constants::Settings::Authentication::DETAILS[:apple_pem][:description] %>
|
||||
<p>
|
||||
<%= f.text_field :apple_pem,
|
||||
class: "crayons-textfield",
|
||||
value: SiteConfig.apple_pem,
|
||||
placeholder: Constants::SiteConfig::DETAILS[:apple_pem][:placeholder] %>
|
||||
value: Settings::Authentication.apple_pem,
|
||||
placeholder: Constants::Settings::Authentication::DETAILS[:apple_pem][:placeholder] %>
|
||||
</div>
|
||||
<div class="crayons-field">
|
||||
<%= admin_config_label :apple_team_id %>
|
||||
<p class="crayons-field__description">
|
||||
<%= Constants::SiteConfig::DETAILS[:apple_team_id][:description] %>
|
||||
<%= Constants::Settings::Authentication::DETAILS[:apple_team_id][:description] %>
|
||||
<p>
|
||||
<%= f.text_field :apple_team_id,
|
||||
class: "crayons-textfield",
|
||||
value: SiteConfig.apple_team_id,
|
||||
placeholder: Constants::SiteConfig::DETAILS[:apple_team_id][:placeholder] %>
|
||||
value: Settings::Authentication.apple_team_id,
|
||||
placeholder: Constants::Settings::Authentication::DETAILS[:apple_team_id][:placeholder] %>
|
||||
</div>
|
||||
<div class="crayons-btn-actions">
|
||||
<% if authentication_provider_enabled?(provider) %>
|
||||
|
|
|
|||
|
|
@ -2,22 +2,22 @@
|
|||
<div class="crayons-field">
|
||||
<%= admin_config_label :"#{provider.provider_name}_key" %>
|
||||
<p class="crayons-field__description">
|
||||
<%= Constants::SiteConfig::DETAILS[:"#{provider.provider_name}_key"][:description] %>
|
||||
<%= Constants::Settings::Authentication::DETAILS[:"#{provider.provider_name}_key"][:description] %>
|
||||
</p>
|
||||
<%= f.text_field :"#{provider.provider_name}_key",
|
||||
class: "crayons-textfield",
|
||||
value: SiteConfig.public_send("#{provider.provider_name}_key"),
|
||||
placeholder: Constants::SiteConfig::DETAILS[:"#{provider.provider_name}_key"][:placeholder] %>
|
||||
value: Settings::Authentication.public_send("#{provider.provider_name}_key"),
|
||||
placeholder: Constants::Settings::Authentication::DETAILS[:"#{provider.provider_name}_key"][:placeholder] %>
|
||||
</div>
|
||||
<div class="crayons-field">
|
||||
<%= admin_config_label :"#{provider.provider_name}_secret" %>
|
||||
<p class="crayons-field__description">
|
||||
<%= Constants::SiteConfig::DETAILS[:"#{provider.provider_name}_secret"][:description] %>
|
||||
<%= Constants::Settings::Authentication::DETAILS[:"#{provider.provider_name}_secret"][:description] %>
|
||||
<p>
|
||||
<%= f.text_field :"#{provider.provider_name}_secret",
|
||||
class: "crayons-textfield",
|
||||
value: SiteConfig.public_send("#{provider.provider_name}_secret"),
|
||||
placeholder: Constants::SiteConfig::DETAILS[:"#{provider.provider_name}_secret"][:placeholder] %>
|
||||
value: Settings::Authentication.public_send("#{provider.provider_name}_secret"),
|
||||
placeholder: Constants::Settings::Authentication::DETAILS[:"#{provider.provider_name}_secret"][:placeholder] %>
|
||||
</div>
|
||||
<div class="crayons-btn-actions">
|
||||
<% if authentication_provider_enabled?(provider) %>
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -24,7 +24,7 @@
|
|||
</div>
|
||||
<% else %>
|
||||
<div class="registration__actions-email" id="sign-in-password-form">
|
||||
<% if SiteConfig.allow_email_password_login %>
|
||||
<% if Settings::Authentication.allow_email_password_login %>
|
||||
<div class="registration__hr">
|
||||
<span class="registration__hr-label">
|
||||
Have a password? Continue with your email address
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<% title "Welcome!" %>
|
||||
|
||||
<% if params[:state] == "email_signup" && SiteConfig.allow_email_password_registration %>
|
||||
<% if params[:state] == "email_signup" && Settings::Authentication.allow_email_password_registration %>
|
||||
<%= render "shared/authentication/email_registration_form" %>
|
||||
<% elsif params[:state] == "email_signup" %>
|
||||
<div class="crayons-notice crayons-notice--danger mb-10 mt-8 mx-auto" style="width: 680px;max-width:94%;">
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@
|
|||
|
||||
<% if ReCaptcha::CheckEnabled.call(current_user) %>
|
||||
<div class="recaptcha-tag-container">
|
||||
<%= recaptcha_tags site_key: SiteConfig.recaptcha_site_key %>
|
||||
<%= recaptcha_tags site_key: Settings::Authentication.recaptcha_site_key %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
|
|
|
|||
|
|
@ -29,15 +29,15 @@
|
|||
<% else %>
|
||||
<p class="pb-4 fw-bold">Create your account</p>
|
||||
<% end %>
|
||||
<% if SiteConfig.display_email_domain_allow_list_publicly &&
|
||||
SiteConfig.allowed_registration_email_domains.any? %>
|
||||
<% if Settings::Authentication.display_email_domain_allow_list_publicly &&
|
||||
Settings::Authentication.allowed_registration_email_domains.any? %>
|
||||
<div class="crayons-notice crayons-notice--info">
|
||||
<% if SiteConfig.allowed_registration_email_domains.one? %>
|
||||
Registration restricted to <strong>@<%= SiteConfig.allowed_registration_email_domains.first %></strong> emails.
|
||||
<% if Settings::Authentication.allowed_registration_email_domains.one? %>
|
||||
Registration restricted to <strong>@<%= Settings::Authentication.allowed_registration_email_domains.first %></strong> emails.
|
||||
<% else %>
|
||||
Registration restricted to the following emails
|
||||
<ul>
|
||||
<% SiteConfig.allowed_registration_email_domains.each do |domain| %>
|
||||
<% Settings::Authentication.allowed_registration_email_domains.each do |domain| %>
|
||||
<li>
|
||||
<strong>@<%= domain %></strong></strong>
|
||||
</li>
|
||||
|
|
@ -89,7 +89,7 @@
|
|||
|
||||
<% if ReCaptcha::CheckRegistrationEnabled.call %>
|
||||
<div class="recaptcha-tag-container mt-2">
|
||||
<%= recaptcha_tags site_key: SiteConfig.recaptcha_site_key %>
|
||||
<%= recaptcha_tags site_key: Settings::Authentication.recaptcha_site_key %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% if params[:state] == "new-user" && SiteConfig.allow_email_password_registration && !SiteConfig.invite_only_mode %>
|
||||
<% if params[:state] == "new-user" && Settings::Authentication.allow_email_password_registration && !Settings::Authentication.invite_only_mode %>
|
||||
<%= link_to "#{inline_svg_tag('email.svg', aria: true, class: 'crayons-icon', title: 'email')}Sign up with Email".html_safe,
|
||||
request.params.merge(state: "email_signup").except("i"),
|
||||
class: "crayons-btn crayons-btn--l crayons-btn--brand-email crayons-btn--icon-left whitespace-nowrap",
|
||||
|
|
|
|||
|
|
@ -1,27 +1,27 @@
|
|||
TWITTER_OMNIAUTH_SETUP = lambda do |env|
|
||||
env["omniauth.strategy"].options[:consumer_key] = SiteConfig.twitter_key
|
||||
env["omniauth.strategy"].options[:consumer_secret] = SiteConfig.twitter_secret
|
||||
env["omniauth.strategy"].options[:consumer_key] = Settings::Authentication.twitter_key
|
||||
env["omniauth.strategy"].options[:consumer_secret] = Settings::Authentication.twitter_secret
|
||||
end
|
||||
|
||||
GITHUB_OMNIUATH_SETUP = lambda do |env|
|
||||
env["omniauth.strategy"].options[:client_id] = SiteConfig.github_key
|
||||
env["omniauth.strategy"].options[:client_secret] = SiteConfig.github_secret
|
||||
env["omniauth.strategy"].options[:client_id] = Settings::Authentication.github_key
|
||||
env["omniauth.strategy"].options[:client_secret] = Settings::Authentication.github_secret
|
||||
env["omniauth.strategy"].options[:scope] = "user:email"
|
||||
end
|
||||
|
||||
FACEBOOK_OMNIAUTH_SETUP = lambda do |env|
|
||||
env["omniauth.strategy"].options[:client_id] = SiteConfig.facebook_key
|
||||
env["omniauth.strategy"].options[:client_secret] = SiteConfig.facebook_secret
|
||||
env["omniauth.strategy"].options[:client_id] = Settings::Authentication.facebook_key
|
||||
env["omniauth.strategy"].options[:client_secret] = Settings::Authentication.facebook_secret
|
||||
env["omniauth.strategy"].options[:token_params][:parse] = :json
|
||||
end
|
||||
|
||||
APPLE_OMNIAUTH_SETUP = lambda do |env|
|
||||
env["omniauth.strategy"].options[:client_id] = SiteConfig.apple_client_id
|
||||
env["omniauth.strategy"].options[:client_id] = Settings::Authentication.apple_client_id
|
||||
env["omniauth.strategy"].options[:scope] = "email name"
|
||||
env["omniauth.strategy"].options[:key_id] = SiteConfig.apple_key_id
|
||||
env["omniauth.strategy"].options[:pem] = SiteConfig.apple_pem.to_s.gsub("\\n", "\n")
|
||||
env["omniauth.strategy"].options[:key_id] = Settings::Authentication.apple_key_id
|
||||
env["omniauth.strategy"].options[:pem] = Settings::Authentication.apple_pem.to_s.gsub("\\n", "\n")
|
||||
env["omniauth.strategy"].options[:provider_ignores_state] = true
|
||||
env["omniauth.strategy"].options[:team_id] = SiteConfig.apple_team_id
|
||||
env["omniauth.strategy"].options[:team_id] = Settings::Authentication.apple_team_id
|
||||
end
|
||||
|
||||
Devise.setup do |config|
|
||||
|
|
|
|||
44
config/initializers/rails_settings.rb
Normal file
44
config/initializers/rails_settings.rb
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
require "request_store"
|
||||
|
||||
# Completely remove original implementation
|
||||
RailsSettings.__send__(:remove_const, :RequestCache)
|
||||
|
||||
module RailsSettings
|
||||
class Base < ActiveRecord::Base # rubocop:disable Rails/ApplicationRecord
|
||||
def self.inherited(subclass)
|
||||
super
|
||||
|
||||
# Define a unique RequestCache class for each settings klass
|
||||
request_cache = Class.new(ActiveSupport::CurrentAttributes) do
|
||||
attribute :settings
|
||||
end
|
||||
subclass.const_set(:RequestCache, request_cache)
|
||||
|
||||
# Override existing methods to use the local RequestCache class
|
||||
subclass.instance_eval do
|
||||
define_singleton_method(:cache_key) do
|
||||
subclass_cache_key = subclass.name.underscore.tr("/", "_")
|
||||
scope = [subclass_cache_key]
|
||||
scope << @cache_prefix.call if @cache_prefix
|
||||
scope.join("/")
|
||||
end
|
||||
|
||||
define_singleton_method(:clear_cache) do
|
||||
subclass::RequestCache.reset
|
||||
Rails.cache.delete(cache_key)
|
||||
end
|
||||
|
||||
define_singleton_method(:_all_settings) do
|
||||
subclass::RequestCache.settings ||=
|
||||
Rails.cache.fetch(cache_key, expires_in: 1.week) do
|
||||
vars = unscoped.select("var, value")
|
||||
result = {}
|
||||
vars.each { |record| result[record.var] = record.value }
|
||||
result.with_indifferent_access
|
||||
end
|
||||
end
|
||||
singleton_class.instance_eval { private :_all_settings }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -53,6 +53,9 @@ Rails.application.routes.draw do
|
|||
resources :organization_memberships, only: %i[update destroy create]
|
||||
resources :permissions, only: %i[index]
|
||||
resources :reactions, only: [:update]
|
||||
namespace :settings do
|
||||
resources :authentications, only: [:create]
|
||||
end
|
||||
namespace :users do
|
||||
resources :gdpr_delete_requests, only: %i[index destroy]
|
||||
end
|
||||
|
|
|
|||
|
|
@ -91,7 +91,6 @@ describe('Authentication Section', () => {
|
|||
.findByText('Update Site Configuration')
|
||||
.click();
|
||||
|
||||
cy.findByText('Setup not complete').should('be.visible');
|
||||
cy.get('.crayons-modal__box__body > ul > li')
|
||||
.contains('facebook')
|
||||
.should('be.visible');
|
||||
|
|
@ -107,8 +106,8 @@ describe('Authentication Section', () => {
|
|||
|
||||
cy.get('@authSectionForm').findByText('Authentication').click();
|
||||
cy.get('#facebook-auth-btn').click();
|
||||
cy.get('#site_config_facebook_key').type('randomkey');
|
||||
cy.get('#site_config_facebook_secret').type('randomsecret');
|
||||
cy.get('#settings_authentication_facebook_key').type('randomkey');
|
||||
cy.get('#settings_authentication_facebook_secret').type('randomsecret');
|
||||
cy.get('@user').then(({ username }) => {
|
||||
cy.get('@authSectionForm')
|
||||
.findByPlaceholderText('Confirmation text')
|
||||
|
|
|
|||
|
|
@ -127,16 +127,16 @@ Cypress.Commands.add(
|
|||
) => {
|
||||
return cy.request(
|
||||
'POST',
|
||||
'/admin/config',
|
||||
`utf8=%E2%9C%93&site_config%5Binvite_only_mode%5D=${toPayload(
|
||||
'/admin/settings/authentications',
|
||||
`utf8=%E2%9C%93&settings_authentication%5Binvite_only_mode%5D=${toPayload(
|
||||
inviteOnlyMode,
|
||||
)}&site_config%5Ballow_email_password_registration%5D=${toPayload(
|
||||
)}&settings_authentication%5Ballow_email_password_registration%5D=${toPayload(
|
||||
emailRegistration,
|
||||
)}&site_config%5Ballowed_registration_email_domains%5D=${allowedEmailDomains}&site_config%5Bdisplay_email_domain_allow_list_publicly%5D=${toPayload(
|
||||
)}&settings_authentication%5Ballowed_registration_email_domains%5D=${allowedEmailDomains}&settings_authentication%5Bdisplay_email_domain_allow_list_publicly%5D=${toPayload(
|
||||
publicEmailDomainList,
|
||||
)}&site_config%5Brequire_captcha_for_email_password_registration%5D=${toPayload(
|
||||
)}&settings_authentication%5Brequire_captcha_for_email_password_registration%5D=${toPayload(
|
||||
requireRecaptcha,
|
||||
)}&site_config%5Brecaptcha_site_key%5D=${recaptchaSiteKey}&site_config%5Brecaptcha_secret_key%5D=${recaptchaSecretKey}&site_config%5Bauth_providers_to_enable%5D=${authProvidersToEnable}&site_config%5Bfacebook_key%5D=${facebookKey}&site_config%5Bfacebook_secret%5D=${facebookSecret}&site_config%5Bgithub_key%5D=${githubKey}&site_config%5Bgithub_secret%5D=${githubSecret}&site_config%5Btwitter_key%5D=${twitterKey}&site_config%5Btwitter_secret%5D=${twitterSecret}&confirmation=My+username+is+%40${username}+and+this+action+is+100%25+safe+and+appropriate.&commit=Update+Site+Configuration`,
|
||||
)}&settings_authentication%5Brecaptcha_site_key%5D=${recaptchaSiteKey}&settings_authentication%5Brecaptcha_secret_key%5D=${recaptchaSecretKey}&settings_authentication%5Bauth_providers_to_enable%5D=${authProvidersToEnable}&settings_authentication%5Bfacebook_key%5D=${facebookKey}&settings_authentication%5Bfacebook_secret%5D=${facebookSecret}&settings_authentication%5Bgithub_key%5D=${githubKey}&settings_authentication%5Bgithub_secret%5D=${githubSecret}&settings_authentication%5Btwitter_key%5D=${twitterKey}&settings_authentication%5Btwitter_secret%5D=${twitterSecret}&confirmation=My+username+is+%40${username}+and+this+action+is+100%25+safe+and+appropriate.&commit=Update+Site+Configuration`,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
|
|
|||
16
db/migrate/20210316091102_create_settings.rb
Normal file
16
db/migrate/20210316091102_create_settings.rb
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
class CreateSettings < ActiveRecord::Migration[6.0]
|
||||
def self.up
|
||||
create_table :settings_authentications do |t|
|
||||
t.string :var, null: false
|
||||
t.text :value, null: true
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
|
||||
add_index :settings_authentications, :var, unique: true
|
||||
end
|
||||
|
||||
def self.down
|
||||
drop_table :settings_authentications
|
||||
end
|
||||
end
|
||||
|
|
@ -1048,6 +1048,14 @@ ActiveRecord::Schema.define(version: 2021_03_31_181505) do
|
|||
t.index ["name"], name: "index_roles_on_name"
|
||||
end
|
||||
|
||||
create_table "settings_authentications", force: :cascade do |t|
|
||||
t.datetime "created_at", precision: 6, null: false
|
||||
t.datetime "updated_at", precision: 6, null: false
|
||||
t.text "value"
|
||||
t.string "var", null: false
|
||||
t.index ["var"], name: "index_settings_authentications_on_var", unique: true
|
||||
end
|
||||
|
||||
create_table "site_configs", force: :cascade do |t|
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ puts "Seeding with multiplication factor: #{SEEDS_MULTIPLIER}\n\n"
|
|||
|
||||
SiteConfig.public = true
|
||||
SiteConfig.waiting_on_first_user = false
|
||||
SiteConfig.authentication_providers = Authentication::Providers.available
|
||||
Settings::Authentication.providers = Authentication::Providers.available
|
||||
|
||||
##############################################################################
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
module DataUpdateScripts
|
||||
class MoveAuthenticationSettings
|
||||
AUTHENTICATION_SETTINGS = %w[
|
||||
allow_email_password_login
|
||||
allow_email_password_registration
|
||||
apple_client_id
|
||||
apple_key_id
|
||||
apple_pem
|
||||
apple_team_id
|
||||
display_email_domain_allow_list_publicly
|
||||
facebook_key
|
||||
facebook_secret
|
||||
github_key
|
||||
github_secret
|
||||
invite_only_mode
|
||||
require_captcha_for_email_password_registration
|
||||
twitter_key
|
||||
twitter_secret
|
||||
].freeze
|
||||
|
||||
ATTRIBUTES = %i[var value created_at updated_at].freeze
|
||||
|
||||
def run
|
||||
return if Settings::Authentication.any?
|
||||
|
||||
SiteConfig.transaction do
|
||||
config_relation = SiteConfig.where(var: AUTHENTICATION_SETTINGS)
|
||||
config_values = config_relation.pluck(*ATTRIBUTES).map do |values|
|
||||
ATTRIBUTES.zip(values).to_h
|
||||
end
|
||||
Settings::Authentication.insert_all(config_values) if config_values.present?
|
||||
|
||||
# This field has a validation we don't want to skip
|
||||
Settings::Authentication.allowed_registration_email_domains =
|
||||
SiteConfig.allowed_registration_email_domains
|
||||
|
||||
# This field got renamed so we migrate it explicitly
|
||||
Settings::Authentication.providers = SiteConfig.authentication_providers
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -58,8 +58,8 @@ RSpec.describe AuthenticationHelper, type: :helper do
|
|||
|
||||
describe "#authentication_provider_enabled?" do
|
||||
before do
|
||||
allow(SiteConfig).to receive(:invite_only_mode).and_return(false)
|
||||
allow(SiteConfig).to receive(:authentication_providers).and_return(%i[twitter github])
|
||||
allow(Settings::Authentication).to receive(:invite_only_mode).and_return(false)
|
||||
allow(Settings::Authentication).to receive(:providers).and_return(%i[twitter github])
|
||||
end
|
||||
|
||||
it "returns true when a provider has been enabled" do
|
||||
|
|
@ -76,9 +76,9 @@ RSpec.describe AuthenticationHelper, type: :helper do
|
|||
describe "tooltip classes, attributes and content" do
|
||||
context "when invite-only-mode enabled and no enabled registration options" do
|
||||
before do
|
||||
allow(SiteConfig).to receive(:invite_only_mode).and_return(true)
|
||||
allow(SiteConfig).to receive(:authentication_providers).and_return([])
|
||||
allow(SiteConfig).to receive(:allow_email_password_registration).and_return(false)
|
||||
allow(Settings::Authentication).to receive(:invite_only_mode).and_return(true)
|
||||
allow(Settings::Authentication).to receive(:providers).and_return([])
|
||||
allow(Settings::Authentication).to receive(:allow_email_password_registration).and_return(false)
|
||||
end
|
||||
|
||||
it "returns 'crayons-tooltip' class for relevant helpers" do
|
||||
|
|
|
|||
19
spec/models/settings/authentication_spec.rb
Normal file
19
spec/models/settings/authentication_spec.rb
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
require "rails_helper"
|
||||
|
||||
RSpec.describe Settings::Authentication, type: :model do
|
||||
describe "validations" do
|
||||
describe "validating domain lists" do
|
||||
it "allows valid domain lists" do
|
||||
expect do
|
||||
described_class.allowed_registration_email_domains = "example.com, example2.com"
|
||||
end.not_to raise_error
|
||||
end
|
||||
|
||||
it "rejects invalid domain lists" do
|
||||
expect do
|
||||
described_class.allowed_registration_email_domains = "example.com, e.c"
|
||||
end.to raise_error(/must be a comma-separated list of valid domains/)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -27,20 +27,6 @@ RSpec.describe SiteConfig, type: :model do
|
|||
end
|
||||
end
|
||||
|
||||
describe "validating domain lists" do
|
||||
it "allows valid domain lists" do
|
||||
expect do
|
||||
described_class.allowed_registration_email_domains = "example.com, example2.com"
|
||||
end.not_to raise_error
|
||||
end
|
||||
|
||||
it "rejects invalid domain lists" do
|
||||
expect do
|
||||
described_class.allowed_registration_email_domains = "example.com, e.c"
|
||||
end.to raise_error(/must be a comma-separated list of valid domains/)
|
||||
end
|
||||
end
|
||||
|
||||
describe "validating emojis strings" do
|
||||
it "allows emoji-only strings" do
|
||||
expect do
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ RSpec.describe User, type: :model do
|
|||
|
||||
before do
|
||||
omniauth_mock_providers_payload
|
||||
allow(SiteConfig).to receive(:authentication_providers).and_return(Authentication::Providers.available)
|
||||
allow(Settings::Authentication).to receive(:providers).and_return(Authentication::Providers.available)
|
||||
end
|
||||
|
||||
describe "validations" do
|
||||
|
|
@ -884,7 +884,7 @@ RSpec.describe User, type: :model do
|
|||
end
|
||||
|
||||
it "returns true if the user has all the enabled providers" do
|
||||
allow(SiteConfig).to receive(:authentication_providers).and_return(Authentication::Providers.available)
|
||||
allow(Settings::Authentication).to receive(:providers).and_return(Authentication::Providers.available)
|
||||
|
||||
user = create(:user, :with_identity)
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ RSpec.describe GithubRepoPolicy, type: :policy do
|
|||
|
||||
before do
|
||||
omniauth_mock_github_payload
|
||||
allow(SiteConfig).to receive(:authentication_providers).and_return(Authentication::Providers.available)
|
||||
allow(Settings::Authentication).to receive(:providers).and_return(Authentication::Providers.available)
|
||||
end
|
||||
|
||||
it { is_expected.to permit_actions(%i[index update_or_create]) }
|
||||
|
|
|
|||
|
|
@ -48,13 +48,12 @@ RSpec.describe "/admin/config", type: :request do
|
|||
end
|
||||
|
||||
it "updates site config admin action taken" do
|
||||
Timecop.freeze do
|
||||
expect(SiteConfig.admin_action_taken_at).not_to eq(5.minutes.ago)
|
||||
allow(SiteConfig).to receive(:admin_action_taken_at).and_return(5.minutes.ago)
|
||||
post "/admin/config", params: { site_config: { health_check_token: "token" },
|
||||
confirmation: confirmation_message }
|
||||
expect(SiteConfig.admin_action_taken_at).to eq(5.minutes.ago)
|
||||
end
|
||||
expect do
|
||||
post "/admin/config", params: {
|
||||
site_config: { health_check_token: "token" },
|
||||
confirmation: confirmation_message
|
||||
}
|
||||
end.to change(SiteConfig, :admin_action_taken_at)
|
||||
end
|
||||
|
||||
describe "API tokens" do
|
||||
|
|
@ -75,15 +74,15 @@ RSpec.describe "/admin/config", type: :request do
|
|||
describe "Authentication" do
|
||||
it "updates enabled authentication providers" do
|
||||
enabled = Authentication::Providers.available.last.to_s
|
||||
post admin_config_path, params: {
|
||||
site_config: {
|
||||
post admin_settings_authentications_path, params: {
|
||||
settings_authentication: {
|
||||
"#{enabled}_key": "someKey",
|
||||
"#{enabled}_secret": "someSecret",
|
||||
auth_providers_to_enable: enabled
|
||||
},
|
||||
confirmation: confirmation_message
|
||||
}
|
||||
expect(SiteConfig.authentication_providers).to eq([enabled])
|
||||
expect(Settings::Authentication.providers).to eq([enabled])
|
||||
end
|
||||
|
||||
describe "Campaigns" do
|
||||
|
|
@ -97,81 +96,97 @@ RSpec.describe "/admin/config", type: :request do
|
|||
it "strips empty elements" do
|
||||
provider = Authentication::Providers.available.last.to_s
|
||||
enabled = "#{provider}, '', nil"
|
||||
post admin_config_path, params: {
|
||||
site_config: {
|
||||
post admin_settings_authentications_path, params: {
|
||||
settings_authentication: {
|
||||
"#{provider}_key": "someKey",
|
||||
"#{provider}_secret": "someSecret",
|
||||
auth_providers_to_enable: enabled
|
||||
},
|
||||
confirmation: confirmation_message
|
||||
}
|
||||
expect(SiteConfig.authentication_providers).to eq([provider])
|
||||
expect(Settings::Authentication.providers).to eq([provider])
|
||||
end
|
||||
|
||||
it "does not update enabled authentication providers if any associated key missing" do
|
||||
enabled = Authentication::Providers.available.first.to_s
|
||||
post admin_config_path, params: {
|
||||
site_config: {
|
||||
post admin_settings_authentications_path, params: {
|
||||
settings_authentication: {
|
||||
"#{enabled}_key": "someKey",
|
||||
"#{enabled}_secret": "",
|
||||
auth_providers_to_enable: enabled
|
||||
},
|
||||
confirmation: confirmation_message
|
||||
}
|
||||
expect(SiteConfig.authentication_providers).to eq([])
|
||||
expect(Settings::Authentication.providers).to eq([])
|
||||
end
|
||||
|
||||
it "enables proper domains to allow list" do
|
||||
proper_list = "dev.to, forem.com, forem.dev"
|
||||
post "/admin/config", params: { site_config: { allowed_registration_email_domains: proper_list },
|
||||
confirmation: confirmation_message }
|
||||
expect(SiteConfig.allowed_registration_email_domains).to eq(%w[dev.to forem.com forem.dev])
|
||||
post admin_settings_authentications_path, params: {
|
||||
settings_authentication: { allowed_registration_email_domains: proper_list },
|
||||
confirmation: confirmation_message
|
||||
}
|
||||
expect(Settings::Authentication.allowed_registration_email_domains).to eq(%w[dev.to forem.com forem.dev])
|
||||
end
|
||||
|
||||
it "allows 2-character domains" do
|
||||
proper_list = "dev.to, forem.com, 2u.com"
|
||||
post "/admin/config", params: { site_config: { allowed_registration_email_domains: proper_list },
|
||||
confirmation: confirmation_message }
|
||||
expect(SiteConfig.allowed_registration_email_domains).to eq(%w[dev.to forem.com 2u.com])
|
||||
post admin_settings_authentications_path, params: {
|
||||
settings_authentication: { allowed_registration_email_domains: proper_list },
|
||||
confirmation: confirmation_message
|
||||
}
|
||||
expect(Settings::Authentication.allowed_registration_email_domains).to eq(%w[dev.to forem.com 2u.com])
|
||||
end
|
||||
|
||||
it "does not allow improper domain list" do
|
||||
impproper_list = "dev.to, foremcom, forem.dev"
|
||||
post "/admin/config", params: { site_config: { allowed_registration_email_domains: impproper_list },
|
||||
confirmation: confirmation_message }
|
||||
expect(SiteConfig.allowed_registration_email_domains).not_to eq(%w[dev.to foremcom forem.dev])
|
||||
post admin_settings_authentications_path, params: {
|
||||
settings_authentication: { allowed_registration_email_domains: impproper_list },
|
||||
confirmation: confirmation_message
|
||||
}
|
||||
expect(Settings::Authentication.allowed_registration_email_domains).not_to eq(%w[dev.to foremcom forem.dev])
|
||||
end
|
||||
|
||||
it "enables display_email_domain_allow_list_publicly" do
|
||||
post "/admin/config", params: { site_config: { display_email_domain_allow_list_publicly: true },
|
||||
confirmation: confirmation_message }
|
||||
expect(SiteConfig.display_email_domain_allow_list_publicly).to be(true)
|
||||
post admin_settings_authentications_path, params: {
|
||||
settings_authentication: { display_email_domain_allow_list_publicly: true },
|
||||
confirmation: confirmation_message
|
||||
}
|
||||
expect(Settings::Authentication.display_email_domain_allow_list_publicly).to be(true)
|
||||
end
|
||||
|
||||
it "enables email authentication" do
|
||||
post "/admin/config", params: { site_config: { allow_email_password_registration: true },
|
||||
confirmation: confirmation_message }
|
||||
expect(SiteConfig.allow_email_password_registration).to be(true)
|
||||
expect(SiteConfig.allow_email_password_login).to be(true)
|
||||
post admin_settings_authentications_path, params: {
|
||||
settings_authentication: { allow_email_password_registration: true },
|
||||
confirmation: confirmation_message
|
||||
}
|
||||
expect(Settings::Authentication.allow_email_password_registration).to be(true)
|
||||
expect(Settings::Authentication.allow_email_password_login).to be(true)
|
||||
end
|
||||
|
||||
it "disables email authentication" do
|
||||
post "/admin/config", params: { site_config: { allow_email_password_registration: false },
|
||||
confirmation: confirmation_message }
|
||||
expect(SiteConfig.allow_email_password_registration).to be(false)
|
||||
expect(SiteConfig.allow_email_password_login).to be(true)
|
||||
post admin_settings_authentications_path, params: {
|
||||
settings_authentication: { allow_email_password_registration: false },
|
||||
confirmation: confirmation_message
|
||||
}
|
||||
expect(Settings::Authentication.allow_email_password_registration).to be(false)
|
||||
expect(Settings::Authentication.allow_email_password_login).to be(true)
|
||||
end
|
||||
|
||||
it "enables invite-only-mode" do
|
||||
post "/admin/config", params: { site_config: { invite_only_mode: true },
|
||||
confirmation: confirmation_message }
|
||||
expect(SiteConfig.invite_only_mode).to be(true)
|
||||
post admin_settings_authentications_path, params: {
|
||||
settings_authentication: { invite_only_mode: true },
|
||||
confirmation: confirmation_message
|
||||
}
|
||||
expect(Settings::Authentication.invite_only_mode).to be(true)
|
||||
end
|
||||
|
||||
it "disables invite-only-mode & enables just email registration" do
|
||||
post "/admin/config", params: { site_config: { invite_only_mode: false },
|
||||
confirmation: confirmation_message }
|
||||
expect(SiteConfig.invite_only_mode).to be(false)
|
||||
post admin_settings_authentications_path, params: {
|
||||
settings_authentication: { invite_only_mode: false },
|
||||
confirmation: confirmation_message
|
||||
}
|
||||
expect(Settings::Authentication.invite_only_mode).to be(false)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -449,7 +464,7 @@ RSpec.describe "/admin/config", type: :request do
|
|||
expect(SiteConfig.mascot_footer_image_width).to eq(expected_default_mascot_footer_image_width)
|
||||
|
||||
post "/admin/config", params: { site_config:
|
||||
{ mascot_footer_image_width: expected_mascot_footer_image_width },
|
||||
{ mascot_footer_image_width: expected_mascot_footer_image_width },
|
||||
confirmation: confirmation_message }
|
||||
expect(SiteConfig.mascot_footer_image_width).to eq(expected_mascot_footer_image_width)
|
||||
end
|
||||
|
|
@ -461,7 +476,7 @@ RSpec.describe "/admin/config", type: :request do
|
|||
expect(SiteConfig.mascot_footer_image_height).to eq(expected_default_mascot_footer_image_height)
|
||||
|
||||
post "/admin/config", params: { site_config:
|
||||
{ mascot_footer_image_height: expected_mascot_footer_image_height },
|
||||
{ mascot_footer_image_height: expected_mascot_footer_image_height },
|
||||
confirmation: confirmation_message }
|
||||
expect(SiteConfig.mascot_footer_image_height).to eq(expected_mascot_footer_image_height)
|
||||
end
|
||||
|
|
@ -738,12 +753,12 @@ RSpec.describe "/admin/config", type: :request do
|
|||
it "updates recaptcha_site_key and recaptcha_secret_key" do
|
||||
site_key = "hi-ho"
|
||||
secret_key = "lets-go"
|
||||
post "/admin/config", params: {
|
||||
site_config: { recaptcha_site_key: site_key, recaptcha_secret_key: secret_key },
|
||||
post admin_settings_authentications_path, params: {
|
||||
settings_authentication: { recaptcha_site_key: site_key, recaptcha_secret_key: secret_key },
|
||||
confirmation: confirmation_message
|
||||
}
|
||||
expect(SiteConfig.recaptcha_site_key).to eq site_key
|
||||
expect(SiteConfig.recaptcha_secret_key).to eq secret_key
|
||||
expect(Settings::Authentication.recaptcha_site_key).to eq site_key
|
||||
expect(Settings::Authentication.recaptcha_secret_key).to eq secret_key
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ RSpec.describe "admin/users", type: :request do
|
|||
|
||||
before do
|
||||
omniauth_mock_providers_payload
|
||||
allow(SiteConfig).to receive(:authentication_providers).and_return(Authentication::Providers.available)
|
||||
allow(Settings::Authentication).to receive(:providers).and_return(Authentication::Providers.available)
|
||||
end
|
||||
|
||||
it "removes the given identity" do
|
||||
|
|
|
|||
|
|
@ -64,9 +64,11 @@ RSpec.describe "Api::V0::Admin::Configs", type: :request do
|
|||
|
||||
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,
|
||||
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])
|
||||
expect(Settings::Authentication.allowed_registration_email_domains).to eq(%w[dev.to forem.com forem.dev])
|
||||
end
|
||||
|
||||
it "does not allow improper domain list" do
|
||||
|
|
@ -74,7 +76,7 @@ RSpec.describe "Api::V0::Admin::Configs", type: :request do
|
|||
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])
|
||||
expect(Settings::Authentication.allowed_registration_email_domains).not_to eq(%w[dev.to foremcom forem.dev])
|
||||
end
|
||||
|
||||
it "removes space suggested_tags" do
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ RSpec.describe "Editor", type: :request do
|
|||
|
||||
context "when email login is allowed in /admin/config" do
|
||||
before do
|
||||
allow(SiteConfig).to receive(:allow_email_password_login).and_return(true)
|
||||
allow(Settings::Authentication).to receive(:allow_email_password_login).and_return(true)
|
||||
end
|
||||
|
||||
it "asks the non logged in user to sign in, with email signin enabled" do
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ RSpec.describe "feedback_messages", type: :request do
|
|||
end
|
||||
|
||||
def mock_recaptcha_config_enabled
|
||||
allow(SiteConfig).to receive(:recaptcha_secret_key).and_return("someSecretKey")
|
||||
allow(SiteConfig).to receive(:recaptcha_site_key).and_return("someSiteKey")
|
||||
allow(Settings::Authentication).to receive(:recaptcha_secret_key).and_return("someSecretKey")
|
||||
allow(Settings::Authentication).to receive(:recaptcha_site_key).and_return("someSiteKey")
|
||||
end
|
||||
|
||||
valid_abuse_report_params = {
|
||||
|
|
@ -81,8 +81,8 @@ RSpec.describe "feedback_messages", type: :request do
|
|||
|
||||
context "with valid params and recaptcha not configured" do
|
||||
before do
|
||||
allow(SiteConfig).to receive(:recaptcha_secret_key).and_return(nil)
|
||||
allow(SiteConfig).to receive(:recaptcha_site_key).and_return(nil)
|
||||
allow(Settings::Authentication).to receive(:recaptcha_secret_key).and_return(nil)
|
||||
allow(Settings::Authentication).to receive(:recaptcha_site_key).and_return(nil)
|
||||
end
|
||||
|
||||
it "does not show the recaptcha tag" do
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ RSpec.describe "GithubRepos", type: :request do
|
|||
|
||||
before do
|
||||
omniauth_mock_github_payload
|
||||
allow(SiteConfig).to receive(:authentication_providers).and_return(Authentication::Providers.available)
|
||||
allow(Settings::Authentication).to receive(:providers).and_return(Authentication::Providers.available)
|
||||
allow(Github::OauthClient).to receive(:new).and_return(github_client)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ RSpec.describe "Registrations", type: :request do
|
|||
|
||||
it "only shows the single sign on options if they are present" do
|
||||
allow(Authentication::Providers).to receive(:enabled).and_return([])
|
||||
allow(SiteConfig).to receive(:allow_email_password_login).and_return(false)
|
||||
allow(Settings::Authentication).to receive(:allow_email_password_login).and_return(false)
|
||||
|
||||
get sign_up_path
|
||||
|
||||
|
|
@ -28,7 +28,7 @@ RSpec.describe "Registrations", type: :request do
|
|||
|
||||
context "when email login is enabled in /admin/config" do
|
||||
before do
|
||||
allow(SiteConfig).to receive(:allow_email_password_login).and_return(true)
|
||||
allow(Settings::Authentication).to receive(:allow_email_password_login).and_return(true)
|
||||
end
|
||||
|
||||
it "shows the sign in text for password based authentication" do
|
||||
|
|
@ -40,7 +40,7 @@ RSpec.describe "Registrations", type: :request do
|
|||
|
||||
context "when email login is disabled in /admin/config" do
|
||||
before do
|
||||
allow(SiteConfig).to receive(:allow_email_password_login).and_return(false)
|
||||
allow(Settings::Authentication).to receive(:allow_email_password_login).and_return(false)
|
||||
end
|
||||
|
||||
it "does not show the sign in text for password based authentication" do
|
||||
|
|
@ -62,7 +62,7 @@ RSpec.describe "Registrations", type: :request do
|
|||
|
||||
describe "Create Account" do
|
||||
context "when email registration allowed" do
|
||||
before { allow(SiteConfig).to receive(:allow_email_password_registration).and_return(true) }
|
||||
before { allow(Settings::Authentication).to receive(:allow_email_password_registration).and_return(true) }
|
||||
|
||||
it "shows the sign in page with email option" do
|
||||
get sign_up_path, params: { state: "new-user" }
|
||||
|
|
@ -78,10 +78,10 @@ RSpec.describe "Registrations", type: :request do
|
|||
end
|
||||
|
||||
context "when email registration not allowed" do
|
||||
before { allow(SiteConfig).to receive(:allow_email_password_registration).and_return(false) }
|
||||
before { allow(Settings::Authentication).to receive(:allow_email_password_registration).and_return(false) }
|
||||
|
||||
it "does not show email sign up option" do
|
||||
allow(SiteConfig).to receive(:allow_email_password_registration).and_return(false)
|
||||
allow(Settings::Authentication).to receive(:allow_email_password_registration).and_return(false)
|
||||
get sign_up_path, params: { state: "new-user" }
|
||||
|
||||
expect(response.body).not_to include("Sign up with Email")
|
||||
|
|
@ -90,10 +90,10 @@ RSpec.describe "Registrations", type: :request do
|
|||
|
||||
context "when email registration allowed and captcha required" do
|
||||
before do
|
||||
allow(SiteConfig).to receive(:recaptcha_secret_key).and_return("someSecretKey")
|
||||
allow(SiteConfig).to receive(:recaptcha_site_key).and_return("someSiteKey")
|
||||
allow(SiteConfig).to receive(:allow_email_password_registration).and_return(true)
|
||||
allow(SiteConfig).to receive(:require_captcha_for_email_password_registration).and_return(true)
|
||||
allow(Settings::Authentication).to receive(:recaptcha_secret_key).and_return("someSecretKey")
|
||||
allow(Settings::Authentication).to receive(:recaptcha_site_key).and_return("someSiteKey")
|
||||
allow(Settings::Authentication).to receive(:allow_email_password_registration).and_return(true)
|
||||
allow(Settings::Authentication).to receive(:require_captcha_for_email_password_registration).and_return(true)
|
||||
end
|
||||
|
||||
it "displays the captcha box on email signup page" do
|
||||
|
|
@ -162,7 +162,8 @@ RSpec.describe "Registrations", type: :request do
|
|||
|
||||
context "when site is not configured to accept email registration" do
|
||||
before do
|
||||
allow(SiteConfig).to receive(:allow_email_password_registration).and_return(false)
|
||||
allow(Settings::Authentication)
|
||||
.to receive(:allow_email_password_registration).and_return(false)
|
||||
end
|
||||
|
||||
it "disallows communities where email registration is not allowed" do
|
||||
|
|
@ -172,7 +173,8 @@ RSpec.describe "Registrations", type: :request do
|
|||
|
||||
context "when site is configured to accept email registration" do
|
||||
before do
|
||||
allow(SiteConfig).to receive(:allow_email_password_registration).and_return(true)
|
||||
allow(Settings::Authentication)
|
||||
.to receive(:allow_email_password_registration).and_return(true)
|
||||
end
|
||||
|
||||
it "does not raise disallowed if community is set to allow email" do
|
||||
|
|
@ -228,8 +230,8 @@ RSpec.describe "Registrations", type: :request do
|
|||
|
||||
context "when email registration allowed and email allow list empty" do
|
||||
before do
|
||||
allow(SiteConfig).to receive(:allow_email_password_registration).and_return(true)
|
||||
allow(SiteConfig).to receive(:allowed_registration_email_domains).and_return([])
|
||||
allow(Settings::Authentication).to receive(:allow_email_password_registration).and_return(true)
|
||||
allow(Settings::Authentication).to receive(:allowed_registration_email_domains).and_return([])
|
||||
end
|
||||
|
||||
it "creates user when email in allow list" do
|
||||
|
|
@ -245,8 +247,9 @@ RSpec.describe "Registrations", type: :request do
|
|||
|
||||
context "when email registration allowed and email allow list present" do
|
||||
before do
|
||||
allow(SiteConfig).to receive(:allow_email_password_registration).and_return(true)
|
||||
allow(SiteConfig).to receive(:allowed_registration_email_domains).and_return(["dev.to", "forem.com"])
|
||||
allow(Settings::Authentication).to receive(:allow_email_password_registration).and_return(true)
|
||||
allow(Settings::Authentication).to receive(:allowed_registration_email_domains).and_return(["dev.to",
|
||||
"forem.com"])
|
||||
end
|
||||
|
||||
it "does not create user when email not in allow list" do
|
||||
|
|
@ -272,10 +275,10 @@ RSpec.describe "Registrations", type: :request do
|
|||
|
||||
context "when site configured to accept email registration AND require captcha" do
|
||||
before do
|
||||
allow(SiteConfig).to receive(:recaptcha_secret_key).and_return("someSecretKey")
|
||||
allow(SiteConfig).to receive(:recaptcha_site_key).and_return("someSiteKey")
|
||||
allow(SiteConfig).to receive(:allow_email_password_registration).and_return(true)
|
||||
allow(SiteConfig).to receive(:require_captcha_for_email_password_registration).and_return(true)
|
||||
allow(Settings::Authentication).to receive(:recaptcha_secret_key).and_return("someSecretKey")
|
||||
allow(Settings::Authentication).to receive(:recaptcha_site_key).and_return("someSiteKey")
|
||||
allow(Settings::Authentication).to receive(:allow_email_password_registration).and_return(true)
|
||||
allow(Settings::Authentication).to receive(:require_captcha_for_email_password_registration).and_return(true)
|
||||
end
|
||||
|
||||
it "creates user when valid params passed and recaptcha completed" do
|
||||
|
|
|
|||
|
|
@ -348,7 +348,7 @@ RSpec.describe "UserSettings", type: :request do
|
|||
|
||||
before do
|
||||
omniauth_mock_providers_payload
|
||||
allow(SiteConfig).to receive(:authentication_providers).and_return(Authentication::Providers.available)
|
||||
allow(Settings::Authentication).to receive(:providers).and_return(Authentication::Providers.available)
|
||||
sign_in user
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ require "rails_helper"
|
|||
RSpec.describe Authentication::Authenticator, type: :service do
|
||||
before do
|
||||
omniauth_mock_providers_payload
|
||||
allow(SiteConfig).to receive(:authentication_providers).and_return(Authentication::Providers.available)
|
||||
allow(Settings::Authentication).to receive(:providers).and_return(Authentication::Providers.available)
|
||||
end
|
||||
|
||||
context "when authenticating through an unknown provider" do
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ RSpec.describe Authentication::Providers, type: :service do
|
|||
end
|
||||
|
||||
it "raises an exception if a provider is available but not enabled" do
|
||||
allow(SiteConfig).to receive(:authentication_providers).and_return(%w[github])
|
||||
allow(Settings::Authentication).to receive(:providers).and_return(%w[github])
|
||||
|
||||
expect do
|
||||
described_class.get!(:twitter)
|
||||
|
|
@ -17,7 +17,7 @@ RSpec.describe Authentication::Providers, type: :service do
|
|||
end
|
||||
|
||||
it "loads the correct provider class" do
|
||||
allow(SiteConfig).to receive(:authentication_providers).and_return(described_class.available)
|
||||
allow(Settings::Authentication).to receive(:providers).and_return(described_class.available)
|
||||
|
||||
is_subclass_of = (
|
||||
described_class.get!(:twitter) < Authentication::Providers::Provider
|
||||
|
|
@ -36,7 +36,7 @@ RSpec.describe Authentication::Providers, type: :service do
|
|||
describe ".enabled" do
|
||||
context "when one of the available providers is disabled" do
|
||||
it "only lists those that remain enabled" do
|
||||
allow(SiteConfig).to receive(:authentication_providers).and_return(%w[github])
|
||||
allow(Settings::Authentication).to receive(:providers).and_return(%w[github])
|
||||
|
||||
expect(described_class.enabled).to eq(%i[github])
|
||||
end
|
||||
|
|
@ -45,13 +45,13 @@ RSpec.describe Authentication::Providers, type: :service do
|
|||
|
||||
describe ".enabled?" do
|
||||
it "returns true if a provider is enabled" do
|
||||
allow(SiteConfig).to receive(:authentication_providers).and_return(%w[github])
|
||||
allow(Settings::Authentication).to receive(:providers).and_return(%w[github])
|
||||
|
||||
expect(described_class.enabled?(:github)).to be(true)
|
||||
end
|
||||
|
||||
it "returns false if a provider is not enabled" do
|
||||
allow(SiteConfig).to receive(:authentication_providers).and_return(%w[twitter])
|
||||
allow(Settings::Authentication).to receive(:providers).and_return(%w[twitter])
|
||||
|
||||
expect(described_class.enabled?(:github)).to be(false)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ RSpec.describe Broadcasts::WelcomeNotification::Generator, type: :service do
|
|||
allow(Notification).to receive(:send_welcome_notification).and_call_original
|
||||
allow(User).to receive(:mascot_account).and_return(mascot_account)
|
||||
allow(SiteConfig).to receive(:staff_user_id).and_return(mascot_account.id)
|
||||
allow(SiteConfig).to receive(:authentication_providers).and_return(Authentication::Providers.available)
|
||||
allow(Settings::Authentication).to receive(:providers).and_return(Authentication::Providers.available)
|
||||
end
|
||||
|
||||
it "requires a valid user id" do
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@ RSpec.describe ReCaptcha::CheckEnabled, type: :request do
|
|||
describe "ReCaptcha for user actions like Abuse Reports (FeedbackMessages)" do
|
||||
context "when recaptcha SiteConfig keys are not configured" do
|
||||
it "marks ReCaptcha as not enabled regardless of the param passed in" do
|
||||
allow(SiteConfig).to receive(:recaptcha_site_key).and_return(nil)
|
||||
allow(SiteConfig).to receive(:recaptcha_secret_key).and_return(nil)
|
||||
allow(Settings::Authentication).to receive(:recaptcha_site_key).and_return(nil)
|
||||
allow(Settings::Authentication).to receive(:recaptcha_secret_key).and_return(nil)
|
||||
|
||||
expect(described_class.call).to be(false)
|
||||
expect(described_class.call(older_user)).to be(false)
|
||||
|
|
@ -24,8 +24,8 @@ RSpec.describe ReCaptcha::CheckEnabled, type: :request do
|
|||
|
||||
context "when recaptcha SiteConfig keys are configured" do
|
||||
before do
|
||||
allow(SiteConfig).to receive(:recaptcha_site_key).and_return("someSecretKey")
|
||||
allow(SiteConfig).to receive(:recaptcha_secret_key).and_return("someSiteKey")
|
||||
allow(Settings::Authentication).to receive(:recaptcha_site_key).and_return("someSecretKey")
|
||||
allow(Settings::Authentication).to receive(:recaptcha_secret_key).and_return("someSiteKey")
|
||||
end
|
||||
|
||||
it "marks ReCaptcha as enabled when logged out (parameter is nil)" do
|
||||
|
|
|
|||
|
|
@ -4,23 +4,25 @@ RSpec.describe ReCaptcha::CheckRegistrationEnabled, type: :request do
|
|||
describe "ReCaptcha for registration" do
|
||||
context "when recaptcha is enabled" do
|
||||
before do
|
||||
allow(SiteConfig).to receive(:require_captcha_for_email_password_registration).and_return(true)
|
||||
allow(Settings::Authentication)
|
||||
.to receive(:require_captcha_for_email_password_registration).and_return(true)
|
||||
end
|
||||
|
||||
it "is enabled if both site & secret keys present" do
|
||||
allow(SiteConfig).to receive(:recaptcha_secret_key).and_return("someSecretKey")
|
||||
allow(SiteConfig).to receive(:recaptcha_site_key).and_return("someSiteKey")
|
||||
allow(Settings::Authentication).to receive(:recaptcha_secret_key).and_return("someSecretKey")
|
||||
allow(Settings::Authentication).to receive(:recaptcha_site_key).and_return("someSiteKey")
|
||||
expect(described_class.call).to be(true)
|
||||
end
|
||||
|
||||
it "is disabled if site or secret key missing" do
|
||||
allow(SiteConfig).to receive(:recaptcha_site_key).and_return("")
|
||||
allow(Settings::Authentication).to receive(:recaptcha_site_key).and_return("")
|
||||
expect(described_class.call).to be(false)
|
||||
end
|
||||
end
|
||||
|
||||
it "is disabled if recaptcha disabled for email signup" do
|
||||
allow(SiteConfig).to receive(:require_captcha_for_email_password_registration).and_return(false)
|
||||
allow(Settings::Authentication)
|
||||
.to receive(:require_captcha_for_email_password_registration).and_return(false)
|
||||
expect(described_class.call).to be(false)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ RSpec.describe TwitterClient::Client, type: :service, vcr: true do
|
|||
|
||||
it "works properly when SiteConfig is set" do
|
||||
VCR.use_cassette("twitter_client_status") do
|
||||
allow(SiteConfig).to receive(:twitter_key).and_return("test")
|
||||
allow(Settings::Authentication).to receive(:twitter_key).and_return("test")
|
||||
tweet = described_class.status(tweet_id)
|
||||
expect(tweet.text).to be_present
|
||||
end
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ RSpec.describe Users::Delete, type: :service do
|
|||
|
||||
before do
|
||||
omniauth_mock_github_payload
|
||||
allow(SiteConfig).to receive(:authentication_providers).and_return(Authentication::Providers.available)
|
||||
allow(Settings::Authentication).to receive(:providers).and_return(Authentication::Providers.available)
|
||||
allow(EdgeCache::Bust).to receive(:new).and_return(cache_bust)
|
||||
allow(cache_bust).to receive(:call)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ RSpec.describe "Beta provider access", type: :system do
|
|||
let(:beta_providers) { ["Apple"] }
|
||||
|
||||
before do
|
||||
allow(SiteConfig).to receive(:authentication_providers).and_return(Authentication::Providers.available)
|
||||
allow(Settings::Authentication).to receive(:providers).and_return(Authentication::Providers.available)
|
||||
end
|
||||
|
||||
context "when a user tries to sign_up" do
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ RSpec.describe "Creator config edit", type: :system, js: true do
|
|||
context "when a creator browses /admin/config" do
|
||||
before do
|
||||
sign_in admin
|
||||
allow(SiteConfig).to receive(:invite_only_mode).and_return(false)
|
||||
allow(Settings::Authentication).to receive(:invite_only_mode).and_return(false)
|
||||
end
|
||||
|
||||
it "presents all available OAuth providers" do
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ RSpec.describe "Omniauth redirect_uri", type: :system do
|
|||
end
|
||||
|
||||
it "relies on SiteConfig.app_domain to generate correct callbacks_url" do
|
||||
allow(SiteConfig).to receive(:authentication_providers).and_return(Authentication::Providers.available)
|
||||
allow(Settings::Authentication).to receive(:providers).and_return(Authentication::Providers.available)
|
||||
visit sign_up_path
|
||||
Authentication::Providers.available.each do |provider_name|
|
||||
provider_auth_button = find("button.crayons-btn--brand-#{provider_name}")
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ RSpec.describe "Redirects authentication using Referer", type: :system do
|
|||
|
||||
before do
|
||||
omniauth_mock_twitter_payload
|
||||
allow(SiteConfig).to receive(:authentication_providers).and_return(Authentication::Providers.available)
|
||||
allow(Settings::Authentication).to receive(:providers).and_return(Authentication::Providers.available)
|
||||
OmniAuth.config.mock_auth[:twitter].info.email = user.email
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ RSpec.describe "Authenticating with Apple", vcr: { cassette_name: "fastly_sloan"
|
|||
before do
|
||||
omniauth_mock_apple_payload
|
||||
Flipper.enable(:apple_auth)
|
||||
allow(SiteConfig).to receive(:authentication_providers).and_return(Authentication::Providers.available)
|
||||
allow(Settings::Authentication).to receive(:providers).and_return(Authentication::Providers.available)
|
||||
end
|
||||
|
||||
context "when a user is new" do
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@ RSpec.describe "Authenticating with Email" do
|
|||
let(:sign_up_link) { "Sign up with Email" }
|
||||
|
||||
before do
|
||||
allow(SiteConfig).to receive(:allow_email_password_registration).and_return(true)
|
||||
allow(SiteConfig).to receive(:allow_email_password_login).and_return(true)
|
||||
allow(Settings::Authentication).to receive(:allow_email_password_registration).and_return(true)
|
||||
allow(Settings::Authentication).to receive(:allow_email_password_login).and_return(true)
|
||||
end
|
||||
|
||||
context "when a user is new" do
|
||||
|
|
@ -112,7 +112,7 @@ RSpec.describe "Authenticating with Email" do
|
|||
|
||||
context "when community is in invite only mode" do
|
||||
before do
|
||||
allow(SiteConfig).to receive(:invite_only_mode).and_return(true)
|
||||
allow(Settings::Authentication).to receive(:invite_only_mode).and_return(true)
|
||||
end
|
||||
|
||||
it "doesn't present the authentication option" do
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ RSpec.describe "Authenticating with Facebook" do
|
|||
|
||||
before do
|
||||
omniauth_mock_facebook_payload
|
||||
allow(SiteConfig).to receive(:authentication_providers).and_return(Authentication::Providers.available)
|
||||
allow(Settings::Authentication).to receive(:providers).and_return(Authentication::Providers.available)
|
||||
end
|
||||
|
||||
context "when a user is new" do
|
||||
|
|
@ -225,7 +225,7 @@ RSpec.describe "Authenticating with Facebook" do
|
|||
|
||||
context "when community is in invite only mode" do
|
||||
before do
|
||||
allow(SiteConfig).to receive(:invite_only_mode).and_return(true)
|
||||
allow(Settings::Authentication).to receive(:invite_only_mode).and_return(true)
|
||||
end
|
||||
|
||||
it "doesn't present the authentication option" do
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ RSpec.describe "Authenticating with GitHub" do
|
|||
|
||||
before do
|
||||
omniauth_mock_github_payload
|
||||
allow(SiteConfig).to receive(:authentication_providers).and_return(Authentication::Providers.available)
|
||||
allow(Settings::Authentication).to receive(:providers).and_return(Authentication::Providers.available)
|
||||
end
|
||||
|
||||
context "when a user is new" do
|
||||
|
|
@ -191,7 +191,7 @@ RSpec.describe "Authenticating with GitHub" do
|
|||
|
||||
context "when community is in invite only mode" do
|
||||
before do
|
||||
allow(SiteConfig).to receive(:invite_only_mode).and_return(true)
|
||||
allow(Settings::Authentication).to receive(:invite_only_mode).and_return(true)
|
||||
end
|
||||
|
||||
it "doesn't present the authentication option" do
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ RSpec.describe "Authenticating with Twitter" do
|
|||
|
||||
before do
|
||||
omniauth_mock_twitter_payload
|
||||
allow(SiteConfig).to receive(:authentication_providers).and_return(Authentication::Providers.available)
|
||||
allow(Settings::Authentication).to receive(:providers).and_return(Authentication::Providers.available)
|
||||
end
|
||||
|
||||
context "when a user is new" do
|
||||
|
|
@ -183,7 +183,7 @@ RSpec.describe "Authenticating with Twitter" do
|
|||
|
||||
context "when community is in invite only mode" do
|
||||
before do
|
||||
allow(SiteConfig).to receive(:invite_only_mode).and_return(true)
|
||||
allow(Settings::Authentication).to receive(:invite_only_mode).and_return(true)
|
||||
end
|
||||
|
||||
it "doesn't present the authentication option" do
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ RSpec.describe "User with suspended username tried to sign up via OAuth" do
|
|||
before do
|
||||
omniauth_mock_twitter_payload
|
||||
|
||||
allow(SiteConfig)
|
||||
.to receive(:authentication_providers)
|
||||
allow(Settings::Authentication)
|
||||
.to receive(:providers)
|
||||
.and_return(Authentication::Providers.available)
|
||||
|
||||
allow(ForemStatsClient).to receive(:increment)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ RSpec.describe "Authenticating with a password" do
|
|||
let!(:user) { create(:user, password: password, password_confirmation: password) }
|
||||
|
||||
before do
|
||||
allow(SiteConfig).to receive(:authentication_providers).and_return(Authentication::Providers.available)
|
||||
allow(Settings::Authentication).to receive(:providers).and_return(Authentication::Providers.available)
|
||||
visit sign_up_path
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ Gem::Specification.new do |s|
|
|||
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
||||
s.require_paths = ["lib".freeze]
|
||||
s.authors = ["Tom Cocca".freeze]
|
||||
s.date = "2021-03-31"
|
||||
s.date = "2021-04-09"
|
||||
s.description = "acts_as_follower is a Rubygem to allow any model to follow any other model. This is accomplished through a double polymorphic relationship on the Follow model. There is also built in support for blocking/un-blocking follow records. Main uses would be for Users to follow other Users or for Users to follow Books, etc\u2026 (Basically, to develop the type of follow system that GitHub has)".freeze
|
||||
s.email = ["tom dot cocca at gmail dot com".freeze]
|
||||
s.files = [".gitignore".freeze, ".travis.yml".freeze, "Gemfile".freeze, "MIT-LICENSE".freeze, "README.rdoc".freeze, "Rakefile".freeze, "acts_as_follower.gemspec".freeze, "init.rb".freeze, "lib/acts_as_follower.rb".freeze, "lib/acts_as_follower/follow_scopes.rb".freeze, "lib/acts_as_follower/followable.rb".freeze, "lib/acts_as_follower/follower.rb".freeze, "lib/acts_as_follower/follower_lib.rb".freeze, "lib/acts_as_follower/railtie.rb".freeze, "lib/acts_as_follower/version.rb".freeze, "lib/generators/USAGE".freeze, "lib/generators/acts_as_follower_generator.rb".freeze, "lib/generators/templates/migration.rb".freeze, "lib/generators/templates/model.rb".freeze, "test/README".freeze, "test/acts_as_followable_test.rb".freeze, "test/acts_as_follower_test.rb".freeze, "test/dummy30/Gemfile".freeze, "test/dummy30/Rakefile".freeze, "test/dummy30/app/models/application_record.rb".freeze, "test/dummy30/app/models/band.rb".freeze, "test/dummy30/app/models/band/punk.rb".freeze, "test/dummy30/app/models/band/punk/pop_punk.rb".freeze, "test/dummy30/app/models/custom_record.rb".freeze, "test/dummy30/app/models/some.rb".freeze, "test/dummy30/app/models/user.rb".freeze, "test/dummy30/config.ru".freeze, "test/dummy30/config/application.rb".freeze, "test/dummy30/config/boot.rb".freeze, "test/dummy30/config/database.yml".freeze, "test/dummy30/config/environment.rb".freeze, "test/dummy30/config/environments/development.rb".freeze, "test/dummy30/config/environments/test.rb".freeze, "test/dummy30/config/initializers/backtrace_silencers.rb".freeze, "test/dummy30/config/initializers/inflections.rb".freeze, "test/dummy30/config/initializers/secret_token.rb".freeze, "test/dummy30/config/initializers/session_store.rb".freeze, "test/dummy30/config/locales/en.yml".freeze, "test/dummy30/config/routes.rb".freeze, "test/factories/bands.rb".freeze, "test/factories/somes.rb".freeze, "test/factories/users.rb".freeze, "test/follow_test.rb".freeze, "test/schema.rb".freeze, "test/test_helper.rb".freeze]
|
||||
|
|
@ -16,7 +16,6 @@ Gem::Specification.new do |s|
|
|||
s.licenses = ["MIT".freeze]
|
||||
s.rubygems_version = "3.1.4".freeze
|
||||
s.summary = "A Rubygem to add Follow functionality for ActiveRecord models".freeze
|
||||
s.test_files = ["test/README".freeze, "test/acts_as_followable_test.rb".freeze, "test/acts_as_follower_test.rb".freeze, "test/dummy30/Gemfile".freeze, "test/dummy30/Rakefile".freeze, "test/dummy30/app/models/application_record.rb".freeze, "test/dummy30/app/models/band.rb".freeze, "test/dummy30/app/models/band/punk.rb".freeze, "test/dummy30/app/models/band/punk/pop_punk.rb".freeze, "test/dummy30/app/models/custom_record.rb".freeze, "test/dummy30/app/models/some.rb".freeze, "test/dummy30/app/models/user.rb".freeze, "test/dummy30/config.ru".freeze, "test/dummy30/config/application.rb".freeze, "test/dummy30/config/boot.rb".freeze, "test/dummy30/config/database.yml".freeze, "test/dummy30/config/environment.rb".freeze, "test/dummy30/config/environments/development.rb".freeze, "test/dummy30/config/environments/test.rb".freeze, "test/dummy30/config/initializers/backtrace_silencers.rb".freeze, "test/dummy30/config/initializers/inflections.rb".freeze, "test/dummy30/config/initializers/secret_token.rb".freeze, "test/dummy30/config/initializers/session_store.rb".freeze, "test/dummy30/config/locales/en.yml".freeze, "test/dummy30/config/routes.rb".freeze, "test/factories/bands.rb".freeze, "test/factories/somes.rb".freeze, "test/factories/users.rb".freeze, "test/follow_test.rb".freeze, "test/schema.rb".freeze, "test/test_helper.rb".freeze]
|
||||
|
||||
s.installed_by_version = "3.1.4" if s.respond_to? :installed_by_version
|
||||
|
||||
|
|
|
|||
BIN
vendor/cache/ahoy_email-2.0.2.gem
vendored
BIN
vendor/cache/ahoy_email-2.0.2.gem
vendored
Binary file not shown.
BIN
vendor/cache/ahoy_email-2.0.3.gem
vendored
Normal file
BIN
vendor/cache/ahoy_email-2.0.3.gem
vendored
Normal file
Binary file not shown.
BIN
vendor/cache/chartkick-3.4.2.gem
vendored
BIN
vendor/cache/chartkick-3.4.2.gem
vendored
Binary file not shown.
BIN
vendor/cache/chartkick-4.0.2.gem
vendored
Normal file
BIN
vendor/cache/chartkick-4.0.2.gem
vendored
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
BIN
vendor/cache/loofah-2.9.0.gem
vendored
BIN
vendor/cache/loofah-2.9.0.gem
vendored
Binary file not shown.
BIN
vendor/cache/loofah-2.9.1.gem
vendored
Normal file
BIN
vendor/cache/loofah-2.9.1.gem
vendored
Normal file
Binary file not shown.
BIN
vendor/cache/marcel-1.0.0.gem
vendored
BIN
vendor/cache/marcel-1.0.0.gem
vendored
Binary file not shown.
BIN
vendor/cache/marcel-1.0.1.gem
vendored
Normal file
BIN
vendor/cache/marcel-1.0.1.gem
vendored
Normal file
Binary file not shown.
BIN
vendor/cache/oauth-0.5.5.gem
vendored
BIN
vendor/cache/oauth-0.5.5.gem
vendored
Binary file not shown.
BIN
vendor/cache/oauth-0.5.6.gem
vendored
Normal file
BIN
vendor/cache/oauth-0.5.6.gem
vendored
Normal file
Binary file not shown.
BIN
vendor/cache/parser-3.0.0.0.gem
vendored
BIN
vendor/cache/parser-3.0.0.0.gem
vendored
Binary file not shown.
BIN
vendor/cache/parser-3.0.1.0.gem
vendored
Normal file
BIN
vendor/cache/parser-3.0.1.0.gem
vendored
Normal file
Binary file not shown.
Loading…
Add table
Reference in a new issue