Modified: trunk/lib/authorization.rb (2548 => 2549)
--- trunk/lib/authorization.rb 2010-11-30 16:59:01 UTC (rev 2548)
+++ trunk/lib/authorization.rb 2010-12-14 15:03:57 UTC (rev 2549)
@@ -178,6 +178,19 @@
return true
end
+ # Rating permissions
+
+ if (object_type == 'Rating') && (action == 'create')
+
+ # Ratings can only be created by authenticated users
+ return false if user.nil?
+
+ # Ratings can only be set on things that a user can view
+ return Authorization.is_authorized?('view', nil, context, user) if context
+
+ return true
+ end
+
# Bookmark permissions
if (object_type == 'Bookmark') && (action == 'create')
Modified: trunk/lib/rest.rb (2548 => 2549)
--- trunk/lib/rest.rb 2010-11-30 16:59:01 UTC (rev 2548)
+++ trunk/lib/rest.rb 2010-12-14 15:03:57 UTC (rev 2549)
@@ -1841,6 +1841,62 @@
favourite_aux('destroy', opts)
end
+# Ratings
+
+def rating_aux(action, opts)
+
+ # Obtain object
+
+ case action
+ when 'create':
+ return rest_response(401) unless Authorization.is_authorized_for_type?('create', 'Rating', opts[:user], nil)
+
+ ob = Rating.new(:user => opts[:user])
+ when 'read', 'update', 'destroy':
+ ob = obtain_rest_resource('Rating', opts[:query]['id'], opts[:query]['version'], opts[:user], action)
+ else
+ raise "Invalid action '#{action}'"
+ end
+
+ return if ob.nil? # appropriate rest response already given
+
+ if action == "destroy"
+
+ ob.destroy
+
+ else
+
+ data = ""
+
+ rating = parse_element(data, :text, '/rating/rating')
+ subject = parse_element(data, :resource, '/rating/subject')
+
+ ob.rating = rating if rating
+
+ 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, 'Rating', opts[:user], subject)
+ ob.rateable = subject
+ end
+
+ return rest_response(400, :object => ob) unless ob.save
+ end
+
+ rest_get_request(ob, "rating", opts[:user], rest_resource_uri(ob), "rating", { "id" => ob.id.to_s })
+end
+
+def post_rating(opts)
+ rating_aux('create', opts)
+end
+
+def put_rating(opts)
+ rating_aux('update', opts)
+end
+
+def delete_rating(opts)
+ rating_aux('destroy', opts)
+end
+
# Call dispatcher
def rest_call_request(req_uri, format, rules, user, query)
Modified: trunk/test/functional/api_controller_test.rb (2548 => 2549)
--- trunk/test/functional/api_controller_test.rb 2010-11-30 16:59:01 UTC (rev 2548)
+++ trunk/test/functional/api_controller_test.rb 2010-12-14 15:03:57 UTC (rev 2549)
@@ -488,6 +488,82 @@
assert_response(:not_found)
end
+ def test_ratings
+
+ login_as(:john)
+
+ # post a workflow to test with
+
+ content = Base64.encode64(File.read('test/fixtures/files/workflow_dilbert.xml'))
+
+ existing_workflows = Workflow.find(:all)
+
+ rest_request(:post, 'workflow', "<?xml version='1.0'?>
+ <workflow>
+ <title>Unique tags</title>
+ <description>A workflow description.</description>
+ <license-type>by-sa</license-type>
+ <content-type>application/vnd.taverna.scufl+xml</content-type>
+ <content>#{content}</content>
+ </workflow>")
+
+ assert_response(:success)
+
+ extra_workflows = Workflow.find(:all) - existing_workflows
+
+ assert_equal(extra_workflows.length, 1)
+
+ workflow = extra_workflows.first
+ workflow_url = rest_resource_uri(workflow)
+
+ # post a rating
+
+ existing_ratings = Rating.find(:all)
+
+ rest_request(:post, 'rating', "<?xml version='1.0'?>
+ <rating>
+ <rating>4</rating>
+ <subject resource='#{workflow_url}'/>
+ </rating>")
+
+ assert_response(:success)
+
+ extra_ratings = Rating.find(:all) - existing_ratings
+
+ assert_equal(extra_ratings.length, 1)
+
+ rating = extra_ratings.first
+
+ assert_equal(rating.user, users(:john));
+ assert_equal(rating.rateable, workflow);
+ assert_equal(rating.rating, 4);
+
+ # update the rating (which should fail)
+
+ rest_request(:put, 'rating', "<?xml version='1.0'?>
+ <rating>
+ <rating>3</rating>
+ </rating>", "id" => rating.id)
+
+ assert_response(:success)
+
+ rating.reload
+
+ assert_equal(rating.rating, 3);
+
+ # delete the rating
+
+ rest_request(:delete, 'rating', nil, "id" => rating.id)
+
+ assert_response(:success)
+
+ # try to get the deleted rating
+
+ rest_request(:get, 'rating', nil, "id" => rating.id)
+
+ assert_response(:not_found)
+ end
+
def test_favourites
login_as(:john)