Diff
Modified: branches/apace/app/controllers/api_controller.rb (2144 => 2145)
--- branches/apace/app/controllers/api_controller.rb 2009-03-29 13:50:59 UTC (rev 2144)
+++ branches/apace/app/controllers/api_controller.rb 2009-03-29 13:56:05 UTC (rev 2145)
@@ -13,6 +13,9 @@
def process_request
+ # all responses from the API are in XML
+ response.content_type = "application/xml"
+
user = current_user
auth = request.env["HTTP_AUTHORIZATION"]
@@ -21,25 +24,20 @@
credentials = Base64.decode64(auth.sub(/^Basic /, '')).split(':')
user = User.authenticate(credentials[0], credentials[1])
- if user.nil?
- render :xml => rest_error_response(401, 'Not authorized').to_s
- return
- end
+ return rest_response(401) if user.nil?
end
- query = CGIMethods.parse_query_parameters(request.query_string)
method = request.method.to_s.upcase
uri = params[:uri]
- # logger.info "current token: #{current_token.inspect}"
- # logger.info "current user: #{user.id}"
- # logger.info "query: #{query}"
- # logger.info "method: #{method}"
- # logger.info "uri: #{uri}"
+ # logger.info "current token: #{current_token.inspect}"
+ # logger.info "current user: #{user.id}"
+ # logger.info "method: #{method}"
+ # logger.info "uri: #{uri}"
- return bad_rest_request if TABLES['REST'][:data][uri].nil?
- return bad_rest_request if TABLES['REST'][:data][uri][method].nil?
+ return rest_response(400) if TABLES['REST'][:data][uri].nil?
+ return rest_response(400) if TABLES['REST'][:data][uri][method].nil?
rules = TABLES['REST'][:data][uri][method]
@@ -54,21 +52,15 @@
permission_found = true if permission.for == requested_permission
end
- if permission_found == false
- render :xml => rest_error_response(403, 'Not authorized').to_s
- return
- end
+ return rest_response(403) if permission_found == false
end
case rules['Type']
- when 'index'; doc = rest_index_request(rules, user, query)
- when 'crud'; doc = rest_crud_request(rules, user)
- when 'call'; doc = rest_call_request(rules, user, query)
- else; bad_rest_request
+ when 'index'; doc = rest_index_request(params[:uri], rules, user, request.query_parameters)
+ when 'crud'; doc = rest_crud_request(params[:uri], rules, user, request.query_parameters)
+ when 'call'; doc = rest_call_request(params[:uri], rules, user, request.query_parameters)
+ else; return rest_response(400)
end
-
- current_token = nil
- render :xml => doc.to_s
end
end
Modified: branches/apace/app/controllers/runners_controller.rb (2144 => 2145)
--- branches/apace/app/controllers/runners_controller.rb 2009-03-29 13:50:59 UTC (rev 2144)
+++ branches/apace/app/controllers/runners_controller.rb 2009-03-29 13:56:05 UTC (rev 2145)
@@ -123,7 +123,7 @@
def error(notice, message, attr=:id)
flash[:error] = notice
- (err = Runner.new.errors).add(attr, message)
+ (err = TavernaEnactor.new.errors).add(attr, message)
respond_to do |format|
format.html { redirect_to runners_url }
Modified: branches/apace/app/controllers/workflows_controller.rb (2144 => 2145)
--- branches/apace/app/controllers/workflows_controller.rb 2009-03-29 13:50:59 UTC (rev 2144)
+++ branches/apace/app/controllers/workflows_controller.rb 2009-03-29 13:56:05 UTC (rev 2145)
@@ -829,7 +829,8 @@
# Set the internal unique name for this particular workflow (or workflow_version).
workflow_to_set.set_unique_name
- workflow_to_set.image, workflow_to_set.svg = processor_instance.get_preview_images if processor_class.can_generate_preview?
+ workflow_to_set.image = processor_instance.get_preview_image if processor_class.can_generate_preview_image?
+ workflow_to_set.svg = processor_instance.get_preview_svg if processor_class.can_generate_preview_svg?
rescue Exception => ex
worked = false
err_msg = "ERROR: some processing failed in workflow processor '#{processor_class.to_s}'.\nEXCEPTION: #{ex}"
Modified: branches/apace/app/helpers/application_helper.rb (2144 => 2145)
--- branches/apace/app/helpers/application_helper.rb 2009-03-29 13:50:59 UTC (rev 2144)
+++ branches/apace/app/helpers/application_helper.rb 2009-03-29 13:56:05 UTC (rev 2145)
@@ -51,21 +51,12 @@
def owner_text(thing)
return '' if thing.nil?
-
- case thing.class.to_s
- when "Workflow"
- return "Original Uploader"
- when "Blob"
- return "Uploader"
- when "Pack"
- return "Creator"
- when "Network"
- return "Admin"
- when "Profile"
- return "User"
- else
- return ''
- end
+
+ text = thing.class.owner_text if thing.class.respond_to?('owner_text')
+
+ return '' if text.nil?
+
+ text
end
def datetime(old_dt, long=true)
Modified: branches/apace/app/helpers/mashup_helper.rb (2144 => 2145)
--- branches/apace/app/helpers/mashup_helper.rb 2009-03-29 13:50:59 UTC (rev 2144)
+++ branches/apace/app/helpers/mashup_helper.rb 2009-03-29 13:56:05 UTC (rev 2145)
@@ -1,86 +1,2 @@
-
-require 'lib/rest'
-
module MashupHelper
-
- def get_rest_routes(type)
-
- routes = []
-
- TABLES['REST'][:data].sort.each do |uri,methods|
- methods.each do |method,rules|
- routes << [uri,method,rules] if rules['Type'] == type
- end
- end
-
- routes
- end
-
- def get_model_attributes(rest_name)
- TABLES['Model'][:data][rest_name]
- end
-
- def get_example_id(rules)
- rules['Example'][rules['REST Attribute'].index('id')]
- end
-
- def rest_example_id(type)
- case type
- when "workflow"; return "20"
- end
- end
-
- def trim_and_wrap(doc)
-
- # Clean up the base64 sections
-
- doc.root.children.each do |node|
- if node["encoding"] == "base64"
-
- text = node.child.to_s
-
- lines = text.strip.split("\n")
- lines = lines[0..9] + ['...'] if lines.length > 10
- lines = lines.map do |line|
- " #{line.strip}"
- end
-
- text = lines.join("\n").strip
- text = "\n #{text}\n "
-
- node.children[0].remove!
- node << text
- end
- end
-
- doc.to_s
- end
-
- def rest_example(method, rest_name, model_name, id, show_version)
-
- query = { 'id' => id, 'all_elements' => 'yes' }
-
- query['version'] = 1 if show_version
-
- ob = eval(model_name.camelize).find_by_id(id.to_i)
-
- return "" if ob.nil?
-
- doc = rest_get_request(ob, rest_name, nil, rest_resource_uri(ob), rest_name, query)
-
- trim_and_wrap(doc)
- end
-
- def rest_index_example(thing)
- doc = rest_index_request(TABLES['REST'][:data][thing]['GET'], nil, {} )
-
- trim_and_wrap(doc)
- end
-
- def try_it_now_link(method, uri)
- target = "#{request.protocol}#{request.host_with_port}#{uri}"
- "#{target} <input type=\"button\" value=\"Try it now\" '#{target}')\" />"
- end
-
end
-
Modified: branches/apace/app/models/blob.rb (2144 => 2145)
--- branches/apace/app/models/blob.rb 2009-03-29 13:50:59 UTC (rev 2144)
+++ branches/apace/app/models/blob.rb 2009-03-29 13:56:05 UTC (rev 2145)
@@ -4,11 +4,15 @@
# See license.txt for details.
require 'acts_as_contributable'
+require 'acts_as_site_entity'
require 'acts_as_creditable'
require 'acts_as_attributor'
require 'acts_as_attributable'
class Blob < ActiveRecord::Base
+
+ acts_as_site_entity :owner_text => 'Uploader'
+
acts_as_contributable
acts_as_bookmarkable
Modified: branches/apace/app/models/blog.rb (2144 => 2145)
--- branches/apace/app/models/blog.rb 2009-03-29 13:50:59 UTC (rev 2144)
+++ branches/apace/app/models/blog.rb 2009-03-29 13:56:05 UTC (rev 2145)
@@ -3,9 +3,13 @@
# Copyright (c) 2007 University of Manchester and the University of Southampton.
# See license.txt for details.
+require 'acts_as_site_entity'
require 'acts_as_contributable'
class Blog < ActiveRecord::Base
+
+ acts_as_site_entity
+
acts_as_contributable
acts_as_bookmarkable
Modified: branches/apace/app/models/comment.rb (2144 => 2145)
--- branches/apace/app/models/comment.rb 2009-03-29 13:50:59 UTC (rev 2144)
+++ branches/apace/app/models/comment.rb 2009-03-29 13:56:05 UTC (rev 2145)
@@ -23,6 +23,10 @@
}
)
+ validates_presence_of :comment
+ validates_presence_of :commentable_type
+ validates_presence_of :commentable_id
+
def simile_title
"Comment by: #{self.user.name}"
end
Modified: branches/apace/app/models/network.rb (2144 => 2145)
--- branches/apace/app/models/network.rb 2009-03-29 13:50:59 UTC (rev 2144)
+++ branches/apace/app/models/network.rb 2009-03-29 13:56:05 UTC (rev 2145)
@@ -5,11 +5,14 @@
require 'acts_as_contributor'
require 'acts_as_creditor'
+require 'acts_as_site_entity'
class Network < ActiveRecord::Base
acts_as_contributor
acts_as_creditor
+ acts_as_site_entity :owner_text => 'Admin'
+
acts_as_commentable
acts_as_taggable
@@ -49,6 +52,8 @@
:class_name => "User",
:foreign_key => :user_id
+ alias_method :contributor, :owner
+
def owner?(userid)
user_id.to_i == userid.to_i
end
Modified: branches/apace/app/models/pack.rb (2144 => 2145)
--- branches/apace/app/models/pack.rb 2009-03-29 13:50:59 UTC (rev 2144)
+++ branches/apace/app/models/pack.rb 2009-03-29 13:56:05 UTC (rev 2145)
@@ -4,6 +4,7 @@
# See license.txt for details.
require 'acts_as_contributable'
+require 'acts_as_site_entity'
require 'uri'
require 'zip/zip'
require 'tempfile'
@@ -11,6 +12,9 @@
class Pack < ActiveRecord::Base
+
+ acts_as_site_entity :owner_text => 'Creator'
+
acts_as_contributable
acts_as_bookmarkable
Modified: branches/apace/app/models/profile.rb (2144 => 2145)
--- branches/apace/app/models/profile.rb 2009-03-29 13:50:59 UTC (rev 2144)
+++ branches/apace/app/models/profile.rb 2009-03-29 13:56:05 UTC (rev 2145)
@@ -3,6 +3,8 @@
# Copyright (c) 2007 University of Manchester and the University of Southampton.
# See license.txt for details.
+require 'acts_as_site_entity'
+
class Profile < ActiveRecord::Base
belongs_to :owner,
@@ -34,6 +36,8 @@
belongs_to :picture
validates_email_veracity_of :email
+
+ acts_as_site_entity :owner_text => 'User'
acts_as_solr :fields => [ :email,
:website,
Modified: branches/apace/app/models/user.rb (2144 => 2145)
--- branches/apace/app/models/user.rb 2009-03-29 13:50:59 UTC (rev 2144)
+++ branches/apace/app/models/user.rb 2009-03-29 13:56:05 UTC (rev 2145)
@@ -5,6 +5,7 @@
require 'digest/sha1'
+require 'acts_as_site_entity'
require 'acts_as_contributor'
require 'acts_as_creditor'
@@ -272,6 +273,8 @@
return Conf.admins.include?(self.username.downcase)
end
+ acts_as_site_entity
+
acts_as_contributor
has_many :blobs, :as => :contributor
Modified: branches/apace/app/models/workflow.rb (2144 => 2145)
--- branches/apace/app/models/workflow.rb 2009-03-29 13:50:59 UTC (rev 2144)
+++ branches/apace/app/models/workflow.rb 2009-03-29 13:56:05 UTC (rev 2145)
@@ -3,8 +3,8 @@
# Copyright (c) 2007 University of Manchester and the University of Southampton.
# See license.txt for details.
+require 'acts_as_site_entity'
require 'acts_as_contributable'
-require 'acts_as_contributable'
require 'acts_as_creditable'
require 'acts_as_attributor'
require 'acts_as_attributable'
@@ -29,6 +29,11 @@
wv.destroy
end }
+ before_validation :check_unique_name
+ before_validation :extract_metadata
+
+ acts_as_site_entity :owner_text => 'Original Uploader'
+
acts_as_contributable
acts_as_bookmarkable
@@ -114,6 +119,10 @@
return list
end
+ def check_unique_name
+ set_unique_name if unique_name.nil?
+ end
+
# Sets an internal unique name for this workflow.
def set_unique_name
salt = rand 1000000
@@ -125,6 +134,29 @@
end
end
+ # This method is called before save and attempts to pull out metadata if it
+ # hasn't been set
+ def extract_metadata
+
+ if !content_blob.nil? && processor_class
+
+ do_image = true if image.nil? && processor_class.can_generate_preview_image?
+ do_svg = true if svg.nil? && processor_class.can_generate_preview_svg?
+ do_title = true if title.nil?
+ do_desc = true if body.nil?
+
+ if do_image || do_svg || do_title || do_desc
+
+ processor = processor_class.new(content_blob.data)
+
+ self.image = processor.get_preview_image if do_image
+ self.svg = processor.get_preview_svg if do_svg
+ self.title = processor.get_title if do_title
+ self.body = processor.get_description if do_desc
+ end
+ end
+ end
+
def processor_class
@processor_class ||= WorkflowTypesHandler.processor_class_for_content_type(self.content_type)
end
Modified: branches/apace/app/views/comments/_comment.rhtml (2144 => 2145)
--- branches/apace/app/views/comments/_comment.rhtml 2009-03-29 13:50:59 UTC (rev 2144)
+++ branches/apace/app/views/comments/_comment.rhtml 2009-03-29 13:56:05 UTC (rev 2145)
@@ -6,7 +6,6 @@
<%= contributor(comment.user_id, 'User', true, 60) %>
</td>
<td class="header" height="1.2em">
- <!--<% unless comment.title.nil? %><b><%=h comment.title %></b><br/><% end %>-->
<%=datetime comment.created_at %>
</td>
</tr>
@@ -32,4 +31,4 @@
</td>
</tr>
</table>
-</li>
\ No newline at end of file
+</li>
Modified: branches/apace/app/views/mashup/api.rhtml (2144 => 2145)
--- branches/apace/app/views/mashup/api.rhtml 2009-03-29 13:50:59 UTC (rev 2144)
+++ branches/apace/app/views/mashup/api.rhtml 2009-03-29 13:56:05 UTC (rev 2145)
@@ -5,34 +5,10 @@
<h1>API version <%= "#{API_VERSION}" %></h1>
-<h2>Table of Contents</h2>
+<p>Please refer to the <%= Conf.sitename %> wiki for
+<a href="" documentation</a>.
+</p>
-<ul>
- <li><a href="" it out</a></li>
- <li><a href="" requests</a></li>
- <ul>
- <% get_rest_routes('index').each do |route| %>
- <li><a href="" "#{route[0]}" %>"><%= "#{route[0]} index" %></a></li>
- <% end %>
- </ul>
- <li><a href="" requests</a></li>
- <ul>
- <% get_rest_routes('crud').each do |route| %>
- <li><a href="" "rest-#{route[1]}-#{route[0]}" %>"><%= "#{route[1]} #{route[0]}" %></a></li>
- <% end %>
- </ul>
- <li><a href="" search</a></li>
- <li><a href="" selection</a></li>
- <li><a href=""
- <li><a href=""
- <li><a href=""
- <li><a href="" filtered by tag</a></li>
-<!--
- <li><a href="" URIs</a></li>
--->
- <li><a href="" version</a></li>
- <li><a href="" responses</a></li>
-</ul>
<h2 id="try-it-out">Try it out</h2>
@@ -57,239 +33,3 @@
<textarea class="try_it_out_box" id="output" cols="100" rows="20" style="font-size: 0.9em"></textarea><br />
</div>
-<!--
-<h2>REST commands</h2>
-
-<table summary="">
-
- <tr>
- <td>Auth ID</td>
- <td><input value="1" id="auth-id" size="4" /></td>
- <td>
-
- <input type="button" value="Login" />
- <input type="button" value="Logout" />
-
- </td>
- </tr>
-
-
- <tr>
- <td>User ID</td>
- <td><input value="1" id="user-id" size="4" /></td>
- <td>
-
- <input type="button" value="New user" />
- <input type="button" value="List users" />
- <input type="button" value="Get user" />
- <input type="button" value="Update user" />
- <input type="button" value="Delete user" />
-
- </td>
- </tr>
-
- <tr>
- <td>Profile ID</td>
- <td><input value="1" id="profile-id" size="4" /></td>
- <td>
-
- <input type="button" value="New profile" />
- <input type="button" value="List profiles" />
- <input type="button" value="Get profile" />
- <input type="button" value="Update profile" />
- <input type="button" value="Delete profile" />
-
- </td>
- </tr>
-
- <tr>
- <td>Group ID</td>
- <td><input value="1" id="group-id" size="4" /></td>
- <td>
-
- <input type="button" value="New group" />
- <input type="button" value="List groups" />
- <input type="button" value="Get group" />
- <input type="button" value="Update group" />
- <input type="button" value="Delete group" />
-
- </td>
- </tr>
-
- <tr>
- <td>Message ID</td>
- <td><input value="1" id="message-id" size="4" /></td>
- <td>
-
- <input type="button" value="New message" />
- <input type="button" value="List messages" />
- <input type="button" value="Get message" />
- <input type="button" value="Update message" />
- <input type="button" value="Delete message" />
-
- </td>
- </tr>
-</table>
--->
-<h2 id="index">Index requests</h2>
-
-<% get_rest_routes('index').each do |route| %>
-
- <h3 id="index-<%= "#{route[0]}" %>">GET <%= "/#{route[0]}.xml" %></h3>
-
- <h4>Example curl request:</h4>
- <p><tt>curl <%= "#{url_for(:controller => '/', : false)}#{route[0]}.xml" %></tt></p>
-
- <pre style="overflow: hidden"><%=h rest_index_example(route[0]) %></pre>
-
-<% end %>
-
-<h2 id="rest">REST (Create/Read/Update/Destroy) requests</h2>
-
-<% get_rest_routes('crud').each do |route| %>
-
- <h3 id="<%= "rest-#{route[1]}-#{route[0]}" %>"><%= "#{route[1]} /#{route[0]}.xml" %></h3>
-
- <% next unless route[1] == 'GET' %>
-
- <div class="rest_table">
- <table>
- <thead>
- <tr>
- <td>Element</td>
- <td>Example</td>
- <td>Read by default</td>
- </tr>
- </thead>
- <tbody>
- <% attrs = get_model_attributes(route[2]['REST Entity']) %>
- <% (0..attrs['REST Attribute'].length).each do |i| %>
-
- <tr>
- <td><%= attrs['REST Attribute'][i] %></td>
- <td><%= attrs['Example'][i] %></td>
- <td><%= attrs['Read by default'][i] %></td>
- </tr>
- <% end %>
- </tbody>
- </table>
- <p><small>Note: You can specify which elements to get by using the
- <a href="" query option.</small></p>
- </div>
-
- <h4>Example curl request:</h4>
- <p><tt>curl <%= "#{url_for(:controller => '/', : false)}#{route[0]}.xml?id=#{get_example_id(attrs)}" %></tt></p>
-
- <pre style="overflow: hidden"><%=h rest_example(route[1], route[2]['REST Entity'], route[2]['Model Entity'], get_example_id(attrs).to_i, false) %></pre>
-
-<% end %>
-
-<h2 id="search">General search</h2>
-
-<p>The search facility is available from the following URL:</p>
-
-<pre> <%= try_it_now_link('GET', '/search.xml?query=bioaid') %></pre>
-
-<p>Particular types can be specified by the <tt>type</tt> query option:</p>
-
-<pre> <%= try_it_now_link('GET', '/search.xml?query=bioaid&type=workflow') %></pre>
-
-<h2 id="elements">Element selection</h2>
-
-<p>The elements within each REST response can be tailored to include only the
-parts of the response of interest. This saves bandwidth and response time!</p>
-
-<pre> <%= try_it_now_link('GET', "/workflow.xml?id=#{rest_example_id('workflow')}&elements=title,description") %></pre>
-
-<p>All elements can be returned too.</p>
-
-<pre> <%= try_it_now_link('GET', "/workflow.xml?id=#{rest_example_id('workflow')}&all_elements=yes") %></pre>
-
-<h2 id="versions">Versions</h2>
-
-<p>For objects that have versions (e.g. Workflows), you may specify the
-specific version to be worked on by including <tt>version</tt> in the URI
-query. For example:</p>
-
-<pre> <%= try_it_now_link('GET', '/workflow.xml?id=20&version=1') %></pre>
-
-<h2 id="sorting">Sorting</h2>
-
-<p>Index and search requests can be sorted. By default, these results are
-sorted by ascending creation order but sorting by creation time
-(<tt>created</tt>), update time (<tt>updated</tt>), title (<tt>title</tt>) and
-name (<tt>name</tt>) is also possible. In addition, the results can be
-returned in reverse order.</p>
-
-<pre> <%= try_it_now_link('GET', '/workflows.xml?sort=title') %></pre>
-
-<pre> <%= try_it_now_link('GET', '/files.xml?sort=title&order=reverse') %></pre>
-
-<h2 id="pagination">Pagination</h2>
-
-<p>For the index requests, a default maximum of 25 results is shown. This can
-be raised to 100 by using adding <tt>num</tt> to the query. A particular
-page of results can be selected by adding <tt>page</tt> to the query.</p>
-
-<pre> <%= try_it_now_link('GET', '/workflows.xml?num=50&page=2') %></pre>
-
-<h2 id="tags">Index filtered by tag</h2>
-
-<p>For indices of taggable items, the index can be filtered on a particular tag.</p>
-
-<pre> <%= try_it_now_link('GET', '/workflows.xml?tag=bioaid') %></pre>
-
-<!--
-<h2 id="rest-uris">REST URIs</h2>
-
-<p>URIs used within the API refer to the <%= Conf.sitename %> records. In addition to
-these, "REST URIs" can be requested within each API response by including
-<tt>rest_uris=yes</tt> in the query.</p>
-
-<p>The REST URIs are useful endpoints for further API calls.</p>
-
-<pre> <%= try_it_now_link('GET', '/workflow.xml?id=36&rest_uris=yes') %></pre>
--->
-
-<h2 id="api-version">API version</h2>
-
-<p>The version of the REST API that the server uses can be requested by
-including <tt>api_version</tt> in the query.</p>
-
-<pre> <%= try_it_now_link('GET', '/workflows.xml?api_version=yes') %></pre>
-
-<h2 id="errors">Error responses</h2>
-
-<p>The general format of an error response from the REST API is an XML document
-with an <tt>error</tt> element. The <tt>code</tt> attribute contains a number
-that determines the class of error. The <tt>message</tt> attribute of the
-error element contains a human readable message describing the error.</p>
-
-<h3>Example error response</h3>
-
-<pre>
-<?xml version="1.0" encoding="UTF-8"?>
-<error message="Resource not found" code="404"/>
-</pre>
-
-<h3>Error messages</h3>
-
-<div class="rest_table" summary="">
- <table>
- <thead>
- <tr>
- <td>Message</td>
- <td>Code</td>
- </tr>
- </thead>
- <tbody>
- <tr><td>Resource not found</td><td>404</td></tr>
- <tr><td>Not authorized</td><td>403</td></tr>
- <tr><td>Resource not versioned</td><td>400</td></tr>
- <tr><td>Resource version not found</td><td>404</td></tr>
- <tr><td>Service unavailable</td><td>503</td></tr>
- </tbody>
- </table>
-</div>
-
-
Modified: branches/apace/app/views/messages/show.rhtml (2144 => 2145)
--- branches/apace/app/views/messages/show.rhtml 2009-03-29 13:50:59 UTC (rev 2144)
+++ branches/apace/app/views/messages/show.rhtml 2009-03-29 13:56:05 UTC (rev 2145)
@@ -18,7 +18,8 @@
</li>
</ul>
-<% if @message.reply? %>
+<% # this makes sure that the message is a reply to something, and that the original message still exists -%>
+<% if @message.reply? && @message.reply_to && address@hidden %>
<br/>
<p class="box_infotext">
<b>This message is a reply to:</b> <%= link_to h(@message.reply_to.subject), message_path(@message.reply_to) %>
Modified: branches/apace/config/settings.yml.pre (2144 => 2145)
--- branches/apace/config/settings.yml.pre 2009-03-29 13:50:59 UTC (rev 2144)
+++ branches/apace/config/settings.yml.pre 2009-03-29 13:56:05 UTC (rev 2145)
@@ -193,6 +193,7 @@
# model_aliases - These are visible names for models where the desired visible
# name might conflict with existing classes (e.g. "File" or
# "Application")
+
model_aliases:
File: Blob
Modified: branches/apace/config/tables.xml
(Binary files differ)
Deleted: branches/apace/db/migrate/074_create_algorithms.rb (2144 => 2145)
--- branches/apace/db/migrate/074_create_algorithms.rb 2009-03-29 13:50:59 UTC (rev 2144)
+++ branches/apace/db/migrate/074_create_algorithms.rb 2009-03-29 13:56:05 UTC (rev 2145)
@@ -1,24 +0,0 @@
-# myExperiment: db/migrate/074_create_algorithms.rb
-#
-# Copyright (c) 2009 University of Manchester and the University of Southampton.
-# See license.txt for details.
-
-class CreateAlgorithms < ActiveRecord::Migration
- def self.up
- create_table :algorithms do |t|
- t.column :contributor_id, :integer
- t.column :contributor_type, :string
- t.column :title, :string
- t.column :description, :text
- t.column :description_html, :text
- t.column :license, :string
- t.column :url, :text
- t.column :created_at, :datetime
- t.column :updated_at, :datetime
- end
- end
-
- def self.down
- drop_table :algorithms
- end
-end
Copied: branches/apace/db/migrate/074_modify_comments.rb (from rev 2143, trunk/db/migrate/074_modify_comments.rb) (0 => 2145)
--- branches/apace/db/migrate/074_modify_comments.rb (rev 0)
+++ branches/apace/db/migrate/074_modify_comments.rb 2009-03-29 13:56:05 UTC (rev 2145)
@@ -0,0 +1,9 @@
+class ModifyComments < ActiveRecord::Migration
+ def self.up
+ remove_column :comments, :title
+ end
+
+ def self.down
+ add_column :comments, :title, :string, :limit => 50, :default => ""
+ end
+end
Copied: branches/apace/db/migrate/075_create_algorithms.rb (from rev 2143, branches/apace/db/migrate/074_create_algorithms.rb) (0 => 2145)
--- branches/apace/db/migrate/075_create_algorithms.rb (rev 0)
+++ branches/apace/db/migrate/075_create_algorithms.rb 2009-03-29 13:56:05 UTC (rev 2145)
@@ -0,0 +1,24 @@
+# myExperiment: db/migrate/074_create_algorithms.rb
+#
+# Copyright (c) 2009 University of Manchester and the University of Southampton.
+# See license.txt for details.
+
+class CreateAlgorithms < ActiveRecord::Migration
+ def self.up
+ create_table :algorithms do |t|
+ t.column :contributor_id, :integer
+ t.column :contributor_type, :string
+ t.column :title, :string
+ t.column :description, :text
+ t.column :description_html, :text
+ t.column :license, :string
+ t.column :url, :text
+ t.column :created_at, :datetime
+ t.column :updated_at, :datetime
+ end
+ end
+
+ def self.down
+ drop_table :algorithms
+ end
+end
Deleted: branches/apace/db/migrate/075_create_apps.rb (2144 => 2145)
--- branches/apace/db/migrate/075_create_apps.rb 2009-03-29 13:50:59 UTC (rev 2144)
+++ branches/apace/db/migrate/075_create_apps.rb 2009-03-29 13:56:05 UTC (rev 2145)
@@ -1,23 +0,0 @@
-# myExperiment: db/migrate/075_create_apps.rb
-#
-# Copyright (c) 2009 University of Manchester and the University of Southampton.
-# See license.txt for details.
-
-class CreateApps < ActiveRecord::Migration
- def self.up
- create_table :apps do |t|
- t.column :contributor_id, :integer
- t.column :contributor_type, :string
- t.column :title, :string
- t.column :description, :text
- t.column :description_html, :text
- t.column :license, :string
- t.column :created_at, :datetime
- t.column :updated_at, :datetime
- end
- end
-
- def self.down
- drop_table :apps
- end
-end
Deleted: branches/apace/db/migrate/076_create_algorithm_instances.rb (2144 => 2145)
--- branches/apace/db/migrate/076_create_algorithm_instances.rb 2009-03-29 13:50:59 UTC (rev 2144)
+++ branches/apace/db/migrate/076_create_algorithm_instances.rb 2009-03-29 13:56:05 UTC (rev 2145)
@@ -1,18 +0,0 @@
-# myExperiment: db/migrate/076_create_algorithm_instances.rb
-#
-# Copyright (c) 2009 University of Manchester and the University of Southampton.
-# See license.txt for details.
-
-class CreateAlgorithmInstances < ActiveRecord::Migration
- def self.up
- create_table :algorithm_instances do |t|
- t.column :algorithm_id, :integer
- t.column :app_id, :integer
- end
- end
-
- def self.down
- drop_table :algorithm_instances
- end
-end
-
Copied: branches/apace/db/migrate/076_create_apps.rb (from rev 2143, branches/apace/db/migrate/075_create_apps.rb) (0 => 2145)
--- branches/apace/db/migrate/076_create_apps.rb (rev 0)
+++ branches/apace/db/migrate/076_create_apps.rb 2009-03-29 13:56:05 UTC (rev 2145)
@@ -0,0 +1,23 @@
+# myExperiment: db/migrate/075_create_apps.rb
+#
+# Copyright (c) 2009 University of Manchester and the University of Southampton.
+# See license.txt for details.
+
+class CreateApps < ActiveRecord::Migration
+ def self.up
+ create_table :apps do |t|
+ t.column :contributor_id, :integer
+ t.column :contributor_type, :string
+ t.column :title, :string
+ t.column :description, :text
+ t.column :description_html, :text
+ t.column :license, :string
+ t.column :created_at, :datetime
+ t.column :updated_at, :datetime
+ end
+ end
+
+ def self.down
+ drop_table :apps
+ end
+end
Copied: branches/apace/db/migrate/077_create_algorithm_instances.rb (from rev 2143, branches/apace/db/migrate/076_create_algorithm_instances.rb) (0 => 2145)
--- branches/apace/db/migrate/077_create_algorithm_instances.rb (rev 0)
+++ branches/apace/db/migrate/077_create_algorithm_instances.rb 2009-03-29 13:56:05 UTC (rev 2145)
@@ -0,0 +1,18 @@
+# myExperiment: db/migrate/076_create_algorithm_instances.rb
+#
+# Copyright (c) 2009 University of Manchester and the University of Southampton.
+# See license.txt for details.
+
+class CreateAlgorithmInstances < ActiveRecord::Migration
+ def self.up
+ create_table :algorithm_instances do |t|
+ t.column :algorithm_id, :integer
+ t.column :app_id, :integer
+ end
+ end
+
+ def self.down
+ drop_table :algorithm_instances
+ end
+end
+
Modified: branches/apace/lib/acts_as_contributable.rb (2144 => 2145)
--- branches/apace/lib/acts_as_contributable.rb 2009-03-29 13:50:59 UTC (rev 2144)
+++ branches/apace/lib/acts_as_contributable.rb 2009-03-29 13:56:05 UTC (rev 2145)
@@ -69,11 +69,6 @@
return contribution.contributor.title if contribution.contributor.respond_to?('title')
end
- def label
- return name if respond_to?('name')
- return title if respond_to?('title')
- end
-
# This is so that the updated_at time on the record tallies up with the
# contributable
def save_contributable_record
Copied: branches/apace/lib/acts_as_site_entity.rb (from rev 2144, trunk/lib/acts_as_site_entity.rb) (0 => 2145)
--- branches/apace/lib/acts_as_site_entity.rb (rev 0)
+++ branches/apace/lib/acts_as_site_entity.rb 2009-03-29 13:56:05 UTC (rev 2145)
@@ -0,0 +1,50 @@
+# myExperiment: lib/acts_as_site_entity.rb
+#
+# Copyright (c) 2009 University of Manchester and the University of Southampton.
+# See license.txt for details.
+
+module MyExperiment
+ module Acts #:nodoc:
+ module SiteEntity #:nodoc:
+ def self.included(mod)
+ mod.extend(ClassMethods)
+ end
+
+ module ClassMethods
+ def acts_as_site_entity(args = {})
+
+ class_eval do
+ extend MyExperiment::Acts::SiteEntity::SingletonMethods
+ end
+ include MyExperiment::Acts::SiteEntity::InstanceMethods
+
+ self.owner_text = args[:owner_text] ? args[:owner_text] : ''
+ end
+ end
+
+ module SingletonMethods
+
+ def owner_text=(new_value)
+ @owner_text = new_value
+ end
+
+ def owner_text
+ @owner_text
+ end
+ end
+
+ module InstanceMethods
+
+ def label
+ return name if respond_to?('name')
+ return title if respond_to?('title')
+ end
+ end
+ end
+ end
+end
+
+ActiveRecord::Base.class_eval do
+ include MyExperiment::Acts::SiteEntity
+end
+
Modified: branches/apace/lib/authorization.rb (2144 => 2145)
--- branches/apace/lib/authorization.rb 2009-03-29 13:50:59 UTC (rev 2144)
+++ branches/apace/lib/authorization.rb 2009-03-29 13:56:05 UTC (rev 2145)
@@ -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";
@@ -92,6 +128,7 @@
# OR
# -- Network instance
# -- Experiment / Job / Runner / TavernaEnactor instance
+ # -- Comment
# -- or any other object instance, for which we'll use the object itself to run .authorized?() on it
thing_instance = thing
thing_type = thing.class.name
@@ -122,7 +159,7 @@
# this is required to get "policy_id" for policy-based aurhorized objects (like workflows / blobs / packs / contributions)
# and to get objects themself for other object types (networks, experiments, jobs, tavernaenactors, runners)
if (thing_contribution.nil? && ["Workflow", "Blob", "Pack", "Contribution"].include?(thing_type)) ||
- (thing_instance.nil? && ["Network", "Experiment", "Job", "TavernaEnactor", "Runner"].include?(thing_type))
+ (thing_instance.nil? && ["Network", "Comment", "Experiment", "Job", "TavernaEnactor", "Runner"].include?(thing_type))
found_thing = find_thing(thing_type, thing_id)
@@ -240,7 +277,20 @@
else
is_authorized = true
end
-
+
+ when "Comment"
+ case action
+ when "destroy"
+ # only the user who posted the comment can delete it
+ is_authorized = Authorization.is_owner?(user_id, thing_instance)
+ when "view"
+ # user can view comment if they can view the item that this comment references
+ is_authorized = Authorization.is_authorized?('view', thing_instance.commentable_type, thing_instance.commentable_id, user)
+ else
+ # 'edit' or any other actions are not allowed on comments
+ is_authorized = false
+ end
+
when "Experiment"
user_instance = get_user(user_id) unless user_instance
@@ -278,13 +328,13 @@
def Authorization.categorize_action(action_name)
case action_name
- when 'show', 'index', 'view', 'search', 'favourite', 'favourite_delete', 'comment', 'comment_delete', 'comments', 'comments_timeline', 'rate', 'tag', 'items', 'statistics', 'tag_suggestions'
+ when 'show', 'index', 'view', 'search', 'favourite', 'favourite_delete', 'comment', 'comment_delete', 'comments', 'comments_timeline', 'rate', 'tag', 'items', 'statistics', 'tag_suggestions', 'read', 'verify'
action = ''
when 'edit', 'new', 'create', 'update', 'new_version', 'create_version', 'destroy_version', 'edit_version', 'update_version', 'new_item', 'create_item', 'edit_item', 'update_item', 'quick_add', 'resolve_link', 'process_tag_suggestions'
action = ''
- when 'download', 'named_download', 'launch', 'submit_job'
+ when 'download', 'named_download', 'launch', 'submit_job', 'save_inputs', 'refresh_status', 'rerun', 'refresh_outputs', 'render_output', 'outputs_xml', 'outputs_package'
action = ''
- when 'destroy', 'destroy_item'
+ when 'destroy', 'delete', 'destroy_item'
action = ''
when 'execute'
# action is available only(?) for runners at the moment;
@@ -314,6 +364,8 @@
found_instance = Contribution.find(thing_id)
when "Network"
found_instance = Network.find(thing_id)
+ when "Comment"
+ found_instance = Comment.find(thing_id)
when "Experiment"
found_instance = Experiment.find(thing_id)
when "Job"
@@ -334,14 +386,21 @@
# checks if "user" is owner of the "thing"
- def Authorization.is_owner?(user_id, thing_contribution)
+ def Authorization.is_owner?(user_id, thing)
is_authorized = false
- # if owner of the "thing" is the "user" then the "user" is authorized
- if thing_contribution.contributor_type == 'User' && thing_contribution.contributor_id == user_id
- is_authorized = true
- elsif thing_contribution.contributor_type == 'Network'
- is_authorized = is_network_admin?(user_id, thing_contribution.contributor_id)
+ case thing.class.name
+ when "Contribution"
+ # if owner of the "thing" is the "user" then the "user" is authorized
+ if thing.contributor_type == 'User' && thing.contributor_id == user_id
+ is_authorized = true
+ elsif thing.contributor_type == 'Network'
+ is_authorized = is_network_admin?(user_id, thing.contributor_id)
+ end
+ when "Comment"
+ is_authorized = (thing.user_id == user_id)
+ #else
+ # do nothing -- unknown "thing" types are not authorized by default
end
return is_authorized
Modified: branches/apace/lib/rest.rb (2144 => 2145)
--- branches/apace/lib/rest.rb 2009-03-29 13:50:59 UTC (rev 2144)
+++ branches/apace/lib/rest.rb 2009-03-29 13:56:05 UTC (rev 2145)
@@ -3,6 +3,7 @@
# Copyright (c) 2007 University of Manchester and the University of Southampton.
# See license.txt for details.
+require 'lib/conf'
require 'lib/excel_xml'
require 'xml/libxml'
require 'uri'
@@ -17,17 +18,15 @@
'Foreign Accessor',
'List Element Name', 'List Element Accessor',
'Example', 'Versioned', 'Key type',
- 'Limited to user' ] },
+ 'Limited to user', 'Permission' ] },
'REST' => { :indices => [ 'URI', 'Method' ] }
} )
# Temporary removals
-TABLES["REST"][:data]["comment"].delete("PUT")
-TABLES["REST"][:data]["comment"].delete("DELETE")
-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|
@@ -37,8 +36,51 @@
end
end
-def bad_rest_request
- render(:text => '400 Bad Request', :status => '400 Bad Request')
+def rest_response(code, args = {})
+
+ if code == 401
+ response.headers['WWW-Authenticate'] = "Basic realm=\"#{Conf.sitename} REST API\""
+ end
+
+ if code == 307
+ response.headers['Location'] = args[:location]
+ end
+
+ message = "Unknown Error"
+
+ case code
+ when 200: message = "OK"
+ when 307: message = "Temporary Redirect"
+ when 400: message = "Bad Request"
+ when 401: message = "Unauthorized"
+ when 403: message = "Forbidden"
+ when 404: message = "Not Found"
+ when 500: message = "Internal Server Error"
+ end
+
+ if (code >= 300) && (code < 400)
+
+ doc = ""
+
+ else
+
+ error = XML::Node.new('error')
+ error["code" ] = code.to_s
+ error["message"] = message
+
+ doc = XML::Document.new
+ doc.root = error
+
+ if args[:object]
+ args[:object].errors.full_messages.each do |message|
+ reason = XML::Node.new('reason')
+ reason << message
+ doc.root << reason
+ end
+ end
+ end
+
+ render(:xml => doc.to_s, :status => "#{code} #{message}")
end
def file_column_url(ob, field)
@@ -52,6 +94,8 @@
def rest_get_element(ob, user, rest_entity, rest_attribute, query, elements)
+ # puts "rest_get_element: #{rest_entity} / #{rest_attribute}"
+
model_data = TABLES['Model'][:data][rest_entity]
i = model_data['REST Attribute'].index(rest_attribute)
@@ -70,6 +114,12 @@
return nil if limited_ob != user
end
+ permission = model_data['Permission'][i]
+
+ if permission
+ return nil if !Authorization.is_authorized?(permission, nil, ob, user)
+ end
+
unless query['all_elements'] == 'yes'
return nil if elements and not elements.index(model_data['REST Attribute'][i])
return nil if not elements and model_data['Read by default'][i] == 'no'
@@ -159,9 +209,12 @@
end
if model_data['Foreign Accessor'][i]
- resource_uri = eval("rest_resource_uri(ob.#{model_data['Foreign Accessor'][i]})")
- attrs['resource'] = resource_uri if resource_uri
- attrs['uri'] = eval("rest_access_uri(ob.#{model_data['Foreign Accessor'][i]})")
+ foreign_ob = eval("ob.#{model_data['Foreign Accessor'][i]}")
+ if foreign_ob != nil
+ resource_uri = rest_resource_uri(foreign_ob)
+ attrs['resource'] = resource_uri if resource_uri
+ attrs['uri'] = rest_access_uri(foreign_ob)
+ end
end
end
@@ -182,9 +235,9 @@
def rest_get_request(ob, req_uri, user, uri, entity_name, query)
if query['version']
- return rest_error_response(400, 'Resource not versioned') unless ob.respond_to?('versions')
- return rest_error_response(404, 'Resource version not found') if query['version'].to_i < 1
- return rest_error_response(404, 'Resource version not found') if ob.versions[query['version'].to_i - 1].nil?
+ return rest_response(400) unless ob.respond_to?('versions')
+ return rest_response(404) if query['version'].to_i < 1
+ return rest_response(404) if ob.versions[query['version'].to_i - 1].nil?
end
elements = query['elements'] ? query['elements'].split(',') : nil
@@ -214,39 +267,17 @@
root << data unless data.nil?
end
- doc
+ render(:xml => doc.to_s)
end
-def rest_error_response(code, message, error_ob = nil)
+def rest_crud_request(req_uri, rules, user, query)
- error = XML::Node.new('error')
- error["code" ] = code.to_s
- error["message"] = message
-
- doc = XML::Document.new
- doc.root = error
-
- if error_ob
- error_ob.errors.full_messages.each do |message|
- reason = XML::Node.new('reason')
- reason << message
- doc.root << reason
- end
- end
-
- doc
-end
-
-def rest_crud_request(rules, user)
-
- query = CGIMethods.parse_query_parameters(request.query_string)
-
rest_name = rules['REST Entity']
model_name = rules['Model Entity']
ob = eval(model_name.camelize).find_by_id(params[:id].to_i)
- return rest_error_response(404, 'Resource not found') if ob.nil?
+ return rest_response(404) if ob.nil?
perm_ob = ob
@@ -254,16 +285,63 @@
case rules['Permission']
when 'public'; # do nothing
- when 'view'; return rest_error_response(403, 'Not authorized') if not Authorization.is_authorized?("show", nil, perm_ob, user)
- when 'owner'; return rest_error_response(403, 'Not authorized') if logged_in?.nil? or object_owner(perm_ob) != user
+ when 'view'; return rest_response(401) if not Authorization.is_authorized?("show", nil, perm_ob, user)
+ when 'owner'; return rest_response(401) if logged_in?.nil? or object_owner(perm_ob) != user
end
- response.content_type = "application/xml"
rest_get_request(ob, params[:uri], user, eval("rest_resource_uri(ob)"), rest_name, query)
end
-def rest_index_request(rules, user, query)
+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']
model_name = rules['Model Entity']
@@ -280,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'])
@@ -306,33 +382,44 @@
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
- # filter out ones they are not allowed to get
- obs = (obs.select do |c| c.respond_to?('contribution') == false or Authorization.is_authorized?("index", nil, c, user) end)
-
- produce_rest_list(rules, query, obs, rest_name.pluralize)
+ produce_rest_list(req_uri, rules, query, obs, rest_name.pluralize, user)
end
-def produce_rest_list(rules, query, obs, tag)
+def produce_rest_list(req_uri, rules, query, obs, tag, user)
root = XML::Node.new(tag)
root['api-version'] = API_VERSION if query['api_version'] == 'yes'
- obs.map do |ob|
- root << rest_reference(ob, query)
+ elements = query['elements'] ? query['elements'].split(',') : nil
+
+ rest_entity = TABLES['REST'][:data][req_uri]['GET']['REST Entity']
+
+ obs.each do |ob|
+
+ el = rest_reference(ob, query, !elements.nil?)
+
+ if elements
+ TABLES['Model'][:data][rest_entity]['REST Attribute'].each do |rest_attribute|
+ data = "" user, rest_entity, rest_attribute, query, elements)
+ el << data unless data.nil?
+ end
+ end
+
+ root << el
end
doc = XML::Document.new
doc.root = root
- doc
+ render(:xml => doc.to_s)
end
def object_owner(ob)
@@ -373,6 +460,7 @@
when 'Creditation'; return nil
when 'Attribution'; return nil
+ when 'Tagging'; return nil
when 'Workflow::Version'; return "#{rest_resource_uri(ob.workflow)}?version=#{ob.version}"
end
@@ -406,6 +494,7 @@
when 'Download'; return "#{base}/download.xml?id=#{ob.id}"
when 'PackContributableEntry'; return "#{base}/internal-pack-item.xml?id=#{ob.id}"
when 'PackRemoteEntry'; return "#{base}/external-pack-item.xml?id=#{ob.id}"
+ when 'Tagging'; return "#{base}/tagging.xml?id=#{ob.id}"
when 'Creditation'; return nil
when 'Attribution'; return nil
@@ -428,6 +517,7 @@
when 'Citation'; return 'citation'
when 'Announcement'; return 'announcement'
when 'Tag'; return 'tag'
+ when 'Tagging'; return 'tagging'
when 'Pack'; return 'pack'
when 'Experiment'; return 'experiment'
when 'Download'; return 'download'
@@ -451,6 +541,7 @@
when 'Citation'; return ob.title
when 'Announcement'; return ob.title
when 'Tag'; return ob.name
+ when 'Tagging'; return ob.tag.name
when 'Pack'; return ob.title
when 'Experiment'; return ob.title
when 'Download'; return ''
@@ -462,26 +553,24 @@
return ''
end
-def rest_reference(ob, query)
+def rest_reference(ob, query, skip_text = false)
- tag = rest_object_tag_text(ob)
- text = rest_object_label_text(ob)
+ el = XML::Node.new(rest_object_tag_text(ob))
- el = XML::Node.new(tag)
-
resource_uri = rest_resource_uri(ob)
el['resource'] = resource_uri if resource_uri
el['uri' ] = rest_access_uri(ob)
el['version' ] = ob.version.to_s if ob.respond_to?('version')
- el << text
+ el << rest_object_label_text(ob) if !skip_text
+
el
end
def parse_resource_uri(str)
- base_uri = URI.parse("#{request.protocol}#{request.host_with_port}/")
+ base_uri = URI.parse("#{Conf.base_uri}/")
uri = base_uri.merge(str)
is_local = base_uri.host == uri.host and base_uri.port == uri.port
@@ -508,76 +597,155 @@
end
-def get_rest_uri(rules, user, query)
+def resolve_resource_node(resource_node, user = nil, permission = nil)
- return bad_rest_request if query['resource'].nil?
+ return nil if resource_node.nil?
- obs = (obs.select do |c| c.respond_to?('contribution') == false or Authorization.is_authorized?("index", nil, c, user) end)
- doc = REXML::Document.new("<?xml version=\"1.0\" encoding=\"UTF-8\"?><rest-uri/>")
- "bing"
+ attr = resource_node.find_first('@resource')
+
+ return nil if attr.nil?
+
+ resource_uri = attr.value
+
+ resource_bits = parse_resource_uri(resource_uri)
+
+ return nil if resource_bits.nil?
+
+ resource = eval(resource_bits[0]).find_by_id(resource_bits[1].to_i)
+
+ return nil if resource.nil?
+
+ if permission
+ return nil if !Authorization.is_authorized?(permission, nil, resource, user)
+ end
+
+ resource
end
+def obtain_rest_resource(type, id, user, permission = nil)
+
+ resource = eval(type).find_by_id(id)
+
+ if resource.nil?
+ rest_response(404)
+ return nil
+ end
+
+ if permission
+ if !Authorization.is_authorized?(permission, nil, resource, user)
+ rest_response(401)
+ return nil
+ end
+ end
+
+ resource
+end
+
+def rest_access_redirect(req_uri, rules, user, query)
+
+ return rest_response(400) if query['resource'].nil?
+
+ bits = parse_resource_uri(query['resource'])
+
+ return rest_response(404) if bits.nil?
+
+ ob = eval(bits[0]).find_by_id(bits[1])
+
+ return rest_response(404) if ob.nil?
+
+ return rest_response(401) if !Authorization.is_authorized?('view', nil, ob, user)
+
+ rest_response(307, :location => rest_access_uri(ob))
+end
+
def create_default_policy(user)
Policy.new(:contributor => user, :name => 'auto', :update_mode => 6, :share_mode => 0)
end
-def post_workflow(rules, user, query)
+def workflow_aux(action, req_uri, rules, user, query)
- return rest_error_response(400, 'Bad Request') if user.nil?
- return rest_error_response(400, 'Bad Request') if params["workflow"].nil?
+ # Obtain object
- elements = params["workflow"]
+ 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
- # build the contributable
+ return if ob.nil? # appropriate rest response already given
- workflow = Workflow.new(:contributor => user)
+ if action == "destroy"
- content = Base64.decode64(elements["content"]) if elements["content"]
+ ob.destroy
- workflow.title = elements["title"] if elements["title"]
- workflow.body = elements["description"] if elements["description"]
- workflow.license = elements["license_type"] if elements["license_type"]
- workflow.content_type = elements["content_type"] if elements["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 params["workflow"]["preview"]
+ # build the contributable
- image = Tempfile.new('image')
- image.write(Base64.decode64(params["workflow"]["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
+ # Handle the preview and svg images. If there's a preview supplied, use
+ # it. Otherwise auto-generate one if we can.
- elsif content and workflow.processor_class and workflow.processor_class.can_generate_preview?
+ if preview
- processor = workflow.processor_class.new(content)
- workflow.image, workflow.svg = processor.get_preview_images
+ image = Tempfile.new('image')
+ image.write(preview)
+ image.rewind
- end
+ image.extend FileUpload
+ image.original_filename = 'preview'
+
+ ob.image = image
- workflow.set_unique_name
+ image.close
+ end
- if not workflow.save
- return rest_error_response(400, 'Bad Request', workflow)
+ 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 post_job(rules, user, query)
+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"]
# description = params["job"]["description"]
@@ -586,20 +754,20 @@
# runner_bits = parse_resource_uri(params["job"]["runner"])
# runnable_bits = parse_resource_uri(params["job"]["runnable"])
#
-# return rest_error_response(400, 'Bad Request') if title.nil?
-# return rest_error_response(400, 'Bad Request') if description.nil?
+# return rest_response(400) if title.nil?
+# return rest_response(400) if description.nil?
#
-# return rest_error_response(400, 'Bad Request') if experiment_bits.nil? or experiment_bits[0] != 'Experiment'
-# return rest_error_response(400, 'Bad Request') if runner_bits.nil? or runner_bits[0] != 'Runner'
-# return rest_error_response(400, 'Bad Request') if runnable_bits.nil? or runnable_bits[0] != 'Workflow'
+# return rest_response(400) if experiment_bits.nil? or experiment_bits[0] != 'Experiment'
+# return rest_response(400) if runner_bits.nil? or runner_bits[0] != 'Runner'
+# return rest_response(400) if runnable_bits.nil? or runnable_bits[0] != 'Workflow'
#
# experiment = Experiment.find_by_id(experiment_bits[1].to_i)
# runner = TavernaEnactor.find_by_id(runner_bits[1].to_i)
# runnable = Workflow.find_by_id(runnable_bits[1].to_i)
#
-# return rest_error_response(400, 'Bad Request') if experiment.nil? or not Authorization.is_authorized?('edit', nil, experiment, user)
-# return rest_error_response(400, 'Bad Request') if runner.nil? or not Authorization.is_authorized?('download', nil, runner, user)
-# return rest_error_response(400, 'Bad Request') if runnable.nil? or not Authorization.is_authorized?('view', nil, runnable, user)
+# return rest_response(400) if experiment.nil? or not Authorization.is_authorized?('edit', nil, experiment, user)
+# return rest_response(400) if runner.nil? or not Authorization.is_authorized?('download', nil, runner, user)
+# return rest_response(400) if runnable.nil? or not Authorization.is_authorized?('view', nil, runnable, user)
#
# puts "#{params[:job]}"
#
@@ -613,13 +781,13 @@
#
# success = job.submit_and_run!
#
-# return rest_error_response(200, 'Failed to submit job') if not success
+# return rest_response(500) if not success
#
# return "<yes/>"
#
# end
-def search(rules, user, query)
+def search(req_uri, rules, user, query)
search_query = query['query']
@@ -654,10 +822,11 @@
doc = XML::Document.new
doc.root = root
- doc
+
+ render(:xml => doc.to_s)
end
-def user_count(rules, user, query)
+def user_count(req_uri, rules, user, query)
users = User.find(:all).select do |user| user.activated? end
@@ -667,21 +836,37 @@
doc = XML::Document.new
doc.root = root
- doc
+ render(:xml => doc.to_s)
end
-def group_count(rules, user, query)
+def group_count(req_uri, rules, user, query)
root = XML::Node.new('group-count')
root << Network.count.to_s
doc = XML::Document.new
doc.root = root
- doc
+
+ render(:xml => doc.to_s)
end
-def pack_count(rules, user, query)
+def workflow_count(req_uri, rules, user, query)
+ workflows = Workflow.find(:all).select do |w|
+ Authorization.is_authorized?('view', nil, w, user)
+ end
+
+ root = XML::Node.new('workflow-count')
+ root << workflows.length.to_s
+
+ doc = XML::Document.new
+ doc.root = root
+
+ render(:xml => doc.to_s)
+end
+
+def pack_count(req_uri, rules, user, query)
+
packs = Pack.find(:all).select do |p|
Authorization.is_authorized?('view', nil, p, user)
end
@@ -691,12 +876,13 @@
doc = XML::Document.new
doc.root = root
- doc
+
+ render(:xml => doc.to_s)
end
-def get_tagged(rules, user, query)
+def get_tagged(req_uri, rules, user, query)
- return rest_error_response(400, 'Bad Request') if query['tag'].nil?
+ return rest_response(400) if query['tag'].nil?
tag = Tag.find_by_name(query['tag'])
@@ -705,10 +891,10 @@
# filter out ones they are not allowed to get
obs = (obs.select do |c| c.respond_to?('contribution') == false or Authorization.is_authorized?("index", nil, c, user) end)
- produce_rest_list(rules, query, obs, 'tagged')
+ produce_rest_list("tagged", rules, query, obs, 'tagged', user)
end
-def tag_cloud(rules, user, query)
+def tag_cloud(req_uri, rules, user, query)
num = 25
type = nil
@@ -743,53 +929,89 @@
root << tag_node
end
- doc
+ render(:xml => doc.to_s)
end
-def post_comment(rules, user, query)
+def whoami_redirect(req_uri, rules, user, query)
+ if user.class == User
+ rest_response(307, :location => rest_access_uri(user))
+ else
+ rest_response(401)
+ end
+end
- title = params[:comment][:title]
- text = params[:comment][:comment]
- resource = params[:comment][:resource]
+def parse_element(doc, kind, query)
+ case kind
+ when :text
+ el = doc.find_first("#{query}/text()")
+ return el.to_s if el
+ when :binary
+ el = doc.find_first("#{query}/text()")
+ return Base64::decode64(el.to_s) if el
+ when :resource
+ return resolve_resource_node(doc.find_first(query))
+ end
+end
- title = '' if title.nil?
+# Comments
- resource_bits = parse_resource_uri(params["comment"]["resource"])
+def comment_aux(action, req_uri, rules, user, query)
- return rest_error_response(400, 'Bad Request') if user.nil?
- return rest_error_response(400, 'Bad Request') if text.nil? or text.length.zero?
- return rest_error_response(400, 'Bad Request') if resource_bits.nil?
+ # Obtain object
- return rest_error_response(400, 'Bad Request') unless ['Blob', 'Network', 'Pack', 'Workflow'].include?(resource_bits[0])
+ case action
+ when 'create':
+ return rest_response(401) unless Authorization.is_authorized_for_type?('create', 'Comment', user, nil)
- resource = eval(resource_bits[0]).find_by_id(resource_bits[1].to_i)
+ ob = Comment.new(:user => user)
+ when 'read', 'update', 'destroy':
+ ob = obtain_rest_resource('Comment', query['id'], user, action)
+ else
+ raise "Invalid action '#{action}'"
+ end
- comment = Comment.create(:user => user, :comment => text)
- resource.comments << comment
+ return if ob.nil? # appropriate rest response already given
- rest_get_request(comment, "comment", user, rest_resource_uri(comment), "comment", { "id" => comment.id.to_s })
+ 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
+
+ rest_get_request(ob, "comment", user, rest_resource_uri(ob), "comment", { "id" => ob.id.to_s })
end
-# def put_comment(rules, user, query)
-# end
-#
-# def delete_comment(rules, user, query)
-#
-# return rest_error_response(400, 'Bad Request') if query['id'].nil?
-#
-# resource = Comment.find_by_id(query['id'])
-#
-# return rest_error_response(404, 'Resource Not Found') if resource.nil?
-#
-# FIXME: The following respond_to? would not work anymore
-#
-# if resource.respond_to?('authorized?')
-# return rest_error_response(403, 'Not Authorized') if not Authorization.is_authorized?('edit', nil, resource, user)
-# end
-#
-# end
+def post_comment(req_uri, rules, user, query)
+ comment_aux('create', req_uri, rules, user, query)
+end
-def rest_call_request(rules, user, query)
- eval("#{rules['Function']}(rules, user, query)")
+def put_comment(req_uri, rules, user, query)
+ comment_aux('update', req_uri, rules, user, query)
end
+def delete_comment(req_uri, rules, user, query)
+ comment_aux('destroy', req_uri, rules, user, query)
+end
+
+# Call dispatcher
+
+def rest_call_request(req_uri, rules, user, query)
+ eval("#{rules['Function']}(req_uri, rules, user, query)")
+end
+
Modified: branches/apace/lib/workflow_processors/interface.rb (2144 => 2145)
--- branches/apace/lib/workflow_processors/interface.rb 2009-03-29 13:50:59 UTC (rev 2144)
+++ branches/apace/lib/workflow_processors/interface.rb 2009-03-29 13:56:05 UTC (rev 2145)
@@ -46,10 +46,14 @@
false
end
- def self.can_generate_preview?
+ def self.can_generate_preview_image?
false
end
+ def self.can_generate_preview_svg?
+ false
+ end
+
# End Class Methods
@@ -74,10 +78,14 @@
nil
end
- def get_preview_images
+ def get_preview_image
nil
end
+ def get_preview_svg
+ nil
+ end
+
def get_workflow_model_object
nil
end
Modified: branches/apace/lib/workflow_processors/taverna2_beta.rb (2144 => 2145)
--- branches/apace/lib/workflow_processors/taverna2_beta.rb 2009-03-29 13:50:59 UTC (rev 2144)
+++ branches/apace/lib/workflow_processors/taverna2_beta.rb 2009-03-29 13:56:05 UTC (rev 2145)
@@ -45,10 +45,14 @@
false
end
- def self.can_generate_preview?
+ def self.can_generate_preview_image?
false
end
+ def self.can_generate_preview_svg?
+ false
+ end
+
# End Class Methods
@@ -69,4 +73,4 @@
# End Instance Methods
end
-end
\ No newline at end of file
+end
Modified: branches/apace/lib/workflow_processors/taverna_scufl.rb (2144 => 2145)
--- branches/apace/lib/workflow_processors/taverna_scufl.rb 2009-03-29 13:50:59 UTC (rev 2144)
+++ branches/apace/lib/workflow_processors/taverna_scufl.rb 2009-03-29 13:56:05 UTC (rev 2145)
@@ -63,10 +63,14 @@
true
end
- def self.can_generate_preview?
+ def self.can_generate_preview_image?
true
end
+ def self.can_generate_preview_svg?
+ true
+ end
+
# End Class Methods
@@ -94,30 +98,42 @@
return @scufl_model.description.description
end
- def get_preview_images
- return nil if @scufl_model.nil?
+ def get_preview_image
+ return nil if @scufl_model.nil? || RUBY_PLATFORM =~ /mswin32/
+
+ title = @scufl_model.description.title.blank? ? "untitled" : @scufl_model.description.title
+ filename = title.gsub(/[^\w\.\-]/,'_').downcase
- if RUBY_PLATFORM =~ /mswin32/
- return nil
- else
- title = @scufl_model.description.title.blank? ? "untitled" : @scufl_model.description.title
- filename = title.gsub(/[^\w\.\-]/,'_').downcase
-
- i = Tempfile.new("image")
- Scufl::Dot.new.write_dot(i, @scufl_model)
- i.close(false)
- img = StringIO.new(`dot -Tpng #{i.path}`)
- svg = StringIO.new(`dot -Tsvg #{i.path}`)
- img.extend FileUpload
- img.original_filename = "#{filename}.png"
- img.content_type = "image/png"
- svg.extend FileUpload
- svg.original_filename = "#{filename}.svg"
- svg.content_type = "image/svg+xml"
- return [img, svg]
- end
+ i = Tempfile.new("image")
+ Scufl::Dot.new.write_dot(i, @scufl_model)
+ i.close(false)
+
+ img = StringIO.new(`dot -Tpng #{i.path}`)
+ img.extend FileUpload
+ img.original_filename = "#{filename}.png"
+ img.content_type = "image/png"
+
+ img
end
-
+
+ def get_preview_svg
+ return nil if @scufl_model.nil? || RUBY_PLATFORM =~ /mswin32/
+
+ title = @scufl_model.description.title.blank? ? "untitled" : @scufl_model.description.title
+ filename = title.gsub(/[^\w\.\-]/,'_').downcase
+
+ i = Tempfile.new("image")
+ Scufl::Dot.new.write_dot(i, @scufl_model)
+ i.close(false)
+
+ svg = StringIO.new(`dot -Tsvg #{i.path}`)
+ svg.extend FileUpload
+ svg.original_filename = "#{filename}.svg"
+ svg.content_type = "image/svg+xml"
+
+ svg
+ end
+
def get_workflow_model_object
@scufl_model
end
Modified: branches/apace/lib/workflow_processors/trident_opc.rb (2144 => 2145)
--- branches/apace/lib/workflow_processors/trident_opc.rb 2009-03-29 13:50:59 UTC (rev 2144)
+++ branches/apace/lib/workflow_processors/trident_opc.rb 2009-03-29 13:56:05 UTC (rev 2145)
@@ -45,10 +45,14 @@
false
end
- def self.can_generate_preview?
+ def self.can_generate_preview_image?
false
end
+ def self.can_generate_preview_svg?
+ false
+ end
+
# End Class Methods
@@ -69,4 +73,4 @@
# End Instance Methods
end
-end
\ No newline at end of file
+end
Modified: branches/apace/lib/workflow_processors/trident_xoml.rb (2144 => 2145)
--- branches/apace/lib/workflow_processors/trident_xoml.rb 2009-03-29 13:50:59 UTC (rev 2144)
+++ branches/apace/lib/workflow_processors/trident_xoml.rb 2009-03-29 13:56:05 UTC (rev 2145)
@@ -45,10 +45,14 @@
false
end
- def self.can_generate_preview?
+ def self.can_generate_preview_image?
false
end
+ def self.can_generate_preview_svg?
+ false
+ end
+
# End Class Methods
@@ -69,4 +73,4 @@
# End Instance Methods
end
-end
\ No newline at end of file
+end
Modified: branches/apace/vendor/plugins/acts_as_taggable_redux/lib/tagging.rb (2144 => 2145)
--- branches/apace/vendor/plugins/acts_as_taggable_redux/lib/tagging.rb 2009-03-29 13:50:59 UTC (rev 2144)
+++ branches/apace/vendor/plugins/acts_as_taggable_redux/lib/tagging.rb 2009-03-29 13:56:05 UTC (rev 2145)
@@ -10,4 +10,8 @@
:order => "created_at DESC",
:limit => limit)
end
-end
\ No newline at end of file
+
+ def label
+ return tag.name if tag
+ end
+end