Merge remote-tracking branch 'origin/master' into 2044-share-button
authorPeter Amstutz <peter.amstutz@curoverse.com>
Thu, 22 May 2014 20:30:34 +0000 (16:30 -0400)
committerPeter Amstutz <peter.amstutz@curoverse.com>
Thu, 22 May 2014 20:30:34 +0000 (16:30 -0400)
apps/workbench/app/controllers/collections_controller.rb
apps/workbench/app/views/collections/_sharing_button.html.erb [new file with mode: 0644]
apps/workbench/app/views/collections/_sharing_popup.html.erb [new file with mode: 0644]
apps/workbench/app/views/collections/_show_files.html.erb
apps/workbench/app/views/collections/sharing_popup.js.erb [new file with mode: 0644]
apps/workbench/app/views/collections/show.html.erb
apps/workbench/config/routes.rb
services/api/app/controllers/arvados/v1/api_client_authorizations_controller.rb
services/api/app/models/arvados_model.rb

index 3b4943f5889a1910815417157c351aa5f1ad7704..3e981e10d8b94de9e64c6b83029fc42495ebb55c 100644 (file)
@@ -120,6 +120,14 @@ class CollectionsController < ApplicationController
     self.response_body = file_enumerator opts
   end
 
+  def sharing_scopes
+    ["GET /arvados/v1/collections/#{@object.uuid}", "GET /arvados/v1/keep_services"]
+  end
+
+  def search_scopes
+    ApiClientAuthorization.where(filters: [['scopes', '=', sharing_scopes]])
+  end
+
   def show
     return super if !@object
     if current_user
@@ -142,6 +150,7 @@ class CollectionsController < ApplicationController
         .where(head_uuid: @object.uuid, tail_uuid: current_user.uuid,
                link_class: 'resources', name: 'wants')
         .results.any?
+      @search_sharing = search_scopes.select { |s| s.scopes != ['all'] }
     end
     @prov_svg = ProvenanceHelper::create_provenance_graph(@object.provenance, "provenance_svg",
                                                           {:request => request,
@@ -154,6 +163,29 @@ class CollectionsController < ApplicationController
                                                                :pdata_only => true}) rescue nil
   end
 
+  def sharing_popup
+    @search_sharing = search_scopes.select { |s| s.scopes != ['all'] }
+    respond_to do |format|
+      format.html
+      format.js
+    end
+  end
+
+  def share
+    a = ApiClientAuthorization.create(scopes: sharing_scopes)
+    @search_sharing = search_scopes.select { |s| s.scopes != ['all'] }
+    render 'sharing_popup'
+  end
+
+  def unshare
+    @search_sharing = search_scopes.select { |s| s.scopes != ['all'] }
+    @search_sharing.each do |s|
+      s.destroy
+    end
+    @search_sharing = search_scopes.select { |s| s.scopes != ['all'] }
+    render 'sharing_popup'
+  end
+
   protected
 
   def find_usable_token(token_list)
diff --git a/apps/workbench/app/views/collections/_sharing_button.html.erb b/apps/workbench/app/views/collections/_sharing_button.html.erb
new file mode 100644 (file)
index 0000000..36952d6
--- /dev/null
@@ -0,0 +1,8 @@
+<% if @search_sharing.any? %>
+  <% linktext = "Shared" %>
+  <% btnstyle = "btn-success" %>
+<% else %>
+  <% linktext = "Share" %>
+  <% btnstyle = "btn-info" %>
+<% end %>
+<%= link_to linktext, sharing_popup_collection_url(id: @object.uuid),  {class: "btn #{btnstyle}", :remote => true, 'data-toggle' =>  "modal", 'data-target' => '#collection-sharing-modal-window'}  %>
diff --git a/apps/workbench/app/views/collections/_sharing_popup.html.erb b/apps/workbench/app/views/collections/_sharing_popup.html.erb
new file mode 100644 (file)
index 0000000..f7f0555
--- /dev/null
@@ -0,0 +1,37 @@
+
+<div class="modal-dialog">
+  <div class="modal-content">
+    <div class="modal-header">
+      <button type="button" class="close" onClick="reset_form()" data-dismiss="modal" aria-hidden="true">&times;</button>
+      <h4 class="modal-title">Sharing</h4>
+    </div>
+    <div class="modal-body">
+      <div id="sharing-text" style="text-align: center; word-wrap: break-word">
+        <% if @search_sharing.any? %>
+          Use this link to share this collection:<br>
+          <big>
+          <% link = collections_url + "/download/#{@object.uuid}/#{@search_sharing.first.api_token}" %>
+          <%= link_to link, link %>
+          </big>
+        <% else %>
+          Not shared.
+        <% end %>
+      </div>
+      <div style="text-align: center; padding-top: 1em">
+      <% if @search_sharing and @search_sharing.any? %>
+        <%= link_to "Unshare", unshare_collection_url, {
+            class: 'btn btn-success',
+              remote: true,
+            method: 'post'
+            } %>
+      <% else %>
+        <%= link_to "Share", share_collection_url, {
+              class: 'btn btn-info',
+              remote: true,
+              method: 'post'
+            } %>
+      <% end %>
+      </div>
+    </div>
+  </div>
+</div>
index c5c12792ce6890371a2c6ac3d99914ae94fd7787..74e02f79fe0c87a18a56b99dfa6c5ab3e0c645ff 100644 (file)
@@ -3,8 +3,9 @@
   <div class="col-md-6"></div>
   <div class="col-md-6">
     <div class="pull-right">
-      Collection storage status:
+      <span style="padding-left: 1em">Collection storage status:</span>
       <%= render partial: 'toggle_persist', locals: { uuid: @object.uuid, current_state: (@is_persistent ? 'persistent' : 'cache') } %>
+
     </div>
   </div>
 </div>
@@ -66,3 +67,7 @@
   <% end  # file_tree.each %>
   <%= raw(dirstack.map { |_| "</ul>" }.join("</li>")) %>
 <% end  # if file_tree %>
+
+<% content_for :footer_html do %>
+<div id="collection-sharing-modal-window" class="modal fade" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"></div>
+<% end %>
diff --git a/apps/workbench/app/views/collections/sharing_popup.js.erb b/apps/workbench/app/views/collections/sharing_popup.js.erb
new file mode 100644 (file)
index 0000000..933f08d
--- /dev/null
@@ -0,0 +1,2 @@
+$("#collection-sharing-modal-window").html("<%= escape_javascript(render partial: 'sharing_popup') %>");
+$("#sharing-button").html("<%= escape_javascript(render partial: 'sharing_button') %>");
index 9fc67ac4cdd4744c56e6767637c10820d4b7217c..c26b74c65a3d77bc000638730af8211f0d2ba40e 100644 (file)
         <!--
        <input type="text" class="form-control" placeholder="Search"/>
         -->
+
+        <div id="sharing-button" style="text-align: center">
+          <%= render partial: 'sharing_button' %>
+        </div>
+
        <div style="height:0.5em;"></div>
         <% if @folders.andand.any? %>
           <p>Included in folders:<br />
           <% end %>
           </p>
         <% end %>
+
       </div>
     </div>
   </div>
index c12cc989d71cd182ac16003909c67e21cecfa04d..6e3d66b86b252a0339b89561c5b8ac5f2e04c974 100644 (file)
@@ -43,6 +43,9 @@ ArvadosWorkbench::Application.routes.draw do
   get '/collections/graph' => 'collections#graph'
   resources :collections do
     post 'set_persistent', on: :member
+    get 'sharing_popup', :on => :member
+    post 'share', :on => :member
+    post 'unshare', :on => :member
   end
   get('/collections/download/:uuid/:reader_token/*file' => 'collections#show_file',
       format: false)
index dc95b2f01da12c00645226f60824468a73eac6ed..4a2bafde04eda0dc6c3639d963796a1d95734c8a 100644 (file)
@@ -27,6 +27,8 @@ class Arvados::V1::ApiClientAuthorizationsController < ApplicationController
       # translate UUID to numeric ID here.
       resource_attrs[:user_id] =
         User.where(uuid: resource_attrs.delete(:owner_uuid)).first.andand.id
+    elsif not resource_attrs[:user_id]
+      resource_attrs[:user_id] = current_user.id
     end
     resource_attrs[:api_client_id] = Thread.current[:api_client].id
     super
index bfd228e5e0441725676dd3c720cd62149e555fca..adff09d53c45de9ebf03593418723b822b7f81bc 100644 (file)
@@ -191,25 +191,16 @@ class ArvadosModel < ActiveRecord::Base
       self.owner_uuid ||= current_user.uuid
     end
     if self.owner_uuid_changed?
-      if current_user.uuid == self.owner_uuid or
+      if new_record?
+        return true
+      elsif current_user.uuid == self.owner_uuid or
           current_user.can? write: self.owner_uuid
         # current_user is, or has :write permission on, the new owner
       else
-        logger.warn "User #{current_user.uuid} tried to change owner_uuid of #{self.class.to_s} #{self.uuid} to #{self.owner_uuid} but does not have permission to write to #{self.owner_uuid}"
+        logger.warn "User #{current_user.uuid} tried to modify #{self.class.to_s} #{self.uuid} but does not have permission to write #{self.owner_uuid_was}"
         raise PermissionDeniedError
       end
     end
-    if new_record?
-      return true
-    elsif current_user.uuid == self.owner_uuid_was or
-        current_user.uuid == self.uuid or
-        current_user.can? write: self.owner_uuid_was
-      # current user is, or has :write permission on, the previous owner
-      return true
-    else
-      logger.warn "User #{current_user.uuid} tried to modify #{self.class.to_s} #{self.uuid} but does not have permission to write #{self.owner_uuid_was}"
-      raise PermissionDeniedError
-    end
   end
 
   def ensure_permission_to_save