From eb5675506811266ead0e4a95a914d31ec0fc0011 Mon Sep 17 00:00:00 2001 From: Devin Howard Date: Fri, 11 Mar 2016 22:10:31 +0800 Subject: [PATCH] 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