From d8cf724056959be050083f386237789b5a264804 Mon Sep 17 00:00:00 2001 From: natacha-beck Date: Thu, 21 Aug 2025 05:15:33 -0400 Subject: [PATCH 01/11] [WIP] new/show DP --- .../controllers/data_providers_controller.rb | 8 +- .../app/views/data_providers/show.html.erb | 349 +++++++++--------- 2 files changed, 186 insertions(+), 171 deletions(-) diff --git a/BrainPortal/app/controllers/data_providers_controller.rb b/BrainPortal/app/controllers/data_providers_controller.rb index b39726684..80062ca76 100644 --- a/BrainPortal/app/controllers/data_providers_controller.rb +++ b/BrainPortal/app/controllers/data_providers_controller.rb @@ -64,6 +64,8 @@ def show #:nodoc: @provider = DataProvider.find(data_provider_id) cb_notice "Provider not accessible by current user." unless @provider.can_be_accessed_by?(current_user) + @typelist = get_type_list + respond_to do |format| format.html # show.html.erb format.xml { @@ -77,6 +79,7 @@ def show #:nodoc: def new #:nodoc: provider_group_id = current_assignable_group.id + @unsaved_meta = {} @provider = DataProvider.new( :user_id => current_user.id, :group_id => provider_group_id, :online => true, @@ -84,12 +87,15 @@ def new #:nodoc: ) @typelist = get_type_list + + render :action => :show # our show is also edit/create end def create #:nodoc: @provider = DataProvider.sti_new(data_provider_params) @provider.user_id ||= current_user.id # disabled field in form DOES NOT send value! @provider.group_id ||= current_assignable_group.id + @unsaved_meta = params[:meta] || {} if @provider.save add_meta_data_from_form(@provider, [:must_move, :no_uploads, :no_viewers, :browse_gid]) @@ -103,7 +109,7 @@ def create #:nodoc: else @typelist = get_type_list respond_to do |format| - format.html { render :action => :new } + format.html { render :action => :show } format.xml { render :xml => @provider.errors, :status => :unprocessable_entity } format.json { render :json => @provider.errors, :status => :unprocessable_entity } end diff --git a/BrainPortal/app/views/data_providers/show.html.erb b/BrainPortal/app/views/data_providers/show.html.erb index fd5de1b3d..56dd1d383 100644 --- a/BrainPortal/app/views/data_providers/show.html.erb +++ b/BrainPortal/app/views/data_providers/show.html.erb @@ -22,40 +22,43 @@ # -%> -<% title 'Data Provider Info' %> +<% is_new_record = @provider.new_record? %> +<% title is_new_record ? 'Create Data Provider' : 'Data Provider Info' %> + <% has_owner_access = (check_role(:admin_user) || @provider.user_id == current_user.id) %> <% is_userkey_dp = @provider.is_a?(UserkeyFlatDirSshDataProvider) %> <% needs_ssh_config = @provider.is_a?(SshDataProvider) || @provider.is_a?(SmartDataProviderInterface) %>

@@ -64,211 +67,215 @@

- <%= show_table(@provider, :as => :data_provider, :edit_condition => has_owner_access) do |t| %> +<%= show_table_context(@provider) do |cf| %> - <% t.edit_cell(:name) do |f| %> - <%= f.text_field :name %> - <% end %> + <%= show_table(@provider, :form_helper => cf, :as => :data_provider, :edit_condition => has_owner_access) do |t| %> - <% t.edit_cell(:description, :content => full_description(@provider.description)) do |f| %> - <%= f.text_area :description, :rows => 10, :cols => 40 %>
- <% end %> - - <% if has_owner_access %> - <% t.attribute_cell(:type) %> - <% else %> - <% t.empty_cell %> - <% end %> - - <% t.edit_cell(:online, :content => (@provider.online ? "Online" : "Offline")) do |f| %> - <%= f.select :online, [["Online", true], ["Offline", false]] %> - <% end %> - - <% t.edit_cell(:user_id, :header => "Owner", :content => link_to_user_with_tooltip(@provider.user), :disabled => ! current_user.has_role?(:admin_user) ) do %> - <%= user_select("data_provider[user_id]", { :selector => @provider } ) %> - <% end %> - - <% t.edit_cell(:read_only, :content => (@provider.read_only ? "Read Only" : "Read/Write"), :header => "Mode") do |f| %> - <%= f.select :read_only, [["Read/Write", false], ["Read Only", true]] %> - <% end %> + <% t.edit_cell(:name) do |f| %> + <%= f.text_field :name %> + <% end %> - <% t.edit_cell(:group_id, :header => "Project", :content => link_to_group_if_accessible(@provider.group) ) do %> - <%= group_select("data_provider[group_id]", { :selector => @provider }) %> - <% end %> + <% t.edit_cell(:description, :content => full_description(@provider.description)) do |f| %> + <%= f.text_area :description, :rows => 10, :cols => 40 %>
+ <% end %> - <% t.edit_cell(:not_syncable, :content => (@provider.not_syncable ? "NOT syncable" : "Fully syncable"), :header => "Syncability") do |f| %> - <%= f.select :not_syncable, [["Fully syncable", false], ["NOT syncable", true]] %> - <% end %> + <% if has_owner_access || is_new_record %> + <% t.edit_cell(:type, :content => @provider.type) do |f| %> + <%= f.select :type, grouped_options_for_select(@typelist, @provider.type) %> + <% end %> + <% else %> + <% t.empty_cell %> + <% end %> - <% if current_user.has_role?(:admin_user) %> - <% t.cell("Revision Info (DataProvider)", :show_width => 2) { DataProvider.revision_info.format() } %> - <% t.cell("Revision Info (#{@provider.type})", :show_width => 2) { @provider.revision_info.format() } %> - <% end %> + <% t.edit_cell(:online, :content => (@provider.online ? "Online" : "Offline")) do |f| %> + <%= f.select :online, [["Online", true], ["Offline", false]] %> + <% end %> - <% if ! is_userkey_dp %> - <% t.edit_cell(:time_zone, :content => (@provider.time_zone || "(Unset)"), :show_width => 2 ) do |f| %> - <%= f.select :time_zone, time_zone_options_for_select(@provider.time_zone, /canada/i), :include_blank => true %> + <% t.edit_cell(:user_id, :header => "Owner", :content => link_to_user_with_tooltip(@provider.user), :disabled => ! current_user.has_role?(:admin_user) ) do %> + <%= user_select("data_provider[user_id]", { :selector => @provider } ) %> <% end %> - <% end %> - <% if has_owner_access %> - <% t.edit_cell(:remote_dir, :header => "Physical Data Location", :show_width => 2) do |f| %> - <%= f.text_field :remote_dir, :size => 80 %> + <% t.edit_cell(:read_only, :content => (@provider.read_only ? "Read Only" : "Read/Write"), :header => "Mode") do |f| %> + <%= f.select :read_only, [["Read/Write", false], ["Read Only", true]] %> <% end %> - <% end %> - <% if current_user.has_role?(:admin_user) %> - <% joint_licenses = @provider.license_agreements.join("\n") %> - <% licenses = @provider.license_agreements.count == 0 ? "(None)": @provider.license_agreements.join("\n") %> - <% t.edit_cell(:license_agreements, :content => licenses, :show_width => 2) do |f| %> - <%= f.text_area :license_agreements, :value => joint_licenses, :content => joint_licenses, :rows => 5, :cols => 40 %>
-
Enter one agreement name per line. Note that only alphanumeric characters, underscores (_) and dashes (-) are accepted.
- <% end %> - <% else %> - <% t.empty_cell %> - <% end %> + <% t.edit_cell(:group_id, :header => "Project", :content => link_to_group_if_accessible(@provider.group) ) do %> + <%= group_select("data_provider[group_id]", { :selector => @provider }) %> + <% end %> - <% end %> + <% t.edit_cell(:not_syncable, :content => (@provider.not_syncable ? "NOT syncable" : "Fully syncable"), :header => "Syncability") do |f| %> + <%= f.select :not_syncable, [["Fully syncable", false], ["NOT syncable", true]] %> + <% end %> - <% if has_owner_access && needs_ssh_config %> - <%= show_table(@provider, :as => :data_provider, :header => "SSH parameters", :edit_condition => true) do |t| %> - <% t.edit_cell(:remote_host, :show_width => 2) do |f| %> - <%= f.text_field :remote_host, :size => 40 %> + <% if current_user.has_role?(:admin_user) %> + <% t.cell("Revision Info (DataProvider)", :show_width => 2) { DataProvider.revision_info.format() } %> + <% t.cell("Revision Info (#{@provider.type})", :show_width => 2) { @provider.revision_info.format() } %> <% end %> - <% if check_role(:admin_user) %> - <% t.edit_cell(:alternate_host, :show_width => 2, :header => "Alternate hostname(s)") do |f| %> - <%= f.text_field :alternate_host, :size => 100 %>
-
Comma-separated list of alternate hostnames; hostname1,hostname2,hostname3,...
+ + <% if ! is_userkey_dp %> + <% t.edit_cell(:time_zone, :content => (@provider.time_zone || "(Unset)"), :show_width => 2 ) do |f| %> + <%= f.select :time_zone, time_zone_options_for_select(@provider.time_zone, /canada/i), :include_blank => true %> <% end %> <% end %> - <% t.edit_cell(:remote_user) do |f| %> - <%= f.text_field :remote_user, :size => 40 %> + + <% if has_owner_access || is_new_record %> + <% t.edit_cell(:remote_dir, :header => "Physical Data Location", :show_width => 2) do |f| %> + <%= f.text_field :remote_dir, :size => 80 %> + <% end %> <% end %> - <% t.edit_cell(:remote_port) do |f| %> - <%= f.text_field :remote_port, :size => 6 %> + + <% if current_user.has_role?(:admin_user) %> + <% joint_licenses = @provider.license_agreements.join("\n") %> + <% licenses = @provider.license_agreements.count == 0 ? "(None)": @provider.license_agreements.join("\n") %> + <% t.edit_cell(:license_agreements, :content => licenses, :show_width => 2) do |f| %> + <%= f.text_area :license_agreements, :value => joint_licenses, :content => joint_licenses, :rows => 5, :cols => 40 %>
+
Enter one agreement name per line. Note that only alphanumeric characters, underscores (_) and dashes (-) are accepted.
+ <% end %> + <% else %> + <% t.empty_cell %> <% end %> + <% end %> - <% end %> - <% if @provider.is_a?(SingSquashfsDataProvider) || @provider.is_a?(SingBindmountDataProvider) %> - <%= show_table(@provider, :as => :data_provider, :header => "Containerized Storage Configuration", :edit_condition => true) do |t| %> - <% t.edit_cell(:containerized_path, :header => 'Containerized Data Path', :show_width => 2) do %> - <%= text_field_tag "data_provider[containerized_path]", @provider.containerized_path, :size => 80 %> + <% if (has_owner_access && needs_ssh_config) || is_new_record %> + <%= show_table(@provider, :form_helper => cf, :as => :data_provider, :header => "SSH parameters", :edit_condition => true) do |t| %> + <% t.edit_cell(:remote_host, :show_width => 2) do |f| %> + <%= f.text_field :remote_host, :size => 40 %> + <% end %> + <% if check_role(:admin_user) %> + <% t.edit_cell(:alternate_host, :show_width => 2, :header => "Alternate hostname(s)") do |f| %> + <%= f.text_field :alternate_host, :size => 100 %>
+
Comma-separated list of alternate hostnames; hostname1,hostname2,hostname3,...
+ <% end %> + <% end %> + <% t.edit_cell(:remote_user) do |f| %> + <%= f.text_field :remote_user, :size => 40 %> + <% end %> + <% t.edit_cell(:remote_port) do |f| %> + <%= f.text_field :remote_port, :size => 6 %> + <% end %> <% end %> <% end %> - <% end %> - <% if @provider.is_a?(S3DataProvider) || @provider.is_a?(S3FlatDataProvider) %> - <%= show_table(@provider, :as => :data_provider, :header => "Cloud Storage Configuration", :edit_condition => true) do |t| %> - <% t.edit_cell(:cloud_storage_client_identifier, :header => 'Client Identifier', :show_width => 2) do |f| %> - <%= f.text_field :cloud_storage_client_identifier, :size => 40, :autocomplete => 'off' %> - <% end %> - <% t.edit_cell(:cloud_storage_client_token, :content => '****************', :header => 'Client Token', :show_width => 2) do |f| %> - <%= f.password_field :cloud_storage_client_token, :size => 80, :autocomplete => 'off' %> - <% end %> - <% t.edit_cell(:cloud_storage_client_bucket_name, :header => 'Client Bucket Name', :show_width => 2) do %> - <%= text_field_tag "data_provider[cloud_storage_client_bucket_name]", @provider.cloud_storage_client_bucket_name, :size => 80 %> - <% end %> - <% t.edit_cell(:cloud_storage_client_path_start, :header => 'Client Starting Path', :show_width => 2) do %> - <%= text_field_tag "data_provider[cloud_storage_client_path_start]", @provider.cloud_storage_client_path_start, :size => 80 %> - <% end %> - <% t.edit_cell(:cloud_storage_endpoint, :header => 'Endpoint', :show_width => 2) do %> - <%= text_field_tag "data_provider[cloud_storage_endpoint]", @provider.cloud_storage_endpoint, :size => 80 %> - <% end %> - <% t.edit_cell(:cloud_storage_region, :header => 'Region', :show_width => 2) do %> - <%= text_field_tag "data_provider[cloud_storage_region]", @provider.cloud_storage_region, :size => 80 %> + <% if (@provider.is_a?(SingSquashfsDataProvider) || @provider.is_a?(SingBindmountDataProvider)) || is_new_record %> + <%= show_table(@provider, :form_helper => cf, :as => :data_provider, :header => "Containerized Storage Configuration", :edit_condition => true) do |t| %> + <% t.edit_cell(:containerized_path, :header => 'Containerized Data Path', :show_width => 2) do %> + <%= text_field_tag "data_provider[containerized_path]", @provider.containerized_path, :size => 80 %> + <% end %> <% end %> <% end %> - <% end %> - <% if @provider.is_a?(DataladDataProvider) %> - <%= show_table(@provider, :as => :data_provider, :header => "Datalad Configuration", :edit_condition => true) do |t| %> - <% t.edit_cell(:datalad_repository_url, :header => 'Datalad Repository URL', :show_width => 2) do |f| %> - <%= f.text_field :datalad_repository_url %> + <% if (@provider.is_a?(S3DataProvider) || @provider.is_a?(S3FlatDataProvider)) || is_new_record %> + <%= show_table(@provider, :form_helper => cf, :as => :data_provider, :header => "Cloud Storage Configuration", :edit_condition => true) do |t| %> + <% t.edit_cell(:cloud_storage_client_identifier, :header => 'Client Identifier', :show_width => 2) do |f| %> + <%= f.text_field :cloud_storage_client_identifier, :size => 40, :autocomplete => 'off' %> + <% end %> + <% t.edit_cell(:cloud_storage_client_token, :content => '****************', :header => 'Client Token', :show_width => 2) do |f| %> + <%= f.password_field :cloud_storage_client_token, :size => 80, :autocomplete => 'off' %> + <% end %> + <% t.edit_cell(:cloud_storage_client_bucket_name, :header => 'Client Bucket Name', :show_width => 2) do %> + <%= text_field_tag "data_provider[cloud_storage_client_bucket_name]", @provider.cloud_storage_client_bucket_name, :size => 80 %> + <% end %> + <% t.edit_cell(:cloud_storage_client_path_start, :header => 'Client Starting Path', :show_width => 2) do %> + <%= text_field_tag "data_provider[cloud_storage_client_path_start]", @provider.cloud_storage_client_path_start, :size => 80 %> + <% end %> + <% t.edit_cell(:cloud_storage_endpoint, :header => 'Endpoint', :show_width => 2) do %> + <%= text_field_tag "data_provider[cloud_storage_endpoint]", @provider.cloud_storage_endpoint, :size => 80 %> + <% end %> + <% t.edit_cell(:cloud_storage_region, :header => 'Region', :show_width => 2) do %> + <%= text_field_tag "data_provider[cloud_storage_region]", @provider.cloud_storage_region, :size => 80 %> + <% end %> <% end %> - <% t.edit_cell(:datalad_relative_path, :header => 'Datalad Relative Path', :show_width => 2) do |f| %> - <%= f.text_field :datalad_relative_path %> + <% end %> + + <% if @provider.is_a?(DataladDataProvider) || is_new_record %> + <%= show_table(@provider, :form_helper => cf, :as => :data_provider, :header => "Datalad Configuration", :edit_condition => true) do |t| %> + <% t.edit_cell(:datalad_repository_url, :header => 'Datalad Repository URL', :show_width => 2) do |f| %> + <%= f.text_field :datalad_repository_url %> + <% end %> + <% t.edit_cell(:datalad_relative_path, :header => 'Datalad Relative Path', :show_width => 2) do |f| %> + <%= f.text_field :datalad_relative_path %> + <% end %> <% end %> <% end %> - <% end %> + <%= show_table(@provider, :form_helper => cf, :as => :data_provider, :header => "Other Properties", :edit_condition => (check_role(:admin_user) || @provider.user_id == current_user.id)) do |t| %> - <%= show_table(@provider, :as => :data_provider, :header => "Other Properties", :edit_condition => (check_role(:admin_user) || @provider.user_id == current_user.id)) do |t| %> + <% t.boolean_edit_cell("meta[no_uploads]", is_new_record ? @unsaved_meta[:no_uploads] || false : !@provider.meta[:no_uploads].blank? , "on", "", :header => "Cannot be used for uploading files in the file manager") %> - <% t.boolean_edit_cell("meta[no_uploads]", @provider.meta["no_uploads"], "on", "", :header => "Cannot be used for uploading files in the file manager") %> + <% t.boolean_edit_cell("meta[no_viewers]", is_new_record ? @unsaved_meta[:no_viewers] || false : !@provider.meta[:no_viewers].blank? , "on", "", :header => "Files cannot be viewed in the file manager") %> - <% t.boolean_edit_cell("meta[no_viewers]", @provider.meta["no_viewers"], "on", "", :header => "Files cannot be viewed in the file manager") %> + <% if @provider.is_browsable? || is_new_record %> - <% if @provider.is_browsable? %> + <% t.boolean_edit_cell("meta[must_move]", is_new_record ? @unsaved_meta[:must_move] || false : !@provider.meta[:must_move].blank? , "on", "", :header => "Files must be copied/moved upon registration") %> - <% t.boolean_edit_cell("meta[must_move]", @provider.meta["must_move"], "on", "", :header => "Files must be copied/moved upon registration") %> + <% browse_gid = !is_new_record ? @provider.meta[:browse_gid].present? : (@unsaved_meta && @unsaved_meta[:browse_gid].present?) %> + <% t.edit_cell("meta[browse_gid]", + :header => "Files can be browsed only by members of this project", + :content => !is_new_record && browse_gid ? link_to_group_if_accessible(@provider.meta[:browse_gid]) : '(Any Users)', + :show_width => 2 + ) do %> + <%= group_select 'meta[browse_gid]', { :selector => (is_new_record ? @unsaved_meta[:browse_gid] : @provider.meta[:browse_gid]) }, { :include_blank => "(Any Users)" } %> + <% end %> - <% t.edit_cell("meta[browse_gid]", - :header => "Files can be browsed only by members of this project", - :content => @provider.meta[:browse_gid].present? ? link_to_group_if_accessible(@provider.meta[:browse_gid]) : '(Any Users)', - :show_width => 2 - ) do %> - <%= group_select 'meta[browse_gid]', { :selector => @provider.meta[:browse_gid] }, { :include_blank => "(Any Users)" } %> <% end %> <% end %> - <% end %> + <% other_dps = DataProvider.find_all_accessible_by_user(current_user).reject { |dp| dp.id == @provider.id } %> + <% dps_by_category = other_dps.to_a.hashed_partitions { |dp| dp.is_browsable? ? :user : :official } %> - <% other_dps = DataProvider.find_all_accessible_by_user(current_user).reject { |dp| dp.id == @provider.id } %> - <% dps_by_category = other_dps.to_a.hashed_partitions { |dp| dp.is_browsable? ? :user : :official } %> + <% if other_dps.size > 0 %> - <% if other_dps.size > 0 %> - - <%= show_table(@provider, :as => :data_provider, :width => 5, :header => 'Files can be copied or moved to these other Data Providers', :edit_condition => (check_role(:admin_user) || @provider.user_id == current_user.id)) do |t| %> - <% if dps_by_category[:official] %> - <% t.row(:class => 'subheader') { "Official Storage".html_safe } %> - <% dps_by_category[:official].sort_by(&:name).each do |dp| %> - <% meta_key = "dp_no_copy_#{dp.id}" %> - <% t.boolean_edit_cell("meta[#{meta_key}]", @provider.meta[meta_key].to_s, "", "disabled", :header => "#{dp.name}", :class => 'checkbox_label') %> + <%= show_table(@provider, :form_helper => cf, :as => :data_provider, :width => 5, :header => 'Files can be copied or moved to these other Data Providers', :edit_condition => (check_role(:admin_user) || @provider.user_id == current_user.id)) do |t| %> + <% if dps_by_category[:official] %> + <% t.row(:class => 'subheader') { "Official Storage".html_safe } %> + <% dps_by_category[:official].sort_by(&:name).each do |dp| %> + <% meta_key = "dp_no_copy_#{dp.id}" %> + <% t.boolean_edit_cell("meta[#{meta_key}]", is_new_record ? @unsaved_meta[meta_key] || false : @provider.meta[meta_key].to_s, "", "disabled", :header => "#{dp.name}", :class => 'checkbox_label') %> + <% end%> <% end%> - <% end%> - <% t.blank_row %> + <% t.blank_row %> - <% if dps_by_category[:user] %> - <% t.row(:class => 'subheader') { "User or Site Storage".html_safe } %> - <% dps_by_category[:user].sort_by(&:name).each do |dp| %> - <% meta_key = "dp_no_copy_#{dp.id}" %> - <% t.boolean_edit_cell("meta[#{meta_key}]", @provider.meta[meta_key].to_s, "", "disabled", :header => "#{dp.name}", :class => 'checkbox_label') %> + <% if dps_by_category[:user] %> + <% t.row(:class => 'subheader') { "User or Site Storage".html_safe } %> + <% dps_by_category[:user].sort_by(&:name).each do |dp| %> + <% meta_key = "dp_no_copy_#{dp.id}" %> + <% t.boolean_edit_cell("meta[#{meta_key}]", is_new_record ? @unsaved_meta[meta_key] || false : @provider.meta[meta_key].to_s, "", "disabled", :header => "#{dp.name}", :class => 'checkbox_label') %> + <% end%> <% end%> <% end%> <% end%> - <% end%> - <% other_rrs = RemoteResource.find_all_accessible_by_user(current_user) %> - <% rrs_by_category = other_rrs.to_a.hashed_partitions { |rr| rr.is_a?(Bourreau) ? :bourreau : :portal } %> + <% other_rrs = RemoteResource.find_all_accessible_by_user(current_user) %> + <% rrs_by_category = other_rrs.to_a.hashed_partitions { |rr| rr.is_a?(Bourreau) ? :bourreau : :portal } %> - <% if other_rrs.size > 0 %> + <% if other_rrs.size > 0 %> - <%= show_table(@provider, :as => :data_provider, :width => 5, :header => 'File contents can be accessed by these Servers', :edit_condition => (check_role(:admin_user) || @provider.user_id == current_user.id)) do |t| %> - <% if rrs_by_category[:portal] %> - <% t.row(:class => 'subheader') { "Portals".html_safe } %> - <% rrs_by_category[:portal].sort_by(&:name).each do |rr| %> - <% meta_key = "rr_no_sync_#{rr.id}" %> - <% t.boolean_edit_cell("meta[#{meta_key}]", @provider.meta[meta_key].to_s, "", "#{rr.name} cannot sync #{@provider.name}", :header => "#{rr.name}", :class => 'checkbox_label') %> + <%= show_table(@provider, :form_helper => cf, :as => :data_provider, :width => 5, :header => 'File contents can be accessed by these Servers', :edit_condition => (check_role(:admin_user) || @provider.user_id == current_user.id)) do |t| %> + <% if rrs_by_category[:portal] %> + <% t.row(:class => 'subheader') { "Portals".html_safe } %> + <% rrs_by_category[:portal].sort_by(&:name).each do |rr| %> + <% meta_key = "rr_no_sync_#{rr.id}" %> + <% t.boolean_edit_cell("meta[#{meta_key}]", is_new_record ? @unsaved_meta[meta_key].to_s : @provider.meta[meta_key].to_s, "", "#{rr.name} cannot sync #{@provider.name}", :header => "#{rr.name}", :class => 'checkbox_label') %> + <% end%> <% end%> - <% end%> - <% t.blank_row %> + <% t.blank_row %> - <% if rrs_by_category[:bourreau] %> - <% t.row(:class => 'subheader') { "Execution Servers".html_safe } %> - <% rrs_by_category[:bourreau].sort_by(&:name).each do |rr| %> - <% meta_key = "rr_no_sync_#{rr.id}" %> - <% t.boolean_edit_cell("meta[#{meta_key}]", @provider.meta[meta_key].to_s, "", "#{rr.name} cannot sync #{@provider.name}", :header => "#{rr.name}", :class => 'checkbox_label') %> + <% if rrs_by_category[:bourreau] %> + <% t.row(:class => 'subheader') { "Execution Servers".html_safe } %> + <% rrs_by_category[:bourreau].sort_by(&:name).each do |rr| %> + <% meta_key = "rr_no_sync_#{rr.id}" %> + <% t.boolean_edit_cell("meta[#{meta_key}]", is_new_record ? @unsaved_meta[meta_key].to_s : @provider.meta[meta_key].to_s, "", "#{rr.name} cannot sync #{@provider.name}", :header => "#{rr.name}", :class => 'checkbox_label') %> + <% end%> <% end%> <% end%> <% end%> - <% end%> - + <% end %>

@@ -276,7 +283,9 @@ <% if has_owner_access %> <% if is_userkey_dp %> <%= render :partial => 'show_user_key' %> - <% elsif needs_ssh_config %> + <% end %> + <% if needs_ssh_config || is_new_record %> +

From cfd7e0e24de942cee5ee2ccc05ab5cf2499d77d2 Mon Sep 17 00:00:00 2001 From: natacha-beck Date: Thu, 18 Sep 2025 13:08:26 -0400 Subject: [PATCH 02/11] [WIP] Need fix for user --- .../controllers/data_providers_controller.rb | 48 +++- .../app/models/s3_flat_data_provider.rb | 8 + BrainPortal/app/models/ssh_data_provider.rb | 11 + .../app/views/data_providers/new.html.erb | 229 ------------------ .../data_providers/new_personal.html.erb | 108 --------- .../app/views/data_providers/show.html.erb | 143 +++++------ 6 files changed, 132 insertions(+), 415 deletions(-) delete mode 100644 BrainPortal/app/views/data_providers/new.html.erb delete mode 100644 BrainPortal/app/views/data_providers/new_personal.html.erb diff --git a/BrainPortal/app/controllers/data_providers_controller.rb b/BrainPortal/app/controllers/data_providers_controller.rb index 80062ca76..b06874a0c 100644 --- a/BrainPortal/app/controllers/data_providers_controller.rb +++ b/BrainPortal/app/controllers/data_providers_controller.rb @@ -32,8 +32,8 @@ class DataProvidersController < ApplicationController :create_personal, :check_personal, :destroy] before_action :login_required - before_action :manager_role_required, :only => [:new, :create] - before_action :admin_role_required, :only => [:new, :create, :report, :repair] + before_action :manager_role_required, :only => [:new, :create ] + before_action :admin_role_required, :only => [:new, :report, :repair] def index #:nodoc: @scope = scope_from_session @@ -79,16 +79,19 @@ def show #:nodoc: def new #:nodoc: provider_group_id = current_assignable_group.id - @unsaved_meta = {} - @provider = DataProvider.new( :user_id => current_user.id, + @provider = DataProvider.new( + :user_id => current_user.id, :group_id => provider_group_id, :online => true, :read_only => false ) - @typelist = get_type_list + @unsaved_meta = {} + @is_personal = false + @typelist = get_type_list - render :action => :show # our show is also edit/create + # Edit/create are the same view + render :action => :show end def create #:nodoc: @@ -123,14 +126,19 @@ def new_personal #:nodoc: :online => true, :read_only => false, ) - @groups = current_user.assignable_groups + @unsaved_meta = {} + @is_personal = true + @typelist = get_personal_type_list + + # Edit/create are the same view + render :action => :show end # Can be create by normal user, # only UserkeyFlatDirSshDataProvider, S3FlatDataProvider, S3MultiLevelDataProvider def create_personal @provider = DataProvider.new(base_provider_params).class_update - @provider.update_attributes(userkey_provider_params) if @provider.is_a?(UserkeyFlatDirSshDataProvider) + @provider.update_attributes(userkey_provider_params) if @provider.is_a?(Userk eyFlatDirSshDataProvider) @provider.update_attributes(s3_provider_params) if @provider.is_a?(S3FlatDataProvider) authorized_type = [UserkeyFlatDirSshDataProvider, S3FlatDataProvider, S3MultiLevelDataProvider] @@ -142,7 +150,7 @@ def create_personal current_user.assignable_group_ids.include?(@provider.group_id) @provider.online = true - if ! @provider.save + if ! @provider.save @groups = current_user.assignable_groups respond_to do |format| format.html { render :action => :new_personal} @@ -814,8 +822,30 @@ def get_type_list #:nodoc: grouped_options = data_provider_list.to_a.hashed_partitions { |name| name.constantize.pretty_category_name } grouped_options.delete(nil) # data providers that can not be on this list return a category name of nil, so we remove them grouped_options.keys.sort.map { |type| [ type, grouped_options[type].sort ] } + + return grouped_options || [] + end + + def get_personal_type_list #:nodoc: + data_provider_list = [ "FlatDirSshDataProvider" ] + data_provider_list = DataProvider.descendants.map(&:name) + + grouped_options = data_provider_list.to_a.hashed_partitions { |name| name.constantize.pretty_category_name } + # Keep only Cloud and DataladProvider + grouped_options = grouped_options.select { |type, values| ["Cloud", "DataladProvider"].include?(type) } + # Remove S3DataProvider + grouped_options["Cloud"].reject! { |v| v == S3DataProvider.name } if grouped_options["Cloud"] + + # Add UserkeyFlatDirSshDataProvider group + category_of_userkey_dp = UserkeyFlatDirSshDataProvider.pretty_category_name + userkey_group = grouped_options.find { |type, _ | type == category_of_userkey_dp } || [] + userkey_group << UserkeyFlatDirSshDataProvider.name + grouped_options[category_of_userkey_dp] = userkey_group + + return grouped_options || [] end + # A name to store the scope for the browsing page; # a distinct scope is used for each distinct DP def browse_scope_name(provider) #:nodoc: diff --git a/BrainPortal/app/models/s3_flat_data_provider.rb b/BrainPortal/app/models/s3_flat_data_provider.rb index 7747302ce..e28390d31 100644 --- a/BrainPortal/app/models/s3_flat_data_provider.rb +++ b/BrainPortal/app/models/s3_flat_data_provider.rb @@ -53,6 +53,14 @@ class S3FlatDataProvider < DataProvider validates :cloud_storage_client_identifier, length: { in: 16..128 } validates :cloud_storage_client_token, length: { in: 20..100 } + # Attributes of: + # - SshDataProvider attributes (not appllicable to S3) + # - Containerized/datalad attributes (not applicable to S3) + # should be absent for this DP class. + validates :remote_host, :remote_user, :remote_dir, :alternate_host, :remote_port, + :containerized_path, :datalad_repository_url, :datalad_relative_path, + absence: true + validates :cloud_storage_client_bucket_name, format: { with: /\A[A-Za-z0-9][A-Za-z0-9\-.]{1,61}[A-Za-z0-9]\z/, # this is good enough; DP will just crash on bad names message: "invalid S3 bucket name, for rules see https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-s3-bucket-naming-requirements.html" diff --git a/BrainPortal/app/models/ssh_data_provider.rb b/BrainPortal/app/models/ssh_data_provider.rb index 853794dee..e42c7c907 100644 --- a/BrainPortal/app/models/ssh_data_provider.rb +++ b/BrainPortal/app/models/ssh_data_provider.rb @@ -35,6 +35,17 @@ class SshDataProvider < DataProvider include SshDataProviderBase + # Attributes of: + # - S3 attributes (not appllicable to Ssh) + # - Containerized/datalad attributes (not applicable to Ssh) + # should be absent for this DP class. + validates :cloud_storage_client_identifier, :cloud_storage_client_token, + :cloud_storage_client_bucket_name, :cloud_storage_client_path_start, + :cloud_storage_endpoint, :cloud_storage_region, + :containerized_path, :datalad_repository_url, :datalad_relative_path, + absence: true + + Revision_info=CbrainFileRevision[__FILE__] #:nodoc: # This returns the category of the data provider diff --git a/BrainPortal/app/views/data_providers/new.html.erb b/BrainPortal/app/views/data_providers/new.html.erb deleted file mode 100644 index c3aec765d..000000000 --- a/BrainPortal/app/views/data_providers/new.html.erb +++ /dev/null @@ -1,229 +0,0 @@ - -<%- -# -# CBRAIN Project -# -# Copyright (C) 2008-2012 -# The Royal Institution for the Advancement of Learning -# McGill University -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# --%> - -<% title 'Add New Data Provider' %> - -

Add New Data Provider

- -<%= error_messages_for(@provider) %> - -<%= form_for @provider, :as => :data_provider, :url => { :action => "create" }, :datatype => "script" do |f| -%> - -
- - -

<%= f.label :name, "Name" %>
- <%= f.text_field :name %>

-
- - -

<%= f.label :description, "Description" %>
- <%= f.text_area :description, :rows => 10, :cols => 40 %>
-

The first line should be a short summary, and the rest are for any special notes for the users.
-

-
- - -

<%= f.label :time_zone, "Time Zone" %>
- <%= f.time_zone_select :time_zone, - ActiveSupport::TimeZone.all.select { |t| t.name =~ /canada/i }, - { :default => ActiveSupport::TimeZone['Eastern Time (US & Canada)'], - :include_blank => true } - %>

-
- - - -

<%= f.label :type, "Type" %>
- <%= f.select :type, grouped_options_for_select(@typelist, @provider.type), { :prompt => "Select Provider Type" } %>
-

<%= show_hide_toggle "(Data Provider Type Information)", "#data_provider_classes", :class => 'action_link' %>
-

- - -
- - -

<%= f.label :user_id, "Owner" %>
- <%= user_select("data_provider[user_id]", { :selector => @provider }, { :disabled => ! current_user.has_role?(:admin_user) } ) %> -

-
- - -

<%= f.label :group_id, "Project" %>
- <%= group_select("data_provider[group_id]", :selector => @provider) %> -

-
- - -

<%= f.label :online, "Status" %>
- <%= f.select :online, { "Online" => true, "Offline" => false } %>

-
- - -

<%= f.label :read_only, "Mode" %>
- <%= f.select :read_only, { "Read/Write" => false, "Read Only" => true } %>

-
- - -

<%= f.label :not_syncable, "Syncability" %>
- <%= f.select :not_syncable, { "Fully syncable" => false, "NOT syncable" => true } %>

-
- -

- -

- SSH parameters for remote Data Providers - -
-

<%= f.label :remote_host, "Remote Hostname" %>
- <%= f.text_field :remote_host %>

-
- -
-

<%= f.label :alternate_host, "Alternate Hostname(s)" %>
- <%= f.text_field :alternate_host %>

-
- -
-

<%= f.label :remote_user, "Remote Username" %>
- <%= f.text_field :remote_user %>

-
- -
-

<%= f.label :remote_port, "Remote Port Number" %>
- <%= f.text_field :remote_port, :size => 6 %>

-
-
- -

- -

- Physical Data Location - - -

<%= f.label :remote_dir, "Full Directory Path" %>
- <%= f.text_field :remote_dir, :size => 80 %>

-
- -
- -

- -

- Containerized Storage Configuration - - -

<%= f.label :containerized_path, "Containerized Data Path" %>
- <%= f.text_field :containerized_path, :size => 80 %>

-
-
- -

- -

- Cloud Storage Configuration - - -

<%= f.label :cloud_storage_client_identifier, "Client Identifier" %>
- <%= f.text_field :cloud_storage_client_identifier, :size => 40, :autocomplete => 'off' %>

-
- - -

<%= f.label :cloud_storage_client_token, "Client Token" %>
- <%= f.password_field :cloud_storage_client_token, :size => 80, :autocomplete => 'off' %>

-
- - -

<%= f.label :cloud_storage_client_bucket_name, "Bucket Name (Only needed for S3FlatDataProvider)" %>
- <%= f.text_field :cloud_storage_client_bucket_name, :size => 80 %>

-
- Keep in mind, the bucket name should be specific enough to be unique to all of AWS. -
-
- - -

<%= f.label :cloud_storage_client_path_start, "Client Starting Path (Only needed for S3FlatDataProvider)" %>
- <%= f.text_field :cloud_storage_client_path_start, :size => 80 %>

-
- - -

<%= f.label :cloud_storage_endpoint, "Endpoint (Only needed for S3FlatDataProvider)" %>
- <%= f.text_field :cloud_storage_endpoint, :size => 80 %>

-
- - -

<%= f.label :cloud_storage_region, "Region (Only needed for S3FlatDataProvider)" %>
- <%= f.text_field :cloud_storage_region, :size => 80 %>

-
-
- -

- -

- Datalad Repository Configuration - - -

<%= f.label :datalad_repository_url, "Datalad URL" %>
- <%= f.text_field :datalad_repository_url, :size => 80 %>

-
- - -

<%= f.label :datalad_relative_path, "Datalad Relative Path" %>
- <%= f.text_field :datalad_relative_path, :size => 80 %>

-
-
- -

- -

- Other properties - -

- <%= check_box_tag 'meta[must_move]', "on", @provider.new_record? ? false : !@provider.meta[:must_move].blank? %> - -

- <%= group_select 'meta[browse_gid]', { :selector => (@provider.new_record? ? nil : @provider.meta[:browse_gid]) }, { :include_blank => "(Any Users)" } %> - -

- <%= check_box_tag 'meta[no_uploads]', "on", @provider.new_record? ? false : !@provider.meta[:no_uploads].blank? %> - -

- <%= check_box_tag 'meta[no_viewers]', "on", @provider.new_record? ? false : !@provider.meta[:no_viewers].blank? %> -

- - -
-

<%= submit_tag 'Create New Data Provider' %>

- -<% end %> - -
-
Public SSH Key for this CBRAIN Portal
- - - -
Public SSH Key for this CBRAIN Portal
This key should be installed on the host machines of SSH or Smart Data Providers to allow remote access.
<%= pretty_ssh_key(RemoteResource.current_resource.get_ssh_public_key || 'Unknown! Talk to sysadmin!') %>
-
diff --git a/BrainPortal/app/views/data_providers/new_personal.html.erb b/BrainPortal/app/views/data_providers/new_personal.html.erb deleted file mode 100644 index 204a1035a..000000000 --- a/BrainPortal/app/views/data_providers/new_personal.html.erb +++ /dev/null @@ -1,108 +0,0 @@ - -<%- -# -# CBRAIN Project -# -# Copyright (C) 2008-2023 -# The Royal Institution for the Advancement of Learning -# McGill University -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# --%> - -<% title 'Add New Personal Data Provider' %> - -

Add New Personal SSH-based Data Provider

- -<%= error_messages_for(@provider) %> - -<%= form_for @provider, :as => :data_provider, :url => { :action => "create_personal" }, :datatype => "script" do |f| -%> - - <% - # Note about the type: the form currently only supports the UserkeyFlatDirSshDataProvider - # but the controller also supports the S3MultiLevelDataProvider. Eventually we - # will allow both. If a user modifies the form in their browser they can still create - # their own S3 type, but that's ok. - %> - <%= hidden_field_tag 'data_provider[type]', 'UserkeyFlatDirSshDataProvider' %> - -
- -
- <%= f.label :name, "Name" %>
- <%= f.text_field :name %> -
This should be a simple identifier with no special characters or spaces
-
- -

- -

- <%= f.label :description, "Description" %>
- <%= f.text_area :description, :rows => 3, :cols => 85 %> -
The first line should be a short summary, and the rest are for any special notes for the users.
-
- -

- -

- <%= f.label :group_id, "Project" %>
- <%= group_select("data_provider[group_id]", { :groups => @groups, :selector => @provider.group_id.to_s }) %> -
This will control which users within CBRAIN can view and access the files on your storage. The default and recommended project is your own private project, '<%= current_user.own_group.name %>'.
-
- -

- -

- SSH parameters - -
- <%= f.label :remote_host, "Remote Hostname" %>
- <%= f.text_field :remote_host, :size => 40 %> -
- -

- -

- <%= f.label :remote_user, "Remote Username" %>
- <%= f.text_field :remote_user, :size => 40 %> -
- -

- -

- <%= f.label :remote_port, "Remote Port Number" %>
- <%= f.text_field :remote_port, :size => 6 %> -
- -

- -

- <%= f.label :remote_dir, "Full Directory Path" %>
- <%= f.text_field :remote_dir, :size => 80 %> -
- -
-
- -

- - <%= render :partial => 'show_user_key' %> - -

- - <%= submit_tag 'Create New Data Provider' %>

- -<% end %> - diff --git a/BrainPortal/app/views/data_providers/show.html.erb b/BrainPortal/app/views/data_providers/show.html.erb index 56dd1d383..27854e8fa 100644 --- a/BrainPortal/app/views/data_providers/show.html.erb +++ b/BrainPortal/app/views/data_providers/show.html.erb @@ -22,44 +22,47 @@ # -%> -<% is_new_record = @provider.new_record? %> -<% title is_new_record ? 'Create Data Provider' : 'Data Provider Info' %> - - -<% has_owner_access = (check_role(:admin_user) || @provider.user_id == current_user.id) %> -<% is_userkey_dp = @provider.is_a?(UserkeyFlatDirSshDataProvider) %> -<% needs_ssh_config = @provider.is_a?(SshDataProvider) || @provider.is_a?(SmartDataProviderInterface) %> +<% + is_new_record = @provider.new_record? + flattened_types = @typelist.values.flatten + include_personal_ssh = flattened_types.include?("UserkeyFlatDirSshDataProvider") + include_ssh = flattened_types.include?("SshDataProvider") || flattened_types.include?("SmartDataProviderInterface") + has_owner_access = (check_role(:admin_user) || @provider.user_id == current_user.id) + is_userkey_dp = @provider.is_a?(UserkeyFlatDirSshDataProvider) + needs_ssh_config = @provider.is_a?(SshDataProvider) || @provider.is_a?(SmartDataProviderInterface) +%> - +<% end %>

@@ -79,7 +82,7 @@ <%= f.text_area :description, :rows => 10, :cols => 40 %>
<% end %> - <% if has_owner_access || is_new_record %> + <% if is_new_record || has_owner_access %> <% t.edit_cell(:type, :content => @provider.type) do |f| %> <%= f.select :type, grouped_options_for_select(@typelist, @provider.type) %> <% end %> @@ -118,7 +121,7 @@ <% end %> <% end %> - <% if has_owner_access || is_new_record %> + <% if is_new_record || has_owner_access %> <% t.edit_cell(:remote_dir, :header => "Physical Data Location", :show_width => 2) do |f| %> <%= f.text_field :remote_dir, :size => 80 %> <% end %> @@ -137,7 +140,7 @@ <% end %> - <% if (has_owner_access && needs_ssh_config) || is_new_record %> + <% if is_new_record || (has_owner_access && needs_ssh_config) %> <%= show_table(@provider, :form_helper => cf, :as => :data_provider, :header => "SSH parameters", :edit_condition => true) do |t| %> <% t.edit_cell(:remote_host, :show_width => 2) do |f| %> <%= f.text_field :remote_host, :size => 40 %> @@ -157,7 +160,7 @@ <% end %> <% end %> - <% if (@provider.is_a?(SingSquashfsDataProvider) || @provider.is_a?(SingBindmountDataProvider)) || is_new_record %> + <% if ( !@is_personal && is_new_record || (@provider.is_a?(SingSquashfsDataProvider) || @provider.is_a?(SingBindmountDataProvider))) %> <%= show_table(@provider, :form_helper => cf, :as => :data_provider, :header => "Containerized Storage Configuration", :edit_condition => true) do |t| %> <% t.edit_cell(:containerized_path, :header => 'Containerized Data Path', :show_width => 2) do %> <%= text_field_tag "data_provider[containerized_path]", @provider.containerized_path, :size => 80 %> @@ -165,7 +168,7 @@ <% end %> <% end %> - <% if (@provider.is_a?(S3DataProvider) || @provider.is_a?(S3FlatDataProvider)) || is_new_record %> + <% if @provider.is_a?(S3DataProvider) || @provider.is_a?(S3FlatDataProvider) || (is_new_record && @typelist.include?("Cloud")) %> <%= show_table(@provider, :form_helper => cf, :as => :data_provider, :header => "Cloud Storage Configuration", :edit_condition => true) do |t| %> <% t.edit_cell(:cloud_storage_client_identifier, :header => 'Client Identifier', :show_width => 2) do |f| %> <%= f.text_field :cloud_storage_client_identifier, :size => 40, :autocomplete => 'off' %> @@ -188,7 +191,7 @@ <% end %> <% end %> - <% if @provider.is_a?(DataladDataProvider) || is_new_record %> + <% if @provider.is_a?(DataladDataProvider) || (is_new_record && @typelist.include?("DataladProvider")) %> <%= show_table(@provider, :form_helper => cf, :as => :data_provider, :header => "Datalad Configuration", :edit_condition => true) do |t| %> <% t.edit_cell(:datalad_repository_url, :header => 'Datalad Repository URL', :show_width => 2) do |f| %> <%= f.text_field :datalad_repository_url %> @@ -199,52 +202,54 @@ <% end %> <% end %> - <%= show_table(@provider, :form_helper => cf, :as => :data_provider, :header => "Other Properties", :edit_condition => (check_role(:admin_user) || @provider.user_id == current_user.id)) do |t| %> + <% if !@is_personal %> + <%= show_table(@provider, :form_helper => cf, :as => :data_provider, :header => "Other Properties", :edit_condition => (check_role(:admin_user) || @provider.user_id == current_user.id)) do |t| %> - <% t.boolean_edit_cell("meta[no_uploads]", is_new_record ? @unsaved_meta[:no_uploads] || false : !@provider.meta[:no_uploads].blank? , "on", "", :header => "Cannot be used for uploading files in the file manager") %> + <% t.boolean_edit_cell("meta[no_uploads]", is_new_record ? @unsaved_meta[:no_uploads] || false : @provider.meta[:no_uploads], "on", "", :header => "Cannot be used for uploading files in the file manager") %> - <% t.boolean_edit_cell("meta[no_viewers]", is_new_record ? @unsaved_meta[:no_viewers] || false : !@provider.meta[:no_viewers].blank? , "on", "", :header => "Files cannot be viewed in the file manager") %> + <% t.boolean_edit_cell("meta[no_viewers]", is_new_record ? @unsaved_meta[:no_viewers] || false : @provider.meta[:no_viewers], "on", "", :header => "Files cannot be viewed in the file manager") %> - <% if @provider.is_browsable? || is_new_record %> + <% if is_new_record || @provider.is_browsable? %> - <% t.boolean_edit_cell("meta[must_move]", is_new_record ? @unsaved_meta[:must_move] || false : !@provider.meta[:must_move].blank? , "on", "", :header => "Files must be copied/moved upon registration") %> + <% t.boolean_edit_cell("meta[must_move]", is_new_record ? @unsaved_meta[:must_move] || false : @provider.meta[:must_move], "on", "", :header => "Files must be copied/moved upon registration") %> + + <% browse_gid = !is_new_record ? @provider.meta[:browse_gid].present? : (@unsaved_meta && @unsaved_meta[:browse_gid].present?) %> + <% t.edit_cell("meta[browse_gid]", + :header => "Files can be browsed only by members of this project", + :content => !is_new_record && browse_gid ? link_to_group_if_accessible(@provider.meta[:browse_gid]) : '(Any Users)', + :show_width => 2 + ) do %> + <%= group_select 'meta[browse_gid]', { :selector => (is_new_record ? @unsaved_meta[:browse_gid] : @provider.meta[:browse_gid]) }, { :include_blank => "(Any Users)" } %> + <% end %> - <% browse_gid = !is_new_record ? @provider.meta[:browse_gid].present? : (@unsaved_meta && @unsaved_meta[:browse_gid].present?) %> - <% t.edit_cell("meta[browse_gid]", - :header => "Files can be browsed only by members of this project", - :content => !is_new_record && browse_gid ? link_to_group_if_accessible(@provider.meta[:browse_gid]) : '(Any Users)', - :show_width => 2 - ) do %> - <%= group_select 'meta[browse_gid]', { :selector => (is_new_record ? @unsaved_meta[:browse_gid] : @provider.meta[:browse_gid]) }, { :include_blank => "(Any Users)" } %> <% end %> <% end %> - <% end %> - - <% other_dps = DataProvider.find_all_accessible_by_user(current_user).reject { |dp| dp.id == @provider.id } %> - <% dps_by_category = other_dps.to_a.hashed_partitions { |dp| dp.is_browsable? ? :user : :official } %> + <% other_dps = DataProvider.find_all_accessible_by_user(current_user).reject { |dp| dp.id == @provider.id } %> + <% dps_by_category = other_dps.to_a.hashed_partitions { |dp| dp.is_browsable? ? :user : :official } %> - <% if other_dps.size > 0 %> + <% if other_dps.size > 0 %> - <%= show_table(@provider, :form_helper => cf, :as => :data_provider, :width => 5, :header => 'Files can be copied or moved to these other Data Providers', :edit_condition => (check_role(:admin_user) || @provider.user_id == current_user.id)) do |t| %> - <% if dps_by_category[:official] %> - <% t.row(:class => 'subheader') { "Official Storage".html_safe } %> - <% dps_by_category[:official].sort_by(&:name).each do |dp| %> - <% meta_key = "dp_no_copy_#{dp.id}" %> - <% t.boolean_edit_cell("meta[#{meta_key}]", is_new_record ? @unsaved_meta[meta_key] || false : @provider.meta[meta_key].to_s, "", "disabled", :header => "#{dp.name}", :class => 'checkbox_label') %> + <%= show_table(@provider, :form_helper => cf, :as => :data_provider, :width => 5, :header => 'Files can be copied or moved to these other Data Providers', :edit_condition => (check_role(:admin_user) || @provider.user_id == current_user.id)) do |t| %> + <% if dps_by_category[:official] %> + <% t.row(:class => 'subheader') { "Official Storage".html_safe } %> + <% dps_by_category[:official].sort_by(&:name).each do |dp| %> + <% meta_key = "dp_no_copy_#{dp.id}" %> + <% t.boolean_edit_cell("meta[#{meta_key}]", is_new_record ? @unsaved_meta[meta_key] || false : @provider.meta[meta_key].to_s, "", "disabled", :header => "#{dp.name}", :class => 'checkbox_label') %> + <% end%> <% end%> - <% end%> - <% t.blank_row %> + <% t.blank_row %> - <% if dps_by_category[:user] %> - <% t.row(:class => 'subheader') { "User or Site Storage".html_safe } %> - <% dps_by_category[:user].sort_by(&:name).each do |dp| %> - <% meta_key = "dp_no_copy_#{dp.id}" %> - <% t.boolean_edit_cell("meta[#{meta_key}]", is_new_record ? @unsaved_meta[meta_key] || false : @provider.meta[meta_key].to_s, "", "disabled", :header => "#{dp.name}", :class => 'checkbox_label') %> + <% if dps_by_category[:user] %> + <% t.row(:class => 'subheader') { "User or Site Storage".html_safe } %> + <% dps_by_category[:user].sort_by(&:name).each do |dp| %> + <% meta_key = "dp_no_copy_#{dp.id}" %> + <% t.boolean_edit_cell("meta[#{meta_key}]", is_new_record ? @unsaved_meta[meta_key] || false : @provider.meta[meta_key].to_s, "", "disabled", :header => "#{dp.name}", :class => 'checkbox_label') %> + <% end%> <% end%> <% end%> <% end%> @@ -281,10 +286,10 @@

<% if has_owner_access %> - <% if is_userkey_dp %> + <% if include_personal_ssh %> <%= render :partial => 'show_user_key' %> <% end %> - <% if needs_ssh_config || is_new_record %> + <% if needs_ssh_config || (is_new_record && include_ssh) %>

From bb57f44ed36d2e58d55e7462d964f40377543f75 Mon Sep 17 00:00:00 2001 From: natacha-beck Date: Fri, 19 Sep 2025 05:59:51 -0400 Subject: [PATCH 03/11] [WIP] --- .../controllers/data_providers_controller.rb | 21 +++++++++++++------ .../app/models/s3_flat_data_provider.rb | 2 +- .../app/views/data_providers/show.html.erb | 5 +++-- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/BrainPortal/app/controllers/data_providers_controller.rb b/BrainPortal/app/controllers/data_providers_controller.rb index b06874a0c..2a901607c 100644 --- a/BrainPortal/app/controllers/data_providers_controller.rb +++ b/BrainPortal/app/controllers/data_providers_controller.rb @@ -32,7 +32,7 @@ class DataProvidersController < ApplicationController :create_personal, :check_personal, :destroy] before_action :login_required - before_action :manager_role_required, :only => [:new, :create ] + before_action :manager_role_required, :only => [:new, :create] before_action :admin_role_required, :only => [:new, :report, :repair] def index #:nodoc: @@ -100,6 +100,10 @@ def create #:nodoc: @provider.group_id ||= current_assignable_group.id @unsaved_meta = params[:meta] || {} + # Fix some attributes + @provider.update_attributes(userkey_provider_params) if @provider.is_a?(UserkeyFlatDirSshDataProvider) + @provider.update_attributes(s3_provider_params) if @provider.is_a?(S3FlatDataProvider) + if @provider.save add_meta_data_from_form(@provider, [:must_move, :no_uploads, :no_viewers, :browse_gid]) @provider.addlog_context(self,"Created by #{current_user.login}") @@ -137,11 +141,15 @@ def new_personal #:nodoc: # Can be create by normal user, # only UserkeyFlatDirSshDataProvider, S3FlatDataProvider, S3MultiLevelDataProvider def create_personal + @unsaved_meta = params[:meta] || {} + + # Fix some attributes @provider = DataProvider.new(base_provider_params).class_update - @provider.update_attributes(userkey_provider_params) if @provider.is_a?(Userk eyFlatDirSshDataProvider) + @provider.update_attributes(userkey_provider_params) if @provider.is_a?(UserkeyFlatDirSshDataProvider) @provider.update_attributes(s3_provider_params) if @provider.is_a?(S3FlatDataProvider) - authorized_type = [UserkeyFlatDirSshDataProvider, S3FlatDataProvider, S3MultiLevelDataProvider] + authorized_type = [UserkeyFlatDirSshDataProvider, S3FlatDataProvider, S3MultiLevelDataProvider, DataladDataProvider] + binding.pry @provider.errors.add(:type, "is not allowed") unless authorized_type.include?(@provider.type) # Fix some attributes @@ -150,13 +158,14 @@ def create_personal current_user.assignable_group_ids.include?(@provider.group_id) @provider.online = true - if ! @provider.save + if ! @provider.save + @typelist = get_personal_type_list @groups = current_user.assignable_groups respond_to do |format| - format.html { render :action => :new_personal} + format.html { render :action => :show } format.json { render :json => @provider.errors, :status => :unprocessable_entity } end - return + return end @provider.addlog_context(self, "Created by #{current_user.login}") diff --git a/BrainPortal/app/models/s3_flat_data_provider.rb b/BrainPortal/app/models/s3_flat_data_provider.rb index e28390d31..fa09c9146 100644 --- a/BrainPortal/app/models/s3_flat_data_provider.rb +++ b/BrainPortal/app/models/s3_flat_data_provider.rb @@ -57,7 +57,7 @@ class S3FlatDataProvider < DataProvider # - SshDataProvider attributes (not appllicable to S3) # - Containerized/datalad attributes (not applicable to S3) # should be absent for this DP class. - validates :remote_host, :remote_user, :remote_dir, :alternate_host, :remote_port, + validates :remote_user, :remote_host, :remote_port, :remote_dir, :containerized_path, :datalad_repository_url, :datalad_relative_path, absence: true diff --git a/BrainPortal/app/views/data_providers/show.html.erb b/BrainPortal/app/views/data_providers/show.html.erb index 27854e8fa..27acd9c33 100644 --- a/BrainPortal/app/views/data_providers/show.html.erb +++ b/BrainPortal/app/views/data_providers/show.html.erb @@ -30,6 +30,8 @@ has_owner_access = (check_role(:admin_user) || @provider.user_id == current_user.id) is_userkey_dp = @provider.is_a?(UserkeyFlatDirSshDataProvider) needs_ssh_config = @provider.is_a?(SshDataProvider) || @provider.is_a?(SmartDataProviderInterface) + is_normal_user = current_user.has_role?(:normal_user) + url = is_normal_user && is_new_record ? url_for(:controller => 'data_providers', :action => 'create_personal') : nil %> <% title is_new_record ? 'Create Data Provider' : 'Data Provider Info' %> @@ -70,8 +72,7 @@
-<%= show_table_context(@provider) do |cf| %> - +<%= show_table_context(@provider, :url => url) do |cf| %> <%= show_table(@provider, :form_helper => cf, :as => :data_provider, :edit_condition => has_owner_access) do |t| %> <% t.edit_cell(:name) do |f| %> From 837f0a5644cc77c08bf3a7441d2663d6a8e5c41a Mon Sep 17 00:00:00 2001 From: natacha-beck Date: Fri, 19 Sep 2025 09:16:38 -0400 Subject: [PATCH 04/11] [FIX] for S3 dp show --- .../controllers/data_providers_controller.rb | 18 ++++++++---------- .../app/views/data_providers/show.html.erb | 18 +++++++++--------- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/BrainPortal/app/controllers/data_providers_controller.rb b/BrainPortal/app/controllers/data_providers_controller.rb index 2a901607c..d4e77db5f 100644 --- a/BrainPortal/app/controllers/data_providers_controller.rb +++ b/BrainPortal/app/controllers/data_providers_controller.rb @@ -143,22 +143,20 @@ def new_personal #:nodoc: def create_personal @unsaved_meta = params[:meta] || {} - # Fix some attributes @provider = DataProvider.new(base_provider_params).class_update - @provider.update_attributes(userkey_provider_params) if @provider.is_a?(UserkeyFlatDirSshDataProvider) - @provider.update_attributes(s3_provider_params) if @provider.is_a?(S3FlatDataProvider) - - authorized_type = [UserkeyFlatDirSshDataProvider, S3FlatDataProvider, S3MultiLevelDataProvider, DataladDataProvider] - binding.pry - @provider.errors.add(:type, "is not allowed") unless authorized_type.include?(@provider.type) - # Fix some attributes @provider.user_id = current_user.id @provider.group_id = current_user.own_group.id unless current_user.assignable_group_ids.include?(@provider.group_id) @provider.online = true - if ! @provider.save + @provider.update_attributes(userkey_provider_params) if @provider.is_a?(UserkeyFlatDirSshDataProvider) + @provider.update_attributes(s3_provider_params) if @provider.is_a?(S3FlatDataProvider) + + authorized_type = ["UserkeyFlatDirSshDataProvider", "S3FlatDataProvider", "S3MultiLevelDataProvider"] + @provider.errors.add(:type, "is not allowed") unless authorized_type.include?(@provider.type) + + if ! @provider.errors.empty? || ! @provider.save @typelist = get_personal_type_list @groups = current_user.assignable_groups respond_to do |format| @@ -841,7 +839,7 @@ def get_personal_type_list #:nodoc: grouped_options = data_provider_list.to_a.hashed_partitions { |name| name.constantize.pretty_category_name } # Keep only Cloud and DataladProvider - grouped_options = grouped_options.select { |type, values| ["Cloud", "DataladProvider"].include?(type) } + grouped_options = grouped_options.select { |type, values| ["Cloud"].include?(type) } # Remove S3DataProvider grouped_options["Cloud"].reject! { |v| v == S3DataProvider.name } if grouped_options["Cloud"] diff --git a/BrainPortal/app/views/data_providers/show.html.erb b/BrainPortal/app/views/data_providers/show.html.erb index 27acd9c33..68dfe8f5e 100644 --- a/BrainPortal/app/views/data_providers/show.html.erb +++ b/BrainPortal/app/views/data_providers/show.html.erb @@ -177,24 +177,24 @@ <% t.edit_cell(:cloud_storage_client_token, :content => '****************', :header => 'Client Token', :show_width => 2) do |f| %> <%= f.password_field :cloud_storage_client_token, :size => 80, :autocomplete => 'off' %> <% end %> - <% t.edit_cell(:cloud_storage_client_bucket_name, :header => 'Client Bucket Name', :show_width => 2) do %> - <%= text_field_tag "data_provider[cloud_storage_client_bucket_name]", @provider.cloud_storage_client_bucket_name, :size => 80 %> + <% t.edit_cell(:cloud_storage_client_bucket_name, :header => 'Client Bucket Name' + (is_new_record ? '' : ' (Only needed for S3FlatDataProvider)'), :show_width => 2) do |f| %> + <%= f.text_field :cloud_storage_client_bucket_name, :size => 80 %> <% end %> - <% t.edit_cell(:cloud_storage_client_path_start, :header => 'Client Starting Path', :show_width => 2) do %> - <%= text_field_tag "data_provider[cloud_storage_client_path_start]", @provider.cloud_storage_client_path_start, :size => 80 %> + <% t.edit_cell(:cloud_storage_client_path_start, :header => 'Client Starting Path' + (is_new_record ? '' : ' (Only needed for S3FlatDataProvider)'), :show_width => 2) do |f| %> + <%= f.text_field :cloud_storage_client_path_start, :size => 80 %> <% end %> - <% t.edit_cell(:cloud_storage_endpoint, :header => 'Endpoint', :show_width => 2) do %> - <%= text_field_tag "data_provider[cloud_storage_endpoint]", @provider.cloud_storage_endpoint, :size => 80 %> + <% t.edit_cell(:cloud_storage_endpoint, :header => 'Endpoint' + (is_new_record ? '' : ' (Only needed for S3FlatDataProvider)'), :show_width => 2) do |f| %> + <%= f.text_field :cloud_storage_endpoint, :size => 80 %> <% end %> - <% t.edit_cell(:cloud_storage_region, :header => 'Region', :show_width => 2) do %> - <%= text_field_tag "data_provider[cloud_storage_region]", @provider.cloud_storage_region, :size => 80 %> + <% t.edit_cell(:cloud_storage_region, :header => 'Region' + (is_new_record ? '' : ' (Only needed for S3FlatDataProvider)'), :show_width => 2) do |f| %> + <%= f.text_field :cloud_storage_region, :size => 80 %> <% end %> <% end %> <% end %> <% if @provider.is_a?(DataladDataProvider) || (is_new_record && @typelist.include?("DataladProvider")) %> <%= show_table(@provider, :form_helper => cf, :as => :data_provider, :header => "Datalad Configuration", :edit_condition => true) do |t| %> - <% t.edit_cell(:datalad_repository_url, :header => 'Datalad Repository URL', :show_width => 2) do |f| %> + <% t.edit_cell(:datalad_repository_url, :header => 'Datalad Repository URL', :show_width => 2) do |f| %> <%= f.text_field :datalad_repository_url %> <% end %> <% t.edit_cell(:datalad_relative_path, :header => 'Datalad Relative Path', :show_width => 2) do |f| %> From 659e712892d6ba59d59f9557f6a4d7624cc8284c Mon Sep 17 00:00:00 2001 From: natacha-beck Date: Mon, 22 Sep 2025 05:22:15 -0400 Subject: [PATCH 05/11] [FIX] DataProvider Spec --- .../spec/controllers/data_providers_controller_spec.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/BrainPortal/spec/controllers/data_providers_controller_spec.rb b/BrainPortal/spec/controllers/data_providers_controller_spec.rb index 4897be9f4..dad0ad97d 100644 --- a/BrainPortal/spec/controllers/data_providers_controller_spec.rb +++ b/BrainPortal/spec/controllers/data_providers_controller_spec.rb @@ -58,9 +58,9 @@ expect(controller).to receive(:get_type_list) get :new end - it "should render the new page" do + it "should render the show page" do get :new - expect(response).to render_template(:new) + expect(response).to render_template(:show) end end describe "create" do @@ -96,9 +96,9 @@ expect(controller).not_to receive(:add_meta_data_from_form) post :create, :xhr => true end - it "should render new page again" do + it "should render show page again" do post :create, :xhr => true - expect(response).to render_template(:new) + expect(response).to render_template(:show) end end end From 4d3bbdc4237c3418f5b2917060565cd02744478a Mon Sep 17 00:00:00 2001 From: natacha-beck Date: Mon, 22 Sep 2025 07:49:37 -0400 Subject: [PATCH 06/11] [FIX] DP documentation --- BrainPortal/app/views/data_providers/show.html.erb | 4 ++++ .../doc/data_providers/dp_types_explained.html} | 0 2 files changed, 4 insertions(+) rename BrainPortal/{app/views/data_providers/_dp_types_explained.html.erb => public/doc/data_providers/dp_types_explained.html} (100%) diff --git a/BrainPortal/app/views/data_providers/show.html.erb b/BrainPortal/app/views/data_providers/show.html.erb index 68dfe8f5e..bb4470ab2 100644 --- a/BrainPortal/app/views/data_providers/show.html.erb +++ b/BrainPortal/app/views/data_providers/show.html.erb @@ -86,6 +86,10 @@ <% if is_new_record || has_owner_access %> <% t.edit_cell(:type, :content => @provider.type) do |f| %> <%= f.select :type, grouped_options_for_select(@typelist, @provider.type) %> + <% if !is_normal_user %> +
+ <%= overlay_ajax_link "(Data Provider Type Information)", "/doc/data_providers/data_provider_info.html", :class => "help_link" %> + <% end %> <% end %> <% else %> <% t.empty_cell %> diff --git a/BrainPortal/app/views/data_providers/_dp_types_explained.html.erb b/BrainPortal/public/doc/data_providers/dp_types_explained.html similarity index 100% rename from BrainPortal/app/views/data_providers/_dp_types_explained.html.erb rename to BrainPortal/public/doc/data_providers/dp_types_explained.html From 751ae5c0b6c9cb31e2f943786d0c17142d03cd6a Mon Sep 17 00:00:00 2001 From: natacha-beck Date: Wed, 24 Sep 2025 09:13:25 -0400 Subject: [PATCH 07/11] [WIP] --- BrainPortal/app/controllers/data_providers_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BrainPortal/app/controllers/data_providers_controller.rb b/BrainPortal/app/controllers/data_providers_controller.rb index d4e77db5f..45faa748e 100644 --- a/BrainPortal/app/controllers/data_providers_controller.rb +++ b/BrainPortal/app/controllers/data_providers_controller.rb @@ -33,7 +33,7 @@ class DataProvidersController < ApplicationController before_action :login_required before_action :manager_role_required, :only => [:new, :create] - before_action :admin_role_required, :only => [:new, :report, :repair] + before_action :admin_role_required, :only => [:new, :create, :report, :repair] def index #:nodoc: @scope = scope_from_session From fb14f4973fa872f2ca489958f585ac125aa710f2 Mon Sep 17 00:00:00 2001 From: natacha-beck Date: Wed, 24 Sep 2025 09:29:56 -0400 Subject: [PATCH 08/11] [RM] datalad reference for now --- BrainPortal/app/controllers/data_providers_controller.rb | 6 ++---- BrainPortal/app/models/s3_flat_data_provider.rb | 2 +- BrainPortal/app/models/ssh_data_provider.rb | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/BrainPortal/app/controllers/data_providers_controller.rb b/BrainPortal/app/controllers/data_providers_controller.rb index 45faa748e..4eab8e6a2 100644 --- a/BrainPortal/app/controllers/data_providers_controller.rb +++ b/BrainPortal/app/controllers/data_providers_controller.rb @@ -90,7 +90,7 @@ def new #:nodoc: @is_personal = false @typelist = get_type_list - # Edit/create are the same view + # Edit/create/show are the same view render :action => :show end @@ -134,7 +134,7 @@ def new_personal #:nodoc: @is_personal = true @typelist = get_personal_type_list - # Edit/create are the same view + # Edit/create/show are the same view render :action => :show end @@ -829,8 +829,6 @@ def get_type_list #:nodoc: grouped_options = data_provider_list.to_a.hashed_partitions { |name| name.constantize.pretty_category_name } grouped_options.delete(nil) # data providers that can not be on this list return a category name of nil, so we remove them grouped_options.keys.sort.map { |type| [ type, grouped_options[type].sort ] } - - return grouped_options || [] end def get_personal_type_list #:nodoc: diff --git a/BrainPortal/app/models/s3_flat_data_provider.rb b/BrainPortal/app/models/s3_flat_data_provider.rb index fa09c9146..2c994e5ad 100644 --- a/BrainPortal/app/models/s3_flat_data_provider.rb +++ b/BrainPortal/app/models/s3_flat_data_provider.rb @@ -58,7 +58,7 @@ class S3FlatDataProvider < DataProvider # - Containerized/datalad attributes (not applicable to S3) # should be absent for this DP class. validates :remote_user, :remote_host, :remote_port, :remote_dir, - :containerized_path, :datalad_repository_url, :datalad_relative_path, + :containerized_path absence: true validates :cloud_storage_client_bucket_name, format: { diff --git a/BrainPortal/app/models/ssh_data_provider.rb b/BrainPortal/app/models/ssh_data_provider.rb index e42c7c907..5c43c3015 100644 --- a/BrainPortal/app/models/ssh_data_provider.rb +++ b/BrainPortal/app/models/ssh_data_provider.rb @@ -42,7 +42,7 @@ class SshDataProvider < DataProvider validates :cloud_storage_client_identifier, :cloud_storage_client_token, :cloud_storage_client_bucket_name, :cloud_storage_client_path_start, :cloud_storage_endpoint, :cloud_storage_region, - :containerized_path, :datalad_repository_url, :datalad_relative_path, + :containerized_path, absence: true From 5a805ccf83a5f965c27693fe48c6b9fb4a70e67a Mon Sep 17 00:00:00 2001 From: natacha-beck Date: Wed, 24 Sep 2025 09:48:45 -0400 Subject: [PATCH 09/11] [WIP] remove othe datalad ref --- BrainPortal/app/controllers/data_providers_controller.rb | 2 +- BrainPortal/app/models/s3_flat_data_provider.rb | 2 +- BrainPortal/app/models/ssh_data_provider.rb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/BrainPortal/app/controllers/data_providers_controller.rb b/BrainPortal/app/controllers/data_providers_controller.rb index 4eab8e6a2..f8303f173 100644 --- a/BrainPortal/app/controllers/data_providers_controller.rb +++ b/BrainPortal/app/controllers/data_providers_controller.rb @@ -836,7 +836,7 @@ def get_personal_type_list #:nodoc: data_provider_list = DataProvider.descendants.map(&:name) grouped_options = data_provider_list.to_a.hashed_partitions { |name| name.constantize.pretty_category_name } - # Keep only Cloud and DataladProvider + # Keep only Cloud grouped_options = grouped_options.select { |type, values| ["Cloud"].include?(type) } # Remove S3DataProvider grouped_options["Cloud"].reject! { |v| v == S3DataProvider.name } if grouped_options["Cloud"] diff --git a/BrainPortal/app/models/s3_flat_data_provider.rb b/BrainPortal/app/models/s3_flat_data_provider.rb index 2c994e5ad..74b85843d 100644 --- a/BrainPortal/app/models/s3_flat_data_provider.rb +++ b/BrainPortal/app/models/s3_flat_data_provider.rb @@ -55,7 +55,7 @@ class S3FlatDataProvider < DataProvider # Attributes of: # - SshDataProvider attributes (not appllicable to S3) - # - Containerized/datalad attributes (not applicable to S3) + # - Containerized attributes (not applicable to S3) # should be absent for this DP class. validates :remote_user, :remote_host, :remote_port, :remote_dir, :containerized_path diff --git a/BrainPortal/app/models/ssh_data_provider.rb b/BrainPortal/app/models/ssh_data_provider.rb index 5c43c3015..ea2616131 100644 --- a/BrainPortal/app/models/ssh_data_provider.rb +++ b/BrainPortal/app/models/ssh_data_provider.rb @@ -37,7 +37,7 @@ class SshDataProvider < DataProvider # Attributes of: # - S3 attributes (not appllicable to Ssh) - # - Containerized/datalad attributes (not applicable to Ssh) + # - Containerized attributes (not applicable to Ssh) # should be absent for this DP class. validates :cloud_storage_client_identifier, :cloud_storage_client_token, :cloud_storage_client_bucket_name, :cloud_storage_client_path_start, From 96dcad4020bc2862b26701e2edc972eab46de3b5 Mon Sep 17 00:00:00 2001 From: natacha-beck Date: Wed, 24 Sep 2025 10:01:38 -0400 Subject: [PATCH 10/11] [WIP] --- BrainPortal/app/models/s3_flat_data_provider.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BrainPortal/app/models/s3_flat_data_provider.rb b/BrainPortal/app/models/s3_flat_data_provider.rb index 74b85843d..10bf53617 100644 --- a/BrainPortal/app/models/s3_flat_data_provider.rb +++ b/BrainPortal/app/models/s3_flat_data_provider.rb @@ -58,7 +58,7 @@ class S3FlatDataProvider < DataProvider # - Containerized attributes (not applicable to S3) # should be absent for this DP class. validates :remote_user, :remote_host, :remote_port, :remote_dir, - :containerized_path + :containerized_path, absence: true validates :cloud_storage_client_bucket_name, format: { From a5791f8c9094d8ef95024ca370a1f4e884d909a7 Mon Sep 17 00:00:00 2001 From: natacha-beck Date: Fri, 26 Sep 2025 09:07:28 -0400 Subject: [PATCH 11/11] [FIX] spacing and return value --- .../controllers/data_providers_controller.rb | 2 + .../app/views/data_providers/show.html.erb | 56 ++++++++++++++----- 2 files changed, 44 insertions(+), 14 deletions(-) diff --git a/BrainPortal/app/controllers/data_providers_controller.rb b/BrainPortal/app/controllers/data_providers_controller.rb index f8303f173..fbd8edf22 100644 --- a/BrainPortal/app/controllers/data_providers_controller.rb +++ b/BrainPortal/app/controllers/data_providers_controller.rb @@ -829,6 +829,8 @@ def get_type_list #:nodoc: grouped_options = data_provider_list.to_a.hashed_partitions { |name| name.constantize.pretty_category_name } grouped_options.delete(nil) # data providers that can not be on this list return a category name of nil, so we remove them grouped_options.keys.sort.map { |type| [ type, grouped_options[type].sort ] } + + return grouped_options || [] end def get_personal_type_list #:nodoc: diff --git a/BrainPortal/app/views/data_providers/show.html.erb b/BrainPortal/app/views/data_providers/show.html.erb index bb4470ab2..3cfe3cb48 100644 --- a/BrainPortal/app/views/data_providers/show.html.erb +++ b/BrainPortal/app/views/data_providers/show.html.erb @@ -73,7 +73,9 @@
<%= show_table_context(@provider, :url => url) do |cf| %> - <%= show_table(@provider, :form_helper => cf, :as => :data_provider, :edit_condition => has_owner_access) do |t| %> + + + <%= show_table(@provider, :form_helper => cf, :as => :data_provider, :edit_condition => has_owner_access) do |t| %> <% t.edit_cell(:name) do |f| %> <%= f.text_field :name %> @@ -87,7 +89,6 @@ <% t.edit_cell(:type, :content => @provider.type) do |f| %> <%= f.select :type, grouped_options_for_select(@typelist, @provider.type) %> <% if !is_normal_user %> -
<%= overlay_ajax_link "(Data Provider Type Information)", "/doc/data_providers/data_provider_info.html", :class => "help_link" %> <% end %> <% end %> @@ -145,68 +146,93 @@ <% end %> + + <% if is_new_record || (has_owner_access && needs_ssh_config) %> <%= show_table(@provider, :form_helper => cf, :as => :data_provider, :header => "SSH parameters", :edit_condition => true) do |t| %> + <% t.edit_cell(:remote_host, :show_width => 2) do |f| %> <%= f.text_field :remote_host, :size => 40 %> <% end %> + <% if check_role(:admin_user) %> <% t.edit_cell(:alternate_host, :show_width => 2, :header => "Alternate hostname(s)") do |f| %> <%= f.text_field :alternate_host, :size => 100 %>
Comma-separated list of alternate hostnames; hostname1,hostname2,hostname3,...
<% end %> <% end %> + <% t.edit_cell(:remote_user) do |f| %> <%= f.text_field :remote_user, :size => 40 %> <% end %> + <% t.edit_cell(:remote_port) do |f| %> <%= f.text_field :remote_port, :size => 6 %> <% end %> + <% end %> <% end %> + <% if ( !@is_personal && is_new_record || (@provider.is_a?(SingSquashfsDataProvider) || @provider.is_a?(SingBindmountDataProvider))) %> + <%= show_table(@provider, :form_helper => cf, :as => :data_provider, :header => "Containerized Storage Configuration", :edit_condition => true) do |t| %> <% t.edit_cell(:containerized_path, :header => 'Containerized Data Path', :show_width => 2) do %> <%= text_field_tag "data_provider[containerized_path]", @provider.containerized_path, :size => 80 %> <% end %> <% end %> + <% end %> + <% if @provider.is_a?(S3DataProvider) || @provider.is_a?(S3FlatDataProvider) || (is_new_record && @typelist.include?("Cloud")) %> + <%= show_table(@provider, :form_helper => cf, :as => :data_provider, :header => "Cloud Storage Configuration", :edit_condition => true) do |t| %> + <% t.edit_cell(:cloud_storage_client_identifier, :header => 'Client Identifier', :show_width => 2) do |f| %> <%= f.text_field :cloud_storage_client_identifier, :size => 40, :autocomplete => 'off' %> <% end %> + <% t.edit_cell(:cloud_storage_client_token, :content => '****************', :header => 'Client Token', :show_width => 2) do |f| %> <%= f.password_field :cloud_storage_client_token, :size => 80, :autocomplete => 'off' %> <% end %> + <% t.edit_cell(:cloud_storage_client_bucket_name, :header => 'Client Bucket Name' + (is_new_record ? '' : ' (Only needed for S3FlatDataProvider)'), :show_width => 2) do |f| %> <%= f.text_field :cloud_storage_client_bucket_name, :size => 80 %> <% end %> + <% t.edit_cell(:cloud_storage_client_path_start, :header => 'Client Starting Path' + (is_new_record ? '' : ' (Only needed for S3FlatDataProvider)'), :show_width => 2) do |f| %> <%= f.text_field :cloud_storage_client_path_start, :size => 80 %> <% end %> + <% t.edit_cell(:cloud_storage_endpoint, :header => 'Endpoint' + (is_new_record ? '' : ' (Only needed for S3FlatDataProvider)'), :show_width => 2) do |f| %> <%= f.text_field :cloud_storage_endpoint, :size => 80 %> <% end %> + <% t.edit_cell(:cloud_storage_region, :header => 'Region' + (is_new_record ? '' : ' (Only needed for S3FlatDataProvider)'), :show_width => 2) do |f| %> <%= f.text_field :cloud_storage_region, :size => 80 %> <% end %> + <% end %> <% end %> + <% if @provider.is_a?(DataladDataProvider) || (is_new_record && @typelist.include?("DataladProvider")) %> + <%= show_table(@provider, :form_helper => cf, :as => :data_provider, :header => "Datalad Configuration", :edit_condition => true) do |t| %> + <% t.edit_cell(:datalad_repository_url, :header => 'Datalad Repository URL', :show_width => 2) do |f| %> <%= f.text_field :datalad_repository_url %> <% end %> + <% t.edit_cell(:datalad_relative_path, :header => 'Datalad Relative Path', :show_width => 2) do |f| %> <%= f.text_field :datalad_relative_path %> <% end %> - <% end %> + + <% end %> <% end %> + <% if !@is_personal %> <%= show_table(@provider, :form_helper => cf, :as => :data_provider, :header => "Other Properties", :edit_condition => (check_role(:admin_user) || @provider.user_id == current_user.id)) do |t| %> @@ -228,11 +254,9 @@ <% end %> <% end %> - <% end %> - - + <% other_dps = DataProvider.find_all_accessible_by_user(current_user).reject { |dp| dp.id == @provider.id } %> <% dps_by_category = other_dps.to_a.hashed_partitions { |dp| dp.is_browsable? ? :user : :official } %> @@ -258,8 +282,10 @@ <% end%> <% end%> <% end%> + <% end%> + <% other_rrs = RemoteResource.find_all_accessible_by_user(current_user) %> <% rrs_by_category = other_rrs.to_a.hashed_partitions { |rr| rr.is_a?(Bourreau) ? :bourreau : :portal } %> @@ -285,6 +311,7 @@ <% end%> <% end%> <% end%> + <% end %>
@@ -294,15 +321,16 @@ <% if include_personal_ssh %> <%= render :partial => 'show_user_key' %> <% end %> + <% if needs_ssh_config || (is_new_record && include_ssh) %> -
-
-
- - - -
Public SSH Key for this CBRAIN Portal
This key should be installed on this Data Provider's host machine to allow remote access.
<%= pretty_ssh_key(RemoteResource.current_resource.get_ssh_public_key || 'Unknown! Talk to sysadmin!') %>
-
+
+
+ + + + +
Public SSH Key for this CBRAIN Portal
This key should be installed on this Data Provider's host machine to allow remote access.
<%= pretty_ssh_key(RemoteResource.current_resource.get_ssh_public_key || 'Unknown! Talk to sysadmin!') %>
+
<% end %>