myexperiment-hackers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[myexperiment-hackers] [2426] trunk: changed authorised_index to use fin


From: noreply
Subject: [myexperiment-hackers] [2426] trunk: changed authorised_index to use find instead of find_by_sql
Date: Tue, 8 Jun 2010 08:55:57 -0400 (EDT)

Revision
2426
Author
dgc
Date
2010-06-08 08:55:56 -0400 (Tue, 08 Jun 2010)

Log Message

changed authorised_index to use find instead of find_by_sql

Modified Paths

Diff

Modified: trunk/app/controllers/workflows_controller.rb (2425 => 2426)


--- trunk/app/controllers/workflows_controller.rb	2010-06-03 13:01:38 UTC (rev 2425)
+++ trunk/app/controllers/workflows_controller.rb	2010-06-08 12:55:56 UTC (rev 2426)
@@ -599,7 +599,7 @@
   def find_workflows_rss
     # Only carry out if request is for RSS
     if params[:format] and params[:format].downcase == 'rss'
-      @rss_workflows = Authorization.authorised_index(:type => Workflow, :limit => 30, :order => 'updated_at DESC', :user => current_user)
+      @rss_workflows = Authorization.authorised_index(Workflow, :all, :limit => 30, :order => 'updated_at DESC', :authorised_user => current_user)
     end
   end
   

Modified: trunk/app/models/contribution.rb (2425 => 2426)


--- trunk/app/models/contribution.rb	2010-06-03 13:01:38 UTC (rev 2425)
+++ trunk/app/models/contribution.rb	2010-06-08 12:55:56 UTC (rev 2426)
@@ -36,9 +36,10 @@
     # This uses the proprietary MySQL feature "SQL_CALC_FOUND_ROWS" to
     # determine the total number of rows if it weren't for the LIMIT clause
 
-    results = Authorization.authorised_index(:type => klass,
+    results = Authorization.authorised_index(klass,
+        :all,
         :select => 'SQL_CALC_FOUND_ROWS contributions.*',
-        :user => user,
+        :authorised_user => user,
         :contribution_records => true,
         :limit => "#{offset}, #{num}",
         :joins => args["joins"],
@@ -77,14 +78,14 @@
   
   # returns the 'most recent' Contributions
   # the maximum number of results is set by #limit#
-  def self.most_recent(limit=10, klass=nil)
-    Authorization.authorised_index(:type => klass ? Object.const_get(klass) : nil, :contribution_records => true, :limit => limit, :order => 'created_at DESC')
+  def self.most_recent(limit = 10, klass = 'Contribution')
+    Authorization.authorised_index(Object.const_get(klass), :all, :contribution_records => true, :limit => limit, :order => 'created_at DESC')
   end
   
   # returns the 'last updated' Contributions
   # the maximum number of results is set by #limit#
-  def self.last_updated(limit=10, klass=nil)
-    Authorization.authorised_index(:type => klass ? Object.const_get(klass) : nil, :contribution_records => true, :limit => limit, :order => 'updated_at DESC')
+  def self.last_updated(limit = 10, klass = 'Contribution')
+    Authorization.authorised_index(Object.const_get(klass), :all, :contribution_records => true, :limit => limit, :order => 'updated_at DESC')
   end
   
   # returns the 'most favourited' Contributions

Modified: trunk/lib/authorization.rb (2425 => 2426)


--- trunk/lib/authorization.rb	2010-06-03 13:01:38 UTC (rev 2425)
+++ trunk/lib/authorization.rb	2010-06-08 12:55:56 UTC (rev 2426)
@@ -732,45 +732,45 @@
     end
   end
 
-  def self.authorised_index(args = {})
+  def self.authorised_index(model, *args)
 
-    def self.get_friend_ids(user)
-      user.friendships_accepted.map  do |fs| fs.user_id   end +
-      user.friendships_completed.map do |fs| fs.friend_id end
-    end
+    def self.view_conditions(user_id = nil, friends = nil, networks = nil)
 
-    def self.get_network_ids(user)
-      (user.networks_owned + user.networks).map do |n| n.id end
-    end
+      return "(share_mode = 0 OR share_mode = 1 OR share_mode = 2)" if user_id.nil?
 
-    def self.view_part(user_id = nil, friends = nil)
+      policy_part =
+        "((contributions.contributor_type = 'User' AND contributions.contributor_id = #{user_id}) OR
+          (share_mode = 0 OR share_mode = 1 OR share_mode = 2) OR
+          ((share_mode = 1 OR share_mode = 3 OR share_mode = 4 OR update_mode = 1 OR (update_mode = 0 AND (share_mode = 1 OR share_mode = 3))) AND
+           (contributions.contributor_type = 'User' AND contributions.contributor_id IN #{friends})))"
 
-      return "share_mode = 0 OR share_mode = 1 OR share_mode = 2" if user_id.nil?
-
-      "((contributions.contributor_type = 'User' AND contributions.contributor_id = #{user_id}) OR
-        (share_mode = 0 OR share_mode = 1 OR share_mode = 2) OR
-        ((share_mode = 1 OR share_mode = 3 OR share_mode = 4 OR update_mode = 1 OR (update_mode = 0 AND (share_mode = 1 OR share_mode = 3))) AND
-         (contributions.contributor_type = 'User' AND contributions.contributor_id IN #{friends})))"
+      "(#{policy_part} OR #{permission_part(['view', 'download', 'edit'], user_id, networks)})"
     end
 
-    def self.download_part(user_id = nil, friends = nil)
+    def self.download_conditions(user_id = nil, friends = nil, networks = nil)
 
-      return "share_mode = 0" if user_id.nil?
+      return "(share_mode = 0)" if user_id.nil?
 
-      "((contributions.contributor_type = 'User' AND contributions.contributor_id = #{user_id}) OR
-        (share_mode = 0) OR
-        ((share_mode = 1 OR share_mode = 3 OR update_mode = 1 OR (update_mode = 0 AND (share_mode = 1 OR share_mode = 3))) AND
-         (contributions.contributor_type = 'User' AND contributions.contributor_id IN #{friends})))"
+      policy_part = 
+        "((contributions.contributor_type = 'User' AND contributions.contributor_id = #{user_id}) OR
+          (share_mode = 0) OR
+          ((share_mode = 1 OR share_mode = 3 OR update_mode = 1 OR (update_mode = 0 AND (share_mode = 1 OR share_mode = 3))) AND
+           (contributions.contributor_type = 'User' AND contributions.contributor_id IN #{friends})))"
+
+      "(#{policy_part} OR #{permission_part(['download', 'edit'], user_id, networks)})"
     end
 
-    def self.edit_part(user_id = nil, friends = nil)
+    def self.edit_conditions(user_id = nil, friends = nil, networks = nil)
 
-      return "share_mode = 0 AND update_mode = 0" if user_id.nil?
+      return "(share_mode = 0 AND update_mode = 0)" if user_id.nil?
 
-      "((contributions.contributor_type = 'User' AND contributions.contributor_id = #{user_id}) OR
-        (share_mode = 0 AND update_mode = 0) OR
-        ((update_mode = 1 OR (update_mode = 0 AND (share_mode = 1 OR share_mode = 3))) AND
-         (contributions.contributor_type = 'User' AND contributions.contributor_id IN #{friends})))"
+      policy_part =
+        "((contributions.contributor_type = 'User' AND contributions.contributor_id = #{user_id}) OR
+          (share_mode = 0 AND update_mode = 0) OR
+          ((update_mode = 1 OR (update_mode = 0 AND (share_mode = 1 OR share_mode = 3))) AND
+           (contributions.contributor_type = 'User' AND contributions.contributor_id IN #{friends})))"
+
+      "(#{policy_part} OR #{permission_part(['edit'], user_id, networks)})"
     end
 
     def self.permission_part(permissions, user_id, networks)
@@ -782,123 +782,90 @@
          (permissions.contributor_type = 'Network' AND permissions.contributor_id IN #{networks})))"
     end
 
-    user = args[:user]
+    # extract the opts hash
 
+    opts = args.last.class == Hash ? args.pop.clone : {}
+
+    user = opts.delete(:authorised_user)
+
+    joins      = []
+    conditions = []
+
     if (user != 0) && (user != nil)
 
       user_id = user.id
 
-      friend_ids  = get_friend_ids(user)
-      network_ids = get_network_ids(user)
+      friend_ids = user.friendships_accepted.map  do |fs| fs.user_id   end +
+                   user.friendships_completed.map do |fs| fs.friend_id end
 
+      network_ids = (user.networks_owned + user.networks).map do |n| n.id end
+
       friends  = friend_ids.empty?  ? "(-1)" : "(#{friend_ids.join(",")})"
       networks = network_ids.empty? ? "(-1)" : "(#{network_ids.join(",")})"
     end
 
-    # pagination
+    # filtering
 
-    if args[:limit]
-      if args[:offset]
-        limit_part = "LIMIT #{args[:offset]}, #{args[:limit]}"
-      else
-        limit_part = "LIMIT #{args[:limit]}"
-      end
-    else
-      limit_part = ""
-    end
+    conditions.push(view_conditions(user_id, friends, networks))
+    conditions.push("contributions.contributable_type = '#{model.name}'") if model != Contribution
 
-    # ordering
+    # result model
 
-    if args[:order]
-      order_part = "ORDER BY #{args[:order]}"
-    else
-      order_part = ''
+    if opts.delete(:contribution_records)
+      model = Contribution
     end
 
-    # filtering
-
-    if user_id
-      where_bits = ["#{view_part(user_id, friends)} OR #{permission_part(['view', 'download', 'edit'], user_id, networks)}"]
-    else
-      where_bits = [view_part]
+    if model != Contribution
+      joins.push("INNER JOIN contributions ON contributions.contributable_id = #{model.table_name}.id AND contributions.contributable_type = '#{model.name}'")
     end
 
-    if args[:type]
-      where_bits.push("contributions.contributable_type = '#{args[:type].name}'")
-    end
-
-    where_part = where_bits.map do |b| "(#{b})" end.join(" AND ")
-
-    # result type
-
-    if !args[:type] || args[:contribution_records] 
-      contributable_type = nil
-      result_model       = Contribution
-      from_part          = "FROM contributions"
-    else
-      contributable_type = args[:type].name.underscore.pluralize
-      result_model       = args[:type]
-      from_part          = "FROM #{contributable_type} INNER JOIN contributions ON contributions.contributable_id = #{contributable_type}.id"
-    end
-
     # selection
 
-    if args[:select]
-      select_part = args[:select]
-    elsif contributable_type
-      select_part = "#{args[:type].name.underscore.pluralize}.*"
-    else 
-      select_part = "contributions.*"
-    end
+    opts[:select] = "#{model.table_name}.*" unless opts[:select]
 
-    # do the query
+    # add in the extra joins needed for the authorisation checks
 
-    if user_id
+    joins.push("INNER JOIN policies ON contributions.policy_id = policies.id")
+    joins.push("LEFT OUTER JOIN permissions ON policies.id = permissions.policy_id") if user_id
 
-      # This is the version used for a member
+    # include the effective permissions in the result?
 
-      query = "
+    if opts.delete(:include_permissions)
 
-        SELECT #{select_part},
+      opts[:select] << ", BIT_OR(#{view_conditions(user_id, friends, networks)})     AS view_permission"
+      opts[:select] << ", BIT_OR(#{download_conditions(user_id, friends, networks)}) AS download_permission"
+      opts[:select] << ", BIT_OR(#{edit_conditions(user_id, friends, networks)})           AS edit_permission"
+    end
 
-          BIT_OR(#{view_part(user_id, friends)}     OR #{permission_part(['view', 'download', 'edit'], user_id, networks)}) AS view,
-          BIT_OR(#{download_part(user_id, friends)} OR #{permission_part(['view', 'download'],         user_id, networks)}) AS download,
-          BIT_OR(#{edit_part(user_id, friends)}     OR #{permission_part(['view'],                     user_id, networks)}) AS edit
+    # merge the joins
 
-        #{from_part}
-        #{args[:joins]}
-        INNER JOIN policies ON contributions.policy_id = policies.id
-        LEFT OUTER JOIN permissions ON policies.id = permissions.policy_id
-        WHERE #{where_part}
-        GROUP BY contributable_type, contributable_id
-        #{order_part}
-        #{limit_part}"
+    if joins.length > 0
+      opts[:joins] = [] unless opts[:joins]
+      opts[:joins] = [opts[:joins]] unless opts[:joins].class == Array
+      opts[:joins] = opts[:joins] + joins
+      opts[:joins] = opts[:joins].join(" ") # Rails 1 does not support arrays here
+    end
 
-      result_model.find_by_sql(query)
+    # merge the conditions
 
-    else 
+    if conditions.length > 0
 
-      # This is the version used for non-members
+      conditions = conditions.map do |c| "(#{c})" end
 
-      query = "
+      case opts[:conditions].class.name
+        when "Array";  opts[:conditions][0] = "(#{([opts[:conditions][0]] + conditions).join(') AND (')})"
+        when "String"; opts[:conditions]    = "(#{([opts[:conditions]] + conditions).join(') AND (')})"
+        else;          opts[:conditions]    = "(#{conditions.join(') AND (')})"
+      end
+    end
 
-        SELECT #{select_part},
+    # enforce grouping by contributable type and id
 
-            BIT_OR(#{view_part})     AS view,
-            BIT_OR(#{download_part}) AS download,
-            BIT_OR(#{edit_part})     AS edit
+    opts[:group] = 'contributable_type, contributable_id'
 
-          #{from_part}
-          #{args[:joins]}
-          INNER JOIN policies ON contributions.policy_id = policies.id
-          WHERE #{where_part}
-          GROUP BY contributable_type, contributable_id
-          #{order_part}
-          #{limit_part}"
+    # do it
 
-      result_model.find_by_sql(query)
-
-    end
+    model.find(*args + [opts])
   end
 end
 

reply via email to

[Prev in Thread] Current Thread [Next in Thread]