From 9d0e9d621d56a5453c040e87143494469095b90d Mon Sep 17 00:00:00 2001
From: Giovanne Marcelo <gms15@inf.ufpr.br>
Date: Tue, 1 Mar 2016 08:41:18 -0300
Subject: [PATCH] [WIP] Adding pundit policies

---
 .../learning_objects_controller.rb            | 14 +++++
 app/controllers/search_controller.rb          | 10 ++--
 app/policies/application_policy.rb            | 53 +++++++++++++++++++
 app/policies/learning_object_policy.rb        | 30 +++++++++++
 app/policies/search_policy.rb                 | 14 +++++
 config/locales/pt-BR.yml                      |  7 ++-
 6 files changed, 123 insertions(+), 5 deletions(-)
 create mode 100644 app/policies/application_policy.rb
 create mode 100644 app/policies/learning_object_policy.rb
 create mode 100644 app/policies/search_policy.rb

diff --git a/app/controllers/learning_objects_controller.rb b/app/controllers/learning_objects_controller.rb
index b2874b35..7d1f0b9e 100644
--- a/app/controllers/learning_objects_controller.rb
+++ b/app/controllers/learning_objects_controller.rb
@@ -2,6 +2,11 @@ require 'uri'
 
 class LearningObjectsController < ApplicationController
   include Reportable
+  include Pundit
+
+
+  rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized
+
 
   before_action :authenticate_user!, except: [:index, :show]
   before_action :set_learning_object, only: [:show, :edit, :update,
@@ -12,6 +17,7 @@ class LearningObjectsController < ApplicationController
   # GET /learning_objects/1
   # GET /learning_objects/1.json
   def show
+    authorize @learning_object
     @liked = !@learning_object.liked?(current_user) if user_signed_in?
     @reviews = Review.where(reviewable: @learning_object)
   end
@@ -128,4 +134,12 @@ class LearningObjectsController < ApplicationController
       redirect_to upload_learning_object_path(id: id) , notice: 'Seu objeto foi criado! Para que ele seja publicado é necessário enviar o arquivo.'
     end
   end
+
+  def user_not_authorized(exception)
+    policy_name = exception.policy.class.to_s.underscore
+
+    flash[:error] = t "#{policy_name}.#{exception.query}", scope: "pundit", default: :default
+    redirect_to(request.referrer || root_path)
+  end
+
 end
diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb
index fad714b6..74bf2439 100644
--- a/app/controllers/search_controller.rb
+++ b/app/controllers/search_controller.rb
@@ -1,6 +1,7 @@
 class SearchController < ApplicationController
-  
+
   include LearningObjectsHelper
+  include Pundit
 
   def index
 
@@ -14,16 +15,17 @@ class SearchController < ApplicationController
   end
 
   def fetch
+
     params[:query] = "*" if params[:query].blank?
 
     case params[:search_class]
     when "LearningObject"
-      @result = LearningObject.search params[:query], where: where_hash(params), order: lo_order_hash(params), page: params[:page] || 1, per_page: 10
+      @result = policy_scope(LearningObject).search params[:query], where: where_hash(params), order: lo_order_hash(params), page: params[:page] || 1, per_page: 10
     when "Collection"
       @result = Collection.search params[:query], where: {privacy: "public"}, order: col_order_hash(params), page: params[:page] || 1, per_page: 10
     when "User"
       @result = User.search params[:query], order: user_order_hash(params), page: params[:page] || 1, per_page: 10
-    else 
+    else
       raise "Wrong search class parameter"
     end
 
@@ -44,7 +46,7 @@ class SearchController < ApplicationController
     when "User"
       params_hash = { fields: ['name'] }
       get_thumbnail = Proc.new { |obj| image_tag(obj.avatar.url(:thumb), 32) }
-    else 
+    else
       raise "Wrong search class parameter"
     end
     render json: autocomplete_search(Object.const_get(params[:search_class]), params_hash, get_thumbnail)
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
diff --git a/app/policies/learning_object_policy.rb b/app/policies/learning_object_policy.rb
new file mode 100644
index 00000000..007c71ef
--- /dev/null
+++ b/app/policies/learning_object_policy.rb
@@ -0,0 +1,30 @@
+class LearningObjectPolicy < ApplicationPolicy
+
+
+  class Scope < Scope
+
+    def resolve
+      if user.is_admin?
+        scope.all
+      else
+        scope.where(state: "published")
+      end
+    end
+
+  end
+
+  def show?
+
+    if user.is_admin?
+      record
+    else
+      record.state == "published"
+    end
+    
+  end
+
+  def update?
+    record.is_published?
+  end
+
+end
diff --git a/app/policies/search_policy.rb b/app/policies/search_policy.rb
new file mode 100644
index 00000000..cee9c0a5
--- /dev/null
+++ b/app/policies/search_policy.rb
@@ -0,0 +1,14 @@
+class SearchPolicy < ApplicationPolicy
+
+  class Scope < Scope
+
+    def resolve
+      if user.is_admin?
+        scope.all
+      else
+        scope.where(state:"published")
+      end
+    end
+  
+
+end
diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml
index 783f03dc..9a27a85f 100644
--- a/config/locales/pt-BR.yml
+++ b/config/locales/pt-BR.yml
@@ -155,4 +155,9 @@ pt-BR:
         less_than: "precisa ser menor do que {{count}}"
         less_than_or_equal_to: "precisa ser menor ou igual a {{count}}"
         odd: "precisa ser ímpar"
-        even: "precisa ser par"
\ No newline at end of file
+        even: "precisa ser par"
+
+  pundit:
+    default: 'You cannot perform this action.'
+    learning_object_policy:
+      show?: 'Este objeto está suspeso!'
-- 
GitLab