Gab Social. All are welcome.

This commit is contained in:
robcolbert
2019-07-02 03:10:25 -04:00
commit bd0b5afc92
5366 changed files with 222812 additions and 0 deletions
@@ -0,0 +1,72 @@
# frozen_string_literal: true
class Settings::ApplicationsController < Settings::BaseController
layout 'admin'
before_action :authenticate_user!
before_action :set_application, only: [:show, :update, :destroy, :regenerate]
before_action :prepare_scopes, only: [:create, :update]
def index
@applications = current_user.applications.order(id: :desc).page(params[:page])
end
def new
@application = Doorkeeper::Application.new(
redirect_uri: Doorkeeper.configuration.native_redirect_uri,
scopes: 'read write follow'
)
end
def show; end
def create
@application = current_user.applications.build(application_params)
if @application.save
redirect_to settings_applications_path, notice: I18n.t('applications.created')
else
render :new
end
end
def update
if @application.update(application_params)
redirect_to settings_applications_path, notice: I18n.t('generic.changes_saved_msg')
else
render :show
end
end
def destroy
@application.destroy
redirect_to settings_applications_path, notice: I18n.t('applications.destroyed')
end
def regenerate
@access_token = current_user.token_for_app(@application)
@access_token.destroy
redirect_to settings_application_path(@application), notice: I18n.t('applications.token_regenerated')
end
private
def set_application
@application = current_user.applications.find(params[:id])
end
def application_params
params.require(:doorkeeper_application).permit(
:name,
:redirect_uri,
:scopes,
:website
)
end
def prepare_scopes
scopes = params.fetch(:doorkeeper_application, {}).fetch(:scopes, nil)
params[:doorkeeper_application][:scopes] = scopes.join(' ') if scopes.is_a? Array
end
end
@@ -0,0 +1,11 @@
# frozen_string_literal: true
class Settings::BaseController < ApplicationController
before_action :set_body_classes
private
def set_body_classes
@body_classes = 'admin'
end
end
@@ -0,0 +1,17 @@
class Settings::Billing::TransactionsController < Settings::BaseController
include Authorization
layout 'admin'
before_action :authenticate_user!
def index
transaction = Transaction.new
transaction.account_id = current_account.id
transaction.amount = 5000
transaction.payment_type = :pro_3_months
transaction.provider_type = :btcpay
#transaction.save
@transactions = Transaction.where(account: current_account)
end
end
@@ -0,0 +1,88 @@
class Settings::Billing::UpgradeController < Settings::BaseController
include Authorization
layout 'admin'
before_action :init_client
skip_before_action :verify_authenticity_token, only: [:btcpay_notification]
def init_client
@client = Btcpay::Client.new(
api_uri: 'https://btcpay.gab.com',
legacy_token: ENV['BTCPAY_LEGACY_TOKEN'],
pub_key: ENV['BTCPAY_PUB_KEY'],
client_id: ENV['BTCPAY_PUB_KEY'],
tokens: { "merchant" => ENV['BTCPAY_MERCHANT_TOKEN'] })
end
def index
authenticate_user!
authorize current_account, :upgrade?
order_id = SecureRandom.hex
plan = params[:plan]
item = get_purchase_item plan
params = {
orderId: order_id,
notificationUrl: settings_billing_btcpay_notification_url,
itemCode: item[:code],
itemDesc: item[:desc],
buyer: {email: current_user.email, name: "Gab Social ##{current_user.id}"}
}
# Create invoice
invoice = @client.create_invoice(facade: 'merchant', price: item[:price], currency: 'USD', params: params)
# Create BTCPayment record
BtcPayment.create(account_id: current_account.id, btcpay_invoice_id: invoice['id'], plan: plan)
# Redirect to BTCPay for payment
redirect_to invoice['url']
end
def btcpay_notification
id = params[:id]
invoice = @client.get_invoice(id: id)
# There are different statuses in BitPay protocol that indicates the payment has been done
statuses_indicating_payment_confirmation = ['complete', 'complete (paidOver)', 'confirmed', 'confirmed (paidOver)', 'paid', 'paid (paidOver)']
payment_confirmed = statuses_indicating_payment_confirmation.include? invoice['status']
invoice_paid invoice if payment_confirmed
render json: {'status': 'ok', 'invoice': invoice['id']}, status: 200
end
def invoice_paid(invoice)
# Get btc payment record
payment = BtcPayment.find_by(btcpay_invoice_id: invoice['id'], success: false)
return if payment.nil?
# Which plan was purchased?
plan = get_purchase_item(payment.plan)
# Mark account as pro
account = payment.account
account.is_pro = true
account.pro_expires_at = (account.pro_expires_at || DateTime.now) + plan[:months].months
account.save
# Mark payment as successful
payment.success = true
payment.save
# Create a transaction
Transaction.create(account_id: current_account.id, amount: plan[:price].to_i * 100)
end
def get_purchase_item(plan)
case plan
when '6M'
{code: 'PRO-6M', desc: 'PRO - 6 Months', price: '30.00', months: 6}
when '1Y'
{code: 'PRO-1Y', desc: 'PRO - 1 Year', price: '60.00', months: 12}
when '5Y'
{code: 'PRO-5Y', desc: 'PRO - 5 Years', price: '200.00', months: 60}
else
raise GabSocial::ValidationError.new 'Plan not selected.'
end
end
end
@@ -0,0 +1,32 @@
# frozen_string_literal: true
class Settings::DeletesController < Settings::BaseController
layout 'admin'
before_action :check_enabled_deletion
before_action :authenticate_user!
def show
@confirmation = Form::DeleteConfirmation.new
end
def destroy
if current_user.valid_password?(delete_params[:password])
Admin::SuspensionWorker.perform_async(current_user.account_id, true)
sign_out
redirect_to new_user_session_path, notice: I18n.t('deletes.success_msg')
else
redirect_to settings_delete_path, alert: I18n.t('deletes.bad_password_msg')
end
end
private
def check_enabled_deletion
redirect_to root_path unless Setting.open_deletion
end
def delete_params
params.require(:form_delete_confirmation).permit(:password)
end
end
@@ -0,0 +1,19 @@
# frozen_string_literal: true
module Settings
module Exports
class BlockedAccountsController < ApplicationController
include ExportControllerConcern
def index
send_export_file
end
private
def export_data
@export.to_blocked_accounts_csv
end
end
end
end
@@ -0,0 +1,19 @@
# frozen_string_literal: true
module Settings
module Exports
class BlockedDomainsController < ApplicationController
include ExportControllerConcern
def index
send_export_file
end
private
def export_data
@export.to_blocked_domains_csv
end
end
end
end
@@ -0,0 +1,19 @@
# frozen_string_literal: true
module Settings
module Exports
class FollowingAccountsController < ApplicationController
include ExportControllerConcern
def index
send_export_file
end
private
def export_data
@export.to_following_accounts_csv
end
end
end
end
@@ -0,0 +1,19 @@
# frozen_string_literal: true
module Settings
module Exports
class ListsController < ApplicationController
include ExportControllerConcern
def index
send_export_file
end
private
def export_data
@export.to_lists_csv
end
end
end
end
@@ -0,0 +1,19 @@
# frozen_string_literal: true
module Settings
module Exports
class MutedAccountsController < ApplicationController
include ExportControllerConcern
def index
send_export_file
end
private
def export_data
@export.to_muted_accounts_csv
end
end
end
end
@@ -0,0 +1,37 @@
# frozen_string_literal: true
class Settings::ExportsController < Settings::BaseController
include Authorization
layout 'admin'
before_action :authenticate_user!
def show
@export = Export.new(current_account)
@backups = current_user.backups
end
def create
raise GabSocial::NotPermittedError unless user_signed_in?
backup = nil
RedisLock.acquire(lock_options) do |lock|
if lock.acquired?
authorize :backup, :create?
backup = current_user.backups.create!
else
raise GabSocial::RaceConditionError
end
end
BackupWorker.perform_async(backup.id)
redirect_to settings_export_path
end
def lock_options
{ redis: Redis.current, key: "backup:#{current_user.id}" }
end
end
@@ -0,0 +1,51 @@
# frozen_string_literal: true
class Settings::FeaturedTagsController < Settings::BaseController
layout 'admin'
before_action :authenticate_user!
before_action :set_featured_tags, only: :index
before_action :set_featured_tag, except: [:index, :create]
before_action :set_most_used_tags, only: :index
def index
@featured_tag = FeaturedTag.new
end
def create
@featured_tag = current_account.featured_tags.new(featured_tag_params)
@featured_tag.reset_data
if @featured_tag.save
redirect_to settings_featured_tags_path
else
set_featured_tags
set_most_used_tags
render :index
end
end
def destroy
@featured_tag.destroy!
redirect_to settings_featured_tags_path
end
private
def set_featured_tag
@featured_tag = current_account.featured_tags.find(params[:id])
end
def set_featured_tags
@featured_tags = current_account.featured_tags.order(statuses_count: :desc).reject(&:new_record?)
end
def set_most_used_tags
@most_used_tags = Tag.most_used(current_account).where.not(id: @featured_tags.map(&:id)).limit(10)
end
def featured_tag_params
params.require(:featured_tag).permit(:name)
end
end
@@ -0,0 +1,63 @@
# frozen_string_literal: true
class Settings::IdentityProofsController < Settings::BaseController
layout 'admin'
before_action :authenticate_user!
before_action :check_required_params, only: :new
def index
@proofs = AccountIdentityProof.where(account: current_account).order(provider: :asc, provider_username: :asc)
@proofs.each(&:refresh!)
end
def new
@proof = current_account.identity_proofs.new(
token: params[:token],
provider: params[:provider],
provider_username: params[:provider_username]
)
if current_account.username.casecmp(params[:username]).zero?
render layout: 'auth'
else
flash[:alert] = I18n.t('identity_proofs.errors.wrong_user', proving: params[:username], current: current_account.username)
redirect_to settings_identity_proofs_path
end
end
def create
@proof = current_account.identity_proofs.where(provider: resource_params[:provider], provider_username: resource_params[:provider_username]).first_or_initialize(resource_params)
@proof.token = resource_params[:token]
if @proof.save
PostStatusService.new.call(current_user.account, text: post_params[:status_text]) if publish_proof?
redirect_to @proof.on_success_path(params[:user_agent])
else
flash[:alert] = I18n.t('identity_proofs.errors.failed', provider: @proof.provider.capitalize)
redirect_to settings_identity_proofs_path
end
end
private
def check_required_params
redirect_to settings_identity_proofs_path unless [:provider, :provider_username, :username, :token].all? { |k| params[k].present? }
end
def resource_params
params.require(:account_identity_proof).permit(:provider, :provider_username, :token)
end
def publish_proof?
ActiveModel::Type::Boolean.new.cast(post_params[:post_status])
end
def post_params
params.require(:account_identity_proof).permit(:post_status, :status_text)
end
def set_body_classes
@body_classes = ''
end
end
@@ -0,0 +1,34 @@
# frozen_string_literal: true
class Settings::ImportsController < Settings::BaseController
layout 'admin'
before_action :authenticate_user!
before_action :set_account
def show
@import = Import.new
end
def create
@import = Import.new(import_params)
@import.account = @account
if @import.save
ImportWorker.perform_async(@import.id)
redirect_to settings_import_path, notice: I18n.t('imports.success')
else
render :show
end
end
private
def set_account
@account = current_user.account
end
def import_params
params.require(:import).permit(:data, :type)
end
end
@@ -0,0 +1,34 @@
# frozen_string_literal: true
class Settings::MigrationsController < Settings::BaseController
layout 'admin'
before_action :authenticate_user!
def show
@migration = Form::Migration.new(account: current_account.moved_to_account)
end
def update
@migration = Form::Migration.new(resource_params)
if @migration.valid? && migration_account_changed?
current_account.update!(moved_to_account: @migration.account)
ActivityPub::UpdateDistributionWorker.perform_async(current_account.id)
redirect_to settings_migration_path, notice: I18n.t('migrations.updated_msg')
else
render :show
end
end
private
def resource_params
params.require(:migration).permit(:acct)
end
def migration_account_changed?
current_account.moved_to_account_id != @migration.account&.id &&
current_account.id != @migration.account&.id
end
end
@@ -0,0 +1,32 @@
# frozen_string_literal: true
class Settings::NotificationsController < Settings::BaseController
layout 'admin'
before_action :authenticate_user!
def show; end
def update
user_settings.update(user_settings_params.to_h)
if current_user.save
redirect_to settings_notifications_path, notice: I18n.t('generic.changes_saved_msg')
else
render :show
end
end
private
def user_settings
UserSettingsDecorator.new(current_user)
end
def user_settings_params
params.require(:user).permit(
notification_emails: %i(follow follow_request reblog favourite mention digest report pending_account),
interactions: %i(must_be_follower must_be_following must_be_following_dm)
)
end
end
@@ -0,0 +1,57 @@
# frozen_string_literal: true
class Settings::PreferencesController < Settings::BaseController
layout 'admin'
before_action :authenticate_user!
def show; end
def update
user_settings.update(user_settings_params.to_h)
if current_user.update(user_params)
I18n.locale = current_user.locale
redirect_to settings_preferences_path, notice: I18n.t('generic.changes_saved_msg')
else
render :show
end
end
private
def user_settings
UserSettingsDecorator.new(current_user)
end
def user_params
params.require(:user).permit(
:locale,
chosen_languages: []
)
end
def user_settings_params
params.require(:user).permit(
:setting_default_privacy,
:setting_default_sensitive,
:setting_default_language,
:setting_unfollow_modal,
:setting_boost_modal,
:setting_delete_modal,
:setting_auto_play_gif,
:setting_display_media,
:setting_expand_spoilers,
:setting_reduce_motion,
:setting_system_font_ui,
:setting_noindex,
:setting_theme,
:setting_hide_network,
:setting_aggregate_reblogs,
:setting_show_application,
:setting_advanced_layout,
notification_emails: %i(follow follow_request reblog favourite mention digest report pending_account),
interactions: %i(must_be_follower must_be_following)
)
end
end
@@ -0,0 +1,37 @@
# frozen_string_literal: true
class Settings::ProfilesController < Settings::BaseController
include ObfuscateFilename
layout 'admin'
before_action :authenticate_user!
before_action :set_account
obfuscate_filename [:account, :avatar]
obfuscate_filename [:account, :header]
def show
@account.build_fields
end
def update
if UpdateAccountService.new.call(@account, account_params)
ActivityPub::UpdateDistributionWorker.perform_async(@account.id)
redirect_to settings_profile_path, notice: I18n.t('generic.changes_saved_msg')
else
@account.build_fields
render :show
end
end
private
def account_params
params.require(:account).permit(:display_name, :note, :avatar, :header, :locked, :bot, :discoverable, fields_attributes: [:name, :value])
end
def set_account
@account = current_account
end
end
@@ -0,0 +1,18 @@
# frozen_string_literal: true
class Settings::SessionsController < Settings::BaseController
before_action :authenticate_user!
before_action :set_session, only: :destroy
def destroy
@session.destroy!
flash[:notice] = I18n.t('sessions.revoke_success')
redirect_to edit_user_registration_path
end
private
def set_session
@session = current_user.session_activations.find(params[:id])
end
end
@@ -0,0 +1,48 @@
# frozen_string_literal: true
module Settings
module TwoFactorAuthentication
class ConfirmationsController < BaseController
layout 'admin'
before_action :authenticate_user!
before_action :ensure_otp_secret
def new
prepare_two_factor_form
end
def create
if current_user.validate_and_consume_otp!(confirmation_params[:code])
flash[:notice] = I18n.t('two_factor_authentication.enabled_success')
current_user.otp_required_for_login = true
@recovery_codes = current_user.generate_otp_backup_codes!
current_user.save!
render 'settings/two_factor_authentication/recovery_codes/index'
else
flash.now[:alert] = I18n.t('two_factor_authentication.wrong_code')
prepare_two_factor_form
render :new
end
end
private
def confirmation_params
params.require(:form_two_factor_confirmation).permit(:code)
end
def prepare_two_factor_form
@confirmation = Form::TwoFactorConfirmation.new
@provision_url = current_user.otp_provisioning_uri(current_user.email, issuer: Rails.configuration.x.local_domain)
@qrcode = RQRCode::QRCode.new(@provision_url)
end
def ensure_otp_secret
redirect_to settings_two_factor_authentication_path unless current_user.otp_secret
end
end
end
end
@@ -0,0 +1,18 @@
# frozen_string_literal: true
module Settings
module TwoFactorAuthentication
class RecoveryCodesController < BaseController
layout 'admin'
before_action :authenticate_user!
def create
@recovery_codes = current_user.generate_otp_backup_codes!
current_user.save!
flash[:notice] = I18n.t('two_factor_authentication.recovery_codes_regenerated')
render :index
end
end
end
end
@@ -0,0 +1,47 @@
# frozen_string_literal: true
module Settings
class TwoFactorAuthenticationsController < BaseController
layout 'admin'
before_action :authenticate_user!
before_action :verify_otp_required, only: [:create]
def show
@confirmation = Form::TwoFactorConfirmation.new
end
def create
current_user.otp_secret = User.generate_otp_secret(32)
current_user.save!
redirect_to new_settings_two_factor_authentication_confirmation_path
end
def destroy
if acceptable_code?
current_user.otp_required_for_login = false
current_user.save!
redirect_to settings_two_factor_authentication_path
else
flash.now[:alert] = I18n.t('two_factor_authentication.wrong_code')
@confirmation = Form::TwoFactorConfirmation.new
render :show
end
end
private
def confirmation_params
params.require(:form_two_factor_confirmation).permit(:code)
end
def verify_otp_required
redirect_to settings_two_factor_authentication_path if current_user.otp_required_for_login?
end
def acceptable_code?
current_user.validate_and_consume_otp!(confirmation_params[:code]) ||
current_user.invalidate_otp_backup_code!(confirmation_params[:code])
end
end
end
@@ -0,0 +1,27 @@
class Settings::Verifications::ModerationController < Admin::BaseController
def index
@verification_requests = AccountVerificationRequest.all
end
def approve
verification_request = AccountVerificationRequest.find params[:id]
# Mark user as verified
account = verification_request.account
account.is_verified = true
account.save()
# Notify user
UserMailer.verification_approved(account.user).deliver_later!
# Remove all traces
verification_request.destroy()
# Redirect back to the form with a proper message
redirect_to settings_verifications_moderation_url, notice: I18n.t('verifications.moderation.approved_msg')
end
def reject
@verification_requests = AccountVerificationRequest.find params[:id]
end
end
@@ -0,0 +1,31 @@
class Settings::Verifications::RequestsController < Settings::BaseController
include Authorization
layout 'admin'
before_action :authenticate_user!
def index
@account_verification_request = AccountVerificationRequest.where(account: current_account)[0] || AccountVerificationRequest.new
end
def create
authorize :account_verification_request, :create?
# POST requests didn't work with only binary input under account_verification_request tag
# Acts like dict input is empty
params = resource_params
params['account'] = current_account
@account_verification_request = AccountVerificationRequest.new(params)
if @account_verification_request.save
redirect_to settings_verifications_requests_path, notice: I18n.t('verifications.requests.created_msg')
else
render :index
end
end
def resource_params
params.require(:account_verification_request).permit(:image)
end
end