myexperiment-hackers
[Top][All Lists]
Advanced

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

[myexperiment-hackers] [2142] trunk: CRUD workflow, full REST index page


From: noreply
Subject: [myexperiment-hackers] [2142] trunk: CRUD workflow, full REST index pages
Date: Fri, 27 Mar 2009 09:51:40 -0400 (EDT)

Revision
2142
Author
dgc
Date
2009-03-27 09:51:40 -0400 (Fri, 27 Mar 2009)

Log Message

CRUD workflow, full REST index pages

Modified Paths

Diff

Modified: trunk/config/tables.xml


(Binary files differ)

Modified: trunk/lib/authorization.rb (2141 => 2142)


--- trunk/lib/authorization.rb	2009-03-27 10:55:26 UTC (rev 2141)
+++ trunk/lib/authorization.rb	2009-03-27 13:51:40 UTC (rev 2142)
@@ -46,6 +46,42 @@
     end
   end
 
+  def Authorization.is_authorized_for_type?(action, object_type, user, context)
+
+    # This method deals with cases where there is no instantiated object to
+    # authorize.  This is usually when thing area created.  The other normal
+    # CRUD actions (read, update and destroy) are handled by is_authorized?
+    # since there's an instantiatable object to authorize on.
+ 
+    # normalise user to nil if this is for an unauthenticated user
+    user = nil if user == 0
+
+    raise "object_type missing in is_authorized_for_type?" if object_type.nil?
+
+    # Workflow permissions
+    
+    if (object_type == 'Workflow') && (action == 'create')
+
+      # Workflows can only be created by authenticated users
+      return !user.nil?
+    end
+    
+    # Comment permissions
+    
+    if (object_type == 'Comment') && (action == 'create')
+
+      # Comments can only be created by authenticated users
+      return false if user.nil?
+
+      # Comments can only be added to things that a user can view
+      return Authorization.is_authorized?('view', nil, context, user) if context
+
+      return true
+    end
+    
+    return false
+  end
+
   # 1) action_name - name of the action that is about to happen with the "thing"
   # 2) thing_type - class name of the thing that needs to be authorized;
   #                 use NIL as a value of this parameter if an instance of the object to be authorized is supplied as "thing";

Modified: trunk/lib/rest.rb (2141 => 2142)


--- trunk/lib/rest.rb	2009-03-27 10:55:26 UTC (rev 2141)
+++ trunk/lib/rest.rb	2009-03-27 13:51:40 UTC (rev 2142)
@@ -25,8 +25,8 @@
 
 # Temporary removals
 
-TABLES["REST"][:data]["workflow"].delete("PUT")
 TABLES["REST"][:data]["job"].delete("POST")
+TABLES["REST"][:data]["messages"].delete("GET")
 
 def rest_routes(map)
   TABLES['REST'][:data].keys.each do |uri|
@@ -292,6 +292,54 @@
   rest_get_request(ob, params[:uri], user, eval("rest_resource_uri(ob)"), rest_name, query)
 end
 
+def find_all_paginated_auth(model, find_args, num, page, user)
+
+  def aux(model, find_args, num, page, user)
+
+    find_args = find_args.clone
+    find_args[:page] = { :size => num, :current => page }
+
+    results = eval(model).find(:all, find_args)
+
+    return nil if results.page > results.page_count
+
+    results.select do |result|
+      Authorization.is_authorized?('view', nil, result, user)
+    end
+  end
+
+  # 'upto' is the number of results needed to fulfil the request
+
+  upto = num * page
+
+  results = []
+  current_page = 1
+
+  # if this isn't the first page, do a single request to fetch all the pages
+  # up to possibly fulfil the request
+
+  if (page > 1)
+    results = aux(model, find_args, upto, 1, user)
+    current_page = page + 1
+  end
+
+  while (results.length < upto)
+
+    results_page = aux(model, find_args, num, current_page, user)
+
+    if results_page.nil?
+      break
+    else
+      results += results_page
+      current_page += 1
+    end
+  end
+
+  range = results[num * (page - 1)..(num * page) - 1]
+  range = [] if range.nil?
+  range
+end
+
 def rest_index_request(req_uri, rules, user, query)
 
   rest_name  = rules['REST Entity']
@@ -310,8 +358,6 @@
   limit = max_limit if limit > max_limit
 
   page = 1 if page < 1
-  
-  part = { :size => limit, :current => page }
 
   if query['tag']
     tag = Tag.find_by_name(query['tag'])
@@ -336,11 +382,11 @@
 
     order = 'DESC' if query['order'] == 'reverse'
 
-    find_args = { :page => part, :order => "#{sort} #{order}" }
+    find_args = { :order => "#{sort} #{order}" }
 
     find_args[:conditions] = conditions if conditions
 
-    obs = eval(model_name.camelize).find(:all, find_args)
+    obs = find_all_paginated_auth(model_name.camelize, find_args, limit, page, user)
   end
 
   produce_rest_list(req_uri, rules, query, obs, rest_name.pluralize, user)
@@ -357,7 +403,6 @@
   rest_entity = TABLES['REST'][:data][req_uri]['GET']['REST Entity']
 
   obs.each do |ob|
-    next if !Authorization.is_authorized?('index', nil, ob, user)
 
     el = rest_reference(ob, query, !elements.nil?)
 
@@ -617,58 +662,89 @@
   Policy.new(:contributor => user, :name => 'auto', :update_mode => 6, :share_mode => 0)
 end
 
-def post_workflow(req_uri, rules, user, query)
+def workflow_aux(action, req_uri, rules, user, query)
 
-  return rest_response(400) if user.nil?
+  # Obtain object
 
-  data = ""
+  case action
+    when 'create':
+      return rest_response(401) unless Authorization.is_authorized_for_type?('create', 'Workflow', user, nil)
+      ob = Workflow.new(:contributor => user)
+    when 'read', 'update', 'destroy':
+      ob = obtain_rest_resource('Workflow', query['id'], user, action)
+    else
+      raise "Invalid action '#{action}'"
+  end
 
-  title        = parse_element(data, :text,   '/workflow/title')
-  description  = parse_element(data, :text,   '/workflow/description')
-  license_type = parse_element(data, :text,   '/workflow/license-type')
-  content_type = parse_element(data, :text,   '/workflow/content-type')
-  content      = parse_element(data, :binary, '/workflow/content')
-  preview      = parse_element(data, :binary, '/workflow/preview')
+  return if ob.nil? # appropriate rest response already given
 
-  # build the contributable
+  if action == "destroy"
 
-  workflow = Workflow.new(:contributor => user)
+    ob.destroy
 
-  workflow.title        = title        if title
-  workflow.body         = description  if description
-  workflow.license      = license_type if license_type
-  workflow.content_type = content_type if content_type
+  else
 
-  workflow.content_blob = ContentBlob.new(:data ="" content) if content
+    data = ""
 
-  # Handle the preview and svg images.  If there's a preview supplied, use it.
-  # Otherwise auto-generate one if we can.
+    title        = parse_element(data, :text,   '/workflow/title')
+    description  = parse_element(data, :text,   '/workflow/description')
+    license_type = parse_element(data, :text,   '/workflow/license-type')
+    content_type = parse_element(data, :text,   '/workflow/content-type')
+    content      = parse_element(data, :binary, '/workflow/content')
+    preview      = parse_element(data, :binary, '/workflow/preview')
 
-  if preview
+    # build the contributable
 
-    image = Tempfile.new('image')
-    image.write(preview)
-    image.rewind
+    ob.title        = title        if title
+    ob.body         = description  if description
+    ob.license      = license_type if license_type
+    ob.content_type = content_type if content_type
 
-    image.extend FileUpload
-    image.original_filename = 'preview'
-    
-    workflow.image = image
+    ob.content_blob = ContentBlob.new(:data ="" content) if content
 
-    image.close
-  end
+    # Handle the preview and svg images.  If there's a preview supplied, use
+    # it.  Otherwise auto-generate one if we can.
 
-  if not workflow.save
-    return rest_response(400, :object => workflow)
+    if preview
+
+      image = Tempfile.new('image')
+      image.write(preview)
+      image.rewind
+
+      image.extend FileUpload
+      image.original_filename = 'preview'
+      
+      ob.image = image
+
+      image.close
+    end
+
+    if not ob.save
+      return rest_response(400, :object => ob)
+    end
+
+    if ob.contribution.policy.nil?
+      ob.contribution.policy = create_default_policy(user)
+      ob.contribution.save
+    end
   end
 
-  workflow.contribution.policy = create_default_policy(user)
-  workflow.contribution.save
+  rest_get_request(ob, "workflow", user,
+      rest_resource_uri(ob), "workflow", { "id" => ob.id.to_s })
+end
 
-  rest_get_request(workflow, "workflow", user,
-      rest_resource_uri(workflow), "workflow", { "id" => workflow.id.to_s })
+def post_workflow(req_uri, rules, user, query)
+  workflow_aux('create', req_uri, rules, user, query)
 end
 
+def put_workflow(req_uri, rules, user, query)
+  workflow_aux('update', req_uri, rules, user, query)
+end
+
+def delete_workflow(req_uri, rules, user, query)
+  workflow_aux('destroy', req_uri, rules, user, query)
+end
+
 # def post_job(req_uri, rules, user, query)
 #
 #   title       = params["job"]["title"]
@@ -879,41 +955,58 @@
 
 # Comments
 
-def update_comment(ob, req_uri, rules, user, query)
+def comment_aux(action, req_uri, rules, user, query)
 
-  data = ""
+  # Obtain object
 
-  comment = parse_element(data, :text,     '/comment/comment')
-  subject = parse_element(data, :resource, '/comment/subject')
+  case action
+    when 'create':
+      return rest_response(401) unless Authorization.is_authorized_for_type?('create', 'Comment', user, nil)
 
-  ob.comment = comment if comment
+      ob = Comment.new(:user => user)
+    when 'read', 'update', 'destroy':
+      ob = obtain_rest_resource('Comment', query['id'], user, action)
+    else
+      raise "Invalid action '#{action}'"
+  end
 
-  if subject
-    return rest_response(400) unless [Blob, Network, Pack, Workflow].include?(subject.class)
-    ob.commentable = subject
+  return if ob.nil? # appropriate rest response already given
+
+  if action == "destroy"
+
+    ob.destroy
+
+  else
+
+    data = ""
+
+    comment = parse_element(data, :text,     '/comment/comment')
+    subject = parse_element(data, :resource, '/comment/subject')
+
+    ob.comment = comment if comment
+
+    if subject
+      return rest_response(400) unless [Blob, Network, Pack, Workflow].include?(subject.class)
+      return rest_response(401) unless Authorization.is_authorized_for_type?(action, 'Comment', user, subject)
+      ob.commentable = subject
+    end
+
+    return rest_response(400, :object => ob) unless ob.save
   end
 
-  return rest_response(400, :object => ob) unless ob.save
-
   rest_get_request(ob, "comment", user, rest_resource_uri(ob), "comment", { "id" => ob.id.to_s })
 end
 
 def post_comment(req_uri, rules, user, query)
-  return rest_response(401) if !Authorization.is_authorized?('create', 'Comment', nil, user)
-  update_comment(Comment.new(:user => user), req_uri, rules, user, query)
+  comment_aux('create', req_uri, rules, user, query)
 end
 
 def put_comment(req_uri, rules, user, query)
-  ob = obtain_rest_resource('Comment', query['id'], user, 'edit')
-  return if ob.nil?
-  update_comment(ob, req_uri, rules, user, query)
+  comment_aux('update', req_uri, rules, user, query)
 end
 
 def delete_comment(req_uri, rules, user, query)
-  ob = obtain_rest_resource('Comment', query['id'], user, 'delete')
-  return if ob.nil?
-  ob.destroy
-  rest_get_request(ob, "comment", user, rest_resource_uri(ob), "comment", { "id" => ob.id.to_s })
+  comment_aux('destroy', req_uri, rules, user, query)
 end
 
 # Call dispatcher

reply via email to

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