From 571e445dc37ffb977415e75ad0f621c6e935e189 Mon Sep 17 00:00:00 2001 From: Kyle Drake Date: Sun, 25 Dec 2016 13:40:35 -0600 Subject: [PATCH] experimental support for site tipping integration via paypal or bitcoin --- app/settings.rb | 18 ++++++++++++ app/site.rb | 1 + ext/bitcoin_validator.rb | 49 +++++++++++++++++++++++++++++++++ migrations/094_site_tipping.rb | 13 +++++++++ models/site.rb | 8 ++++++ views/layout.erb | 1 + views/settings/site.erb | 6 ++++ views/settings/site/tipping.erb | 28 +++++++++++++++++++ views/site.erb | 7 +++-- views/site/_tip.erb | 17 ++++++++++++ 10 files changed, 146 insertions(+), 2 deletions(-) create mode 100644 ext/bitcoin_validator.rb create mode 100644 migrations/094_site_tipping.rb create mode 100644 views/settings/site/tipping.erb create mode 100644 views/site/_tip.erb diff --git a/app/settings.rb b/app/settings.rb index 688326fc..673b5fdb 100644 --- a/app/settings.rb +++ b/app/settings.rb @@ -96,6 +96,24 @@ post '/settings/:username/change_name' do end end +post '/settings/:username/tipping' do + require_login + require_ownership_for_settings + + current_site.tipping_enabled = params[:site][:tipping_enabled] + current_site.tipping_paypal = params[:site][:tipping_paypal] + current_site.tipping_bitcoin = params[:site][:tipping_bitcoin] + + if current_site.valid? + current_site.save_changes + flash[:success] = "Tip settings have been updated." + else + flash[:error] = current_site.errors.first.last.first + end + + redirect "/settings/#{current_site.username}#tipping" +end + post '/settings/:username/change_nsfw' do require_login require_ownership_for_settings diff --git a/app/site.rb b/app/site.rb index c3f378f1..0a151cd8 100644 --- a/app/site.rb +++ b/app/site.rb @@ -148,6 +148,7 @@ end get '/site/:username/tip' do |username| @site = Site[username: username] + redirect request.referrer unless @site.tipping_enabled? @title = "Tip #{@site.title}" erb :'tip' end diff --git a/ext/bitcoin_validator.rb b/ext/bitcoin_validator.rb new file mode 100644 index 00000000..3a594334 --- /dev/null +++ b/ext/bitcoin_validator.rb @@ -0,0 +1,49 @@ +class BitcoinValidator + class << self + def address_version + "00" + end + + def p2sh_version + "05" + end + + def valid_address?(address) + hex = decode_base58(address) rescue nil + return false unless hex && hex.bytesize == 50 + return false unless [address_version, p2sh_version].include?(hex[0...2]) + base58_checksum?(address) + end + + def decode_base58(base58_val) + s = base58_to_int(base58_val).to_s(16); s = (s.bytesize.odd? ? '0'+s : s) + s = '' if s == '00' + leading_zero_bytes = (base58_val.match(/^([1]+)/) ? $1 : '').size + s = ("00"*leading_zero_bytes) + s if leading_zero_bytes > 0 + s + end + + def base58_checksum?(base58) + hex = decode_base58(base58) rescue nil + return false unless hex + checksum( hex[0...42] ) == hex[-8..-1] + end + + def checksum(hex) + b = [hex].pack("H*") # unpack hex + Digest::SHA256.hexdigest( Digest::SHA256.digest(b) )[0...8] + end + + + def base58_to_int(base58_val) + alpha = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" + int_val, base = 0, alpha.size + base58_val.reverse.each_char.with_index do |char,index| + raise ArgumentError, 'Value not a valid Base58 String.' unless char_index = alpha.index(char) + int_val += char_index*(base**index) + end + int_val + end + + end +end diff --git a/migrations/094_site_tipping.rb b/migrations/094_site_tipping.rb new file mode 100644 index 00000000..45093494 --- /dev/null +++ b/migrations/094_site_tipping.rb @@ -0,0 +1,13 @@ +Sequel.migration do + up { + DB.add_column :sites, :tipping_enabled, :boolean, default: false + DB.add_column :sites, :tipping_paypal, String + DB.add_column :sites, :tipping_bitcoin, String + } + + down { + DB.drop_column :sites, :tipping_enabled + DB.drop_column :sites, :tipping_paypal + DB.drop_column :sites, :tipping_bitcoin + } +end diff --git a/models/site.rb b/models/site.rb index 5a58ca5e..ac219dc3 100644 --- a/models/site.rb +++ b/models/site.rb @@ -910,6 +910,14 @@ class Site < Sequel::Model errors.add :email, 'A valid email address is required.' end + if !values[:tipping_paypal].blank? && (values[:tipping_paypal] =~ EMAIL_SANITY_REGEX).nil? + errors.add :tipping_paypal, 'A valid PayPal tipping email address is required.' + end + + if !values[:tipping_bitcoin].blank? && !BitcoinValidator.valid_address?(values[:tipping_bitcoin]) + errors.add :tipping_bitcoin, 'Bitcoin tipping address is not valid.' + end + # Check for existing user user = self.class.select(:id, :username).filter(username: values[:username]).first diff --git a/views/layout.erb b/views/layout.erb index 9ccb5b40..4190694a 100644 --- a/views/layout.erb +++ b/views/layout.erb @@ -62,6 +62,7 @@ $("a#like").tooltip({html: true}) $("a.comment_like").tooltip({html: true}) $('#shareButton').popover({html: true}) + $('#tipButton').popover({html: true}) $('.typeahead').typeahead({ minLength: 2, diff --git a/views/settings/site.erb b/views/settings/site.erb index 0658d0ca..05f48c37 100644 --- a/views/settings/site.erb +++ b/views/settings/site.erb @@ -27,6 +27,9 @@
  • Custom Domain
  • Change Site (User) Name
  • + <% if current_site.supporter? %> +
  • Tipping
  • + <% end %> <% if @site.admin_nsfw != true %>
  • 18+
  • @@ -49,6 +52,9 @@
    <%== erb :'settings/site/username' %>
    +
    + <%== erb :'settings/site/tipping' %> +
    <% if @site.admin_nsfw != true %>
    diff --git a/views/settings/site/tipping.erb b/views/settings/site/tipping.erb new file mode 100644 index 00000000..e19270ed --- /dev/null +++ b/views/settings/site/tipping.erb @@ -0,0 +1,28 @@ +

    Site Tipping

    + +

    + This adds a "Send a Tip" button to your site profile, allowing people to send tips to you for your site. This will send users to PayPal to send money to your account. If you have a Bitcoin address, you can add that too. +

    + +
    +
    + <%== csrf_token_input_html %> +
    + +

    + Enable Site Tipping: checked<% end %> + > +

    + + + + + + + +
    + + +
    +
    diff --git a/views/site.erb b/views/site.erb index c8d67edb..d6c7a5b1 100644 --- a/views/site.erb +++ b/views/site.erb @@ -54,8 +54,11 @@ <% end %> - '> - Share + '> Share + + <% if site.tipping_enabled && (!site.tipping_paypal.blank? || !site.tipping_bitcoin.blank?) %> + '> Send a Tip + <% end %>
    diff --git a/views/site/_tip.erb b/views/site/_tip.erb new file mode 100644 index 00000000..1817b41f --- /dev/null +++ b/views/site/_tip.erb @@ -0,0 +1,17 @@ +<% unless site.tipping_paypal.blank? %> +
    + + + + + + + + Credit Card +
    + PayPal +
    +<% end %> +<% unless site.tipping_bitcoin.blank? %> + ">Bitcoin +<% end %>