diff --git a/BrainPortal/app/assets/stylesheets/neurohub.scss.erb b/BrainPortal/app/assets/stylesheets/neurohub.scss.erb
index 1010e4ae1..4c6eb2034 100644
--- a/BrainPortal/app/assets/stylesheets/neurohub.scss.erb
+++ b/BrainPortal/app/assets/stylesheets/neurohub.scss.erb
@@ -3220,6 +3220,7 @@ $DASHBOARD_CARD_MIN_WIDTH: 25;
border: 1px solid $DEFAULT_ALT;
border-radius: 2px;
overflow: scroll;
+ box-sizing: border-box;
}
.license-list {
background: $PRIMARY_WASH;
@@ -3265,6 +3266,42 @@ $DASHBOARD_CARD_MIN_WIDTH: 25;
}
}
+#nh_portal_license {
+ .status {
+ @include text("xs");
+ svg {
+ @include mr(1);
+ width: 1rem;
+ }
+ &.success {
+ color: $SUCCESS_ALT;
+ svg {
+ fill: $SUCCESS_ALT;
+ stroke: $SUCCESS_ALT;
+ }
+ }
+ &.error {
+ color: $ERROR_BG;
+ svg {
+ fill: $ERROR_BG;
+ stroke: $ERROR_BG;
+ }
+ }
+ }
+
+
+ * , *:before, *:after {
+ box-sizing: border-box;
+ }
+ .license-text {
+ overflow: auto;
+ }
+ .btn-section {
+ align-self: flex-start;
+ flex: unset;
+ }
+}
+
/*
=============================================================
| STORAGES
diff --git a/BrainPortal/app/controllers/application_controller.rb b/BrainPortal/app/controllers/application_controller.rb
index 6ad51d9b4..3eb5a66a2 100644
--- a/BrainPortal/app/controllers/application_controller.rb
+++ b/BrainPortal/app/controllers/application_controller.rb
@@ -120,7 +120,7 @@ def activate_user_time_zone #:nodoc:
# or sign license agreements.
def check_account_validity #:nodoc:
return false unless current_user
- return true if params[:controller] == "sessions"
+ return true if params[:controller] =~ /sessions$/
return false unless check_mandatory_globus_id_linkage()
return false unless check_password_reset()
return false unless check_license_agreements()
@@ -149,7 +149,7 @@ def check_license_agreements #:nodoc:
return true if params[:controller] == "portal" && params[:action] =~ /license$/
return true if params[:controller] == "users" && (params[:action] == "change_password" || params[:action] == "update")
- unsigned_agreements = current_user.unsigned_license_agreements
+ unsigned_agreements = current_user.cbrain_unsigned_license_agreements
unless unsigned_agreements.empty?
if File.exists?(Rails.root + "public/licenses/#{unsigned_agreements.first}.html")
respond_to do |format|
diff --git a/BrainPortal/app/controllers/neurohub_application_controller.rb b/BrainPortal/app/controllers/neurohub_application_controller.rb
index 79beb3516..d868f2377 100644
--- a/BrainPortal/app/controllers/neurohub_application_controller.rb
+++ b/BrainPortal/app/controllers/neurohub_application_controller.rb
@@ -82,10 +82,28 @@ def check_if_locked
end
- # For the moment on the NeuroHub side, we bypass checking the site-wide
- # licenses. They'll still be required if the user switch to CBRAIN.
- def check_license_agreements
- true
+ # overrides check_license_agreements, as list of NeuroHub licenses may differ from cbrains
+ def check_license_agreements #:nodoc:
+
+ current_user.meta.reload
+ return true if current_user.neurohub_licenses_signed.present?
+ return true if params[:controller] == "neurohub_portal" && params[:action] =~ /license$/
+ return true if params[:controller] == "nh_users" && (params[:action] == "change_password" || params[:action] == "update")
+
+ unsigned_agreements = current_user.neurohub_unsigned_license_agreements
+ unless unsigned_agreements.empty?
+ if File.exists?(Rails.root + "public/licenses/#{unsigned_agreements.first}.html")
+ respond_to do |format|
+ format.html { redirect_to :controller => :neurohub_portal, :action => :nh_show_license, :license => unsigned_agreements.first }
+ format.json { render :status => 403, :json => { "error" => "Some license agreements are not signed." } }
+ format.xml { render :status => 403, :xml => { "error" => "Some license agreements are not signed." } }
+ end
+ return false
+ end
+ end
+
+ current_user.neurohub_licenses_signed = "yes"
+ return true
end
########################################################################
diff --git a/BrainPortal/app/controllers/neurohub_portal_controller.rb b/BrainPortal/app/controllers/neurohub_portal_controller.rb
index 61c797ded..410c6378c 100644
--- a/BrainPortal/app/controllers/neurohub_portal_controller.rb
+++ b/BrainPortal/app/controllers/neurohub_portal_controller.rb
@@ -60,5 +60,38 @@ def search
@projects = report[:projects]
end
-end
+ def nh_sign_license #:nodoc:
+ @license = params[:license]
+ unless params.has_key?(:agree) # no validation for info pages
+ flash[:error] = "#Neurohub cannot be used without signing the End User Licence Agreement."
+ redirect_to '/signout'
+ return
+ end
+ num_checkboxes = params[:num_checkboxes].to_i
+ if num_checkboxes > 0
+ num_checks = params.keys.grep(/\Alicense_check/).size
+ if num_checks < num_checkboxes
+ flash[:error] = "There was a problem with your submission. Please read the agreement and check all checkboxes."
+ redirect_to :action => :nh_show_license, :license => @license
+ return
+ end
+ end
+ current_user.accept_license_agreement @license
+ redirect_to :action => :welcome
+ end
+
+ def nh_show_license #:nodoc:
+ @license = params[:license].gsub(/[^\w-]+/, "")
+ # NeuroHub signed licenses to be shown in NeuroHub, CBRAIN signed licenses to be shown in CBRAIN
+ unless @license.start_with? 'nh-'
+ flash[:error] = 'Redirecting to CBRAIN, this license is best viewed via CBRAIN'
+ redirect_to :controller => :portal, :action => :show_license, :license => @license
+ return
+ end
+
+ @is_signed = current_user.custom_licenses_signed.include?(@license_id)
+ render :nh_show_infolicense if @license&.end_with? "_info" # info license does not require to accept it
+ end
+
+end
diff --git a/BrainPortal/app/controllers/portal_controller.rb b/BrainPortal/app/controllers/portal_controller.rb
index fdb65b600..fef0adc58 100644
--- a/BrainPortal/app/controllers/portal_controller.rb
+++ b/BrainPortal/app/controllers/portal_controller.rb
@@ -196,10 +196,21 @@ def portal_log #:nodoc:
def show_license #:nodoc:
@license = params[:license].gsub(/[^\w-]+/, "")
+
+ # to reduce user confusion
+ # NeuroHub signed licenses are showed in NeuroHub, CBRAIN signed licenses are shown in CBRAIN
+ if @license.start_with? 'nh-'
+ flash[:notice] = 'You are redirected to NeuroHub, this license is best viewed via NeuroHub'
+ redirect_to :controller => :neurohub_portal, :action => :nh_show_license, :license => @license
+ return
+ end
+
+ render :show_infolicense if @license&.end_with? "_info" # info license does not require to accept it
end
def sign_license #:nodoc:
@license = params[:license]
+ #todo add @license.length check, max 4k perhaps?
unless params.has_key?(:agree)
flash[:error] = "CBRAIN cannot be used without signing the End User Licence Agreement."
redirect_to "/logout"
@@ -214,10 +225,7 @@ def sign_license #:nodoc:
return
end
end
- signed_agreements = current_user.meta[:signed_license_agreements] || []
- signed_agreements << @license
- current_user.meta[:signed_license_agreements] = signed_agreements
- current_user.addlog("Signed license agreement '#{@license}'.")
+ current_user.accept_license_agreement @license
redirect_to start_page_path
end
diff --git a/BrainPortal/app/models/user.rb b/BrainPortal/app/models/user.rb
index c06063e17..c5643155d 100644
--- a/BrainPortal/app/models/user.rb
+++ b/BrainPortal/app/models/user.rb
@@ -148,18 +148,20 @@ def signed_license_agreements(license_agreement_set=self.license_agreement_set)
self.meta[:signed_license_agreements] || []
end
- def unsigned_license_agreements #:nodoc:
- license_agreement_set = self.license_agreement_set
+ def cbrain_unsigned_license_agreements #:nodoc:
+ # Difference between all cbrain license agreements and signed by the user
+ cbrain_license_agreement_set - (strip_prefix signed_license_agreements)
+ end
- # Difference between all license agreements and whom signed by the user
- license_agreement_set - self.signed_license_agreements(license_agreement_set)
+ def neurohub_unsigned_license_agreements #:nodoc:
+ neurohub_license_agreement_set - (add_prefix signed_license_agreements)
end
- def license_agreement_set #:nodoc:
+ # all NeuroHub and cbrain agreements (on accessible objects)
+ def license_agreement_set
all_object_with_license = RemoteResource.find_all_accessible_by_user(self) +
Tool.find_all_accessible_by_user(self) +
DataProvider.find_all_accessible_by_user(self)
-
license_agreements = []
# List all license_agreements
all_object_with_license.each do |o|
@@ -170,6 +172,17 @@ def license_agreement_set #:nodoc:
RemoteResource.current_resource.license_agreements + license_agreements
end
+ # cbrain required licenses
+ def cbrain_license_agreement_set
+ license_agreement_set.reject {|l| l.start_with?('nh-')}
+ end
+
+ # neurohub license agreement set
+ def neurohub_license_agreement_set
+ RemoteResource.current_resource.license_agreements.select {|l| l.start_with?('nh-')}
+ end
+
+ # a flag that all required cbrain licenses are signed
def all_licenses_signed #:nodoc:
self.meta.reload
self.meta[:all_licenses_signed]
@@ -180,6 +193,25 @@ def all_licenses_signed=(x) #:nodoc:
self.meta[:all_licenses_signed] = x
end
+ # neurohub specific licenses are signed flag
+ def neurohub_licenses_signed #:nodoc:
+ self.meta.reload
+ self.meta['neurohub_licenses_signed']
+ end
+
+ # neurohub specific licenses are signed flag setter
+ def neurohub_licenses_signed=(x) #:nodoc:
+ self.meta.reload
+ self.meta['neurohub_licenses_signed'] = x
+ end
+
+ def accept_license_agreement(license) # logs and saves signed agreement id (either on cbrain or neurohub side)
+ signed_agreements = self.meta[:signed_license_agreements] || []
+ signed_agreements << license
+ self.meta[:signed_license_agreements] = signed_agreements
+ self.addlog("Signed license agreement '#{@license}'.")
+ end
+
#############################################################
#
# Custom, user-created licenses for misc objects
@@ -613,4 +645,20 @@ def add_system_groups #:nodoc:
true
end
+ # strips prefix in a string array
+ def strip_prefix(a, prefix='nh-')
+ a.map {|l| l.sub(/\A#{prefix}/, "")}
+ end
+
+ # add prefix to string array if missing
+ def add_prefix(a, prefix='nh-')
+ a.map do |l|
+ if l.start_with? prefix
+ l
+ else
+ prefix + l
+ end
+ end
+ end
+
end
diff --git a/BrainPortal/app/views/bourreaux/show.html.erb b/BrainPortal/app/views/bourreaux/show.html.erb
index 1327a9cde..3afa19c54 100644
--- a/BrainPortal/app/views/bourreaux/show.html.erb
+++ b/BrainPortal/app/views/bourreaux/show.html.erb
@@ -88,7 +88,10 @@
<% licenses = @bourreau.license_agreements.count == 0 ? "(None)": @bourreau.license_agreements.join("\n") %>
<% t.edit_cell(:license_agreements, :content => licenses) do |f| %>
<%= f.text_area :license_agreements, :value => @bourreau.license_agreements.join("\n"), :rows => 5, :cols => 40 %>
-
Enter one agreement name per line. Note that only alphanumeric characters, underscores (_) and dashes (-) are accepted.
+
Enter one agreement name per line. Note that only alphanumeric characters, underscores (_) and dashes (-) are accepted.
+ the licenses starting with nh- prefix are reserved for NeuroHub. _info suffix indicates optional information
+ which does not oblige user to accept anything. It should be used to communicating important information.
+
<% end %>
<% if is_bourreau %>
diff --git a/BrainPortal/app/views/neurohub_portal/_list_licenses.html.erb b/BrainPortal/app/views/neurohub_portal/_list_licenses.html.erb
new file mode 100644
index 000000000..309af516e
--- /dev/null
+++ b/BrainPortal/app/views/neurohub_portal/_list_licenses.html.erb
@@ -0,0 +1,44 @@
+<%-
+#
+# NeuroHub Project
+#
+# Copyright (C) 2020
+# 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 .
+#
+-%>
+
+<% if licenses.present? %>
+
+<% end %>
diff --git a/BrainPortal/app/views/neurohub_portal/_show_license_text.html.erb b/BrainPortal/app/views/neurohub_portal/_show_license_text.html.erb
new file mode 100644
index 000000000..c0cfcb1c0
--- /dev/null
+++ b/BrainPortal/app/views/neurohub_portal/_show_license_text.html.erb
@@ -0,0 +1,40 @@
+<%-
+#
+# NeuroHub Project
+#
+# Copyright (C) 2020
+# 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 .
+#
+-%>
+
+
diff --git a/BrainPortal/app/views/neurohub_portal/nh_show_infolicense.html.erb b/BrainPortal/app/views/neurohub_portal/nh_show_infolicense.html.erb
new file mode 100644
index 000000000..d4edc5b4e
--- /dev/null
+++ b/BrainPortal/app/views/neurohub_portal/nh_show_infolicense.html.erb
@@ -0,0 +1,60 @@
+<%-
+#
+# NeuroHub Project
+#
+# Copyright (C) 2020
+# 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 .
+#
+-%>
+
+
+ <%= submit_tag "I have read this, Continue to NeuroHub", :name => :agree, :class => "btn-solid primary m-1" %>
+
+
+ <% end %>
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BrainPortal/app/views/neurohub_portal/nh_show_license.html.erb b/BrainPortal/app/views/neurohub_portal/nh_show_license.html.erb
new file mode 100644
index 000000000..df9d01b30
--- /dev/null
+++ b/BrainPortal/app/views/neurohub_portal/nh_show_license.html.erb
@@ -0,0 +1,52 @@
+
+<%-
+ #
+ # NeuroHub Project
+ #
+ # Copyright (C) 2020
+ # 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("License #{@license_id}", '') %>
+
+
diff --git a/BrainPortal/app/views/users/show.html.erb b/BrainPortal/app/views/users/show.html.erb
index 03546fded..69e9c66ab 100644
--- a/BrainPortal/app/views/users/show.html.erb
+++ b/BrainPortal/app/views/users/show.html.erb
@@ -257,9 +257,19 @@
<% end %>
- <% if @user.signed_license_agreements.present? %>
+ <% info_pages, true_licenses = @user.signed_license_agreements.partition { |x| x.end_with?('_info')} %>
+
+ <% if true_licenses.present? %>
<%= show_table(@user, :as => :user, :header => "License Agreements", :width => 3) do |t| %>
- <% @user.signed_license_agreements.each do |la| %>
+ <% true_licenses.each do |la| %>
+ <% t.cell("", :no_header => true) { link_to la, "/show_license/#{la}" } %>
+ <% end %>
+ <% end %>
+ <% end %>
+
+ <% if info_pages.present? %>
+ <%= show_table(@user, :as => :user, :header => "Important Informational and Subscription Pages", :width => 3) do |t| %>
+ <% info_pages.each do |la| %>
<% t.cell("", :no_header => true) { link_to la, "/show_license/#{la}" } %>
<% end %>
<% end %>
diff --git a/BrainPortal/config/routes.rb b/BrainPortal/config/routes.rb
index 00c74a9c0..31c9a131c 100644
--- a/BrainPortal/config/routes.rb
+++ b/BrainPortal/config/routes.rb
@@ -275,6 +275,10 @@
get '/signout' => 'nh_sessions#destroy'
get '/myaccount' => 'nh_users#myaccount'
+ # License routes
+ get '/nh_show_license/:license', :controller => :neurohub_portal, :action => :nh_show_license
+ post '/nh_sign_license/:license', :controller => :neurohub_portal, :action => :nh_sign_license
+
# Globus authentication
get '/nh_globus' => 'nh_sessions#nh_globus'
post '/nh_unlink_globus' => 'nh_sessions#nh_unlink_globus'
diff --git a/BrainPortal/lib/license_agreements.rb b/BrainPortal/lib/license_agreements.rb
index 572920fa7..3cee9ae66 100644
--- a/BrainPortal/lib/license_agreements.rb
+++ b/BrainPortal/lib/license_agreements.rb
@@ -22,6 +22,14 @@
# Module containing common methods for set and access the
# license agreements
+# Cbrain License texts are stored in public/licenses folder.
+# Portal license with id/filename that starts from nh- are shown only on neurohub portal.
+# Note that licenses gpl-1 and nh-gpl-1 are considered equivalent.
+# that is user who already signed nh-gpl-1 does not have to sign gpl_1
+#
+# suffix _info indicates informational page which should be shown just once
+# those pages have 'Continue' button instead of Agree/Disagree
+
module LicenseAgreements
Revision_info=CbrainFileRevision[__FILE__] #:nodoc:
@@ -54,7 +62,7 @@ def license_agreements=(agreements)
unless agrs.is_a? Array
agrs = agrs.to_s.split(/[,\s]+/)
end
- agrs = agrs.map { |a| a.sub(/\.html\z/, "").gsub(/[^\w-]+/, "") }.uniq.sort
+ agrs = agrs.map { |a| a.sub(/\.html\z/, "").gsub(/[^\/\w-]+/, "") }.uniq.sort
@license_agreements = agrs
end
@@ -91,10 +99,11 @@ def register_license_agreements
orig_agreements = (@_license_agreements_original || []).sort
return true if new_agreements == orig_agreements
self.meta[:license_agreements] = license_agreements
- @_license_agreements_original = license_agreements
+ @_license_agreements_original = license_agreements
# Unset all licenses signed when a new license is added
User.all.each do |u|
- u.all_licenses_signed = nil
+ u.all_licenses_signed = nil
+ u.neurohub_licenses_signed = nil
end
true
end
diff --git a/BrainPortal/public/licenses/README.txt b/BrainPortal/public/licenses/README.txt
index 0f96f4d1e..c192d8f81 100644
--- a/BrainPortal/public/licenses/README.txt
+++ b/BrainPortal/public/licenses/README.txt
@@ -1,7 +1,13 @@
This directory is where the CBRAIN administrator can install
-HTML license files that will be presented to the user when
+HTML license and other important information files that will be presented to the user when
logging in. A description of what the HTML files should
contain and how to configure the licenses in CBRAIN can
be found in the documentation.
+The information files which do not require signing should ends
+with _info.html, for example maillist_form_info.html. Files relevant to
+NeuroHub should start with nh- prefix, e.g. nh-Mailist_Subscription_info.html.
+If CBRAIN and NeuroHub files are
+named similiary (save for nh- prefix), they are considered equivalent and
+shown just once. The semantic of double nh- prefix is undefined, avoid it.
diff --git a/BrainPortal/spec/controllers/data_providers_controller_spec.rb b/BrainPortal/spec/controllers/data_providers_controller_spec.rb
index ef14c7465..26a013a90 100644
--- a/BrainPortal/spec/controllers/data_providers_controller_spec.rb
+++ b/BrainPortal/spec/controllers/data_providers_controller_spec.rb
@@ -31,7 +31,7 @@
before(:each) do
allow(controller).to receive(:current_user).and_return(admin_user)
allow(admin_user).to receive(:license_agreement_set).and_return([])
- allow(admin_user).to receive(:unsigned_license_agreements).and_return([])
+ allow(admin_user).to receive(:cbrain_unsigned_license_agreements).and_return([])
session[:user_id] = admin_user.id
session[:session_id] = 'session_id'
end
diff --git a/BrainPortal/spec/controllers/userfiles_controller_spec.rb b/BrainPortal/spec/controllers/userfiles_controller_spec.rb
index 88c5b31df..e64e40427 100644
--- a/BrainPortal/spec/controllers/userfiles_controller_spec.rb
+++ b/BrainPortal/spec/controllers/userfiles_controller_spec.rb
@@ -702,7 +702,7 @@ class << file; attr_reader :tempfile; end
session[:session_id] = 'session_id'
allow(controller).to receive(:current_user).and_return(admin)
allow(admin).to receive(:license_agreement_set).and_return([])
- allow(admin).to receive(:unsigned_license_agreements).and_return([])
+ allow(admin).to receive(:cbrain_unsigned_license_agreements).and_return([])
allow(DataProvider).to receive_message_chain(:find_all_accessible_by_user, :where, :first).and_return(mock_model(DataProvider).as_null_object)
allow(CBRAIN).to receive(:spawn_with_active_records).and_yield
allow(Userfile).to receive(:find_accessible_by_user).and_return(mock_userfile)
diff --git a/BrainPortal/spec/models/user_spec.rb b/BrainPortal/spec/models/user_spec.rb
index 909bc29b4..6e92c42c9 100644
--- a/BrainPortal/spec/models/user_spec.rb
+++ b/BrainPortal/spec/models/user_spec.rb
@@ -192,19 +192,19 @@
- describe "#unsigned_license_agreements" do
+ describe "#cbrain_unsigned_license_agreements" do
before (:each) do
allow(RemoteResource).to receive_message_chain(:current_resource, :license_agreements).and_return(["license1","license2"])
end
it "should return an empty array if user signed all agreements" do
normal_user.meta[:signed_license_agreements] = ["license1","license2"]
- expect(normal_user.unsigned_license_agreements).to eq([])
+ expect(normal_user.cbrain_unsigned_license_agreements).to eq([])
end
it "should return an array with the unsigned agreements" do
normal_user.meta[:signed_license_agreements] = ["license1"]
- expect(normal_user.unsigned_license_agreements).to eq(["license2"])
+ expect(normal_user.cbrain_unsigned_license_agreements).to eq(["license2"])
end
end
diff --git a/cbrain_file_revisions.csv b/cbrain_file_revisions.csv
index a9d46ac4f..40a3eb423 100644
--- a/cbrain_file_revisions.csv
+++ b/cbrain_file_revisions.csv
@@ -283,6 +283,9 @@ ca0d9a40fa5d6ed3dbfb8bea7b6d0e203b022f5a -#- 2022-05-03 17:00:47 -0400 -#- Pierr
5cc2e8488608abd4a90eae0a18cd865f8159147a -#- 2022-04-18 09:34:44 -0400 -#- Pierre Rioux -#- BrainPortal/app/controllers/messages_controller.rb
02ffac07d8fcd0b19875c496d5dbdb865331415b -#- 2022-07-28 12:49:11 -0400 -#- Pierre Rioux -#- BrainPortal/app/controllers/neurohub_application_controller.rb
7c73cae7f8a1a8e78a91ec90566fcd7158620577 -#- 2022-04-16 13:08:30 -0400 -#- Pierre Rioux -#- BrainPortal/app/controllers/neurohub_portal_controller.rb
+fa68a44bee394caedb3ec707819777d44e6d64e6 -#- 2020-11-02 12:30:57 -0500 -#- MontrealSergiy -#- BrainPortal/app/controllers/messages_controller.rb
+fa68a44bee394caedb3ec707819777d44e6d64e6 -#- 2020-11-02 12:30:57 -0500 -#- MontrealSergiy -#- BrainPortal/app/controllers/neurohub_application_controller.rb
+df83dc571792dcee95506b370f2a25f29ba4a627 -#- 2020-07-23 23:30:08 -0400 -#- Natacha Beck -#- BrainPortal/app/controllers/neurohub_portal_controller.rb
783f532abb91f341b2725b6263209513a463a372 -#- 2021-11-24 15:39:35 -0500 -#- Pierre Rioux -#- BrainPortal/app/controllers/nh_invitations_controller.rb
65de15a23183bd21f5fb70cbc77f62cdd2dd07c0 -#- 2023-01-17 17:15:09 -0500 -#- Natacha Beck -#- BrainPortal/app/controllers/nh_loris_hooks_controller.rb
fa68a44bee394caedb3ec707819777d44e6d64e6 -#- 2020-11-02 12:30:57 -0500 -#- MontrealSergiy -#- BrainPortal/app/controllers/nh_messages_controller.rb