diff --git a/Gemfile b/Gemfile index 7dbdc9ea2..8ba09b3c5 100644 --- a/Gemfile +++ b/Gemfile @@ -3,7 +3,6 @@ source 'https://rubygems.org' gem 'rails', '4.0.2' #gem 'turbolinks' -gem 'protected_attributes' # support legacy 'attr_accessible' gem 'rails-i18n' gem 'pg' diff --git a/Gemfile.lock b/Gemfile.lock index 430a06ade..443bcfb9e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -282,8 +282,6 @@ GEM polyglot (0.3.3) private_pub (1.0.3) faye - protected_attributes (1.0.5) - activemodel (>= 4.0.1, < 5.0) pry (0.9.12.4) coderay (~> 1.0) method_source (~> 0.8) @@ -470,7 +468,6 @@ DEPENDENCIES pg_search! poltergeist private_pub - protected_attributes pry-rails rack-cache rails (= 4.0.2) diff --git a/app/controllers/api/messages_controller.rb b/app/controllers/api/messages_controller.rb index 206a1a852..136ef571d 100644 --- a/app/controllers/api/messages_controller.rb +++ b/app/controllers/api/messages_controller.rb @@ -13,7 +13,7 @@ def create good = good || @talk.venue.users.include?(user) return render text: 'Computer says no', status: 740 unless good - message = @talk.messages.build(params[:message]) + message = @talk.messages.build(message_params) message.user = user message.save! @@ -43,4 +43,8 @@ def verified_request? super || form_authenticity_token == request.headers['X-XSRF-TOKEN'] end + def message_params + params.require(:message).permit(:content) + end + end diff --git a/app/controllers/api/social_shares_controller.rb b/app/controllers/api/social_shares_controller.rb index 0999d5029..92ab0a5f1 100644 --- a/app/controllers/api/social_shares_controller.rb +++ b/app/controllers/api/social_shares_controller.rb @@ -3,7 +3,7 @@ class Api::SocialSharesController < ApplicationController before_filter :authenticate_user! def create - @social_share = SocialShare.new(params[:social_share]) + @social_share = SocialShare.new(social_share_params) @social_share.request_ip = request.remote_addr @social_share.user_agent = request.user_agent @social_share.user_id = current_user.id @@ -18,9 +18,11 @@ def create end private + def social_share_params - params.require(:social_share).permit(:request_ip, :user_agent, - :shareable_id, :shareable_type, - :social_network) + params.require(:social_share).permit( :shareable_id, + :shareable_type, + :social_network ) end + end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 340d4df0f..94894e64f 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -76,10 +76,10 @@ def store_location before_filter :update_sanitized_params, if: :devise_controller? + # strong parameters for devise def update_sanitized_params devise_parameter_sanitizer.for(:sign_up) do |u| - u.permit(:firstname, :lastname, :accept_terms_of_use, - :email, :password, :password_confirmation) + u.permit(UsersController::PERMITTED_ATTRS) end end diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb index 68eca3ee0..c37627e80 100644 --- a/app/controllers/comments_controller.rb +++ b/app/controllers/comments_controller.rb @@ -7,7 +7,7 @@ def create authorize! :create, Comment venue = Venue.find(params[:venue_id]) - comment = venue.comments.build(params[:comment]) + comment = venue.comments.build(comment_params) comment.user = current_user if comment.save @@ -29,4 +29,8 @@ def send_email(comment, users) end end + def comment_params + params.require(:comment).permit(:content) + end + end diff --git a/app/controllers/embed_talks_controller.rb b/app/controllers/embed_talks_controller.rb index 478b519f2..a870dc842 100644 --- a/app/controllers/embed_talks_controller.rb +++ b/app/controllers/embed_talks_controller.rb @@ -1,4 +1,5 @@ class EmbedTalksController < ApplicationController + after_action :allow_iframe, only: :show def show @@ -14,4 +15,5 @@ def show def allow_iframe response.headers.except! 'X-Frame-Options' end + end diff --git a/app/controllers/errors_controller.rb b/app/controllers/errors_controller.rb index 275e1819e..8b6c63b74 100644 --- a/app/controllers/errors_controller.rb +++ b/app/controllers/errors_controller.rb @@ -1,4 +1,5 @@ class ErrorsController < ApplicationController + skip_before_filter :check_browser # Handling exceptions dynamically using middleware. @@ -16,4 +17,5 @@ def show # Dedicated landing page for outdated browsers def upgrade_browser end + end diff --git a/app/controllers/reminders_controller.rb b/app/controllers/reminders_controller.rb new file mode 100644 index 000000000..794a9a85f --- /dev/null +++ b/app/controllers/reminders_controller.rb @@ -0,0 +1,36 @@ +# TODO use cancan for authorization +class RemindersController < ApplicationController + + before_action :authenticate_user! + + # GET /reminders + def index + @reminders = current_user.reminders + end + + # POST /reminders + def create + @reminder = Reminder.new + @reminder.user = current_user + + rememberable ||= Talk.find(params[:talk_id]) + rememberable ||= Venue.find(params[:venue_id]) + raise "Cannot find Rememberable with #{params.inspect}" if rememberable.nil? + @reminder.rememberable = rememberable + + if @reminder.save + redirect_to rememberable, notice: I18n.t('reminders.create.success') + else + redirect_to rememberable, error: I18n.t('reminders.create.failure') + end + end + + # DELETE /reminders/1 + def destroy + @reminder = Reminder.find(params[:id]) + @reminder.destroy + redirect_to current_user, anchor: 'reminders', + notice: I18n.t('reminders.destroy.success') + end + +end diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index 1b3e50619..0f3fa3bb2 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -2,15 +2,15 @@ class SearchController < ApplicationController PER_PAGE = 10 + before_action :set_query + # POST /search def create - redirect_to "/search/1/" + u(params[:query]) + redirect_to "/search/1/" + u(@query) end # GET /search/1/:query def show - @query = params[:query] - @results = PgSearch.multisearch(@query). paginate(page: params[:page], per_page: PER_PAGE) @@ -33,4 +33,9 @@ def u(str) ERB::Util.url_encode(str) end + def set_query + params.permit(:query) + @query = params[:query] + end + end diff --git a/app/controllers/talks_controller.rb b/app/controllers/talks_controller.rb index 8b298f4b8..28a5fc849 100644 --- a/app/controllers/talks_controller.rb +++ b/app/controllers/talks_controller.rb @@ -115,7 +115,8 @@ def talk_params params.require(:talk).permit(:title, :teaser, :starts_at_date, :starts_at_time, :duration, :description, :collect, :image, - :tag_list, :guest_list, :language) + :tag_list, :guest_list, :language, + :format) end end diff --git a/app/controllers/users/omniauth_callbacks_controller.rb b/app/controllers/users/omniauth_callbacks_controller.rb index 15c2ad5e7..81fd369bc 100644 --- a/app/controllers/users/omniauth_callbacks_controller.rb +++ b/app/controllers/users/omniauth_callbacks_controller.rb @@ -1,10 +1,10 @@ -require 'pp' - class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController + include Devise::Controllers::Rememberable def facebook - logger.debug("OmniauthCallbacks#facebook - omniauth.auth: \n #{request.env['omniauth.auth']}\n") + logger.debug("OmniauthCallbacks#facebook - omniauth.auth: \n" + + " #{request.env['omniauth.auth']}\n") @user = User.find_for_facebook_oauth(request.env["omniauth.auth"], current_user) unless @user.valid? @@ -12,7 +12,7 @@ def facebook flash[:error] = @user.errors.full_message(:email, "is in use") redirect_to new_user_registration_url and return end - + if @user.persisted? flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Facebook" remember_me(@user) diff --git a/app/controllers/users/registrations_controller.rb b/app/controllers/users/registrations_controller.rb index 12c3e22f9..ce42cf4a6 100644 --- a/app/controllers/users/registrations_controller.rb +++ b/app/controllers/users/registrations_controller.rb @@ -1,6 +1,7 @@ class Users::RegistrationsController < Devise::RegistrationsController + def new - resource = build_resource(params[:user]) + resource = build_resource(user_params) respond_with resource end @@ -8,4 +9,12 @@ def create @guest_user = session[:guest_user_id] = nil super end + + private + + def user_params + return {} unless params[:user] # for redirect on subscribe + params.require(:user).permit(:firstname, :lastname, :email) + end + end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index bba13b47e..46917e667 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -1,5 +1,14 @@ class UsersController < ApplicationController + PERMITTED_ATTRS = [ :firstname, + :lastname, + :accept_terms_of_use, + :email, + :avatar, + :header, + :password, + :password_confirmation ] + before_filter :authenticate_user!, :only => [:edit,:update,:destroy] # layout "application", :only => [:welcome] @@ -47,7 +56,7 @@ def edit # POST /users # POST /users.json def create - @user = User.new(params[:user]) + @user = User.new(user_params) respond_to do |format| if @user.save @@ -69,7 +78,7 @@ def update authorize! :update, @user respond_to do |format| - if @user.update_attributes(params[:user]) + if @user.update_attributes(user_params) format.html do redirect_to @user, flash: { notice: I18n.t("flash.actions.update.notice") } end @@ -100,4 +109,10 @@ def destroy end end + private + + def user_params + params.require(:user).permit(PERMITTED_ATTRS) + end + end diff --git a/app/controllers/venues_controller.rb b/app/controllers/venues_controller.rb index ab68c6c15..b5cce7b4a 100644 --- a/app/controllers/venues_controller.rb +++ b/app/controllers/venues_controller.rb @@ -23,10 +23,10 @@ def show format.html do @upcoming_talks = @venue.talks.where(state: [:prelive, :live]).ordered @archived_talks = @venue.talks.archived.ordered - + @participation = @venue.participations.find_by(user_id: current_user.id) - + @show_join = @participation.nil? && current_user != @venue.user end @@ -51,9 +51,6 @@ def new # GET /venues/1/edit def edit - if params[:renew] - @renew = true - end authorize! :edit, @venue respond_to do |format| format.html {} @@ -64,7 +61,7 @@ def edit # POST /venues # POST /venues.json def create - @venue = Venue.new(params[:venue]) + @venue = Venue.new(venue_params) @venue.user = current_user authorize! :create, @venue @@ -90,7 +87,7 @@ def update authorize! :update, @venue respond_to do |format| - if @venue.update_attributes(params[:venue]) + if @venue.update_attributes(venue_params) format.html { redirect_to @venue, notice: 'Venue was successfully updated.' } format.json { head :no_content } else @@ -113,7 +110,7 @@ def destroy end end - def tags # TODO: check if needed + def tags scope = ActsAsTaggableOn::Tag.where(["name ILIKE ?", "%#{params[:q]}%"]) tags = scope.paginate(:page => params[:page], :per_page => params[:limit] || 10) render json: { tags: tags, total: scope.count } @@ -131,4 +128,10 @@ def set_venue @venue = Venue.find(params[:id]) end + # Only allow a trusted parameter "white list" through. + def venue_params + params.require(:venue).permit(:title, :teaser, :description, + :image, :tag_list) + end + end diff --git a/app/models/appearance.rb b/app/models/appearance.rb index f4026f40f..d0a99578e 100644 --- a/app/models/appearance.rb +++ b/app/models/appearance.rb @@ -6,8 +6,6 @@ # * user_id [integer] - belongs to :user class Appearance < ActiveRecord::Base - attr_accessible :user_id - validates :user, :talk, presence: true belongs_to :user diff --git a/app/models/comment.rb b/app/models/comment.rb index 3a2ba0080..396ccd629 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -8,8 +8,6 @@ # * user_id [integer, not null] - belongs to :user class Comment < ActiveRecord::Base - attr_accessible :content - belongs_to :commentable, polymorphic: true belongs_to :user diff --git a/app/models/message.rb b/app/models/message.rb index 330f0d5c6..2693e3fb9 100644 --- a/app/models/message.rb +++ b/app/models/message.rb @@ -7,8 +7,6 @@ # * user_id [integer] - belongs to :user class Message < ActiveRecord::Base - attr_accessible :content - belongs_to :user belongs_to :talk diff --git a/app/models/reminder.rb b/app/models/reminder.rb new file mode 100644 index 000000000..99268ae56 --- /dev/null +++ b/app/models/reminder.rb @@ -0,0 +1,6 @@ +class Reminder < ActiveRecord::Base + belongs_to :user + belongs_to :rememberable, polymorphic: true + + validates :user, presence: true +end diff --git a/app/models/setting.rb b/app/models/setting.rb index b934b6445..1e5547644 100644 --- a/app/models/setting.rb +++ b/app/models/setting.rb @@ -22,8 +22,6 @@ class Setting < ActiveRecord::Base validates :key, :value, presence: true - attr_accessible :key, :value - class << self def get(key) # try to find an entry in the db diff --git a/app/models/social_share.rb b/app/models/social_share.rb index 13e99cfee..9ef6c3836 100644 --- a/app/models/social_share.rb +++ b/app/models/social_share.rb @@ -9,10 +9,9 @@ # * user_agent [string] - TODO: document me # * user_id [integer] - TODO: document me class SocialShare < ActiveRecord::Base - attr_accessible :request_ip, :user_agent, :user_id, :shareable_id, - :shareable_type, :social_network belongs_to :shareable, polymorphic: true validates :shareable_type, inclusion: %w(talk venue) + end diff --git a/app/models/talk.rb b/app/models/talk.rb index ed1a83750..5ff763c17 100644 --- a/app/models/talk.rb +++ b/app/models/talk.rb @@ -85,11 +85,6 @@ class Talk < ActiveRecord::Base acts_as_taggable - attr_accessible :title, :teaser, :duration, :uri, - :description, :collect, :image, :tag_list, - :guest_list, :starts_at_date, :starts_at_time, - :language - belongs_to :venue, :inverse_of => :talks has_many :appearances, dependent: :destroy has_many :guests, through: :appearances, source: :user diff --git a/app/models/user.rb b/app/models/user.rb index c71a87190..edd947ee2 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -29,19 +29,14 @@ class User < ActiveRecord::Base extend FriendlyId friendly_id :name, use: [:slugged, :finders] - attr_accessible :password, :password_confirmation, :remember_me - attr_accessible :email, :firstname, :lastname - attr_accessible :provider, :uid, :last_request_at - attr_accessible :accept_terms_of_use, :guest, :header, :avatar, :about - attr_accessible :timezone, :website - has_many :comments, dependent: :destroy has_many :messages, dependent: :destroy has_many :venues # as owner has_many :participations, dependent: :destroy has_many :participating_venues, through: :participations, source: :venue - + has_many :reminders, dependent: :destroy + dragonfly_accessor :header do default Rails.root.join('app/assets/images/defaults/user-header.jpg') end @@ -134,5 +129,10 @@ def for_select def insider? !!(email =~ /@voicerepublic.com$/) end + + def remembers?(model) + reminders.exists?( rememberable_id: model.id, + rememberable_type: model.class.name ) + end end diff --git a/app/models/venue.rb b/app/models/venue.rb index e9c5a8019..94f764156 100644 --- a/app/models/venue.rb +++ b/app/models/venue.rb @@ -22,9 +22,6 @@ class Venue < ActiveRecord::Base acts_as_taggable - attr_accessible :title, :teaser, :description, :tag_list, - :talks_attributes, :image, :uri - # TODO: rename to host belongs_to :user diff --git a/app/views/shared/_podcast.rss.builder b/app/views/shared/_podcast.rss.builder index 7231ac940..7743fc855 100644 --- a/app/views/shared/_podcast.rss.builder +++ b/app/views/shared/_podcast.rss.builder @@ -45,7 +45,7 @@ xml.rss namespaces.merge(version: '2.0') do langs = @podcast.talks.map(&:language).compact langs = %w(en) if langs.empty? main_lang = langs.inject(Hash.new { |h, k| h[k] = 0 }) { |h, l| h[l]+=1; h }.to_a.sort_by { |e| e.last }.last.first - xml.language main_lang + xml.language main_lang xml.image do xml.url @podcast.image_url xml.title do @@ -80,7 +80,7 @@ xml.rss namespaces.merge(version: '2.0') do talks.each do |talk| # skip talks where media is missing for whatever reason next unless talk.podcast_file - + xml.item do xml.title h talk.title @@ -89,6 +89,7 @@ xml.rss namespaces.merge(version: '2.0') do xml.itunes :summary, talk.description_as_plaintext xml.itunes :subtitle, talk.teaser + # TODO: Maybe we want to show the speakers here? xml.itunes :author, talk.venue.user.name xml.itunes :duration, talk.podcast_file[:duration] xml.itunes :explicit, 'no' diff --git a/app/views/shared/_reminder.html.haml b/app/views/shared/_reminder.html.haml new file mode 100644 index 000000000..2041b56c9 --- /dev/null +++ b/app/views/shared/_reminder.html.haml @@ -0,0 +1,8 @@ +%li + - target = reminder.rememberable + - case target + - when Talk + = render partial: 'shared/talk_medium_box', locals: { talk: target } + - else + - raise "Hey, you need to implement display of #{target.class.name}" + = link_to t('.delete_reminder'), reminder, method: 'delete' diff --git a/app/views/shared/_social_meta_tags.html.haml b/app/views/shared/_social_meta_tags.html.haml index 66e736e16..58743276b 100644 --- a/app/views/shared/_social_meta_tags.html.haml +++ b/app/views/shared/_social_meta_tags.html.haml @@ -2,7 +2,7 @@ - title = @talk.title - image = "https://#{request.host}#{@talk.flyer.path}" - keywords = @talk.try(:tag_list) -- author = @talk.venue.user.name +- author = @talk.speakers || @talk.venue.user.name - _user_url = user_url(@talk.user) - _venue_url = venue_url(@talk.venue) -# Google diff --git a/app/views/shared/_talk_medium_box.html.haml b/app/views/shared/_talk_medium_box.html.haml index a3aa350b2..ccf873351 100644 --- a/app/views/shared/_talk_medium_box.html.haml +++ b/app/views/shared/_talk_medium_box.html.haml @@ -1,4 +1,4 @@ -- talk = talk_medium_box +- talk ||= talk_medium_box %li.talk-medium-box.box-grey .left-box diff --git a/app/views/talks/_fields.html.haml b/app/views/talks/_fields.html.haml index a4e54f9f0..a90b0be2f 100644 --- a/app/views/talks/_fields.html.haml +++ b/app/views/talks/_fields.html.haml @@ -17,7 +17,8 @@ = f.input :language, as: :grouped_select, collection: Talk::LANGUAGES, input_html: { class: 'languageSelect' }, group_method: :last, label_method: :last, value_method: :first - + = f.input :format, collection: t('.formats') + %br %br -#testdatepicker diff --git a/app/views/talks/show.html.haml b/app/views/talks/show.html.haml index 54bbc4570..6e0052ea5 100644 --- a/app/views/talks/show.html.haml +++ b/app/views/talks/show.html.haml @@ -159,26 +159,36 @@ .talk-talkers-box.row .large-12.columns.text-center - .avatar.avatar-host - .avatar-box - = render partial: "shared/avatar_image", locals: {user: @talk.venue.user, img_size: 62} - .avatar-name.text-center - = @talk.venue.user.name - .avatar(ng-repeat="guest in guests()") - .avatar-box - = render partial: "shared/avatar_image", locals: {user: 'guest', img_size: 62} - .avatar-name.text-center - {{ guest.name }} - .host-actions(ng-show='showHostActions()') - .guest-demote-link(ng-click="demote(guest.id)") - = t('.demote') - + - unless @talk.speakers.blank? + %p.speakers= @talk.speakers + - else + .avatar.avatar-host + .avatar-box + = render partial: "shared/avatar_image", locals: {user: @talk.venue.user, img_size: 62} + .avatar-name.text-center + = @talk.venue.user.name + .avatar(ng-repeat="guest in guests()") + .avatar-box + = render partial: "shared/avatar_image", locals: {user: 'guest', img_size: 62} + .avatar-name.text-center + {{ guest.name }} + .host-actions(ng-show='showHostActions()') + .guest-demote-link(ng-click="demote(guest.id)") + = t('.demote') + .talk-visitors-action-box.row.collapse-large-only(ng-show="userIsAListener()") .large-12.columns .participate-button-box.text-center - url = [ @talk.venue, :participations ] = link_to t('.participate'), url, method: 'post', class: 'button-vr' + - unless current_user.remembers?(@talk) + .row + .large-12.columns + .remember-button-box.text-center + - url = [ @talk, :reminders ] + = link_to t('.remember'), url, method: 'post', class: 'button-vr' + .talk-host-and-participants-action-box.row .large-12.columns.text-center .talkers-action-box diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml index 3306286bb..3f6d525b6 100644 --- a/app/views/users/show.html.haml +++ b/app/views/users/show.html.haml @@ -34,6 +34,10 @@ %a(href="#venues") %span.icon-guide = t('.venues') + %dd.text-center + %a(href="#reminders") + %span.icon-reminders + = t('.reminders') -# -#%dd.text-center -# %a(href="#schedule") @@ -50,6 +54,13 @@ #venues.venues-content.content.active = render partial: 'shared/venue_medium_box', collection: @user.venues + #reminders.reminders-content.content + - if @user.reminders.empty? + = t('.no-reminders') + - else + %ul + = render partial: 'shared/reminder', collection: @user.reminders + #schedule.content TODO #activity.content TODO diff --git a/config/locales/en.yml b/config/locales/en.yml index 79e07d17f..c77f6d19b 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -805,7 +805,7 @@ en: download_flyer: Download embed_player: Embed Player download_talk: Download Talk - initializing: Initializing + initializing: Initializing talk_is_processing: Talk is processing please_reload_this_page: Please reload this page discussion: Chat @@ -836,6 +836,15 @@ en: title: Title teaser: Teaser tag_list: Tag list + formats: + - Conference + - Reading + - Lecture + - Meeting + - Discussion + - Podcast + - Concert + - Other index: talks_on_voice_republic: TALKS ON VOICE REPUBLIC now_live: NOW LIVE @@ -930,3 +939,14 @@ en: