diff --git a/ruby/Gemfile b/ruby/Gemfile index d7935fb3b..8352f613f 100644 --- a/ruby/Gemfile +++ b/ruby/Gemfile @@ -47,6 +47,7 @@ gem 'fog' gem 'rest-client' gem 'iso-639' gem 'rubyzip' +gem 'sanitize' group :test do gem 'simplecov', '~> 0.7.1' diff --git a/ruby/lib/jam_ruby.rb b/ruby/lib/jam_ruby.rb index fe5843a31..eb8fc345e 100755 --- a/ruby/lib/jam_ruby.rb +++ b/ruby/lib/jam_ruby.rb @@ -36,6 +36,7 @@ require "jam_ruby/lib/profanity" require "jam_ruby/lib/json_validator" require "jam_ruby/lib/em_helper" require "jam_ruby/lib/nav" +require "jam_ruby/lib/html_sanitize" require "jam_ruby/resque/audiomixer" require "jam_ruby/resque/icecast_config_writer" require "jam_ruby/resque/resque_hooks" diff --git a/ruby/lib/jam_ruby/lib/html_sanitize.rb b/ruby/lib/jam_ruby/lib/html_sanitize.rb new file mode 100644 index 000000000..b9579ec06 --- /dev/null +++ b/ruby/lib/jam_ruby/lib/html_sanitize.rb @@ -0,0 +1,55 @@ +require 'sanitize' + +module JamRuby + module HtmlSanitize + + SAFE = ['a', 'strong', 'em', 'i', 'ul', 'ol', 'li', 'p', 'b'] + + extend ActiveSupport::Concern + + included do + class_attribute :html_sanitize_options + self.sanitize + end + + + def sanitize_fields + + return if self.html_sanitize_options.nil? + + # strict means use Sanitize's strictest settings, which removes all tags + strict_fields = html_sanitize_options[:strict] || [] + + strict_fields.each do |field| + value = self[field] + + next if value.nil? || !value.is_a?(String) + + self[field] = Sanitize.fragment(value) + end + + # safe means to allow formatting tags only + safe_fields = html_sanitize_options[:safe] || [] + + safe_fields.each do |field| + value = self[field] + + next if value.nil? || !value.is_a?(String) + + self[field] = Sanitize.fragment(value, elements: SAFE) + end + + end + + module ClassMethods + + def html_sanitize(options = {strict: []}) + self.html_sanitize_options = options + end + + def sanitize (options = {}) + before_validation :sanitize_fields + end + end + end +end diff --git a/ruby/lib/jam_ruby/models/band.rb b/ruby/lib/jam_ruby/models/band.rb index a52d65735..24dee5dae 100644 --- a/ruby/lib/jam_ruby/models/band.rb +++ b/ruby/lib/jam_ruby/models/band.rb @@ -1,5 +1,7 @@ module JamRuby class Band < ActiveRecord::Base + include HtmlSanitize + html_sanitize strict: [:biography, :website, :name] attr_accessible :name, :website, :biography, :city, :state, :country, :original_fpfile_photo, :cropped_fpfile_photo, :cropped_large_fpfile_photo, @@ -11,7 +13,7 @@ module JamRuby before_save :stringify_photo_info , :if => :updating_photo validates :biography, no_profanity: true, presence:true, length: {maximum: 4000} - validates :name, presence: true + validates :name, presence: true, no_profanity: true validates :country, presence: true, :unless => :skip_location_validation validates :state, presence: true, :unless => :skip_location_validation validates :city, presence: true, :unless => :skip_location_validation diff --git a/ruby/lib/jam_ruby/models/chat_message.rb b/ruby/lib/jam_ruby/models/chat_message.rb index 028e2d411..52046d7b3 100644 --- a/ruby/lib/jam_ruby/models/chat_message.rb +++ b/ruby/lib/jam_ruby/models/chat_message.rb @@ -1,5 +1,7 @@ module JamRuby class ChatMessage < ActiveRecord::Base + include HtmlSanitize + html_sanitize strict: [:message] self.table_name = 'chat_messages' self.primary_key = 'id' diff --git a/ruby/lib/jam_ruby/models/claimed_recording.rb b/ruby/lib/jam_ruby/models/claimed_recording.rb index d984d6a3c..9fa1e569a 100644 --- a/ruby/lib/jam_ruby/models/claimed_recording.rb +++ b/ruby/lib/jam_ruby/models/claimed_recording.rb @@ -1,5 +1,7 @@ module JamRuby class ClaimedRecording < ActiveRecord::Base + include HtmlSanitize + html_sanitize strict: [:name, :description] attr_accessible :name, :description, :is_public, :genre_id, :recording_id, :user_id, as: :admin diff --git a/ruby/lib/jam_ruby/models/connection.rb b/ruby/lib/jam_ruby/models/connection.rb index 027a9d945..5866f230e 100644 --- a/ruby/lib/jam_ruby/models/connection.rb +++ b/ruby/lib/jam_ruby/models/connection.rb @@ -3,6 +3,7 @@ require 'aasm' module JamRuby class Connection < ActiveRecord::Base + include HtmlSanitize # client_types TYPE_CLIENT = 'client' TYPE_BROWSER = 'browser' diff --git a/ruby/lib/jam_ruby/models/friend_request.rb b/ruby/lib/jam_ruby/models/friend_request.rb index ca5a8c978..4f99e5d21 100644 --- a/ruby/lib/jam_ruby/models/friend_request.rb +++ b/ruby/lib/jam_ruby/models/friend_request.rb @@ -1,5 +1,7 @@ module JamRuby class FriendRequest < ActiveRecord::Base + include HtmlSanitize + html_sanitize strict: [:message] self.primary_key = 'id' diff --git a/ruby/lib/jam_ruby/models/invited_user.rb b/ruby/lib/jam_ruby/models/invited_user.rb index 63d5e5c4a..ee3db45ad 100644 --- a/ruby/lib/jam_ruby/models/invited_user.rb +++ b/ruby/lib/jam_ruby/models/invited_user.rb @@ -1,5 +1,7 @@ module JamRuby class InvitedUser < ActiveRecord::Base + include HtmlSanitize + html_sanitize strict: [:note] VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i diff --git a/ruby/lib/jam_ruby/models/join_request.rb b/ruby/lib/jam_ruby/models/join_request.rb index d7c4f1f28..9fc094d3f 100644 --- a/ruby/lib/jam_ruby/models/join_request.rb +++ b/ruby/lib/jam_ruby/models/join_request.rb @@ -1,5 +1,7 @@ module JamRuby class JoinRequest < ActiveRecord::Base + include HtmlSanitize + html_sanitize strict: [:text] REQUESTOR_MUST_BE_A_MUSICIAN = "requestor must be a musician" diff --git a/ruby/lib/jam_ruby/models/music_session.rb b/ruby/lib/jam_ruby/models/music_session.rb index f522889ad..5c55602bc 100644 --- a/ruby/lib/jam_ruby/models/music_session.rb +++ b/ruby/lib/jam_ruby/models/music_session.rb @@ -2,6 +2,8 @@ require 'iso-639' module JamRuby class MusicSession < ActiveRecord::Base + include HtmlSanitize + html_sanitize strict: [:name, :description] @@log = Logging.logger[MusicSession] diff --git a/ruby/lib/jam_ruby/models/music_session_comment.rb b/ruby/lib/jam_ruby/models/music_session_comment.rb index 72cc94178..f7a545f94 100644 --- a/ruby/lib/jam_ruby/models/music_session_comment.rb +++ b/ruby/lib/jam_ruby/models/music_session_comment.rb @@ -1,5 +1,7 @@ module JamRuby class MusicSessionComment < ActiveRecord::Base + include HtmlSanitize + html_sanitize strict: [:comment] self.table_name = "music_sessions_comments" @@ -15,5 +17,6 @@ module JamRuby :class_name => "JamRuby::User", :foreign_key => "creator_id") + validates :comment, length: {maximum: 1000}, no_profanity: true end end \ No newline at end of file diff --git a/ruby/lib/jam_ruby/models/recording_comment.rb b/ruby/lib/jam_ruby/models/recording_comment.rb index 5747da52f..914c5614f 100644 --- a/ruby/lib/jam_ruby/models/recording_comment.rb +++ b/ruby/lib/jam_ruby/models/recording_comment.rb @@ -1,5 +1,7 @@ module JamRuby class RecordingComment < ActiveRecord::Base + include HtmlSanitize + html_sanitize strict: [:comment] self.table_name = "recordings_comments" @@ -10,5 +12,6 @@ module JamRuby belongs_to :recording, :class_name => "JamRuby::Recording", :foreign_key => "recording_id" belongs_to :user, :class_name => "JamRuby::User", :foreign_key => "creator_id" + validates :comment, length: {maximum: 1000}, no_profanity: true end end \ No newline at end of file diff --git a/ruby/lib/jam_ruby/models/session_info_comment.rb b/ruby/lib/jam_ruby/models/session_info_comment.rb index fa0833807..c46ce3e62 100644 --- a/ruby/lib/jam_ruby/models/session_info_comment.rb +++ b/ruby/lib/jam_ruby/models/session_info_comment.rb @@ -1,5 +1,7 @@ module JamRuby class SessionInfoComment < ActiveRecord::Base + include HtmlSanitize + html_sanitize strict: [:comment] self.table_name = "session_info_comments" @@ -10,7 +12,7 @@ module JamRuby belongs_to(:music_session, :class_name => "JamRuby::MusicSession", :foreign_key => "music_session_id") belongs_to(:user, :class_name => "JamRuby::User", :foreign_key => "creator_id") - # validates :comment, length: {maximum: 1000}, no_profanity: true + validates :comment, length: {maximum: 1000}, no_profanity: true end end \ No newline at end of file diff --git a/ruby/lib/jam_ruby/models/user.rb b/ruby/lib/jam_ruby/models/user.rb index 15eb46d2f..59e688aba 100644 --- a/ruby/lib/jam_ruby/models/user.rb +++ b/ruby/lib/jam_ruby/models/user.rb @@ -3,6 +3,10 @@ include Devise::Models module JamRuby class User < ActiveRecord::Base + include Geokit::ActsAsMappable::Glue unless defined?(acts_as_mappable) + include HtmlSanitize + html_sanitize strict: [:first_name, :last_name, :city, :state, :country, :biography] + #devise: for later: :trackable @@log = Logging.logger[User] @@ -17,7 +21,6 @@ module JamRuby devise :database_authenticatable, :recoverable, :rememberable - include Geokit::ActsAsMappable::Glue unless defined?(acts_as_mappable) acts_as_mappable # after_save :check_lat_lng diff --git a/ruby/spec/jam_ruby/models/music_session_spec.rb b/ruby/spec/jam_ruby/models/music_session_spec.rb index 07d2521dd..dc458d5e6 100644 --- a/ruby/spec/jam_ruby/models/music_session_spec.rb +++ b/ruby/spec/jam_ruby/models/music_session_spec.rb @@ -861,5 +861,15 @@ describe MusicSession do end end + + describe "html_sanitize" do + it "sanitizes" do + music_session1.name = 'dog' + music_session1.description = 'cat' + music_session1.save! + music_session1.name.should == 'dog' + music_session1.description.should == 'cat' + end + end end diff --git a/ruby/spec/jam_ruby/models/user_spec.rb b/ruby/spec/jam_ruby/models/user_spec.rb index 0cf68d4d8..36c729554 100644 --- a/ruby/spec/jam_ruby/models/user_spec.rb +++ b/ruby/spec/jam_ruby/models/user_spec.rb @@ -493,6 +493,25 @@ describe User do end end + describe "html_sanitize" do + it "sanitizes" do + @user.first_name = 'first_name' + @user.last_name = 'last_name' + @user.biography = 'biography' + @user.country = 'country' + @user.state = 'state
' + @user.city = 'city' + + @user.save! + @user.first_name.should == 'first_name' + @user.last_name.should == 'last_name' + @user.biography.should == 'biography' + @user.country.should == 'country' + @user.state.should == 'state' + @user.city.should == 'city' + end + end + describe "update_locidispids" do before(:each) do diff --git a/web/Gemfile b/web/Gemfile index dfe7723e3..257bad644 100644 --- a/web/Gemfile +++ b/web/Gemfile @@ -1,5 +1,4 @@ source 'http://rubygems.org' - unless ENV["LOCAL_DEV"] == "1" source 'https://jamjam:blueberryjam@int.jamkazam.com/gems/' end @@ -79,6 +78,7 @@ gem 'language_list' gem 'rubyzip' gem 'slim' gem 'htmlentities' +gem 'sanitize' group :development, :test do gem 'rspec-rails', '2.14.2' diff --git a/web/app/assets/javascripts/networkTestHelper.js b/web/app/assets/javascripts/networkTestHelper.js index 944f37fb2..340c91916 100644 --- a/web/app/assets/javascripts/networkTestHelper.js +++ b/web/app/assets/javascripts/networkTestHelper.js @@ -297,6 +297,17 @@ return testSummary.attempts.length == 0 || testSummary.attempts.length == 1; } + function hasGoneDown() { + var goneDown = false; + context._.each(testSummary.attempts, function(attempt) { + if(attempt.num_clients == STARTING_NUM_CLIENTS - 1) { + goneDown = true + return false; + } + }); + return goneDown; + } + // is this a retry attempt? If so, how many times now has it been. // 0 = this is the 1st attempt // > 0 indicates the number of retries. @@ -577,6 +588,12 @@ attempt.reason = "success"; testFinished(); } + else if(hasGoneDown()) { + // this means we've gone up before... so don't go back down (i.e., creating a loop) + attempt.reason = "success"; + testSummary.final = { reason: 'success', num_clients: numClientsToTest } + testFinished(); + } else { numClientsToTest++; logger.debug("increasing number of clients to " + numClientsToTest); diff --git a/web/app/assets/stylesheets/client/dragDropTracks.css.scss b/web/app/assets/stylesheets/client/dragDropTracks.css.scss index 986f97236..ad339bb03 100644 --- a/web/app/assets/stylesheets/client/dragDropTracks.css.scss +++ b/web/app/assets/stylesheets/client/dragDropTracks.css.scss @@ -41,7 +41,7 @@ //padding-right:18px; // to keep draggables off of scrollbar. maybe necessary &.compensate { - .ftue-input:not('.hovering') { + .ftue-input:not(.hovering) { } } .ftue-input { diff --git a/web/app/assets/stylesheets/web/welcome.css.scss b/web/app/assets/stylesheets/web/welcome.css.scss index 4b48ce171..0fd187c1f 100644 --- a/web/app/assets/stylesheets/web/welcome.css.scss +++ b/web/app/assets/stylesheets/web/welcome.css.scss @@ -18,6 +18,14 @@ body.web { } } } + + .follow-links { + position: absolute; + right: 0; + top: -60px; + z-index: 100000; + } + .share_links { position: absolute; top: 116px; diff --git a/web/app/controllers/api_users_controller.rb b/web/app/controllers/api_users_controller.rb index 30d507bc7..adb4a7ee7 100644 --- a/web/app/controllers/api_users_controller.rb +++ b/web/app/controllers/api_users_controller.rb @@ -1,3 +1,4 @@ +require 'sanitize' class ApiUsersController < ApiController before_filter :api_signed_in_user, :except => [:create, :show, :signup_confirm, :auth_session_create, :complete, :finalize_update_email, :isp_scoring, :add_play] @@ -338,7 +339,7 @@ class ApiUsersController < ApiController end def notification_create - @notification = Notification.send_text_message(params[:message], current_user, User.find_by_id(params[:receiver])) + @notification = Notification.send_text_message(Sanitize.fragment(params[:message], elements: HtmlSanitize::SAFE), current_user, User.find_by_id(params[:receiver])) respond_with_model(@notification, new: true) end diff --git a/web/app/views/users/welcome.html.haml b/web/app/views/users/welcome.html.haml index 46b03d70e..d41505f1c 100644 --- a/web/app/views/users/welcome.html.haml +++ b/web/app/views/users/welcome.html.haml @@ -7,9 +7,9 @@ = link_to image_tag("web/cta_button.png", :alt => "Sign up now for your free account!"), signup_path, class: "signup", id: "signup" .clearleft = link_to "Already have an account?", signin_path, class: "signin", id: "signin" -= render :partial => 'users/share_links' - content_for :after_black_bar do + = render :partial => 'users/follow_links' - if @jamfest_2014 .jamfest{style: 'top:-70px;position:relative'} %a{ href: event_path(@jamfest_2014.slug), style: 'font-size:20px;margin-top:11px' } diff --git a/web/spec/features/bands_spec.rb b/web/spec/features/bands_spec.rb index 6ddb8966a..d47f97de5 100644 --- a/web/spec/features/bands_spec.rb +++ b/web/spec/features/bands_spec.rb @@ -120,8 +120,8 @@ describe "Bands", :js => true, :type => :feature, :capybara_feature => true do band_website = garbage(2000) complete_band_setup_form(band_name, band_bio, 'band-website' => band_website) - expect(page).to have_selector('#band-profile-name', text: band_name) - expect(page).to have_selector('#band-profile-biography', text: band_bio) + expect(page).to have_selector('#band-profile-name', text: Sanitize.fragment(band_name)) + expect(page).to have_selector('#band-profile-biography', text: Sanitize.fragment(band_bio)) end it "another user receives invite notification during Band Setup" diff --git a/websocket-gateway/Gemfile b/websocket-gateway/Gemfile index d34aefc34..5da51e402 100644 --- a/websocket-gateway/Gemfile +++ b/websocket-gateway/Gemfile @@ -51,6 +51,7 @@ gem 'netaddr' gem 'iso-639' gem 'language_list' gem 'rubyzip' +gem 'sanitize' group :development do gem 'pry'