From 66f1d2ec0b8cb3387c9760707df614d25021ae92 Mon Sep 17 00:00:00 2001 From: Devin Howard Date: Sat, 13 Feb 2016 17:28:09 +0800 Subject: [PATCH 01/19] install pundit --- Gemfile | 2 +- Gemfile.lock | 5 ++- app/controllers/application_controller.rb | 1 + app/policies/application_policy.rb | 53 +++++++++++++++++++++++ 4 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 app/policies/application_policy.rb diff --git a/Gemfile b/Gemfile index 8379a7db..eec31832 100644 --- a/Gemfile +++ b/Gemfile @@ -6,7 +6,7 @@ gem 'rails', '4.2.4' gem 'devise' gem 'redis' gem 'pg' -gem 'cancancan' +gem 'pundit' gem 'formula' gem 'formtastic' gem 'json' diff --git a/Gemfile.lock b/Gemfile.lock index eb8edec5..2f10214a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -56,7 +56,6 @@ GEM builder (3.2.2) byebug (5.0.0) columnize (= 0.9.0) - cancancan (1.13.1) climate_control (0.0.3) activesupport (>= 3.0) cocaine (0.5.7) @@ -141,6 +140,8 @@ GEM pry (~> 0.10) pry-rails (0.3.4) pry (>= 0.9.10) + pundit (1.1.0) + activesupport (>= 3.0.0) quiet_assets (1.1.0) railties (>= 3.1, < 5.0) rack (1.6.4) @@ -243,7 +244,6 @@ DEPENDENCIES best_in_place better_errors binding_of_caller - cancancan coffee-rails devise dotenv @@ -260,6 +260,7 @@ DEPENDENCIES pg pry-byebug pry-rails + pundit quiet_assets rails (= 4.2.4) rails3-jquery-autocomplete diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 71d3d6ea..c380f96c 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,4 +1,5 @@ class ApplicationController < ActionController::Base + include Pundit protect_from_forgery before_filter :get_invite_link diff --git a/app/policies/application_policy.rb b/app/policies/application_policy.rb new file mode 100644 index 00000000..2a0bbc52 --- /dev/null +++ b/app/policies/application_policy.rb @@ -0,0 +1,53 @@ +class ApplicationPolicy + attr_reader :user, :record + + def initialize(user, record) + @user = user + @record = record + end + + def index? + false + end + + def show? + scope.where(:id => record.id).exists? + end + + def create? + false + end + + def new? + create? + end + + def update? + false + end + + def edit? + update? + end + + def destroy? + false + end + + def scope + Pundit.policy_scope!(user, record.class) + end + + class Scope + attr_reader :user, :scope + + def initialize(user, scope) + @user = user + @scope = scope + end + + def resolve + scope + end + end +end From 52facb9c1da665e36ea6f81b9a712fa6e1f1a361 Mon Sep 17 00:00:00 2001 From: Devin Howard Date: Sat, 13 Feb 2016 17:28:16 +0800 Subject: [PATCH 02/19] topic policy --- app/policies/topic_policy.rb | 40 ++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 app/policies/topic_policy.rb diff --git a/app/policies/topic_policy.rb b/app/policies/topic_policy.rb new file mode 100644 index 00000000..55e79c2d --- /dev/null +++ b/app/policies/topic_policy.rb @@ -0,0 +1,40 @@ +class TopicPolicy < ApplicationPolicy + class Scope < Scope + def resolve + scope.where('permission IN ("public", "commons") OR user_id = ?', user.id) + end + end + + def create? + user.present? + end + + def show? + record.permission == 'commons' || record.permission == 'public' || record.user == user + end + + def update? + # user.present? && (record.permission == 'commons' || record.user == user) + true + end + + def destroy? + record.user == user || user.admin + end + + def autocomplete_topic? + user.present? + end + + def network? + show? + end + + def relative_numbers? + show? + end + + def relatives? + show? + end +end From baca4aac83f08fe26d3f4f078ba745310bca8385 Mon Sep 17 00:00:00 2001 From: Devin Howard Date: Sat, 13 Feb 2016 17:28:21 +0800 Subject: [PATCH 03/19] synapse policy --- app/policies/synapse_policy.rb | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 app/policies/synapse_policy.rb diff --git a/app/policies/synapse_policy.rb b/app/policies/synapse_policy.rb new file mode 100644 index 00000000..7cd305bf --- /dev/null +++ b/app/policies/synapse_policy.rb @@ -0,0 +1,25 @@ +class SynapsePolicy < ApplicationPolicy + class Scope < Scope + def resolve + scope.where('permission IN ("public", "commons") OR user_id = ?', user.id) + end + end + + def create? + user.present? + end + + def show? + #record.permission == 'commons' || record.permission == 'public' || record.user == user + true + end + + def update? + #user.present? && (record.permission == 'commons' || record.user == user) + true + end + + def destroy? + record.user == user || user.admin + end +end From 8ef847bd6d374daecf2a98f1adda9a9dca91f67b Mon Sep 17 00:00:00 2001 From: Devin Howard Date: Sat, 13 Feb 2016 17:42:36 +0800 Subject: [PATCH 04/19] factor maps#index into 4 separate functions --- app/controllers/maps_controller.rb | 80 ++++++++++++++++++------------ config/routes.rb | 11 ++-- 2 files changed, 55 insertions(+), 36 deletions(-) diff --git a/app/controllers/maps_controller.rb b/app/controllers/maps_controller.rb index 9ad05810..80568b90 100644 --- a/app/controllers/maps_controller.rb +++ b/app/controllers/maps_controller.rb @@ -6,47 +6,66 @@ class MapsController < ApplicationController autocomplete :map, :name, :full => true, :extra_data => [:user_id] # GET /explore/active - # GET /explore/featured - # GET /explore/mapper/:id - def index - return redirect_to activemaps_url if request.path == "/explore" - + def activemaps @current = current_user - @maps = [] page = params[:page].present? ? params[:page] : 1 + @maps = Map.where("maps.permission != ?", "private").order("updated_at DESC").page(page).per(20) + @request = "active" - if request.path.index("/explore/active") != nil - @maps = Map.where("maps.permission != ?", "private").order("updated_at DESC").page(page).per(20) - @request = "active" - elsif request.path.index("/explore/featured") != nil - @maps = Map.where("maps.featured = ? AND maps.permission != ?", true, "private").order("updated_at DESC").page(page).per(20) - @request = "featured" - elsif request.path.index('/explore/mine') != nil # looking for maps by me - return redirect_to activemaps_url if !authenticated? - - # don't need to exclude private maps because they all belong to you - @maps = Map.where("maps.user_id = ?", @current.id).order("updated_at DESC").page(page).per(20) - @request = "you" - elsif request.path.index('/explore/mapper/') != nil # looking for maps by a mapper - @user = User.find(params[:id]) - @maps = Map.where("maps.user_id = ? AND maps.permission != ?", @user.id, "private").order("updated_at DESC").page(page).per(20) - @request = "mapper" - end + redirect_to root_url and return if authenticated? respond_to do |format| - format.html { - if @request == "active" && authenticated? - redirect_to root_url and return - end - respond_with(@maps, @request, @user) - } + format.html { respond_with(@maps, @request, @user) } + format.json { render json: @maps } + end + end + + # GET /explore/featured + def featuredmaps + @current = current_user + page = params[:page].present? ? params[:page] : 1 + @maps = Map.where("maps.featured = ? AND maps.permission != ?", true, "private") + .order("updated_at DESC").page(page).per(20) + @request = "featured" + + respond_to do |format| + format.html { respond_with(@maps, @request, @user) } + format.json { render json: @maps } + end + end + + # GET /explore/mine + def mymaps + return redirect_to activemaps_url if !authenticated? + + @current = current_user + page = params[:page].present? ? params[:page] : 1 + # don't need to exclude private maps because they all belong to you + @maps = Map.where("maps.user_id = ?", @current.id).order("updated_at DESC").page(page).per(20) + @request = "you" + + respond_to do |format| + format.html { respond_with(@maps, @request, @user) } + format.json { render json: @maps } + end + end + + # GET /explore/mapper/:id + def usermaps + @current = current_user + page = params[:page].present? ? params[:page] : 1 + @user = User.find(params[:id]) + @maps = Map.where("maps.user_id = ? AND maps.permission != ?", @user.id, "private").order("updated_at DESC").page(page).per(20) + @request = "mapper" + + respond_to do |format| + format.html { respond_with(@maps, @request, @user) } format.json { render json: @maps } end end # GET maps/:id def show - @current = current_user @map = Map.find(params[:id]).authorize_to_show(@current) @@ -72,7 +91,6 @@ class MapsController < ApplicationController # GET maps/:id/contains def contains - @current = current_user @map = Map.find(params[:id]).authorize_to_show(@current) diff --git a/config/routes.rb b/config/routes.rb index a3ab6e3a..76d281ce 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -20,11 +20,12 @@ Metamaps::Application.routes.draw do get 'topics/:id/relative_numbers', to: 'topics#relative_numbers', as: :relative_numbers get 'topics/:id/relatives', to: 'topics#relatives', as: :relatives - get 'explore/active', to: 'maps#index', as: :activemaps - get 'explore/featured', to: 'maps#index', as: :featuredmaps - get 'explore/mine', to: 'maps#index', as: :mymaps - get 'explore/mapper/:id', to: 'maps#index', as: :usermaps - resources :maps, except: [:new, :edit] + resources :maps, except: [:index, :new, :edit] + get 'explore/active', to: 'maps#activemaps' + get 'explore/featured', to: 'maps#featuredmaps' + get 'explore/mine', to: 'maps#mymaps' + get 'explore/mapper/:id', to: 'maps#usermaps' + get 'maps/:id/contains', to: 'maps#contains', as: :contains post 'maps/:id/upload_screenshot', to: 'maps#screenshot', as: :screenshot From bbc36de62830166df0b023bd1092416efab416ea Mon Sep 17 00:00:00 2001 From: Devin Howard Date: Sat, 13 Feb 2016 17:44:11 +0800 Subject: [PATCH 05/19] update maps spec --- spec/controllers/maps_controller_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/controllers/maps_controller_spec.rb b/spec/controllers/maps_controller_spec.rb index b2f0abec..67950d75 100644 --- a/spec/controllers/maps_controller_spec.rb +++ b/spec/controllers/maps_controller_spec.rb @@ -10,7 +10,7 @@ RSpec.describe MapsController, type: :controller do describe 'GET #index' do it 'viewable maps as @maps' do - get :index, {} + get :activemaps expect(assigns(:maps)).to eq([map]) end end From bc7db85c8c354aca9de9157f9f28ccc775075a75 Mon Sep 17 00:00:00 2001 From: Devin Howard Date: Sun, 28 Feb 2016 13:13:44 +0800 Subject: [PATCH 06/19] update map index views --- app/controllers/maps_controller.rb | 12 +++------ app/views/maps/activemaps.html.erb | 15 +++++++++++ app/views/maps/featuredmaps.html.erb | 15 +++++++++++ app/views/maps/index.html.erb | 38 ---------------------------- app/views/maps/mymaps.html.erb | 15 +++++++++++ app/views/maps/usermaps.html.erb | 18 +++++++++++++ 6 files changed, 67 insertions(+), 46 deletions(-) create mode 100644 app/views/maps/activemaps.html.erb create mode 100644 app/views/maps/featuredmaps.html.erb delete mode 100644 app/views/maps/index.html.erb create mode 100644 app/views/maps/mymaps.html.erb create mode 100644 app/views/maps/usermaps.html.erb diff --git a/app/controllers/maps_controller.rb b/app/controllers/maps_controller.rb index 80568b90..cad6d8f6 100644 --- a/app/controllers/maps_controller.rb +++ b/app/controllers/maps_controller.rb @@ -10,12 +10,11 @@ class MapsController < ApplicationController @current = current_user page = params[:page].present? ? params[:page] : 1 @maps = Map.where("maps.permission != ?", "private").order("updated_at DESC").page(page).per(20) - @request = "active" redirect_to root_url and return if authenticated? respond_to do |format| - format.html { respond_with(@maps, @request, @user) } + format.html { respond_with(@maps, @user) } format.json { render json: @maps } end end @@ -26,10 +25,9 @@ class MapsController < ApplicationController page = params[:page].present? ? params[:page] : 1 @maps = Map.where("maps.featured = ? AND maps.permission != ?", true, "private") .order("updated_at DESC").page(page).per(20) - @request = "featured" respond_to do |format| - format.html { respond_with(@maps, @request, @user) } + format.html { respond_with(@maps, @user) } format.json { render json: @maps } end end @@ -42,10 +40,9 @@ class MapsController < ApplicationController page = params[:page].present? ? params[:page] : 1 # don't need to exclude private maps because they all belong to you @maps = Map.where("maps.user_id = ?", @current.id).order("updated_at DESC").page(page).per(20) - @request = "you" respond_to do |format| - format.html { respond_with(@maps, @request, @user) } + format.html { respond_with(@maps, @user) } format.json { render json: @maps } end end @@ -56,10 +53,9 @@ class MapsController < ApplicationController page = params[:page].present? ? params[:page] : 1 @user = User.find(params[:id]) @maps = Map.where("maps.user_id = ? AND maps.permission != ?", @user.id, "private").order("updated_at DESC").page(page).per(20) - @request = "mapper" respond_to do |format| - format.html { respond_with(@maps, @request, @user) } + format.html { respond_with(@maps, @user) } format.json { render json: @maps } end end diff --git a/app/views/maps/activemaps.html.erb b/app/views/maps/activemaps.html.erb new file mode 100644 index 00000000..90156321 --- /dev/null +++ b/app/views/maps/activemaps.html.erb @@ -0,0 +1,15 @@ +<% # + # @file + # Shows a list of recently active maps + # GET /explore/active(.:format) + # %> + + diff --git a/app/views/maps/featuredmaps.html.erb b/app/views/maps/featuredmaps.html.erb new file mode 100644 index 00000000..048d23a4 --- /dev/null +++ b/app/views/maps/featuredmaps.html.erb @@ -0,0 +1,15 @@ +<% # + # @file + # Shows a list of featured maps + # GET /explore/featured(.:format) + # %> + + diff --git a/app/views/maps/index.html.erb b/app/views/maps/index.html.erb deleted file mode 100644 index 0e067a63..00000000 --- a/app/views/maps/index.html.erb +++ /dev/null @@ -1,38 +0,0 @@ -<% # - # @file - # Shows a list of all maps, or just a user's maps. - # GET /explore/active(.:format) - # GET /explore/featured(.:format) - # GET /explore/mine(.:format) - # GET /explore/mapper/:id(.:format) - # GET /maps(.:format) - # %> - - diff --git a/app/views/maps/mymaps.html.erb b/app/views/maps/mymaps.html.erb new file mode 100644 index 00000000..76a96ec1 --- /dev/null +++ b/app/views/maps/mymaps.html.erb @@ -0,0 +1,15 @@ +<% # + # @file + # Shows a list of current user's maps + # GET /explore/mine(.:format) + # %> + + diff --git a/app/views/maps/usermaps.html.erb b/app/views/maps/usermaps.html.erb new file mode 100644 index 00000000..4107fbb7 --- /dev/null +++ b/app/views/maps/usermaps.html.erb @@ -0,0 +1,18 @@ +<% # + # @file + # Shows a list of a user's maps + # GET /explore/mapper/:id(.:format) + # %> + + From cec6d3bfcd3776f23bb2d3472554763c1a442ac5 Mon Sep 17 00:00:00 2001 From: Devin Howard Date: Sun, 28 Feb 2016 13:24:55 +0800 Subject: [PATCH 07/19] handle pundit errors with http 403 --- config/application.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config/application.rb b/config/application.rb index 399b32c9..658a4203 100644 --- a/config/application.rb +++ b/config/application.rb @@ -53,5 +53,8 @@ module Metamaps g.test_framework :rspec end config.active_record.raise_in_transactional_callbacks = true + + # pundit errors return 403 FORBIDDEN + config.action_dispatch.rescue_responses["Pundit::NotAuthorizedError"] = :forbidden end end From 1e01ff8bc976fe5e2b5ccd1f8b53419631f247e6 Mon Sep 17 00:00:00 2001 From: Devin Howard Date: Sun, 28 Feb 2016 13:28:28 +0800 Subject: [PATCH 08/19] map policy --- app/policies/map_policy.rb | 48 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 app/policies/map_policy.rb diff --git a/app/policies/map_policy.rb b/app/policies/map_policy.rb new file mode 100644 index 00000000..96a0b724 --- /dev/null +++ b/app/policies/map_policy.rb @@ -0,0 +1,48 @@ +class MapPolicy < ApplicationPolicy + class Scope < Scope + def resolve + scope.where('permission IN ("public", "commons") OR user_id = ?', @user.id) + end + end + + def activemaps? + @user.blank? # redirect to root url if authenticated for some reason + end + + def featuredmaps? + true + end + + def mymaps? + @user.present? + end + + def usermaps? + true + end + + def show? + @record.permission == 'commons' || @record.permission == 'public' || @record.user == @user + end + + def contains? + show? + end + + def create? + @user.present? + end + + def update? + @user.present? && (@record.permission == 'commons' || @record.user == @user) + true + end + + def screenshot? + update? + end + + def destroy? + @record.user == @user || @user.admin + end +end From 3ed6ffbdba12fac5d031c5bfafb95de7d5212ef0 Mon Sep 17 00:00:00 2001 From: Devin Howard Date: Sun, 28 Feb 2016 13:29:33 +0800 Subject: [PATCH 09/19] @record/@user in topic/synapse policy --- app/policies/synapse_policy.rb | 10 +++++----- app/policies/topic_policy.rb | 12 ++++++------ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/app/policies/synapse_policy.rb b/app/policies/synapse_policy.rb index 7cd305bf..f7db11ed 100644 --- a/app/policies/synapse_policy.rb +++ b/app/policies/synapse_policy.rb @@ -1,25 +1,25 @@ class SynapsePolicy < ApplicationPolicy class Scope < Scope def resolve - scope.where('permission IN ("public", "commons") OR user_id = ?', user.id) + scope.where('permission IN ("public", "commons") OR user_id = ?', @user.id) end end def create? - user.present? + @user.present? end def show? - #record.permission == 'commons' || record.permission == 'public' || record.user == user + # @record.permission == 'commons' || @record.permission == 'public' || @record.user == @user true end def update? - #user.present? && (record.permission == 'commons' || record.user == user) + # @user.present? && (@record.permission == 'commons' || @record.user == @user) true end def destroy? - record.user == user || user.admin + @record.user == @user || @user.admin end end diff --git a/app/policies/topic_policy.rb b/app/policies/topic_policy.rb index 55e79c2d..2978cb13 100644 --- a/app/policies/topic_policy.rb +++ b/app/policies/topic_policy.rb @@ -1,29 +1,29 @@ class TopicPolicy < ApplicationPolicy class Scope < Scope def resolve - scope.where('permission IN ("public", "commons") OR user_id = ?', user.id) + scope.where('permission IN ("public", "commons") OR user_id = ?', @user.id) end end def create? - user.present? + @user.present? end def show? - record.permission == 'commons' || record.permission == 'public' || record.user == user + @record.permission == 'commons' || @record.permission == 'public' || @record.user == @user end def update? - # user.present? && (record.permission == 'commons' || record.user == user) + # @user.present? && (@record.permission == 'commons' || @record.user == @user) true end def destroy? - record.user == user || user.admin + @record.user == @user || @user.admin end def autocomplete_topic? - user.present? + @user.present? end def network? From cbb6b648bee1fd833a29e00d133e08790314465d Mon Sep 17 00:00:00 2001 From: Devin Howard Date: Sun, 28 Feb 2016 16:53:59 +0800 Subject: [PATCH 10/19] implement main_policy (headless). also remove all @current references --- app/controllers/main_controller.rb | 9 +++---- app/controllers/maps_controller.rb | 35 ++++++++++---------------- app/controllers/synapses_controller.rb | 2 +- app/controllers/topics_controller.rb | 30 +++++++++------------- app/policies/main_policy.rb | 26 +++++++++++++++++++ 5 files changed, 55 insertions(+), 47 deletions(-) create mode 100644 app/policies/main_policy.rb diff --git a/app/controllers/main_controller.rb b/app/controllers/main_controller.rb index 1cd0f577..31a55abc 100644 --- a/app/controllers/main_controller.rb +++ b/app/controllers/main_controller.rb @@ -8,15 +8,13 @@ class MainController < ApplicationController # home page def home - @current = current_user - + @maps = Map.where("maps.permission != ?", "private").order("updated_at DESC").page(1).per(20) respond_to do |format| format.html { if authenticated? - @maps = Map.where("maps.permission != ?", "private").order("updated_at DESC").page(1).per(20) - respond_with(@maps, @current) + render 'main/home' else - respond_with(@current) + render 'maps/activemaps' end } end @@ -213,5 +211,4 @@ class MainController < ApplicationController render json: autocomplete_synapse_array_json(@synapses) end - end diff --git a/app/controllers/maps_controller.rb b/app/controllers/maps_controller.rb index cad6d8f6..cb949098 100644 --- a/app/controllers/maps_controller.rb +++ b/app/controllers/maps_controller.rb @@ -7,10 +7,10 @@ class MapsController < ApplicationController # GET /explore/active def activemaps - @current = current_user page = params[:page].present? ? params[:page] : 1 @maps = Map.where("maps.permission != ?", "private").order("updated_at DESC").page(page).per(20) + # root url => main/home. main/home renders maps/activemaps view. redirect_to root_url and return if authenticated? respond_to do |format| @@ -21,7 +21,6 @@ class MapsController < ApplicationController # GET /explore/featured def featuredmaps - @current = current_user page = params[:page].present? ? params[:page] : 1 @maps = Map.where("maps.featured = ? AND maps.permission != ?", true, "private") .order("updated_at DESC").page(page).per(20) @@ -36,10 +35,9 @@ class MapsController < ApplicationController def mymaps return redirect_to activemaps_url if !authenticated? - @current = current_user page = params[:page].present? ? params[:page] : 1 # don't need to exclude private maps because they all belong to you - @maps = Map.where("maps.user_id = ?", @current.id).order("updated_at DESC").page(page).per(20) + @maps = Map.where("maps.user_id = ?", current_user.id).order("updated_at DESC").page(page).per(20) respond_to do |format| format.html { respond_with(@maps, @user) } @@ -49,7 +47,6 @@ class MapsController < ApplicationController # GET /explore/mapper/:id def usermaps - @current = current_user page = params[:page].present? ? params[:page] : 1 @user = User.find(params[:id]) @maps = Map.where("maps.user_id = ? AND maps.permission != ?", @user.id, "private").order("updated_at DESC").page(page).per(20) @@ -62,8 +59,7 @@ class MapsController < ApplicationController # GET maps/:id def show - @current = current_user - @map = Map.find(params[:id]).authorize_to_show(@current) + @map = Map.find(params[:id]).authorize_to_show(current_user) if not @map redirect_to root_url, notice: "Access denied. That map is private." and return @@ -72,11 +68,11 @@ class MapsController < ApplicationController respond_to do |format| format.html { @allmappers = @map.contributors - @alltopics = @map.topics.to_a.delete_if {|t| t.permission == "private" && (!authenticated? || (authenticated? && @current.id != t.user_id)) } - @allsynapses = @map.synapses.to_a.delete_if {|s| s.permission == "private" && (!authenticated? || (authenticated? && @current.id != s.user_id)) } + @alltopics = @map.topics.to_a.delete_if {|t| t.permission == "private" && (!authenticated? || (authenticated? && current_user.id != t.user_id)) } + @allsynapses = @map.synapses.to_a.delete_if {|s| s.permission == "private" && (!authenticated? || (authenticated? && current_user.id != s.user_id)) } @allmappings = @map.mappings.to_a.delete_if {|m| object = m.mappable - !object || (object.permission == "private" && (!authenticated? || (authenticated? && @current.id != object.user_id))) + !object || (object.permission == "private" && (!authenticated? || (authenticated? && current_user.id != object.user_id))) } respond_with(@allmappers, @allmappings, @allsynapses, @alltopics, @map) @@ -87,19 +83,18 @@ class MapsController < ApplicationController # GET maps/:id/contains def contains - @current = current_user - @map = Map.find(params[:id]).authorize_to_show(@current) + @map = Map.find(params[:id]).authorize_to_show(current_user) if not @map redirect_to root_url, notice: "Access denied. That map is private." and return end @allmappers = @map.contributors - @alltopics = @map.topics.to_a.delete_if {|t| t.permission == "private" && (!authenticated? || (authenticated? && @current.id != t.user_id)) } - @allsynapses = @map.synapses.to_a.delete_if {|s| s.permission == "private" && (!authenticated? || (authenticated? && @current.id != s.user_id)) } + @alltopics = @map.topics.to_a.delete_if {|t| t.permission == "private" && (!authenticated? || (authenticated? && current_user.id != t.user_id)) } + @allsynapses = @map.synapses.to_a.delete_if {|s| s.permission == "private" && (!authenticated? || (authenticated? && current_user.id != s.user_id)) } @allmappings = @map.mappings.to_a.delete_if {|m| object = m.mappable - !object || (object.permission == "private" && (!authenticated? || (authenticated? && @current.id != object.user_id))) + !object || (object.permission == "private" && (!authenticated? || (authenticated? && current_user.id != object.user_id))) } @json = Hash.new() @@ -167,8 +162,7 @@ class MapsController < ApplicationController # PUT maps/:id def update - @current = current_user - @map = Map.find(params[:id]).authorize_to_edit(@current) + @map = Map.find(params[:id]).authorize_to_edit(current_user) respond_to do |format| if !@map @@ -183,8 +177,7 @@ class MapsController < ApplicationController # POST maps/:id/upload_screenshot def screenshot - @current = current_user - @map = Map.find(params[:id]).authorize_to_edit(@current) + @map = Map.find(params[:id]).authorize_to_edit(current_user) if @map png = Base64.decode64(params[:encoded_image]['data:image/png;base64,'.length .. -1]) @@ -207,9 +200,7 @@ class MapsController < ApplicationController # DELETE maps/:id def destroy - @current = current_user - - @map = Map.find(params[:id]).authorize_to_delete(@current) + @map = Map.find(params[:id]).authorize_to_delete(current_user) @map.delete if @map diff --git a/app/controllers/synapses_controller.rb b/app/controllers/synapses_controller.rb index f19dc053..e706aac4 100644 --- a/app/controllers/synapses_controller.rb +++ b/app/controllers/synapses_controller.rb @@ -9,7 +9,7 @@ class SynapsesController < ApplicationController def show @synapse = Synapse.find(params[:id]) - #.authorize_to_show(@current) + #.authorize_to_show(current_user) #if not @synapse # redirect_to root_url and return diff --git a/app/controllers/topics_controller.rb b/app/controllers/topics_controller.rb index 19062ba9..47105396 100644 --- a/app/controllers/topics_controller.rb +++ b/app/controllers/topics_controller.rb @@ -7,7 +7,6 @@ class TopicsController < ApplicationController # GET /topics/autocomplete_topic def autocomplete_topic - @current = current_user term = params[:term] if term && !term.empty? @topics = Topic.where('LOWER("name") like ?', term.downcase + '%').order('"name"') @@ -15,7 +14,7 @@ class TopicsController < ApplicationController #read this next line as 'delete a topic if its private and you're either #1. logged out or 2. logged in but not the topic creator @topics.to_a.delete_if {|t| t.permission == "private" && - (!authenticated? || (authenticated? && @current.id != t.user_id)) } + (!authenticated? || (authenticated? && current_user.id != t.user_id)) } else @topics = [] end @@ -24,8 +23,7 @@ class TopicsController < ApplicationController # GET topics/:id def show - @current = current_user - @topic = Topic.find(params[:id]).authorize_to_show(@current) + @topic = Topic.find(params[:id]).authorize_to_show(current_user) if not @topic redirect_to root_url, notice: "Access denied. That topic is private." and return @@ -33,8 +31,8 @@ class TopicsController < ApplicationController respond_to do |format| format.html { - @alltopics = ([@topic] + @topic.relatives).delete_if {|t| t.permission == "private" && (!authenticated? || (authenticated? && @current.id != t.user_id)) } # should limit to topics visible to user - @allsynapses = @topic.synapses.to_a.delete_if {|s| s.permission == "private" && (!authenticated? || (authenticated? && @current.id != s.user_id)) } + @alltopics = ([@topic] + @topic.relatives).delete_if {|t| t.permission == "private" && (!authenticated? || (authenticated? && current_user.id != t.user_id)) } # should limit to topics visible to user + @allsynapses = @topic.synapses.to_a.delete_if {|s| s.permission == "private" && (!authenticated? || (authenticated? && current_user.id != s.user_id)) } @allcreators = [] @alltopics.each do |t| @@ -56,15 +54,14 @@ class TopicsController < ApplicationController # GET topics/:id/network def network - @current = current_user - @topic = Topic.find(params[:id]).authorize_to_show(@current) + @topic = Topic.find(params[:id]).authorize_to_show(current_user) if not @topic redirect_to root_url, notice: "Access denied. That topic is private." and return end - @alltopics = @topic.relatives.to_a.delete_if {|t| t.permission == "private" && (!authenticated? || (authenticated? && @current.id != t.user_id)) } - @allsynapses = @topic.synapses.to_a.delete_if {|s| s.permission == "private" && (!authenticated? || (authenticated? && @current.id != s.user_id)) } + @alltopics = @topic.relatives.to_a.delete_if {|t| t.permission == "private" && (!authenticated? || (authenticated? && current_user.id != t.user_id)) } + @allsynapses = @topic.synapses.to_a.delete_if {|s| s.permission == "private" && (!authenticated? || (authenticated? && current_user.id != s.user_id)) } @allcreators = [] @allcreators.push(@topic.user) @alltopics.each do |t| @@ -91,8 +88,7 @@ class TopicsController < ApplicationController # GET topics/:id/relative_numbers def relative_numbers - @current = current_user - @topic = Topic.find(params[:id]).authorize_to_show(@current) + @topic = Topic.find(params[:id]).authorize_to_show(current_user) if not @topic redirect_to root_url, notice: "Access denied. That topic is private." and return @@ -102,7 +98,7 @@ class TopicsController < ApplicationController @alltopics = @topic.relatives.to_a.delete_if {|t| @topicsAlreadyHas.index(t.id.to_s) != nil || - (t.permission == "private" && (!authenticated? || (authenticated? && @current.id != t.user_id))) + (t.permission == "private" && (!authenticated? || (authenticated? && current_user.id != t.user_id))) } @alltopics.uniq! @@ -123,8 +119,7 @@ class TopicsController < ApplicationController # GET topics/:id/relatives def relatives - @current = current_user - @topic = Topic.find(params[:id]).authorize_to_show(@current) + @topic = Topic.find(params[:id]).authorize_to_show(current_user) if not @topic redirect_to root_url, notice: "Access denied. That topic is private." and return @@ -135,7 +130,7 @@ class TopicsController < ApplicationController @alltopics = @topic.relatives.to_a.delete_if {|t| @topicsAlreadyHas.index(t.id.to_s) != nil || (params[:metacode] && t.metacode_id.to_s != params[:metacode]) || - (t.permission == "private" && (!authenticated? || (authenticated? && @current.id != t.user_id))) + (t.permission == "private" && (!authenticated? || (authenticated? && current_user.id != t.user_id))) } @alltopics.uniq! @@ -198,8 +193,7 @@ class TopicsController < ApplicationController # DELETE topics/:id def destroy - @current = current_user - @topic = Topic.find(params[:id]).authorize_to_delete(@current) + @topic = Topic.find(params[:id]).authorize_to_delete(current_user) @topic.delete if @topic respond_to do |format| diff --git a/app/policies/main_policy.rb b/app/policies/main_policy.rb new file mode 100644 index 00000000..ee7f9fc9 --- /dev/null +++ b/app/policies/main_policy.rb @@ -0,0 +1,26 @@ +class MainPolicy < ApplicationPolicy + def initialize(user, record) + @user = user + @record = nil + end + + def home? + true + end + + def searchtopics? + true + end + + def searchmaps? + true + end + + def searchmappers? + true + end + + def searchsynapses? + true + end +end From 895b872bda07e8a1ed38b09b7e337961c0160567 Mon Sep 17 00:00:00 2001 From: Devin Howard Date: Sun, 28 Feb 2016 16:57:25 +0800 Subject: [PATCH 11/19] remove unneeded https stuff --- app/controllers/application_controller.rb | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index c380f96c..d3f14f99 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -13,13 +13,7 @@ class ApplicationController < ActionController::Base helper_method :admin? def after_sign_in_path_for(resource) - unsafe_uri = request.env["REQUEST_URI"] - if unsafe_uri.starts_with?('http') && !unsafe_uri.starts_with?('https') - protocol = 'http' - else - protocol = 'https' - end - sign_in_url = url_for(:action => 'new', :controller => 'sessions', :only_path => false, :protocol => protocol) + sign_in_url = url_for(:action => 'new', :controller => 'sessions', :only_path => false, :protocol => 'https') if request.referer == sign_in_url super From 155eac41d875ff2730f797ef77e27e4f5aa8bf1c Mon Sep 17 00:00:00 2001 From: Devin Howard Date: Sun, 28 Feb 2016 17:24:00 +0800 Subject: [PATCH 12/19] @ symbols unneeded --- app/policies/map_policy.rb | 14 +++++++------- app/policies/synapse_policy.rb | 10 +++++----- app/policies/topic_policy.rb | 12 ++++++------ 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/app/policies/map_policy.rb b/app/policies/map_policy.rb index 96a0b724..2cdbdee2 100644 --- a/app/policies/map_policy.rb +++ b/app/policies/map_policy.rb @@ -1,12 +1,12 @@ class MapPolicy < ApplicationPolicy class Scope < Scope def resolve - scope.where('permission IN ("public", "commons") OR user_id = ?', @user.id) + scope.where('permission IN ("public", "commons") OR user_id = ?', user.id) end end def activemaps? - @user.blank? # redirect to root url if authenticated for some reason + user.blank? # redirect to root url if authenticated for some reason end def featuredmaps? @@ -14,7 +14,7 @@ class MapPolicy < ApplicationPolicy end def mymaps? - @user.present? + user.present? end def usermaps? @@ -22,7 +22,7 @@ class MapPolicy < ApplicationPolicy end def show? - @record.permission == 'commons' || @record.permission == 'public' || @record.user == @user + record.permission == 'commons' || record.permission == 'public' || record.user == user end def contains? @@ -30,11 +30,11 @@ class MapPolicy < ApplicationPolicy end def create? - @user.present? + user.present? end def update? - @user.present? && (@record.permission == 'commons' || @record.user == @user) + user.present? && (record.permission == 'commons' || record.user == user) true end @@ -43,6 +43,6 @@ class MapPolicy < ApplicationPolicy end def destroy? - @record.user == @user || @user.admin + record.user == user || user.admin end end diff --git a/app/policies/synapse_policy.rb b/app/policies/synapse_policy.rb index f7db11ed..6d332fbf 100644 --- a/app/policies/synapse_policy.rb +++ b/app/policies/synapse_policy.rb @@ -1,25 +1,25 @@ class SynapsePolicy < ApplicationPolicy class Scope < Scope def resolve - scope.where('permission IN ("public", "commons") OR user_id = ?', @user.id) + scope.where('permission IN ("public", "commons") OR user_id = ?', user.id) end end def create? - @user.present? + user.present? end def show? - # @record.permission == 'commons' || @record.permission == 'public' || @record.user == @user + # record.permission == 'commons' || record.permission == 'public' || record.user == user true end def update? - # @user.present? && (@record.permission == 'commons' || @record.user == @user) + # user.present? && (record.permission == 'commons' || record.user == user) true end def destroy? - @record.user == @user || @user.admin + record.user == user || user.admin end end diff --git a/app/policies/topic_policy.rb b/app/policies/topic_policy.rb index 2978cb13..55e79c2d 100644 --- a/app/policies/topic_policy.rb +++ b/app/policies/topic_policy.rb @@ -1,29 +1,29 @@ class TopicPolicy < ApplicationPolicy class Scope < Scope def resolve - scope.where('permission IN ("public", "commons") OR user_id = ?', @user.id) + scope.where('permission IN ("public", "commons") OR user_id = ?', user.id) end end def create? - @user.present? + user.present? end def show? - @record.permission == 'commons' || @record.permission == 'public' || @record.user == @user + record.permission == 'commons' || record.permission == 'public' || record.user == user end def update? - # @user.present? && (@record.permission == 'commons' || @record.user == @user) + # user.present? && (record.permission == 'commons' || record.user == user) true end def destroy? - @record.user == @user || @user.admin + record.user == user || user.admin end def autocomplete_topic? - @user.present? + user.present? end def network? From ef5d85c2bffc516025d6941073890c46f3bcecf8 Mon Sep 17 00:00:00 2001 From: Devin Howard Date: Sun, 28 Feb 2016 17:48:18 +0800 Subject: [PATCH 13/19] before_filter => before_action --- app/controllers/application_controller.rb | 2 +- app/controllers/mappings_controller.rb | 2 +- app/controllers/maps_controller.rb | 2 +- app/controllers/metacode_sets_controller.rb | 2 +- app/controllers/metacodes_controller.rb | 2 +- app/controllers/synapses_controller.rb | 2 +- app/controllers/topics_controller.rb | 2 +- app/controllers/users/registrations_controller.rb | 4 ++-- app/controllers/users_controller.rb | 2 +- 9 files changed, 10 insertions(+), 10 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index d3f14f99..0e6503ef 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -2,7 +2,7 @@ class ApplicationController < ActionController::Base include Pundit protect_from_forgery - before_filter :get_invite_link + before_action :get_invite_link after_action :allow_embedding # this is for global login diff --git a/app/controllers/mappings_controller.rb b/app/controllers/mappings_controller.rb index c20b0153..6ce37234 100644 --- a/app/controllers/mappings_controller.rb +++ b/app/controllers/mappings_controller.rb @@ -1,6 +1,6 @@ class MappingsController < ApplicationController - before_filter :require_user, only: [:create, :update, :destroy] + before_action :require_user, only: [:create, :update, :destroy] respond_to :json diff --git a/app/controllers/maps_controller.rb b/app/controllers/maps_controller.rb index cb949098..9fbf95e0 100644 --- a/app/controllers/maps_controller.rb +++ b/app/controllers/maps_controller.rb @@ -1,5 +1,5 @@ class MapsController < ApplicationController - before_filter :require_user, only: [:create, :update, :screenshot, :destroy] + before_action :require_user, only: [:create, :update, :screenshot, :destroy] respond_to :html, :json diff --git a/app/controllers/metacode_sets_controller.rb b/app/controllers/metacode_sets_controller.rb index 720076c1..e76f4c9a 100644 --- a/app/controllers/metacode_sets_controller.rb +++ b/app/controllers/metacode_sets_controller.rb @@ -1,6 +1,6 @@ class MetacodeSetsController < ApplicationController - before_filter :require_admin + before_action :require_admin # GET /metacode_sets # GET /metacode_sets.json diff --git a/app/controllers/metacodes_controller.rb b/app/controllers/metacodes_controller.rb index 54956c60..77f9ba54 100644 --- a/app/controllers/metacodes_controller.rb +++ b/app/controllers/metacodes_controller.rb @@ -1,5 +1,5 @@ class MetacodesController < ApplicationController - before_filter :require_admin, except: [:index] + before_action :require_admin, except: [:index] # GET /metacodes # GET /metacodes.json diff --git a/app/controllers/synapses_controller.rb b/app/controllers/synapses_controller.rb index e706aac4..46592dcc 100644 --- a/app/controllers/synapses_controller.rb +++ b/app/controllers/synapses_controller.rb @@ -1,7 +1,7 @@ class SynapsesController < ApplicationController include TopicsHelper - before_filter :require_user, only: [:create, :update, :destroy] + before_action :require_user, only: [:create, :update, :destroy] respond_to :json diff --git a/app/controllers/topics_controller.rb b/app/controllers/topics_controller.rb index 47105396..4d11f8ca 100644 --- a/app/controllers/topics_controller.rb +++ b/app/controllers/topics_controller.rb @@ -1,7 +1,7 @@ class TopicsController < ApplicationController include TopicsHelper - before_filter :require_user, only: [:create, :update, :destroy] + before_action :require_user, only: [:create, :update, :destroy] respond_to :html, :js, :json diff --git a/app/controllers/users/registrations_controller.rb b/app/controllers/users/registrations_controller.rb index c77edb50..88474e21 100644 --- a/app/controllers/users/registrations_controller.rb +++ b/app/controllers/users/registrations_controller.rb @@ -1,6 +1,6 @@ class Users::RegistrationsController < Devise::RegistrationsController - before_filter :configure_sign_up_params, only: [:create] - before_filter :configure_account_update_params, only: [:update] + before_action :configure_sign_up_params, only: [:create] + before_action :configure_account_update_params, only: [:update] protected def after_sign_up_path_for(resource) diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 063ab866..f5b0aab9 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -1,5 +1,5 @@ class UsersController < ApplicationController - before_filter :require_user, only: [:edit, :update, :updatemetacodes] + before_action :require_user, only: [:edit, :update, :updatemetacodes] respond_to :html, :json From e64a16f1b830a3bd327b14566c728d49589858a8 Mon Sep 17 00:00:00 2001 From: Devin Howard Date: Sun, 28 Feb 2016 18:55:48 +0800 Subject: [PATCH 14/19] main#home view simplify for only unauthenticated users --- app/views/main/home.html.erb | 88 ++++++++++++++++-------------------- 1 file changed, 39 insertions(+), 49 deletions(-) diff --git a/app/views/main/home.html.erb b/app/views/main/home.html.erb index 3c1319e0..6089b7df 100644 --- a/app/views/main/home.html.erb +++ b/app/views/main/home.html.erb @@ -2,52 +2,42 @@ # @file # Located at / # Shows 3 most recently created topics, synapses, and maps. - #%> - -<% if !authenticated? %> - <% content_for :title, "Home | Metamaps" %> -
-
-
Make Sense with Metamaps
-
- METAMAPS.CC is a free and open source platform that supports real-time sense-making, distributed collaboration, and the creative intelligence of individuals, organizations and communities. We are currently in an invite-only beta. -
-
-
-
- -
-

Who finds it useful?

-

Designers, inventors, artists, educators, strategists, consultants, facilitators, entrepreneurs, systems thinkers, changemakers, analysts, students, researchers... maybe you!

- - EXPLORE FEATURED MAPS - REQUEST INVITE -
-
-
-
-
-
- <% # our partners %> -
-
-
- - -<% elsif authenticated? %> - <% content_for :title, "Explore Active Maps | Metamaps" %> - -<% end %> + # +%> + +<% content_for :title, "Home | Metamaps" %> +
+
+
Make Sense with Metamaps
+
+ METAMAPS.CC is a free and open source platform that supports real-time sense-making, distributed collaboration, and the creative intelligence of individuals, organizations and communities. We are currently in an invite-only beta. +
+
+
+
+ +
+

Who finds it useful?

+

Designers, inventors, artists, educators, strategists, consultants, facilitators, entrepreneurs, systems thinkers, changemakers, analysts, students, researchers... maybe you!

+ + EXPLORE FEATURED MAPS + REQUEST INVITE +
+
+
+
+
+
+ <% # our partners %> +
+
+
+ + From d8cc588efb9ea11a43a3a9b6da71471068aff37f Mon Sep 17 00:00:00 2001 From: Devin Howard Date: Fri, 11 Mar 2016 21:25:24 +0800 Subject: [PATCH 15/19] basics of admin_override policy function --- app/policies/application_policy.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/policies/application_policy.rb b/app/policies/application_policy.rb index 2a0bbc52..6bd56c64 100644 --- a/app/policies/application_policy.rb +++ b/app/policies/application_policy.rb @@ -34,6 +34,14 @@ class ApplicationPolicy false end + # TODO update this function to enable some flag in the interface + # so that admins usually can't do super admin stuff unless they + # explicitly say they want to (E.g. seeing/editing/deleting private + # maps - they should be able to, but not by accident) + def admin_override + user.admin + end + def scope Pundit.policy_scope!(user, record.class) end From 615eaf580eb68a15e195338bf62d11e25f45907b Mon Sep 17 00:00:00 2001 From: Devin Howard Date: Fri, 11 Mar 2016 21:30:54 +0800 Subject: [PATCH 16/19] mapping policy --- app/policies/mapping_policy.rb | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 app/policies/mapping_policy.rb diff --git a/app/policies/mapping_policy.rb b/app/policies/mapping_policy.rb new file mode 100644 index 00000000..44e7bfd7 --- /dev/null +++ b/app/policies/mapping_policy.rb @@ -0,0 +1,31 @@ +class MappingPolicy < ApplicationPolicy + class Scope < Scope + def resolve + # TODO base this on the map policy + # it would be nice if we could also base this on the mappable, but that + # gets really complicated. Devin thinks it's OK to SHOW a mapping for + # a private topic, since you can't see the private topic anyways + scope.joins(:maps).where('maps.permission IN ("public", "commons") OR user_id = ?', user.id) + end + end + + def show? + map = policy(record.map, user) + mappable = policy(record.mappable, user) + map.show? && mappable.show? + end + + def create? + map = policy(record.map, user) + map.edit? + end + + def update? + map = policy(record.map, user) + map.update? + end + + def destroy? + record.user == user || admin_override + end +end From 73b82801cc8d5712d3b100ac56b195cacd5bd564 Mon Sep 17 00:00:00 2001 From: Devin Howard Date: Fri, 11 Mar 2016 21:32:18 +0800 Subject: [PATCH 17/19] consistent permissions --- app/policies/map_policy.rb | 2 +- app/policies/synapse_policy.rb | 8 +++----- app/policies/topic_policy.rb | 5 ++--- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/app/policies/map_policy.rb b/app/policies/map_policy.rb index 2cdbdee2..671eea83 100644 --- a/app/policies/map_policy.rb +++ b/app/policies/map_policy.rb @@ -43,6 +43,6 @@ class MapPolicy < ApplicationPolicy end def destroy? - record.user == user || user.admin + record.user == user || admin_override end end diff --git a/app/policies/synapse_policy.rb b/app/policies/synapse_policy.rb index 6d332fbf..6763014a 100644 --- a/app/policies/synapse_policy.rb +++ b/app/policies/synapse_policy.rb @@ -10,16 +10,14 @@ class SynapsePolicy < ApplicationPolicy end def show? - # record.permission == 'commons' || record.permission == 'public' || record.user == user - true + record.permission == 'commons' || record.permission == 'public' || record.user == user end def update? - # user.present? && (record.permission == 'commons' || record.user == user) - true + user.present? && (record.permission == 'commons' || record.user == user) end def destroy? - record.user == user || user.admin + record.user == user || admin_override end end diff --git a/app/policies/topic_policy.rb b/app/policies/topic_policy.rb index 55e79c2d..03b42895 100644 --- a/app/policies/topic_policy.rb +++ b/app/policies/topic_policy.rb @@ -14,12 +14,11 @@ class TopicPolicy < ApplicationPolicy end def update? - # user.present? && (record.permission == 'commons' || record.user == user) - true + user.present? && (record.permission == 'commons' || record.user == user) end def destroy? - record.user == user || user.admin + record.user == user || admin_override end def autocomplete_topic? From 7395811ba5cdb23442710d537082d6821558850f Mon Sep 17 00:00:00 2001 From: Devin Howard Date: Fri, 11 Mar 2016 21:35:48 +0800 Subject: [PATCH 18/19] handle unauthorized with baaaaad 403 --- app/controllers/application_controller.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 0e6503ef..6d10c553 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,5 +1,6 @@ class ApplicationController < ActionController::Base include Pundit + rescue_from Pundit::NotAuthorizedError, with: :handle_unauthorized protect_from_forgery before_action :get_invite_link @@ -23,6 +24,10 @@ class ApplicationController < ActionController::Base stored_location_for(resource) || request.referer || root_path end end + + def handle_unauthorized + head :forbidden # TODO make this better + end private From eb5675506811266ead0e4a95a914d31ec0fc0011 Mon Sep 17 00:00:00 2001 From: Devin Howard Date: Fri, 11 Mar 2016 22:10:31 +0800 Subject: [PATCH 19/19] implement five policies into their controllers --- app/controllers/main_controller.rb | 3 + app/controllers/mappings_controller.rb | 8 +- app/controllers/maps_controller.rb | 80 +++++----- app/controllers/synapses_controller.rb | 16 +- app/controllers/topics_controller.rb | 209 ++++++++++--------------- 5 files changed, 142 insertions(+), 174 deletions(-) diff --git a/app/controllers/main_controller.rb b/app/controllers/main_controller.rb index 31a55abc..29c11777 100644 --- a/app/controllers/main_controller.rb +++ b/app/controllers/main_controller.rb @@ -3,6 +3,9 @@ class MainController < ApplicationController include MapsHelper include UsersHelper include SynapsesHelper + + after_action :verify_authorized, except: :index + after_action :verify_policy_scoped, only: :index respond_to :html, :json diff --git a/app/controllers/mappings_controller.rb b/app/controllers/mappings_controller.rb index 6ce37234..ea2aaf0e 100644 --- a/app/controllers/mappings_controller.rb +++ b/app/controllers/mappings_controller.rb @@ -1,12 +1,14 @@ class MappingsController < ApplicationController - before_action :require_user, only: [:create, :update, :destroy] + after_action :verify_authorized, except: :index + after_action :verify_policy_scoped, only: :index respond_to :json # GET /mappings/1.json def show @mapping = Mapping.find(params[:id]) + authorize! @mapping render json: @mapping end @@ -14,6 +16,7 @@ class MappingsController < ApplicationController # POST /mappings.json def create @mapping = Mapping.new(mapping_params) + authorize! @mapping if @mapping.save render json: @mapping, status: :created @@ -25,6 +28,7 @@ class MappingsController < ApplicationController # PUT /mappings/1.json def update @mapping = Mapping.find(params[:id]) + authorize! @mapping if @mapping.update_attributes(mapping_params) head :no_content @@ -36,7 +40,7 @@ class MappingsController < ApplicationController # DELETE /mappings/1.json def destroy @mapping = Mapping.find(params[:id]) - @map = @mapping.map + authorize! @mapping @mapping.destroy diff --git a/app/controllers/maps_controller.rb b/app/controllers/maps_controller.rb index 9fbf95e0..016ba7b5 100644 --- a/app/controllers/maps_controller.rb +++ b/app/controllers/maps_controller.rb @@ -1,5 +1,7 @@ class MapsController < ApplicationController before_action :require_user, only: [:create, :update, :screenshot, :destroy] + after_action :verify_authorized, except: :activemaps, :featuredmaps, :mymaps, :usermaps + after_action :verify_policy_scoped, only: :activemaps, :featuredmaps, :mymaps, :usermaps respond_to :html, :json @@ -8,7 +10,8 @@ class MapsController < ApplicationController # GET /explore/active def activemaps page = params[:page].present? ? params[:page] : 1 - @maps = Map.where("maps.permission != ?", "private").order("updated_at DESC").page(page).per(20) + @maps = policy_scope(Map).order("updated_at DESC") + .page(page).per(20) # root url => main/home. main/home renders maps/activemaps view. redirect_to root_url and return if authenticated? @@ -22,8 +25,10 @@ class MapsController < ApplicationController # GET /explore/featured def featuredmaps page = params[:page].present? ? params[:page] : 1 - @maps = Map.where("maps.featured = ? AND maps.permission != ?", true, "private") - .order("updated_at DESC").page(page).per(20) + @maps = policy_scope( + Map.where("maps.featured = ? AND maps.permission != ?", + true, "private") + ).order("updated_at DESC").page(page).per(20) respond_to do |format| format.html { respond_with(@maps, @user) } @@ -36,8 +41,9 @@ class MapsController < ApplicationController return redirect_to activemaps_url if !authenticated? page = params[:page].present? ? params[:page] : 1 - # don't need to exclude private maps because they all belong to you - @maps = Map.where("maps.user_id = ?", current_user.id).order("updated_at DESC").page(page).per(20) + @maps = policy_scope( + Map.where("maps.user_id = ?", current_user.id) + ).order("updated_at DESC").page(page).per(20) respond_to do |format| format.html { respond_with(@maps, @user) } @@ -49,7 +55,8 @@ class MapsController < ApplicationController def usermaps page = params[:page].present? ? params[:page] : 1 @user = User.find(params[:id]) - @maps = Map.where("maps.user_id = ? AND maps.permission != ?", @user.id, "private").order("updated_at DESC").page(page).per(20) + @maps = policy_scope(Map.where(user: @user)) + .order("updated_at DESC").page(page).per(20) respond_to do |format| format.html { respond_with(@maps, @user) } @@ -59,7 +66,8 @@ class MapsController < ApplicationController # GET maps/:id def show - @map = Map.find(params[:id]).authorize_to_show(current_user) + @map = Map.find(params[:id]) + authorize! @map if not @map redirect_to root_url, notice: "Access denied. That map is private." and return @@ -83,7 +91,8 @@ class MapsController < ApplicationController # GET maps/:id/contains def contains - @map = Map.find(params[:id]).authorize_to_show(current_user) + @map = Map.find(params[:id]) + authorize! @map if not @map redirect_to root_url, notice: "Access denied. That map is private." and return @@ -130,6 +139,7 @@ class MapsController < ApplicationController mapping.xloc = topic[1] mapping.yloc = topic[2] @map.topicmappings << mapping + authorize! mapping, :create mapping.save end @@ -142,6 +152,7 @@ class MapsController < ApplicationController mapping.map = @map mapping.mappable = Synapse.find(synapse_id) @map.synapsemappings << mapping + authorize! mapping, :create mapping.save end end @@ -149,6 +160,8 @@ class MapsController < ApplicationController @map.arranged = true end + authorize! @map + if @map.save respond_to do |format| format.json { render :json => @map } @@ -162,7 +175,8 @@ class MapsController < ApplicationController # PUT maps/:id def update - @map = Map.find(params[:id]).authorize_to_edit(current_user) + @map = Map.find(params[:id]) + authorize! @map respond_to do |format| if !@map @@ -177,42 +191,36 @@ class MapsController < ApplicationController # POST maps/:id/upload_screenshot def screenshot - @map = Map.find(params[:id]).authorize_to_edit(current_user) + @map = Map.find(params[:id]) + authorize! @map - if @map - png = Base64.decode64(params[:encoded_image]['data:image/png;base64,'.length .. -1]) - StringIO.open(png) do |data| - data.class.class_eval { attr_accessor :original_filename, :content_type } - data.original_filename = "map-" + @map.id.to_s + "-screenshot.png" - data.content_type = "image/png" - @map.screenshot = data - end + png = Base64.decode64(params[:encoded_image]['data:image/png;base64,'.length .. -1]) + StringIO.open(png) do |data| + data.class.class_eval { attr_accessor :original_filename, :content_type } + data.original_filename = "map-" + @map.id.to_s + "-screenshot.png" + data.content_type = "image/png" + @map.screenshot = data + end - if @map.save - render :json => {:message => "Successfully uploaded the map screenshot."} - else - render :json => {:message => "Failed to upload image."} - end - else - render :json => {:message => "Unauthorized to set map screenshot."} - end + if @map.save + render :json => {:message => "Successfully uploaded the map screenshot."} + else + render :json => {:message => "Failed to upload image."} + end end # DELETE maps/:id def destroy - @map = Map.find(params[:id]).authorize_to_delete(current_user) + @map = Map.find(params[:id]) + authorize! @map - @map.delete if @map + @map.delete - respond_to do |format| - format.json { - if @map - render json: "success" - else - render json: "unauthorized" - end - } + respond_to do |format| + format.json do + head :no_content end + end end private diff --git a/app/controllers/synapses_controller.rb b/app/controllers/synapses_controller.rb index 46592dcc..f242ad38 100644 --- a/app/controllers/synapses_controller.rb +++ b/app/controllers/synapses_controller.rb @@ -2,19 +2,16 @@ class SynapsesController < ApplicationController include TopicsHelper before_action :require_user, only: [:create, :update, :destroy] + after_action :verify_authorized, except: :index + after_action :verify_policy_scoped, only: :index respond_to :json # GET /synapses/1.json def show @synapse = Synapse.find(params[:id]) + authorize! @synapse - #.authorize_to_show(current_user) - - #if not @synapse - # redirect_to root_url and return - #end - render json: @synapse end @@ -23,6 +20,7 @@ class SynapsesController < ApplicationController def create @synapse = Synapse.new(synapse_params) @synapse.desc = "" if @synapse.desc.nil? + authorize! @synapse respond_to do |format| if @synapse.save @@ -38,6 +36,7 @@ class SynapsesController < ApplicationController def update @synapse = Synapse.find(params[:id]) @synapse.desc = "" if @synapse.desc.nil? + authorize! @synapse respond_to do |format| if @synapse.update_attributes(synapse_params) @@ -50,8 +49,9 @@ class SynapsesController < ApplicationController # DELETE synapses/:id def destroy - @synapse = Synapse.find(params[:id]).authorize_to_delete(current_user) - @synapse.delete if @synapse + @synapse = Synapse.find(params[:id]) + authorize! @synapse + @synapse.delete respond_to do |format| format.json { head :no_content } diff --git a/app/controllers/topics_controller.rb b/app/controllers/topics_controller.rb index 4d11f8ca..125005f9 100644 --- a/app/controllers/topics_controller.rb +++ b/app/controllers/topics_controller.rb @@ -2,19 +2,15 @@ class TopicsController < ApplicationController include TopicsHelper before_action :require_user, only: [:create, :update, :destroy] - + after_action :verify_authorized + respond_to :html, :js, :json # GET /topics/autocomplete_topic def autocomplete_topic term = params[:term] if term && !term.empty? - @topics = Topic.where('LOWER("name") like ?', term.downcase + '%').order('"name"') - - #read this next line as 'delete a topic if its private and you're either - #1. logged out or 2. logged in but not the topic creator - @topics.to_a.delete_if {|t| t.permission == "private" && - (!authenticated? || (authenticated? && current_user.id != t.user_id)) } + @topics = policy_scope(Topic.where('LOWER("name") like ?', term.downcase + '%')).order('"name"') else @topics = [] end @@ -23,28 +19,16 @@ class TopicsController < ApplicationController # GET topics/:id def show - @topic = Topic.find(params[:id]).authorize_to_show(current_user) - - if not @topic - redirect_to root_url, notice: "Access denied. That topic is private." and return - end + @topic = Topic.find(params[:id]) + authorize! @topic respond_to do |format| format.html { - @alltopics = ([@topic] + @topic.relatives).delete_if {|t| t.permission == "private" && (!authenticated? || (authenticated? && current_user.id != t.user_id)) } # should limit to topics visible to user - @allsynapses = @topic.synapses.to_a.delete_if {|s| s.permission == "private" && (!authenticated? || (authenticated? && current_user.id != s.user_id)) } + @alltopics = ([@topic] + policy_scope(@topic.relatives) + @allsynapses = policy_scope(@topic.synapses) - @allcreators = [] - @alltopics.each do |t| - if @allcreators.index(t.user) == nil - @allcreators.push(t.user) - end - end - @allsynapses.each do |s| - if @allcreators.index(s.user) == nil - @allcreators.push(s.user) - end - end + @allcreators = @alltopics.map(&:user).uniq + @allcreators += @allsynapses.map(&:user).uniq respond_with(@allsynapses, @alltopics, @allcreators, @topic) } @@ -54,27 +38,15 @@ class TopicsController < ApplicationController # GET topics/:id/network def network - @topic = Topic.find(params[:id]).authorize_to_show(current_user) + @topic = Topic.find(params[:id]) + authorize! @topic - if not @topic - redirect_to root_url, notice: "Access denied. That topic is private." and return - end + @alltopics = [@topic] + policy_scope(@topic.relatives) + @allsynapses = policy_scope(@topic.synapses) + + @allcreators = @alltopics.map(&:user).uniq + @allcreators += @allsynapses.map(&:user).uniq - @alltopics = @topic.relatives.to_a.delete_if {|t| t.permission == "private" && (!authenticated? || (authenticated? && current_user.id != t.user_id)) } - @allsynapses = @topic.synapses.to_a.delete_if {|s| s.permission == "private" && (!authenticated? || (authenticated? && current_user.id != s.user_id)) } - @allcreators = [] - @allcreators.push(@topic.user) - @alltopics.each do |t| - if @allcreators.index(t.user) == nil - @allcreators.push(t.user) - end - end - @allsynapses.each do |s| - if @allcreators.index(s.user) == nil - @allcreators.push(s.user) - end - end - @json = Hash.new() @json['topic'] = @topic @json['creators'] = @allcreators @@ -88,118 +60,99 @@ class TopicsController < ApplicationController # GET topics/:id/relative_numbers def relative_numbers - @topic = Topic.find(params[:id]).authorize_to_show(current_user) + @topic = Topic.find(params[:id]) + authorize @topic - if not @topic - redirect_to root_url, notice: "Access denied. That topic is private." and return + topicsAlreadyHas = params[:network] ? params[:network].split(',').map(&:to_i) : [] + + @alltopics = policy_scope(@topic.relatives).to_a.uniq + @alltopics.delete_if! do |topic| + topicsAlreadyHas.index(topic.id) != nil end - @topicsAlreadyHas = params[:network] ? params[:network].split(',') : [] - - @alltopics = @topic.relatives.to_a.delete_if {|t| - @topicsAlreadyHas.index(t.id.to_s) != nil || - (t.permission == "private" && (!authenticated? || (authenticated? && current_user.id != t.user_id))) - } - - @alltopics.uniq! - - @json = Hash.new() + @json = Hash.new(0) @alltopics.each do |t| - if @json[t.metacode.id] - @json[t.metacode.id] += 1 - else - @json[t.metacode.id] = 1 - end + @json[t.metacode.id] += 1 end respond_to do |format| - format.json { render json: @json } + format.json { render json: @json } end end # GET topics/:id/relatives def relatives - @topic = Topic.find(params[:id]).authorize_to_show(current_user) + @topic = Topic.find(params[:id]) + authorize! @topic - if not @topic - redirect_to root_url, notice: "Access denied. That topic is private." and return - end + topicsAlreadyHas = params[:network] ? params[:network].split(',').map(&:to_i) : [] - @topicsAlreadyHas = params[:network] ? params[:network].split(',') : [] + alltopics = policy_scope(@topic.relatives).to_a.uniq.delete_if do |topic| + topicsAlreadyHas.index(topic.id.to_s) != nil + end - @alltopics = @topic.relatives.to_a.delete_if {|t| - @topicsAlreadyHas.index(t.id.to_s) != nil || - (params[:metacode] && t.metacode_id.to_s != params[:metacode]) || - (t.permission == "private" && (!authenticated? || (authenticated? && current_user.id != t.user_id))) - } + #find synapses between topics in alltopics array + allsynapses = policy_scope(@topic.synapses) + synapse_ids = (allsynapses.map(&:topic1_id) + allsynapses.map(&:topic2_id)).uniq + allsynapses.delete_if! do |synapse| + synapse_ids.index(synapse.id) != nil + end - @alltopics.uniq! + creatorsAlreadyHas = params[:creators] ? params[:creators].split(',').map(&:to_i) : [] + allcreators = (alltopics.map(&:user) + allsynapses.map(&:user)).uniq.delete_if do |user| + creatorsAlreadyHas.index(user.id) != nil + end - @allsynapses = @topic.synapses.to_a.delete_if {|s| - (s.topic1 == @topic && @alltopics.index(s.topic2) == nil) || - (s.topic2 == @topic && @alltopics.index(s.topic1) == nil) - } + @json = Hash.new() + @json['topics'] = alltopics + @json['synapses'] = allsynapses + @json['creators'] = allcreators - @creatorsAlreadyHas = params[:creators] ? params[:creators].split(',') : [] - @allcreators = [] - @alltopics.each do |t| - if @allcreators.index(t.user) == nil && @creatorsAlreadyHas.index(t.user_id.to_s) == nil - @allcreators.push(t.user) - end - end - @allsynapses.each do |s| - if @allcreators.index(s.user) == nil && @creatorsAlreadyHas.index(s.user_id.to_s) == nil - @allcreators.push(s.user) - end - end - - @json = Hash.new() - @json['topics'] = @alltopics - @json['synapses'] = @allsynapses - @json['creators'] = @allcreators - - respond_to do |format| - format.json { render json: @json } - end + respond_to do |format| + format.json { render json: @json } + end end - # POST /topics - # POST /topics.json - def create - @topic = Topic.new(topic_params) + # POST /topics + # POST /topics.json + def create + @topic = Topic.new(topic_params) + authorize! @topic - respond_to do |format| - if @topic.save - format.json { render json: @topic, status: :created } - else - format.json { render json: @topic.errors, status: :unprocessable_entity } - end - end + respond_to do |format| + if @topic.save + format.json { render json: @topic, status: :created } + else + format.json { render json: @topic.errors, status: :unprocessable_entity } + end end + end - # PUT /topics/1 - # PUT /topics/1.json - def update - @topic = Topic.find(params[:id]) + # PUT /topics/1 + # PUT /topics/1.json + def update + @topic = Topic.find(params[:id]) + authorize! @topic - respond_to do |format| - if @topic.update_attributes(topic_params) - format.json { head :no_content } - else - format.json { render json: @topic.errors, status: :unprocessable_entity } - end - end + respond_to do |format| + if @topic.update_attributes(topic_params) + format.json { head :no_content } + else + format.json { render json: @topic.errors, status: :unprocessable_entity } + end end + end - # DELETE topics/:id - def destroy - @topic = Topic.find(params[:id]).authorize_to_delete(current_user) - @topic.delete if @topic + # DELETE topics/:id + def destroy + @topic = Topic.find(params[:id]) + authorize! @topic - respond_to do |format| - format.json { head :no_content } - end + @topic.delete + respond_to do |format| + format.json { head :no_content } end + end private