diff --git a/BrainPortal/app/controllers/application_controller.rb b/BrainPortal/app/controllers/application_controller.rb
index 6ad51d9b4..7b447dd68 100644
--- a/BrainPortal/app/controllers/application_controller.rb
+++ b/BrainPortal/app/controllers/application_controller.rb
@@ -61,6 +61,7 @@ class ApplicationController < ActionController::Base
protect_from_forgery with: :exception, unless: -> { request.format.json? || request.format.xml? }
+ rescue_from CbrainLicenseException, with: :redirect_show_license
########################################################################
@@ -69,6 +70,15 @@ class ApplicationController < ActionController::Base
private
+
+ def redirect_show_license
+ if params[:id].present? && params[:controller] == "groups"
+ redirect_to show_license_group_path(params[:id])
+ else
+ redirect_to groups_path
+ end
+ end
+
# Re-compute the host and IP from the request (when not logged in, or changed)
def adjust_remote_ip_and_host #:nodoc:
from_ip = cbrain_session[:guessed_remote_ip].presence || '(None)' # what we had previously
diff --git a/BrainPortal/app/controllers/groups_controller.rb b/BrainPortal/app/controllers/groups_controller.rb
index 7ee6f2c33..2d5e32208 100644
--- a/BrainPortal/app/controllers/groups_controller.rb
+++ b/BrainPortal/app/controllers/groups_controller.rb
@@ -33,6 +33,9 @@ class GroupsController < ApplicationController
before_action :license_check, :only => [:show, :create, :switch, :edit, :update, :unregister, :destroy]
+ # few license related attributes are updated here
+ before_action :group_license_attributes, :only => [:show, :new_license, :add_license, :show_license, :sign_license]
+
# GET /groups
# GET /groups.xml
def index #:nodoc:
@@ -268,6 +271,114 @@ def license_redirect #:nodoc:
end
end
+ def new_license #:nodoc:
+ cb_error "Only owner can set licensing", :redirect => { :action => :show } unless @can_add_license
+ end
+
+ def add_license #:nodoc:
+ cb_error("Only owner can set licensing", :redirect => { :action => :show }) unless @can_add_license
+
+ license_text = params[:license_text]
+ cb_error 'Empty licenses are presently not allowed' if license_text.blank?
+
+ timestamp = Time.zone.now.strftime("%Y-%m-%dT%H:%M:%S")
+ group_name = @group.name.gsub(/[^\w]+/, "")
+ file_name = "license_#{group_name}_#{timestamp}.txt"
+ license = @group.register_custom_license(license_text, current_user, file_name)
+ current_user.signs_license_for_project(license, @group, model='group')
+
+ flash[:notice] = 'A license is added. You can force users to sign multiple license agreements if needed.'
+ redirect_to :action => :show
+ end
+
+ def show_license #:nodoc:
+ # @group = @current_user.visible_groups.where(id: params[id]).first
+
+ unsigned_licenses = current_user.unsigned_custom_licenses(@group)
+
+ if unsigned_licenses.empty?
+ if @current_licenses.present?
+ flash[:notice] = 'You already signed all licenses'
+ else
+ flash[:notice] = 'No licenses are defined for this project'
+ redirect_to :action => :show
+ return
+ end
+ end
+
+ # What to show. If a license is given in params,
+ # we make sure it's a registered one and we pick that.
+ @license_id = false unless @current_licenses.include? @license_id
+ # If no valid license was given and there are unsigned licenses, pick the first
+ @license_id ||= unsigned_licenses.first.try(:to_i)
+ # Otherwise, show the first license.
+ @license_id ||= @current_licenses.first
+
+ # Load the text of the license
+ userfile = Userfile.find(@license_id)
+ userfile.sync_to_cache
+ @license_text = userfile.cache_readhandle { |fh| fh.read }
+
+ # Identifies if the current user has already signed it,
+ # and whether they are the author
+ end
+
+ def sign_license #:nodoc:
+
+ unless @group.custom_license_agreements.include?(@license_id)
+ flash[:error] = 'You are trying to access unrelated license. Try again or report the issue to the support.'
+ redirect_to :action => :show
+ return
+ end
+
+ if @is_signed
+ flash[:error] = 'You have already signed this license.'
+ redirect_to :action => :show
+ return
+ end
+
+ unless params.has_key?(:agree)
+ flash[:error] = "You cannot access that project without signing the License Agreement first."
+ redirect_to :action => :index
+ return
+ end
+
+ if params[:license_check].blank? || params[:license_check].to_i == 0
+ flash[:error] = "There was a problem with your submission. Please read the agreement and check the checkbox."
+ redirect_to show_license_group_path(@group)
+ return
+ end
+
+ license = Userfile.find(@license_id)
+ current_user.signs_license_for_project(license, @group, model='group')
+
+ if current_user.unsigned_custom_licenses(@group).empty?
+ flash[:notice] = 'You signed all the project licenses'
+ else
+ flash[:notice] = 'This project has at least one other license agreement'
+ end
+ redirect_to :action => :show, :id => @group.id
+ end
+
+ # check license for project (group) with id pid,
+ def license_check(pid=false)
+ pid = pid || params[:id]
+
+
+ return true if pid == 'all' ## to do && current_user.has_role(:admin)
+ # if unexpected id - let the action method handle the error message
+ begin
+ @group = current_user.viewable_groups.find(pid)
+ rescue ActiveRecord::RecordNotFound
+ return true
+ end
+ if current_user.unsigned_custom_licenses(@group).present?
+ flash[:error] = "Access to the project #{@group.name} is blocked due to licensing issues. Please sign the license"
+ # license_redirect
+ raise CbrainLicenseException
+ end
+ end
+
private
def group_params #:nodoc:
@@ -285,19 +396,14 @@ def group_params #:nodoc:
end
end
- def license_check
- return true if params[:id].blank?
- return true if params[:id] == 'all'
- # if unexpected id - let the action method handle the error message
- begin
- @group = current_user.viewable_groups.find(params[:id])
- rescue ActiveRecord::RecordNotFound
- return true
- end
- if current_user.unsigned_custom_licenses(@group).present?
- flash[:error] = "Access to the project #{@group.name} is blocked due to licensing issues. Please consult with the project maintainer or support for details"
- license_redirect
- end
+ def group_license_attributes # helper updates custom license attribute
+ @group = @current_user.viewable_groups.find(params[:id])
+ @can_add_license = current_user.id == @group&.creator_id
+ @current_licenses = @group.custom_license_agreements
+
+ param_lic_id = params['license_id'].presence
+ @license_id = param_lic_id && param_lic_id.to_i # nil if param is nil-like, otherwise cast to integer
+ @is_signed = current_user.custom_licenses_signed.include?(@license_id)
end
end
diff --git a/BrainPortal/app/controllers/nh_projects_controller.rb b/BrainPortal/app/controllers/nh_projects_controller.rb
index 79df20493..4b267b785 100644
--- a/BrainPortal/app/controllers/nh_projects_controller.rb
+++ b/BrainPortal/app/controllers/nh_projects_controller.rb
@@ -163,7 +163,7 @@ def add_license #:nodoc:
group_name = @nh_project.name.gsub(/[^\w]+/,"")
file_name = "license_#{group_name}_#{timestamp}.txt"
license = @nh_project.register_custom_license(license_text, current_user, file_name)
- user_signs_license_for_project(current_user, license, @nh_project)
+ current_user.signs_license_for_project(license, @nh_project)
flash[:notice] = 'A license is added. You can force users to sign multiple license agreements if needed.'
redirect_to :action => :show
@@ -236,7 +236,7 @@ def sign_license #:nodoc:
end
license = Userfile.find(@license_id)
- user_signs_license_for_project(current_user, license, @nh_project)
+ current_user.signs_license_for_project(license, @nh_project)
if current_user.unsigned_custom_licenses(@nh_project).empty?
flash[:notice] = 'You signed all the project licenses'
@@ -332,14 +332,5 @@ def redirect_show_license
end
end
- # Records that +user+ signed the +license+ file for +project+
- # with nice log messages to that effect.
- def user_signs_license_for_project(user, license, project)
- user.add_signed_custom_license(license)
-
- user.addlog("Signed custom license agreement '#{license.name}' (ID #{license.id}) for project '#{project.name}' (ID #{project.id}).")
- project.addlog("User #{user.login} signed license agreement '#{license.name}' (ID #{license.id}).")
- end
-
end
diff --git a/BrainPortal/app/models/user.rb b/BrainPortal/app/models/user.rb
index c06063e17..a7b820595 100644
--- a/BrainPortal/app/models/user.rb
+++ b/BrainPortal/app/models/user.rb
@@ -203,8 +203,6 @@ def custom_licenses_signed=(licenses) #:nodoc:
self.meta[:custom_licenses_signed] = Array(licenses)
end
- # Records that a custom license agreement has
- # been signed by adding it to the list of signed ones.
def add_signed_custom_license(license_file)
cb_error "A license file is supposed to be a TextFile" unless license_file.is_a?(TextFile)
signed = self.custom_licenses_signed
@@ -213,6 +211,15 @@ def add_signed_custom_license(license_file)
self.custom_licenses_signed = signed
end
+ # Records that +user+ signed the +license+ file for +project+
+ # with nice log messages to that effect. When signed on CBRAIN model should be 'group' and 'project' on NeuroHub's
+ def signs_license_for_project(license, project, model='project')
+ self.add_signed_custom_license(license)
+ self.addlog("Signed custom license agreement '#{license.name}' (ID #{license.id}) for #{model} '#{project.name}' (ID #{project.id}).")
+ project.addlog("User #{self.login} signed license agreement '#{license.name}' (ID #{license.id}).")
+ end
+
+
###############################################
#
# Password and login gestion
diff --git a/BrainPortal/app/views/groups/_show_license_text.html.erb b/BrainPortal/app/views/groups/_show_license_text.html.erb
new file mode 100644
index 000000000..ac546dccf
--- /dev/null
+++ b/BrainPortal/app/views/groups/_show_license_text.html.erb
@@ -0,0 +1,42 @@
+
+<%-
+ #
+ # 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
Carefully read this license agreement.
+<%= @license_text %>+ <% if @is_signed %> + <% if @is_author %> +
+ +
++ <%= text_area_tag "license_text", "", :required => true, :rows => 20, :class => "whole_width" %> + +
+
@@ -165,6 +170,28 @@
<% end %>
<% end %>
+
+
+
+
+ <% if @current_licenses.size > 0 %>
+
+ <% default_text = array_to_table(@current_licenses, :table_class => 'simple bordered float_left', :cols => 20, :min_data => 20, :fill_by_columns => true ) {|id, r, c|
+ link_to "License ##{id}", show_license_group_path(:group_id => @group.id, :license_id => id)
+ } %>
+
+
+ <%= show_table(@group, :as => :group, :header => 'Project License Agreements', :edit_condition => false) do |t| %>
+ <% t.edit_cell(:licenses, :show_width => 2,
+ :header => 'Licenses',
+ :content => default_text) do %>
+
+ <% end %>
+ <% end %>
+
+ <% end %>
+
+
<% if @group.can_be_edited_by?(current_user) %>
@@ -172,3 +199,5 @@
<%= render :partial => "layouts/log_report", :locals => { :log => @group.getlog, :title => 'Project Log' } %>
<% end %>
+
+
diff --git a/BrainPortal/app/views/groups/show_license.html.erb b/BrainPortal/app/views/groups/show_license.html.erb
new file mode 100644
index 000000000..0b5e03b4f
--- /dev/null
+++ b/BrainPortal/app/views/groups/show_license.html.erb
@@ -0,0 +1,78 @@
+
+<%-
+#
+# CBRAIN 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
+ + <%#= render :partial => 'show_license_text' %> + +
<%= @license_text %>+ + <% unless @is_signed %> +
+ <%= check_box_tag :license_check, 1, nil, :class => "my-2" %> + By clicking here, I agree with all the conditions above. +
++ <%= submit_tag "I agree with the above statement", :name => :agree, :class => "button" %> + <%= submit_tag "I do not agree", :name => :not_agree, :class => "button" %> +
+ <% end %> + <% end %> ++ Licenses for the project <%= @group.name %> +
+Important: All members of the project will be required to sign the agreement in order to access the project. You, as the author, will be be considered as having signed it implicitly.
+Important: All members of the project will be required to sign the agreement in order to access the project. You, as the author, will be considered as having signed it implicitly.